void USART6_IRQHandler( void ) { // Clear all interrupts. It's safe to do so because only RXNE interrupt is enabled USART6->SR = (uint16_t) (USART6->SR | 0xffff); // Update tail uart_interfaces[ STM32_UART_6 ].rx_buffer->tail = uart_interfaces[ STM32_UART_6 ].rx_buffer->size - uart_mapping[ STM32_UART_6 ].rx_dma_stream->NDTR; // Notify thread if sufficient data are available if ( ( uart_interfaces[ STM32_UART_6 ].rx_size > 0 ) && ( ring_buffer_used_space( uart_interfaces[ STM32_UART_6 ].rx_buffer ) >= uart_interfaces[ STM32_UART_6 ].rx_size ) ) { #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &uart_interfaces[ STM32_UART_6 ].rx_complete ); #else uart_interfaces[ STM32_UART_1 ].rx_complete = true; #endif uart_interfaces[ STM32_UART_6 ].rx_size = 0; } #ifndef NO_MICO_RTOS if(uart_interfaces[ STM32_UART_6 ].sem_wakeup) mico_rtos_set_semaphore(&uart_interfaces[ STM32_UART_6 ].sem_wakeup); #endif }
uint8_t ring_buffer_is_full(ring_buffer_t *ring_buffer) { if (ring_buffer_used_space(ring_buffer) >= ring_buffer->size - 1) return 1; else return 0; }
void platform_uart_irq( platform_uart_driver_t* driver ) { platform_uart_port_t* uart = (platform_uart_port_t*) driver->peripheral->port; // Clear all interrupts. It's safe to do so because only RXNE interrupt is enabled uart->SR = (uint16_t) ( uart->SR | 0xffff ); // Update tail driver->rx_buffer->tail = driver->rx_buffer->size - driver->peripheral->rx_dma_config.stream->NDTR; // Notify thread if sufficient data are available if ( ( driver->rx_size > 0 ) && ( ring_buffer_used_space( driver->rx_buffer ) >= driver->rx_size ) ) { #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &driver->rx_complete ); #else driver->rx_complete = true; #endif driver->rx_size = 0; } #ifndef NO_MICO_RTOS if( driver->sem_wakeup ) mico_rtos_set_semaphore( &driver->sem_wakeup ); #endif }
OSStatus platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms ) { OSStatus err = kNoErr; //platform_mcu_powersave_disable(); require_action_quiet( ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ), exit, err = kParamErr); mico_rtos_get_semaphore( &driver->rx_complete, 0 ); if ( driver->rx_buffer != NULL) { while ( expected_data_size != 0 ) { uint32_t transfer_size = MIN( driver->rx_buffer->size / 2, expected_data_size ); /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->last_receive_result = kNoErr; driver->rx_size = transfer_size; /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( driver->rx_buffer ) ) { err = mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms ); /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ driver->rx_size = 0; if( err != kNoErr ) goto exit; }else { driver->rx_size = 0; } err = driver->last_receive_result; expected_data_size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; ring_buffer_get_data( driver->rx_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data_in, available_data, bytes_available ); transfer_size -= bytes_available; data_in = ( (uint8_t*) data_in + bytes_available ); ring_buffer_consume( driver->rx_buffer, bytes_available ); } while ( transfer_size != 0 ); } } else { err = receive_bytes( driver, data_in, expected_data_size, timeout_ms ); } exit: //platform_mcu_powersave_enable(); return err; }
uint32_t MicoUartGetLengthInBuffer( mico_uart_t uart ) { if(uart_mapping[uart].uart == FUART) return ring_buffer_used_space( uart_interfaces[uart].rx_buffer ); else if(uart_mapping[uart].uart == BUART){ return BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); } return 0; }
OSStatus platform_uart_get_length_in_buffer( platform_uart_driver_t* driver ) { if( driver->peripheral->uart == FUART ) return ring_buffer_used_space( driver->rx_buffer ); else if( driver->peripheral->uart == BUART ){ return BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); } return 0; }
void platform_uart_irq( platform_uart_driver_t* driver ) { uint32_t status = usart_get_status( driver->peripheral->peripheral ); uint32_t mask = usart_get_interrupt_mask( driver->peripheral->peripheral ); Pdc* pdc_register = usart_get_pdc_base( driver->peripheral->peripheral ); /* ENDTX flag is set when Tx DMA transfer is done */ if ( ( mask & US_IMR_ENDTX ) && ( status & US_CSR_ENDTX ) ) { pdc_packet_t dma_packet; /* ENDTX is cleared when TCR or TNCR is set to a non-zero value, which effectively * starts another Tx DMA transaction. To work around this, disable Tx before * performing a dummy Tx init. */ pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->peripheral ), PERIPH_PTCR_TXTDIS ); dma_packet.ul_addr = (uint32_t)0; dma_packet.ul_size = (uint32_t)1; pdc_tx_init( usart_get_pdc_base( USART1 ), &dma_packet, NULL ); /* Notifies waiting thread that Tx DMA transfer is complete */ host_rtos_set_semaphore( &driver->tx_dma_complete, WICED_TRUE ); } /* ENDRX flag is set when RCR is 0. RNPR and RNCR values are then copied into * RPR and RCR, respectively, while the Tx tranfer continues. We now need to * prepare RNPR and RNCR for the next iteration. */ if ( ( mask & US_IMR_ENDRX ) && ( status & US_CSR_ENDRX ) ) { pdc_register->PERIPH_RNPR = (uint32_t)driver->rx_ring_buffer->buffer; pdc_register->PERIPH_RNCR = (uint32_t)driver->rx_ring_buffer->size; } /* RXRDY interrupt is triggered and flag is set when a new character has been * received but not yet read from the US_RHR. When this interrupt executes, * the DMA engine already read the character out from the US_RHR and RXRDY flag * is no longer asserted. The code below updates the ring buffer parameters * to keep them current */ if ( mask & US_CSR_RXRDY ) { driver->rx_ring_buffer->tail = driver->rx_ring_buffer->size - pdc_register->PERIPH_RCR; // Notify thread if sufficient data are available if ( ( driver->rx_transfer_size > 0 ) && ( ring_buffer_used_space( driver->rx_ring_buffer ) >= driver->rx_transfer_size ) ) { host_rtos_set_semaphore( &driver->rx_dma_complete, WICED_TRUE ); driver->rx_transfer_size = 0; } } }
void FuartInterrupt(void) { int status; uint8_t rxData; status = FuartIOctl(UART_IOCTL_RXSTAT_GET,0); if(status & 0x1E){ /* * clear FIFO before clear other flags */ FuartIOctl(UART_IOCTL_RXFIFO_CLR,0); /* * clear other error flags */ FuartIOctl(UART_IOCTL_RXINT_CLR,0); } if(status & 0x01) { //or,you can receive them in the interrupt directly while(FuartRecvByte(&rxData) > 0){ ring_buffer_write( uart_interfaces[ AP80xx_FUART ].rx_buffer, &rxData,1 ); } FuartIOctl(UART_IOCTL_RXINT_CLR,0); // Notify thread if sufficient data are available if ( ( uart_interfaces[ 0 ].rx_size > 0 ) && ( ring_buffer_used_space( uart_interfaces[ AP80xx_FUART ].rx_buffer ) >= uart_interfaces[ AP80xx_FUART ].rx_size ) ) { #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &uart_interfaces[ AP80xx_FUART ].rx_complete ); #else uart_interfaces[ AP80xx_FUART ].rx_complete = true; #endif uart_interfaces[ AP80xx_FUART ].rx_size = 0; } } if(FuartIOctl(UART_IOCTL_TXSTAT_GET,0) & 0x01) { FuartIOctl(UART_IOCTL_TXINT_CLR,0); #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &uart_interfaces[ AP80xx_FUART ].tx_complete ); #else uart_interfaces[ AP80xx_FUART ].tx_complete = true; #endif } }
uint32_t MicoUartGetLengthInBuffer( mico_uart_t uart ) { #if RING_BUFF_ON return ring_buffer_used_space( uart_interfaces[uart].rx_buffer ); #else uart_state_t * uState = &uartState; uint32_t len = 0; len = uState->pRxSize; if(len != 0){ uState->pRxSize = 0; } return len; // return 0; //test #endif }
void platform_uart_irq( platform_uart_driver_t* driver ) { platform_uart_port_t* uart = (platform_uart_port_t*) driver->interface->uart_base; uint8_t data=0; while (Chip_UART_GetLineStatus(uart) & UART_LSR_RDR) { Chip_UART_ReceiveByte(uart,&data); ring_buffer_write( driver->rx_buffer,&data, 1 ); } // Notify thread if sufficient data are available if ( ( driver->rx_size > 0 ) && ( ring_buffer_used_space( driver->rx_buffer ) >= driver->rx_size ) ) { host_rtos_set_semaphore( &driver->rx_complete, WICED_TRUE ); driver->rx_size = 0; } }
void USARTx_IRQHandler( void ) { // Clear all interrupts. It's safe to do so because only RXNE interrupt is enabled USARTx->SR = (uint16_t) (USARTx->SR | 0xffff); // Update tail rx_buffer.tail = rx_buffer.size - UART_RX_DMA_Stream->NDTR; // Notify thread if sufficient data are available if ( ( rx_size > 0 ) && ( ring_buffer_used_space( &rx_buffer ) >= rx_size ) && sem_init ) { mico_rtos_set_semaphore( &rx_complete ); rx_size = 0; } #ifdef MCULowPowerMode mico_rtos_set_semaphore(&wakeup); #endif }
int UART_Recv(u8 *recvBuf, u32 bufLen, u32 timeOut) { while (bufLen != 0){ uint32_t transfer_size = MIN(rx_buffer.size / 2, bufLen); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( &rx_buffer ) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ rx_size = transfer_size; if ( mico_rtos_get_semaphore( &rx_complete, timeOut ) != 0 ){ rx_size = 0; return -1; } /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ rx_size = 0; } bufLen -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; ring_buffer_get_data( &rx_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( recvBuf, available_data, bytes_available ); transfer_size -= bytes_available; recvBuf = ( (uint8_t*) recvBuf + bytes_available ); ring_buffer_consume( &rx_buffer, bytes_available ); } while ( transfer_size != 0 ); } if ( bufLen != 0 ) { return -1; } else{ return 0; } }
wiced_result_t ring_buffer_read( wiced_ring_buffer_t* ring_buffer, uint8_t* data, uint32_t data_length, uint32_t* number_of_bytes_read ) { uint32_t max_bytes_to_read; uint32_t i; uint32_t head = ring_buffer->head; wiced_assert("Bad args", ring_buffer != NULL && data != NULL && number_of_bytes_read != NULL); max_bytes_to_read = MIN(data_length, ring_buffer_used_space(ring_buffer)); if ( max_bytes_to_read != 0 ) { for ( i = 0; i != max_bytes_to_read; i++, ( head = ( head + 1 ) % ring_buffer->size ) ) { data[ i ] = ring_buffer->buffer[ head ]; } ring_buffer_consume( ring_buffer, max_bytes_to_read ); } *number_of_bytes_read = max_bytes_to_read; return WICED_SUCCESS; }
int ring_buffer_read( ring_buffer_t* ring_buffer, uint8_t* data, uint32_t data_length, uint32_t* number_of_bytes_read ) { uint32_t max_bytes_to_read; uint32_t i; uint32_t head; head = ring_buffer->head; max_bytes_to_read = MIN(data_length, ring_buffer_used_space(ring_buffer)); if ( max_bytes_to_read != 0 ) { for ( i = 0; i != max_bytes_to_read; i++, ( head = ( head + 1 ) % ring_buffer->size ) ) { data[ i ] = ring_buffer->buffer[ head ]; } ring_buffer_consume( ring_buffer, max_bytes_to_read ); } *number_of_bytes_read = max_bytes_to_read; return 0; }
OSStatus MicoUartRecv( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout ) { #if RING_BUFF_ON if (uart_interfaces[uart].rx_buffer != NULL) { while (size != 0) { uint32_t transfer_size = MIN(uart_interfaces[uart].rx_buffer->size / 2, size); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( uart_interfaces[uart].rx_buffer ) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ uart_interfaces[uart].rx_size = transfer_size; #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout) != kNoErr ) { uart_interfaces[uart].rx_size = 0; return kTimeoutErr; } #else uart_interfaces[uart].rx_complete = false; int delay_start = mico_get_time_no_os(); while(uart_interfaces[uart].rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ uart_interfaces[uart].rx_size = 0; return kTimeoutErr; } } #endif /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ uart_interfaces[uart].rx_size = 0; } size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; //platform_log("uart receive 03"); ring_buffer_get_data( uart_interfaces[uart].rx_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data, available_data, bytes_available ); transfer_size -= bytes_available; data = ( (uint8_t*) data + bytes_available ); ring_buffer_consume( uart_interfaces[uart].rx_buffer, bytes_available ); } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } } else { return platform_uart_receive_bytes( uart, data, size, timeout ); } #else return platform_uart_receive_bytes( uart, data, size, timeout ); #endif // return kNoErr; }
platform_result_t platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms ) { UNUSED_PARAMETER(driver); UNUSED_PARAMETER(data_in); UNUSED_PARAMETER(expected_data_size); UNUSED_PARAMETER(timeout_ms); if ( driver->rx_ring_buffer != NULL ) { while ( expected_data_size != 0 ) { uint32_t transfer_size = MIN(driver->rx_ring_buffer->size / 2, expected_data_size); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( driver->rx_ring_buffer ) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->rx_transfer_size = transfer_size; if ( host_rtos_get_semaphore( &driver->rx_dma_complete, timeout_ms, WICED_FALSE ) != WWD_SUCCESS ) { driver->rx_transfer_size = 0; return PLATFORM_TIMEOUT; } /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ driver->rx_transfer_size = 0; } expected_data_size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; ring_buffer_get_data( driver->rx_ring_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data_in, available_data, bytes_available ); transfer_size -= bytes_available; data_in = ( (uint8_t*)data_in + bytes_available ); ring_buffer_consume( driver->rx_ring_buffer, bytes_available ); } while ( transfer_size != 0 ); } if ( expected_data_size != 0 ) { return PLATFORM_ERROR; } else { return PLATFORM_SUCCESS; } } else { /* TODO: need to implement this */ return PLATFORM_UNSUPPORTED; } }
platform_result_t platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms ) { /*The following is a temporary implemenration of the UART*/ platform_result_t result = PLATFORM_SUCCESS; wiced_assert( "bad argument", ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ) ); if ( driver->rx_buffer != NULL ) { while ( expected_data_size != 0 ) { uint32_t transfer_size = MIN( driver->rx_buffer->size / 2, expected_data_size ); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( driver->rx_buffer ) ) { wwd_result_t wwd_result; /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ WICED_DISABLE_INTERRUPTS( ); driver->last_receive_result = PLATFORM_SUCCESS; driver->rx_size = transfer_size; WICED_ENABLE_INTERRUPTS( ); wwd_result = host_rtos_get_semaphore( &driver->rx_complete, timeout_ms, WICED_TRUE ); /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ WICED_DISABLE_INTERRUPTS( ); driver->rx_size = 0; WICED_ENABLE_INTERRUPTS( ); if ( wwd_result == WWD_TIMEOUT ) { /* Semaphore timeout. breaks from the while loop */ result = PLATFORM_TIMEOUT; break; } else { /* No timeout. retrieve result */ result = driver->last_receive_result; } } expected_data_size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; ring_buffer_get_data( driver->rx_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data_in, available_data, bytes_available ); transfer_size -= bytes_available; data_in = ( (uint8_t*) data_in + bytes_available ); ring_buffer_consume( driver->rx_buffer, bytes_available ); } while ( transfer_size != 0 ); } return result; } else { return result; } }
OSStatus platform_uart_get_length_in_buffer( platform_uart_driver_t* driver ) { return ring_buffer_used_space( driver->rx_buffer ); }
OSStatus platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms ) { OSStatus err = kNoErr; uint32_t transfer_size; //platform_mcu_powersave_disable(); require_action_quiet( ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ), exit, err = kParamErr); require_action_quiet( driver->rx_ring_buffer != NULL , exit, err = kUnsupportedErr); while ( expected_data_size != 0 ) { transfer_size = MIN(driver->rx_ring_buffer->size / 2, expected_data_size); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( driver->rx_ring_buffer ) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->rx_size = transfer_size; #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms ) != kNoErr ) { driver->rx_size = 0; err = kTimeoutErr; goto exit; } /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ driver->rx_size = 0; #else driver->rx_complete = false; int delay_start = mico_get_time_no_os(); while(driver->rx_complete == false) { if(mico_get_time_no_os() >= delay_start + timeout_ms && timeout_ms != MICO_NEVER_TIMEOUT) { driver->rx_size = 0; err = kTimeoutErr; goto exit; } } driver->rx_size = 0; #endif } expected_data_size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; ring_buffer_get_data( driver->rx_ring_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data_in, available_data, bytes_available ); transfer_size -= bytes_available; data_in = ( (uint8_t*)data_in + bytes_available ); ring_buffer_consume( driver->rx_ring_buffer, bytes_available ); } while ( transfer_size != 0 ); } require_action( expected_data_size == 0, exit, err = kReadErr); exit: //platform_mcu_powersave_enable(); return err; }
uint32_t MicoUartGetLengthInBuffer( mico_uart_t uart ) { return ring_buffer_used_space( uart_interfaces[uart].rx_buffer ); }
static OSStatus FUartRecv( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout ) { if ( driver->rx_buffer != NULL ) { while (size != 0) { uint32_t transfer_size = MIN( driver->rx_buffer->size/2, size ); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( driver->rx_buffer ) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->rx_size = transfer_size; #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; return kTimeoutErr; } #else driver->rx_complete = false; int delay_start = mico_get_time_no_os(); while(driver->rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ driver->rx_size = 0; return kTimeoutErr; } } #endif /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ driver->rx_size = 0; } size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; ring_buffer_get_data( driver->rx_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data, available_data, bytes_available ); transfer_size -= bytes_available; data = ( (uint8_t*) data + bytes_available ); ring_buffer_consume( driver->rx_buffer, bytes_available ); } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } } else { mico_thread_msleep(timeout); return kNoMemoryErr; } }