void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) { if( xRxEnable ) UART_ItConfig( MB_UART_DEV, UART_RxBufFull, ENABLE ); else UART_ItConfig( MB_UART_DEV, UART_RxBufFull, DISABLE ); if( xTxEnable ) UART_ItConfig( MB_UART_DEV, UART_TxHalfEmpty, ENABLE ); else UART_ItConfig( MB_UART_DEV, UART_TxHalfEmpty, DISABLE ); }
u32_t sio_write( sio_fd_t fd, u8_t * buf, u32_t size ) { u32_t ch_left; volatile serdev_t *dev = fd; if( dev->ready ) { ch_left = size; while( ch_left > 0 ) { vPortEnterCritical( ); while( ( dev->tx_buf_cnt < DEFAULT_TX_BUFSIZE ) && ( ch_left > 0 ) ) { dev->tx_buf[dev->tx_buf_wrpos] = *buf++; dev->tx_buf_wrpos = ( dev->tx_buf_wrpos + 1 ) % DEFAULT_TX_BUFSIZE; dev->tx_buf_cnt++; ch_left--; } /* Enable transmit FIFO empty interrupts and block. */ UART_ItConfig( dev->UARTx, UART_TxHalfEmpty, ENABLE ); vPortExitCritical( ); /* Not all characters sent within one write. Block on a semaphore * which is triggered when the buffer is empty again. */ if( ch_left != 0 ) { while( xSemaphoreTake( dev->tx_sem, portMAX_DELAY ) != pdTRUE ); } } } return size; }
/* * See the serial2.h header file. */ xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { xComPortHandle xReturn; /* Create the queues used to hold Rx and Tx characters. */ xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); /* If the queues were created correctly then setup the serial port hardware. */ if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) { portENTER_CRITICAL(); { /* Setup the UART port pins. */ GPIO_Config( GPIO0, UART0_Tx_Pin, GPIO_AF_PP ); GPIO_Config( GPIO0, UART0_Rx_Pin, GPIO_IN_TRI_CMOS ); /* Configure the UART. */ UART_OnOffConfig( UART0, ENABLE ); UART_FifoConfig( UART0, DISABLE ); UART_FifoReset( UART0, UART_RxFIFO ); UART_FifoReset( UART0, UART_TxFIFO ); UART_LoopBackConfig(UART0, DISABLE ); UART_Config( UART0, ulWantedBaud, UART_NO_PARITY, UART_1_StopBits, UARTM_8D ); UART_RxConfig( UART0, ENABLE ); /* Configure the IEC for the UART interrupts. */ EIC_IRQChannelPriorityConfig( UART0_IRQChannel, 1 ); EIC_IRQChannelConfig( UART0_IRQChannel, ENABLE ); EIC_IRQConfig( ENABLE ); UART_ItConfig( UART0, UART_RxBufFull, ENABLE ); } portEXIT_CRITICAL(); } else { xReturn = ( xComPortHandle ) 0; } /* This demo file only supports a single port but we have to return something to comply with the standard demo header file. */ return xReturn; }
void sio_serial_isr( UART_TypeDef * UARTx, u8_t * need_ctx_switch ) { int i; u16 status; volatile serdev_t *dev = SIO_FD_NULL; portBASE_TYPE rx_woken = pdFALSE; portBASE_TYPE tx_woken = pdFALSE; for( i = 0; i < UART_DEVICES_MAX; i++ ) { if( devices[i].ready && ( devices[i].UARTx == UARTx ) ) { dev = &devices[i]; break; } } if( dev != SIO_FD_NULL ) { status = UART_FlagStatus( dev->UARTx ); /* If there are characters in the UART fifo place them into the * ring buffer. In case the buffer is filled half or the requested * number of bytes has been read wakeup the receiver. */ if( status & UART_RxBufFull ) { do { /* Store the character in the ring buffer and advance write * position. */ dev->rx_buf[dev->rx_buf_wrpos] = dev->UARTx->RxBUFR; dev->rx_buf_wrpos = ( dev->rx_buf_wrpos + 1 ) % DEFAULT_RX_BUFSIZE; /* Increment the receiver buffer counter. Check for a buffer * overrun. In that case we have overwritten a old character. * Therefore we have to advance the read position. Note that * in this error case we must not increment the read counter * because an old character was lost. */ if( dev->rx_buf_cnt >= DEFAULT_RX_BUFSIZE ) { /* LWIP_ASSERT( "sio_serial_isr: receiver buffer overflow", 0 ); */ dev->rx_buf_rdpos = ( dev->rx_buf_rdpos + 1 ) % DEFAULT_RX_BUFSIZE; } else { dev->rx_buf_cnt++; } /* Get the new status from the UART. */ status = UART_FlagStatus( dev->UARTx ); } while( status & UART_RxBufFull ); /* Wakeup receiver if buffer is starting to fill. */ if( dev->rx_buf_cnt > ( DEFAULT_RX_BUFSIZE / 2 ) ) { rx_woken = xSemaphoreGiveFromISR( dev->rx_sem, rx_woken ); } } /* Check if we must send characters. */ if( ( dev->tx_buf_cnt > 0 ) && ( status & UART_TxHalfEmpty ) ) { do { /* Fetch character from the ring buffer and place them into * the FIFO. */ dev->UARTx->TxBUFR = dev->tx_buf[dev->tx_buf_rdpos]; dev->tx_buf_rdpos = ( dev->tx_buf_rdpos + 1 ) % DEFAULT_TX_BUFSIZE; dev->tx_buf_cnt--; /* Get the new status from the UART. */ status = UART_FlagStatus( dev->UARTx ); } while( ( dev->tx_buf_cnt > 0 ) && ( status & UART_TxHalfEmpty ) ); if( dev->tx_buf_cnt == 0 ) { tx_woken = xSemaphoreGiveFromISR( dev->tx_sem, tx_woken ); UART_ItConfig( dev->UARTx, UART_TxHalfEmpty, DISABLE ); } } if( tx_woken || rx_woken ) { *need_ctx_switch = 1; } } }
sio_fd_t sio_open_new( u8_t devnr, u32_t baudrate, u8_t databits, sio_stop_t stopbits, sio_parity_t parity ) { int i; err_t error = ERR_OK; serdev_t *dev; UARTParity_TypeDef eUARTParity = UART_NO_PARITY; UARTMode_TypeDef eUARTMode = UARTM_8D; UARTStopBits_TypeDef eUARTStopBits; if( !initialized ) { for( i = 0; i < UART_DEVICES_MAX; i++ ) { SIO_RESET_STATE( &devices[i] ); } initialized = 1; } /* Check if devicename is valid and not in use. */ if( ( devnr < UART_DEVICES_MAX ) && ( devices[devnr].ready == 0 ) ) { dev = ( serdev_t * ) & devices[devnr]; switch ( parity ) { case SIO_PAR_EVEN: eUARTParity = UART_EVEN_PARITY; break; case SIO_PAR_ODD: eUARTParity = UART_ODD_PARITY; break; case SIO_PAR_NONE: eUARTParity = UART_NO_PARITY; break; default: error = ERR_VAL; } switch ( databits ) { case 7: if( parity != SIO_PAR_NONE ) { eUARTMode = UARTM_7D_P; } break; case 8: eUARTMode = parity == SIO_PAR_NONE ? UARTM_8D : UARTM_8D_P; break; default: error = ERR_VAL; } switch ( stopbits ) { case SIO_STOP_0_5: eUARTStopBits = UART_0_5_StopBits; break; case SIO_STOP_1: eUARTStopBits = UART_1_StopBits; break; case SIO_STOP_1_5: eUARTStopBits = UART_1_5_StopBits; break; case SIO_STOP_2: eUARTStopBits = UART_2_StopBits; break; default: error = ERR_VAL; } if( error == ERR_OK ) { SIO_RESET_STATE( dev ); vSemaphoreCreateBinary( dev->rx_sem ); vSemaphoreCreateBinary( dev->tx_sem ); vPortEnterCritical( ); if( ( error = sio_open_low_level( devnr, dev ) ) != ERR_OK ) { /* Hardware interface does not exist. */ } else if( dev->tx_sem == ( xSemaphoreHandle ) 0 ) { error = ERR_MEM; } else if( dev->rx_sem == ( xSemaphoreHandle ) 0 ) { error = ERR_MEM; } else { /* UART parameter correct and hardware device available. */ UART_OnOffConfig( dev->UARTx, ENABLE ); UART_FifoConfig( dev->UARTx, ENABLE ); UART_FifoReset( dev->UARTx, UART_RxFIFO ); UART_FifoReset( dev->UARTx, UART_TxFIFO ); UART_LoopBackConfig( dev->UARTx, DISABLE ); UART_Config( dev->UARTx, baudrate, eUARTParity, eUARTStopBits, eUARTMode ); UART_TimeOutPeriodConfig( dev->UARTx, 0xFF ); UART_ItConfig( dev->UARTx, UART_RxBufFull, ENABLE ); UART_RxConfig( dev->UARTx, ENABLE ); /* Device is now ready for use. */ dev->ready = 1; } if( error != ERR_OK ) { sio_close( dev ); } vPortExitCritical( ); } } else { error = ERR_VAL; } return error == ERR_OK ? ( void * )dev : SIO_FD_NULL; }