From 776fc2910771562d74d2aa2bd47d454ae33450ee Mon Sep 17 00:00:00 2001 From: Fabio Utzig Date: Thu, 14 May 2015 22:12:57 -0300 Subject: Fix some issues with serial driver --- os/hal/ports/NRF51/NRF51822/serial_lld.c | 62 +++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/os/hal/ports/NRF51/NRF51822/serial_lld.c b/os/hal/ports/NRF51/NRF51822/serial_lld.c index c98405d..6cb6943 100644 --- a/os/hal/ports/NRF51/NRF51822/serial_lld.c +++ b/os/hal/ports/NRF51/NRF51822/serial_lld.c @@ -32,6 +32,8 @@ /* Driver local definitions. */ /*===========================================================================*/ +#define INVALID_BAUDRATE 0xFFFFFFFF + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -56,6 +58,33 @@ static const SerialConfig default_config = { /* Driver local functions. */ /*===========================================================================*/ +/* + * @brief Maps a baudrate speed to a BAUDRATE register value. + */ +static uint32_t regval_from_baudrate(uint32_t speed) +{ + switch (speed) { + case 1200: return 0x0004F000; + case 2400: return 0x0009D000; + case 4800: return 0x0013B000; + case 9600: return 0x00275000; + case 14400: return 0x003B0000; + case 19200: return 0x004EA000; + case 28800: return 0x0075F000; + case 38400: return 0x009D5000; + case 57600: return 0x00EBF000; + case 76800: return 0x013A9000; + case 115200: return 0x01D7E000; + case 230400: return 0x03AFB000; + case 250000: return 0x04000000; + case 460800: return 0x075F7000; + case 921600: return 0x0EBEDFA4; + case 1000000: return 0x10000000; + } + return INVALID_BAUDRATE; +} + + /** * @brief Driver output notification. */ @@ -64,15 +93,12 @@ static void notify1(io_queue_t *qp) { (void)qp; - //if (NRF_UART0->EVENTS_TXDRDY) { - msg_t b = oqGetI(&SD1.oqueue); - if (b < Q_OK) { - chnAddFlagsI(&SD1, CHN_OUTPUT_EMPTY); - return; - } - NRF_UART0->TXD = b; - //NRF_UART0->INTENCLR = 0x80; // clear TX interrupt - //} + msg_t b = oqGetI(&SD1.oqueue); + if (b < Q_OK) { + chnAddFlagsI(&SD1, CHN_OUTPUT_EMPTY); + return; + } + NRF_UART0->TXD = b; } #endif @@ -87,18 +113,20 @@ OSAL_IRQ_HANDLER(Vector48) { OSAL_IRQ_PROLOGUE(); if (NRF_UART0->EVENTS_RXDRDY) { + NRF_UART0->EVENTS_RXDRDY = 0; osalSysLockFromISR(); if (iqIsEmptyI(&SD1.iqueue)) chnAddFlagsI(&SD1, CHN_INPUT_AVAILABLE); if (iqPutI(&SD1.iqueue, NRF_UART0->RXD) < Q_OK) chnAddFlagsI(&SD1, SD_OVERRUN_ERROR); - //NRF_UART0->INTENCLR = 4; osalSysUnlockFromISR(); } if (NRF_UART0->EVENTS_TXDRDY) { msg_t b; + NRF_UART0->EVENTS_TXDRDY = 0; + osalSysLockFromISR(); b = oqGetI(&SD1.oqueue); osalSysUnlockFromISR(); @@ -107,12 +135,14 @@ OSAL_IRQ_HANDLER(Vector48) { osalSysLockFromISR(); chnAddFlagsI(&SD1, CHN_OUTPUT_EMPTY); osalSysUnlockFromISR(); - NRF_UART0->INTENCLR = 0x80; // clear TX interrupt } else { NRF_UART0->TXD = b; } } + //TODO + NRF_UART0->EVENTS_ERROR = 0; + OSAL_IRQ_EPILOGUE(); } #endif @@ -153,6 +183,8 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { #if NRF51_SERIAL_USE_UART0 == TRUE if (sdp == &SD1) { + uint32_t regval; + /* FIXME: some board specific, some hardcodeds! */ /* Configure PINs */ @@ -163,12 +195,16 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { NRF_UART0->PSELTXD = 9; NRF_UART0->PSELRXD = 11; - /* 38400!!! */ - NRF_UART0->BAUDRATE = 0x009D5000; + regval = regval_from_baudrate(config->speed); + osalDbgAssert(regval != INVALID_BAUDRATE, "invalid baudrate speed"); + NRF_UART0->BAUDRATE = regval; /* Enable interrupts for RX, TX and ERROR */ NRF_UART0->INTENSET = 0x284; + NRF_UART0->EVENTS_RXDRDY = 0; + NRF_UART0->EVENTS_TXDRDY = 0; + nvicEnableVector(UART0_IRQn, 12); NRF_UART0->ENABLE = 4; -- cgit v1.2.3