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 BuartInterrupt(void) { int status; uint8_t rxData; status = BuartIOctl(UART_IOCTL_RXSTAT_GET,0); if(status & 0x1E){ /* * clear FIFO before clear other flags */ BuartIOctl(UART_IOCTL_RXFIFO_CLR,0); /* * clear other error flags */ BuartIOctl(UART_IOCTL_RXINT_CLR,0); } if(status & 0x01) { BuartIOctl(UART_IOCTL_RXINT_SET, 0); BuartIOctl(UART_IOCTL_RXINT_CLR,0); // Notify thread if sufficient data are available if ( ( uart_interfaces[ AP80xx_BUART ].rx_size > 0 ) && ( (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) >= uart_interfaces[ AP80xx_BUART ].rx_size ) ) { #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &uart_interfaces[ AP80xx_BUART ].rx_complete ); #else uart_interfaces[ AP80xx_BUART ].rx_complete = true; #endif uart_interfaces[ AP80xx_BUART ].rx_size = 0; } } // #ifndef NO_MICO_RTOS // if(uart_interfaces[ 0 ].sem_wakeup) // mico_rtos_set_semaphore(&uart_interfaces[ 0 ].sem_wakeup); // #endif if(BuartIOctl(UART_IOCTL_TXSTAT_GET,0) & 0x01) { BuartIOctl(UART_IOCTL_TXINT_CLR,0); #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &uart_interfaces[ AP80xx_BUART ].tx_complete ); #else uart_interfaces[ AP80xx_BUART ].tx_complete = true; #endif } }
void platform_buart_irq( platform_uart_driver_t* driver ) { int status; status = BuartIOctl(UART_IOCTL_RXSTAT_GET,0); if(status & 0x1E){ /* * clear FIFO before clear other flags */ BuartIOctl(UART_IOCTL_RXFIFO_CLR,0); /* * clear other error flags */ BuartIOctl(UART_IOCTL_RXINT_CLR,0); } if(status & 0x01 ) { BuartIOctl(UART_IOCTL_RXINT_SET, 0); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); // Notify thread if sufficient data are available if ( ( driver->rx_size > 0 ) && ( (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) >= driver->rx_size ) ) { driver->rx_size = 0; } { #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &driver->rx_complete ); #else driver->rx_complete = true; #endif } } if(BuartIOctl(UART_IOCTL_TXSTAT_GET,0) & 0x01) { BuartIOctl(UART_IOCTL_TXINT_CLR,0); #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &driver->tx_complete ); #else driver->tx_complete = true; #endif } }
OSStatus BUartRecv( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout ) { 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 > (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ uart_interfaces[uart].rx_size = transfer_size; BuartIOctl(BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, uart_interfaces[uart].rx_size-1); BuartIOctl(UART_IOCTL_RXINT_SET, 1); #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout) != kNoErr ) { //BuartIOctl(UART_IOCTL_RXINT_SET, 0); 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 { uint32_t bytes_available; bytes_available = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); bytes_available = MIN( bytes_available, transfer_size ); BuartRecv(data, bytes_available, 0); transfer_size -= bytes_available; data = ( (uint8_t*) data + bytes_available ); } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } }
OSStatus internal_uart_init( mico_uart_t uart, const mico_uart_config_t* config, ring_buffer_t* optional_rx_buffer ) { OSStatus err = kNoErr; require_action(optional_rx_buffer!=NULL, exit, err = kParamErr); #ifndef NO_MICO_RTOS mico_rtos_init_semaphore(&uart_interfaces[uart].tx_complete, 1); mico_rtos_init_semaphore(&uart_interfaces[uart].rx_complete, 1); mico_rtos_init_mutex(&uart_interfaces[uart].tx_mutex); #else uart_interfaces[uart].tx_complete = false; uart_interfaces[uart].rx_complete = false; #endif if(uart_mapping[uart].uart == FUART){ if( uart_mapping[uart].pin_tx->port == GPIOA && uart_mapping[uart].pin_tx->pin == 1 ) GpioFuartTxIoConfig(0); else if( uart_mapping[uart].pin_tx->port == GPIOB && uart_mapping[uart].pin_tx->pin == 7 ) GpioFuartTxIoConfig(1); else if( uart_mapping[uart].pin_tx->port == GPIOC && uart_mapping[uart].pin_tx->pin == 3 ) GpioFuartTxIoConfig(2); else return kUnsupportedErr; if( uart_mapping[uart].pin_rx->port == GPIOA && uart_mapping[uart].pin_rx->pin == 1 ) GpioFuartRxIoConfig(0); else if( uart_mapping[uart].pin_rx->port == GPIOB && uart_mapping[uart].pin_rx->pin == 6 ) GpioFuartRxIoConfig(1); else if( uart_mapping[uart].pin_rx->port == GPIOC && uart_mapping[uart].pin_rx->pin == 4 ) GpioFuartRxIoConfig(2); else return kUnsupportedErr; require_action( config->flow_control == FLOW_CONTROL_DISABLED, exit, err = kUnsupportedErr ); err = FuartInit(config->baud_rate, config->data_width + 5, config->parity, config->stop_bits + 1); require_noerr(err, exit); FuartIOctl(UART_IOCTL_RXINT_SET, 1); if (optional_rx_buffer != NULL){ /* Note that the ring_buffer should've been initialised first */ uart_interfaces[uart].rx_buffer = optional_rx_buffer; uart_interfaces[uart].rx_size = 0; //platform_uart_receive_bytes( uart, optional_rx_buffer->buffer, optional_rx_buffer->size, 0 ); } }else if(uart_mapping[uart].uart == BUART){ if( uart_mapping[uart].pin_tx->port == GPIOA && uart_mapping[uart].pin_tx->pin == 16 ) GpioBuartTxIoConfig(0); else if( uart_mapping[uart].pin_tx->port == GPIOA && uart_mapping[uart].pin_tx->pin == 25 ) GpioBuartTxIoConfig(1); else if( uart_mapping[uart].pin_tx->port == GPIOB && uart_mapping[uart].pin_tx->pin == 9 ) GpioBuartTxIoConfig(2); else if( uart_mapping[uart].pin_tx->port == GPIOB && uart_mapping[uart].pin_tx->pin == 28 ) GpioBuartTxIoConfig(3); else return kUnsupportedErr; if( uart_mapping[uart].pin_rx->port == GPIOA && uart_mapping[uart].pin_rx->pin == 13 ) GpioBuartRxIoConfig(0); else if( uart_mapping[uart].pin_rx->port == GPIOA && uart_mapping[uart].pin_rx->pin == 24 ) GpioBuartRxIoConfig(1); else if( uart_mapping[uart].pin_rx->port == GPIOB && uart_mapping[uart].pin_rx->pin == 8 ) GpioBuartRxIoConfig(2); else if( uart_mapping[uart].pin_rx->port == GPIOB && uart_mapping[uart].pin_rx->pin == 29 ) GpioBuartRxIoConfig(3); else return kUnsupportedErr; require_action( config->flow_control == FLOW_CONTROL_DISABLED, exit, err = kUnsupportedErr ); err = BuartExFifoInit( (32-2-1)*1024, 1024*2, 1024, 1); require_noerr(err, exit); err = BuartInit(config->baud_rate, config->data_width + 5, config->parity, config->stop_bits + 1); require_noerr(err, exit); BuartIOctl(UART_IOCTL_RXINT_SET, 1); BuartIOctl(UART_IOCTL_TXINT_SET, 1); }else return kUnsupportedErr; exit: return err; }
OSStatus platform_uart_init( platform_uart_driver_t* driver, const platform_uart_t* peripheral, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer ) { OSStatus err = kNoErr; platform_mcu_powersave_disable(); require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr); driver->rx_size = 0; driver->tx_size = 0; driver->last_transmit_result = kNoErr; driver->last_receive_result = kNoErr; driver->peripheral = (platform_uart_t*)peripheral; driver->buart_fifo_head = 0; #ifndef NO_MICO_RTOS mico_rtos_init_semaphore( &driver->tx_complete, 1 ); mico_rtos_init_semaphore( &driver->rx_complete, 1 ); mico_rtos_init_mutex ( &driver->tx_mutex ); #else driver->tx_complete = false; driver->rx_complete = false; #endif if ( peripheral->uart == FUART ){ if( peripheral->pin_tx->port == GPIOA && peripheral->pin_tx->pin == 1 ) GpioFuartTxIoConfig(0); else if( peripheral->pin_tx->port == GPIOB && peripheral->pin_tx->pin == 7 ) GpioFuartTxIoConfig(1); else if( peripheral->pin_tx->port == GPIOC && peripheral->pin_tx->pin == 3 ) GpioFuartTxIoConfig(2); else return kUnsupportedErr; if( peripheral->pin_rx->port == GPIOA && peripheral->pin_rx->pin == 1 ) GpioFuartRxIoConfig(0); else if( peripheral->pin_rx->port == GPIOB && peripheral->pin_rx->pin == 6 ) GpioFuartRxIoConfig(1); else if( peripheral->pin_rx->port == GPIOC && peripheral->pin_rx->pin == 4 ) GpioFuartRxIoConfig(2); else return kUnsupportedErr; require_action( config->flow_control == FLOW_CONTROL_DISABLED, exit, err = kUnsupportedErr ); err = FuartInit(config->baud_rate, config->data_width + 5, config->parity, config->stop_bits + 1); require_noerr(err, exit); FuartIOctl(UART_IOCTL_RXINT_SET, 1); if (optional_ring_buffer != NULL){ /* Note that the ring_buffer should've been initialised first */ driver->rx_buffer = optional_ring_buffer; driver->rx_size = 0; //platform_uart_receive_bytes( uart, optional_rx_buffer->buffer, optional_rx_buffer->size, 0 ); } }else if( peripheral->uart == BUART ){ if( peripheral->pin_tx->port == GPIOA && peripheral->pin_tx->pin == 16 ) GpioBuartTxIoConfig(0); else if( peripheral->pin_tx->port == GPIOA && peripheral->pin_tx->pin == 25 ) GpioBuartTxIoConfig(1); else if( peripheral->pin_tx->port == GPIOB && peripheral->pin_tx->pin == 9 ) GpioBuartTxIoConfig(2); else if( peripheral->pin_tx->port == GPIOB && peripheral->pin_tx->pin == 28 ) GpioBuartTxIoConfig(3); else return kUnsupportedErr; if( peripheral->pin_rx->port == GPIOA && peripheral->pin_rx->pin == 13 ) GpioBuartRxIoConfig(0); else if( peripheral->pin_rx->port == GPIOA && peripheral->pin_rx->pin == 24 ) GpioBuartRxIoConfig(1); else if( peripheral->pin_rx->port == GPIOB && peripheral->pin_rx->pin == 8 ) GpioBuartRxIoConfig(2); else if( peripheral->pin_rx->port == GPIOB && peripheral->pin_rx->pin == 29 ) GpioBuartRxIoConfig(3); else return kUnsupportedErr; require_action( config->flow_control == FLOW_CONTROL_DISABLED, exit, err = kUnsupportedErr ); err = BuartExFifoInit( BUART_FIFO_START, BUART_RX_FIFO_SIZE, BUART_TX_FIFO_SIZE, 1 ); require_noerr(err, exit); err = BuartInit( config->baud_rate, config->data_width + 5, config->parity, config->stop_bits + 1 ); require_noerr(err, exit); BuartIOctl( UART_IOCTL_TXINT_SET, 1 ); }else return kUnsupportedErr; exit: return err; }
static OSStatus BUartRecv( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout ) { int next_trigger; uint32_t recved_data_len = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); uint32_t delay_start = 0; while (size != 0) { uint32_t transfer_size = MIN( BUART_RX_FIFO_SIZE / 2, size ); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > recved_data_len ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->rx_size = transfer_size; next_trigger = (driver->buart_fifo_head + driver->rx_size - 1)% BUART_RX_FIFO_SIZE; /* */ if( next_trigger < driver->buart_fifo_head && (driver->buart_fifo_head + recved_data_len) < BUART_RX_FIFO_SIZE ){ BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, BUART_RX_FIFO_SIZE - 1 ); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl(UART_IOCTL_RXINT_SET, 1); #ifndef NO_MICO_RTOS #if 0 if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } #else delay_start = mico_get_time(); while(1){ mico_rtos_get_semaphore( &driver->rx_complete, 50); if( (BUART_RX_FIFO_SIZE - driver->buart_fifo_head) <= (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) break; if( mico_get_time() - delay_start > timeout ){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif #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; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif mico_thread_msleep(20); } #ifndef NO_MICO_RTOS #if 1 recved_data_len = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); if ( transfer_size > recved_data_len ){ BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } else{ driver->rx_size = 0; } #else //platform_log( "Waiting...,head:%d expext:%d trigger:%d", driver->buart_fifo_head, driver->rx_size, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); delay_start = mico_get_time(); while(1){ mico_rtos_get_semaphore( &driver->rx_complete, 50); if( driver->rx_size <= (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) break; if( mico_get_time() - delay_start > timeout ){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif #else BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); driver->rx_complete = false; 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; BuartIOctl(UART_IOCTL_RXINT_SET, 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 { uint32_t bytes_available; bytes_available = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); bytes_available = MIN( bytes_available, transfer_size ); BuartRecv(data, bytes_available, 0); driver->buart_fifo_head = (driver->buart_fifo_head + bytes_available)% BUART_RX_FIFO_SIZE; transfer_size -= bytes_available; } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } }