int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint) #endif { // DMA usage is currently ignored (void) hint; // Check buffer is ok MBED_ASSERT(tx != (void*)0); MBED_ASSERT(tx_width == 8); // support only 8b width if (tx_length == 0) return 0; // Set up buffer h_serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width); // Set up events h_serial_tx_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events h_serial_tx_enable_event(obj, event, 1); // Set only the wanted events UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; // Enable interrupt IRQn_Type irqn = h_serial_get_irq_index(obj); NVIC_ClearPendingIRQ(irqn); NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 1); NVIC_SetVector(irqn, (uint32_t)handler); NVIC_EnableIRQ(irqn); #if DEVICE_SERIAL_ASYNCH_DMA // Enable DMA interrupt irqn = h_serial_tx_get_irqdma_index(obj); NVIC_ClearPendingIRQ(irqn); NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 1); NVIC_SetVector(irqn, (uint32_t)handler); NVIC_EnableIRQ(irqn); // the following function will enable program and enable the DMA transfer if (HAL_UART_Transmit_DMA(handle, (uint8_t*)tx, tx_length) != HAL_OK) { /* Transfer error in transmission process */ return 0; } #else // the following function will enable UART_IT_TXE and error interrupts if (HAL_UART_Transmit_IT(handle, (uint8_t*)tx, tx_length) != HAL_OK) { /* Transfer error in transmission process */ return 0; } #endif DEBUG_PRINTF("UART%u: Tx: 0=(%u, %u) %x\n", obj->serial.module+1, tx_length, tx_width, HAL_UART_GetState(handle)); return tx_length; }
/** Begin asynchronous TX transfer. The used buffer is specified in the serial object, * tx_buff * * @param obj The serial object * @param tx The buffer for sending * @param tx_length The number of words to transmit * @param tx_width The bit width of buffer word * @param handler The serial handler * @param event The logical OR of events to be registered * @param hint A suggestion for how to use DMA with this transfer * @return Returns number of data transfered, or 0 otherwise */ int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint) { // Check buffer is ok MBED_ASSERT(tx != (void*)0); MBED_ASSERT(tx_width == 8); // support only 8b width if (tx_length == 0) return 0; // Set up buffer h_serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width); // Set up events h_serial_tx_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events h_serial_tx_enable_event(obj, event, 1); // Set only the wanted events // Enable interrupt IRQn_Type irqn = h_serial_get_irq_index(obj); NVIC_ClearPendingIRQ(irqn); NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 1); NVIC_SetVector(irqn, (uint32_t)handler); UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart); NVIC_EnableIRQ(irqn); #if DEVICE_SERIAL_ASYNCH_DMA // Enable DMA interrupt irqn = h_serial_tx_get_irqdma_index(obj); NVIC_ClearPendingIRQ(irqn); NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 1); // NVIC_SetVector(irqn, (uint32_t)&h_serial_txdma_irq_handler_asynch); NVIC_SetVector(irqn, (uint32_t)handler); NVIC_EnableIRQ(irqn); // the following function will enable program and enable the DMA transfer if (HAL_UART_Transmit_DMA(&UartHandle, (uint8_t*)tx, tx_length) != HAL_OK) { /* Transfer error in transmission process */ return 0; } #else // the following function will enable UART_IT_TXE and error interrupts if (HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)tx, tx_length) != HAL_OK) { /* Transfer error in transmission process */ return 0; } #endif return tx_length; }
/** Begin asynchronous RX transfer (enable interrupt for data collecting) * The used buffer is specified in the serial object - rx_buff * * @param obj The serial object * @param rx The buffer for sending * @param rx_length The number of words to transmit * @param rx_width The bit width of buffer word * @param handler The serial handler * @param event The logical OR of events to be registered * @param handler The serial handler * @param char_match A character in range 0-254 to be matched * @param hint A suggestion for how to use DMA with this transfer */ void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint) { // DMA usage is currently ignored (void) hint; /* Sanity check arguments */ MBED_ASSERT(obj); MBED_ASSERT(rx != (void*)0); MBED_ASSERT(rx_width == 8); // support only 8b width h_serial_rx_enable_event(obj, SERIAL_EVENT_RX_ALL, 0); h_serial_rx_enable_event(obj, event, 1); // set CharMatch if (char_match != SERIAL_RESERVED_CHAR_MATCH) { obj->char_match = char_match; } h_serial_rx_buffer_set(obj, rx, rx_length, rx_width); IRQn_Type irqn = h_serial_get_irq_index(obj); NVIC_ClearPendingIRQ(irqn); NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 0); NVIC_SetVector(irqn, (uint32_t)handler); NVIC_EnableIRQ(irqn); UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; // flush current data + error flags __HAL_UART_CLEAR_PEFLAG(handle); #if DEVICE_SERIAL_ASYNCH_DMA // Enable DMA interrupt irqn = h_serial_rx_get_irqdma_index(obj); NVIC_ClearPendingIRQ(irqn); NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 1); NVIC_SetVector(irqn, (uint32_t)handler); NVIC_EnableIRQ(irqn); // following HAL function will program and enable the DMA transfer MBED_UART_Receive_DMA(handle, (uint8_t*)rx, rx_length); #else // following HAL function will enable the RXNE interrupt + error interrupts HAL_UART_Receive_IT(handle, (uint8_t*)rx, rx_length); #endif /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_UART_ENABLE_IT(handle, UART_IT_ERR); DEBUG_PRINTF("UART%u: Rx: 0=(%u, %u, %u) %x\n", obj->serial.module+1, rx_length, rx_width, char_match, HAL_UART_GetState(handle)); return; }