1
void setup_crsf_serial_port(uint32_t baud,crsf_read_cb_t read_cb) { if(g_crsf_read_callback==0) { g_crsf_read_callback = read_cb; //uart_single_init(bdrate,DEFAULT_SYSTEM_CLOCK,bdrate);//Set single wire mode. SIM->SCGC4 |= SIM_SCGC4_UART2_MASK;// Enable the clock to the selected UART /* Make sure that the transmitter and receiver are disabled while we * change settings.*/ UART2->C2 &= ~(UART_C2_TE_MASK|UART_C2_RE_MASK); /* Configure single wire , 8-bit mode, no parity*/ UART2->C1 |= (UART_C1_LOOPS_MASK | UART_C1_RSRC_MASK); /* Calculate baud settings */ uint16_t sbr = (uint16_t)(DEFAULT_SYSTEM_CLOCK/2/(baud *16)); /* Save off the current value of the UARTx_BDH except for the SBR field */ /* Save off the current value of the UARTx_BDH except for the SBR field */ uint8_t temp = UART2->BDH & (~UART_BDH_SBR(0x1F)); UART2->BDH= temp | UART_BDH_SBR(((sbr & 0x1F00) >> 8)); UART2->BDL = (uint8_t)(sbr & UART_BDL_SBR_MASK); #if 0 /* Determine if a fractional divider is needed to get closer to the baud rate */ uint16_t brfa = (((DEFAULT_SYSTEM_CLOCK*32000)/(baud * 16)) - (sbr * 32)); /* Save off the current value of the UARTx_C4 register except for the BRFA field */ temp = UART2->C4 & ~(0x1F); UART2->C4 = temp | brfa; #endif /* Enable receiver and transmitter, and enable receive */ UART2->C2 |= (UART_C2_TE_MASK|UART_C2_RE_MASK); //uart inverted UART2->C3 |= UART_C3_TXINV_MASK; UART2->S2 |= UART_S2_RXINV_MASK; NVIC_EnableIRQ(UART2_IRQn); } } bool uart_clear_error() { bool has_error = false; if(UART2->S1 & UART_S1_OR_MASK ) { //To clear OR,write a logic 1 to the OR flag. UART2->S1 |= UART_S1_OR_MASK; has_error = true ; } //clear all if( UART2->S1 & UART_S1_FE_MASK ) { UART2->S1 |= UART_S1_FE_MASK; has_error = true ; } if( UART2->S1 & UART_S1_PF_MASK ) { UART2->S1 |= UART_S1_PF_MASK; has_error = true ; } if( UART2->S1 & UART_S1_NF_MASK ) { UART2->S1 |=UART_S1_NF_MASK; has_error = true ; } return has_error; } uint8_t *g_crsf_send_buf= 0; uint32_t g_crsf_send_len = 0; uint32_t g_crsf_send_pos = 0; void crsf_send_data(uint8_t *buf, uint32_t len) { uint8_t dat; cli(); //while(!(UART2->S1&UART_S1_TDRE_MASK)); //while(!(UART2->S1 & UART_S1_TC_MASK)); // PTE->PDDR |= 1C2 &=~(UART_C2_RIE_MASK); UART2->C3 &=~(UART_C3_ORIE_MASK); UART2->C3 |= UART_C3_TXDIR_MASK; #if USE_IE_UART_TX g_crsf_send_buf = buf; g_crsf_send_len = len; g_crsf_send_pos =0; UART2->C2 |= UART_C2_TIE_MASK; #else for(int i=0;iS1&UART_S1_TDRE_MASK)); UART2->D = buf[i]; } while(!(UART2->S1 & UART_S1_TC_MASK)) { } UART2->C3 &= ~UART_C3_TXDIR_MASK; /* Configure the module1 TXD pin as an input */ // PTE->PDDR &= ~(1C3 &= ~UART_C3_TXDIR_MASK; UART2->C2 |=UART_C2_RIE_MASK; #endif // UART_EnableInterrupts(UART2, kUART_RxDataRegFullInterruptEnable| kUART_RxOverrunInterruptEnable); sei(); } #if 1 void UART2_IRQHandler(void ) { #if USE_IE_UART_TX if(!UART2->C3 & UART_C3_TXDIR_MASK) #endif { uint8_t dat; if(uart_clear_error()) { dat = UART2->D; return; } } if(UART2->S1 & UART_S1_RDRF_MASK) { uint8_t dat = UART2->D; if(g_crsf_read_callback) { (*g_crsf_read_callback)(dat); } } #if USE_IE_UART_TX else if(UART2->S1 & UART_S1_TDRE_MASK) { if(g_crsf_send_pos < g_crsf_send_len) { UART2->D = g_crsf_send_buf[g_crsf_send_pos++]; } else{ while(!(UART2->S1 & UART_S1_TC_MASK)) { } UART2->C2 &= ~UART_C2_TIE_MASK; UART2->C3 &= ~UART_C3_TXDIR_MASK; UART2->C2 |=UART_C2_RIE_MASK; } } #endif } #endif void shutdown_crsf_serial_port() { if( g_crsf_read_callback != NULL) { g_crsf_read_callback = NULL; UART2->C2 &= ~(UART_C2_RE_MASK|UART_C2_RIE_MASK|UART_C2_TE_MASK|UART_C2_TIE_MASK); UART2->C3 &=~(UART_C3_ORIE_MASK); NVIC_DisableIRQ(UART2_IRQn); SIM->SCGC4 &=~SIM_SCGC4_UART2_MASK; } } int crsf_is_sending() { if(UART2->C3 & UART_C3_TXDIR_MASK) return 1; return 0; }