void UART_irq(uart *u) { if (u->hw == 0) return; if ((UART_CHECK_RX(u)) && (UART_HW(u)->CR1 & USART_CR1_RXNEIE)) { u8_t c = USART_ReceiveData(UART_HW(u)); u->rx.buf[u->rx.wix++] = c; if (u->rx.wix >= UART_RX_BUFFER) { u->rx.wix = 0; } if (u->rx_f) { u->rx_f(u->arg, c); } } if ((UART_CHECK_TX(u))) { if (UART_ALWAYS_SYNC_TX || u->sync_tx) { USART_ITConfig(UART_HW(u), USART_IT_TXE, DISABLE); } else { if (u->tx.wix != u->tx.rix) { USART_SendData(UART_HW(u), u->tx.buf[u->tx.rix++]); if (u->tx.rix >= UART_TX_BUFFER) { u->tx.rix = 0; } } if (u->tx.wix == u->tx.rix) { UART_TX_IRQ_OFF(u); } } } if (UART_CHECK_OR(u)) { (void)USART_ReceiveData(UART_HW(u)); } }
bool UART_config(uart *uart, u32_t baud, UART_databits databits, UART_stopbits stopbits, UART_parity parity, UART_flowcontrol flowcontrol, bool activate) { USART_InitTypeDef cfg; USART_Cmd(UART_HW(uart), DISABLE); if (activate) { cfg.USART_BaudRate = baud; switch (databits) { case UART_DATABITS_8: cfg.USART_WordLength = USART_WordLength_8b; break; case UART_DATABITS_9: cfg.USART_WordLength = USART_WordLength_9b; break; default: return FALSE; } switch (stopbits) { case UART_STOPBITS_0_5: cfg.USART_StopBits = USART_StopBits_0_5; break; case UART_STOPBITS_1: cfg.USART_StopBits = USART_StopBits_1; break; case UART_STOPBITS_1_5: cfg.USART_StopBits = USART_StopBits_1_5; break; case UART_STOPBITS_2: cfg.USART_StopBits = USART_StopBits_2; break; default: return FALSE; } switch (parity) { case UART_PARITY_NONE: cfg.USART_Parity = USART_Parity_No; break; case UART_PARITY_EVEN: cfg.USART_Parity = USART_Parity_Even; break; case UART_PARITY_ODD: cfg.USART_Parity = USART_Parity_Odd; break; default: return FALSE; } switch (flowcontrol) { case UART_FLOWCONTROL_NONE: cfg.USART_HardwareFlowControl = USART_HardwareFlowControl_None; break; case UART_FLOWCONTROL_RTS: cfg.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS; break; case UART_FLOWCONTROL_CTS: cfg.USART_HardwareFlowControl = USART_HardwareFlowControl_CTS; break; case UART_FLOWCONTROL_RTS_CTS: cfg.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; break; default: return FALSE; } cfg.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(UART_HW(uart), &cfg); // Enable USART interrupts USART_ITConfig(UART_HW(uart), USART_IT_TC, DISABLE); USART_ITConfig(UART_HW(uart), USART_IT_TXE, DISABLE); USART_ITConfig(UART_HW(uart), USART_IT_RXNE, ENABLE); USART_Cmd(UART_HW(uart), ENABLE); } else { USART_ITConfig(UART_HW(uart), USART_IT_TC, DISABLE); USART_ITConfig(UART_HW(uart), USART_IT_TXE, DISABLE); USART_ITConfig(UART_HW(uart), USART_IT_RXNE, DISABLE); USART_Cmd(UART_HW(uart), DISABLE); } return TRUE; }
void UART_irq(uart *u) { if (u->hw == NULL) return; if (UART_CHECK_RX(u) && UART_IS_RX_IRQ_ON(u)) { u8_t c = UART_HW(u)->RDR; u->rx.buf[u->rx.wix++] = c; if (u->rx.wix >= UART_RX_BUFFER) { u->rx.wix = 0; } // not needed acc to spec __HAL_UART_SEND_REQ(UART_HW(u), UART_RXDATA_FLUSH_REQUEST); if (u->rx_f) { u->rx_f(u->arg, c); } } if (UART_CHECK_TX(u)) { if (UART_ALWAYS_SYNC_TX || u->sync_tx) { //_UART_DISABLE_IT(UART_HW(u), USART_IT_TXE); //UART_SET_TX_IRQ_OFF(u); _UART_DISABLE_IT(UART_HW(u), USART_IT_TC); } else { if (u->tx.wix != u->tx.rix) { UART_HW(u)->TDR = u->tx.buf[u->tx.rix++]; if (u->tx.rix >= UART_TX_BUFFER) { u->tx.rix = 0; } } if (u->tx.wix == u->tx.rix) { UART_SET_TX_IRQ_OFF(u); _UART_DISABLE_IT(UART_HW(u), USART_IT_TXE); _UART_DISABLE_IT(UART_HW(u), USART_IT_TC); } } } // TODO //if (UART_CHECK_OR(u)) { // __HAL_UART_CLEAR_IT(UART_HW(u), UART_CLEAR_OREF); //} }
bool UART_config(uart *uart, u32_t baud, UART_databits databits, UART_stopbits stopbits, UART_parity parity, UART_flowcontrol flowcontrol, bool activate) { UART_HW(uart)->CR1 &= ~USART_CR1_UE; // disable uart if (activate) { u32_t sdatabits = 0; u32_t sstopbits = 0; u32_t sparity = 0; u32_t sflowcontrol = 0; uint16_t usartdiv = 0x0000; UART_ClockSourceTypeDef clocksource = UART_CLOCKSOURCE_UNDEFINED; switch (databits) { case UART_DATABITS_8: sdatabits = USART_WORDLENGTH_8B; break; case UART_DATABITS_9: sdatabits = USART_WORDLENGTH_9B; break; default: return FALSE; } switch (stopbits) { case UART_STOPBITS_0_5: sstopbits = USART_STOPBITS_1; break; case UART_STOPBITS_1: sstopbits = USART_STOPBITS_1; break; case UART_STOPBITS_1_5: sstopbits = USART_STOPBITS_1_5; break; case UART_STOPBITS_2: sstopbits = USART_STOPBITS_2; break; default: return FALSE; } switch (parity) { case UART_PARITY_NONE: sparity = USART_PARITY_NONE; break; case UART_PARITY_EVEN: sparity = USART_PARITY_EVEN; break; case UART_PARITY_ODD: sparity = USART_PARITY_ODD; break; default: return FALSE; } switch (flowcontrol) { case UART_FLOWCONTROL_NONE: sflowcontrol = UART_HWCONTROL_NONE; break; case UART_FLOWCONTROL_CTS: sflowcontrol = UART_HWCONTROL_CTS; break; case UART_FLOWCONTROL_RTS: sflowcontrol = UART_HWCONTROL_RTS; break; case UART_FLOWCONTROL_RTS_CTS: sflowcontrol = UART_HWCONTROL_RTS_CTS; break; default: return FALSE; } UART_HW(uart)->CR1 = 0; UART_HW(uart)->CR2 = 0; UART_HW(uart)->CR3 = 0; /*-------------------------- USART CR1 Configuration -----------------------*/ MODIFY_REG(UART_HW(uart)->CR1, USART_CR1_FIELDS, sdatabits | sparity | USART_CR1_OVER8 | USART_CR1_RE | USART_CR1_TE); /*---------------------------- USART CR2 Configuration ---------------------*/ MODIFY_REG(UART_HW(uart)->CR2, USART_CR2_STOP, sstopbits); UART_HW(uart)->CR2 &= ~USART_CR2_LINEN; /*-------------------------- USART CR3 Configuration -----------------------*/ MODIFY_REG(UART_HW(uart)->CR3, (USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT), sflowcontrol); _UART_GETCLOCKSOURCE(UART_HW(uart), clocksource); switch (clocksource) { case UART_CLOCKSOURCE_PCLK1: usartdiv = (uint16_t)(_UART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), baud)); break; case UART_CLOCKSOURCE_PCLK2: usartdiv = (uint16_t)(_UART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), baud)); break; case UART_CLOCKSOURCE_HSI: usartdiv = (uint16_t)(_UART_DIV_SAMPLING8(HSI_VALUE, baud)); break; case UART_CLOCKSOURCE_SYSCLK: usartdiv = (uint16_t)(_UART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), baud)); break; case UART_CLOCKSOURCE_LSE: usartdiv = (uint16_t)(_UART_DIV_SAMPLING8(LSE_VALUE, baud)); break; case UART_CLOCKSOURCE_UNDEFINED: default: return FALSE; break; } u32_t brrtemp = usartdiv & 0xFFF0; brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U); UART_HW(uart)->BRR = brrtemp; // enable usart interrupts _UART_ENABLE_IT(UART_HW(uart), USART_IT_TC); _UART_ENABLE_IT(UART_HW(uart), USART_IT_TXE); _UART_ENABLE_IT(UART_HW(uart), USART_IT_RXNE); UART_HW(uart)->CR1 |= USART_CR1_UE; // enable uart } else {
void UART_tx_force_char(uart *u, u8_t c) { while (UART_CHECK_TX(u) == 0) ; UART_HW(u)->TDR = (uint8_t) c; }
void UART_tx_force_char(uart *u, u8_t c) { while (UART_CHECK_TX(u) == 0) ; USART_SendData(UART_HW(u), (uint8_t) c); }