From 827720aa8444bd1c8229f72e0465cc09a69f8231 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 2 Dec 2019 11:22:06 -0700 Subject: [PATCH 01/11] Adding buffering of TX chars --- cores/arduino/ard_sup/uart/ap3_uart.cpp | 77 +++++++++++++++++++++---- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/cores/arduino/ard_sup/uart/ap3_uart.cpp b/cores/arduino/ard_sup/uart/ap3_uart.cpp index c31cc871..ac96aac7 100644 --- a/cores/arduino/ard_sup/uart/ap3_uart.cpp +++ b/cores/arduino/ard_sup/uart/ap3_uart.cpp @@ -119,17 +119,42 @@ size_t Uart::write(const uint8_t *buffer, size_t size) { uint32_t ui32BytesWritten = 0; - // todo: use a local buffer to guarantee lifespan of data (maybe txbuffer, but maybe not a ring buffer? b/c of efficiency + not breaking up transfers) + //FIFO on Apollo3 is 32 bytes - const am_hal_uart_transfer_t sUartWrite = - { - .ui32Direction = AM_HAL_UART_WRITE, - .pui8Data = (uint8_t *)buffer, - .ui32NumBytes = size, - .ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER, - .pui32BytesTransferred = (uint32_t *)&ui32BytesWritten, - }; - am_hal_uart_transfer(_handle, &sUartWrite); + //If TX UART is sitting idle, load it. This will start the ISR TX handler as well. + uint32_t uartFlags = 0; + am_hal_uart_flags_get(_handle, &uartFlags); + + // am_hal_uart_tx_flush(_handle); + if (uartFlags & AM_HAL_UART_FR_TX_EMPTY) + //if (1) + { + uint32_t amtToSend = size; + if (amtToSend > AM_HAL_UART_FIFO_MAX) + amtToSend = AM_HAL_UART_FIFO_MAX; + + //Transfer to local buffer + uint8_t tempTX[AM_HAL_UART_FIFO_MAX]; + for (int x = 0; x < amtToSend; x++) + tempTX[x] = _tx_buffer.read_char(); + + const am_hal_uart_transfer_t sUartWrite = + { + .ui32Direction = AM_HAL_UART_WRITE, + .pui8Data = (uint8_t *)buffer, + .ui32NumBytes = size, + .ui32TimeoutMs = 0, //Use non-blocking xfer + .pui32BytesTransferred = (uint32_t *)&ui32BytesWritten, + }; + am_hal_uart_transfer(_handle, &sUartWrite); + } + else + { + //UART is already sending bytes so load the ring buffer instead + for (int x = 0; x < size; x++) + _tx_buffer.store_char(buffer[x]); + ui32BytesWritten = size; + } return ui32BytesWritten; } @@ -370,9 +395,9 @@ ap3_err_t Uart::_begin(void) UARTn(_instance)->LCRH_b.FEN = 0; // Disable that pesky FIFO - // Enable RX interrupts + // Enable TX and RX interrupts NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + _instance)); - am_hal_uart_interrupt_enable(_handle, (AM_HAL_UART_INT_RX)); + am_hal_uart_interrupt_enable(_handle, (AM_HAL_UART_INT_RX | AM_HAL_UART_INT_TX)); am_hal_interrupt_master_enable(); // Register the class into the local list @@ -517,6 +542,34 @@ inline void Uart::rx_isr(void) _rx_buffer.store_char(rx_c); } } + + if (ui32Status & AM_HAL_UART_INT_TX) + { + //If bytes are sitting in TX buffer, load them into UART buffer for transfer + if (_tx_buffer.available()) + { + uint32_t ui32BytesWritten = 0; + + uint32_t amtToSend = _tx_buffer.available(); + if (amtToSend > AM_HAL_UART_FIFO_MAX) + amtToSend = AM_HAL_UART_FIFO_MAX; + + //Transfer to local buffer + uint8_t tempTX[AM_HAL_UART_FIFO_MAX]; + for (int x = 0; x < amtToSend; x++) + tempTX[x] = _tx_buffer.read_char(); + + const am_hal_uart_transfer_t sUartWrite = + { + .ui32Direction = AM_HAL_UART_WRITE, + .pui8Data = (uint8_t *)tempTX, + .ui32NumBytes = (uint32_t)amtToSend, + .ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER, + .pui32BytesTransferred = (uint32_t *)&ui32BytesWritten, + }; + am_hal_uart_transfer(_handle, &sUartWrite); + } + } } // Individual ISR implementations for the two UART peripherals on the Apollo3 From f12b6ef9a877f21e1211f2293946dd861c1d8821 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 2 Dec 2019 11:55:51 -0700 Subject: [PATCH 02/11] Fix error in am_hal_uart_flags_get in HAL --- .../am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c | 294 +++++++++--------- 1 file changed, 147 insertions(+), 147 deletions(-) diff --git a/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c b/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c index c9bb9c0a..d6023173 100644 --- a/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c +++ b/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c @@ -15,24 +15,24 @@ // // Copyright (c) 2019, Ambiq Micro // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the copyright holder nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. -// +// // Third party software included in this distribution is subject to the // additional license terms as defined in the /docs/licenses directory. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -58,11 +58,11 @@ // UART magic number for handle verification. // //***************************************************************************** -#define AM_HAL_MAGIC_UART 0xEA9E06 +#define AM_HAL_MAGIC_UART 0xEA9E06 -#define AM_HAL_UART_CHK_HANDLE(h) \ - ((h) && \ - ((am_hal_handle_prefix_t *)(h))->s.bInit && \ +#define AM_HAL_UART_CHK_HANDLE(h) \ + ((h) && \ + ((am_hal_handle_prefix_t *)(h))->s.bInit && \ (((am_hal_handle_prefix_t *)(h))->s.magic == AM_HAL_MAGIC_UART)) //***************************************************************************** @@ -70,10 +70,10 @@ // Convenience macro for passing errors. // //***************************************************************************** -#define RETURN_ON_ERROR(x) \ - if ((x) != AM_HAL_STATUS_SUCCESS) \ - { \ - return (x); \ +#define RETURN_ON_ERROR(x) \ + if ((x) != AM_HAL_STATUS_SUCCESS) \ + { \ + return (x); \ }; //***************************************************************************** @@ -81,8 +81,8 @@ // Baudrate to byte-time in microseconds with a little extra margin. // //***************************************************************************** -#define ONE_BYTE_US(baudrate) (12000000/(baudrate)) -#define ONE_BYTE_DELAY(handle) \ +#define ONE_BYTE_US(baudrate) (12000000 / (baudrate)) +#define ONE_BYTE_DELAY(handle) \ am_hal_flash_delay(FLASH_CYCLES_US(ONE_BYTE_US((handle)->ui32BaudRate))) //***************************************************************************** @@ -100,8 +100,7 @@ typedef struct uint32_t regCR; uint32_t regIFLS; uint32_t regIER; -} -am_hal_uart_register_state_t; +} am_hal_uart_register_state_t; //***************************************************************************** // @@ -122,8 +121,7 @@ typedef struct am_hal_queue_t sRxQueue; uint32_t ui32BaudRate; -} -am_hal_uart_state_t; +} am_hal_uart_state_t; //***************************************************************************** // @@ -169,7 +167,7 @@ am_hal_uart_initialize(uint32_t ui32Module, void **ppHandle) // // Check that the request module is in range. // - if (ui32Module >= AM_REG_UART_NUM_MODULES ) + if (ui32Module >= AM_REG_UART_NUM_MODULES) { return AM_HAL_STATUS_OUT_OF_RANGE; } @@ -251,12 +249,11 @@ am_hal_uart_power_control(void *pHandle, am_hal_sysctrl_power_state_e ePowerState, bool bRetainState) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; - am_hal_pwrctrl_periph_e eUARTPowerModule = ((am_hal_pwrctrl_periph_e) - (AM_HAL_PWRCTRL_PERIPH_UART0 + - ui32Module)); + am_hal_pwrctrl_periph_e eUARTPowerModule = ((am_hal_pwrctrl_periph_e)(AM_HAL_PWRCTRL_PERIPH_UART0 + + ui32Module)); // // Check to make sure this is a valid handle. @@ -271,79 +268,79 @@ am_hal_uart_power_control(void *pHandle, // switch (ePowerState) { + // + // Turn on the UART. + // + case AM_HAL_SYSCTRL_WAKE: // - // Turn on the UART. + // Make sure we don't try to restore an invalid state. // - case AM_HAL_SYSCTRL_WAKE: - // - // Make sure we don't try to restore an invalid state. - // - if (bRetainState && !pState->sRegState.bValid) - { - return AM_HAL_STATUS_INVALID_OPERATION; - } + if (bRetainState && !pState->sRegState.bValid) + { + return AM_HAL_STATUS_INVALID_OPERATION; + } + + // + // Enable power control. + // + am_hal_pwrctrl_periph_enable(eUARTPowerModule); + if (bRetainState) + { // - // Enable power control. + // Restore UART registers // - am_hal_pwrctrl_periph_enable(eUARTPowerModule); + AM_CRITICAL_BEGIN - if (bRetainState) - { - // - // Restore UART registers - // - AM_CRITICAL_BEGIN - - UARTn(ui32Module)->ILPR = pState->sRegState.regILPR; - UARTn(ui32Module)->IBRD = pState->sRegState.regIBRD; - UARTn(ui32Module)->FBRD = pState->sRegState.regFBRD; - UARTn(ui32Module)->LCRH = pState->sRegState.regLCRH; - UARTn(ui32Module)->CR = pState->sRegState.regCR; - UARTn(ui32Module)->IFLS = pState->sRegState.regIFLS; - UARTn(ui32Module)->IER = pState->sRegState.regIER; - - pState->sRegState.bValid = false; - - AM_CRITICAL_END - } - break; + UARTn(ui32Module)->ILPR = pState->sRegState.regILPR; + UARTn(ui32Module)->IBRD = pState->sRegState.regIBRD; + UARTn(ui32Module)->FBRD = pState->sRegState.regFBRD; + UARTn(ui32Module)->LCRH = pState->sRegState.regLCRH; + UARTn(ui32Module)->CR = pState->sRegState.regCR; + UARTn(ui32Module)->IFLS = pState->sRegState.regIFLS; + UARTn(ui32Module)->IER = pState->sRegState.regIER; + + pState->sRegState.bValid = false; + + AM_CRITICAL_END + } + break; + + // + // Turn off the UART. + // + case AM_HAL_SYSCTRL_NORMALSLEEP: + case AM_HAL_SYSCTRL_DEEPSLEEP: + if (bRetainState) + { + AM_CRITICAL_BEGIN + + pState->sRegState.regILPR = UARTn(ui32Module)->ILPR; + pState->sRegState.regIBRD = UARTn(ui32Module)->IBRD; + pState->sRegState.regFBRD = UARTn(ui32Module)->FBRD; + pState->sRegState.regLCRH = UARTn(ui32Module)->LCRH; + pState->sRegState.regCR = UARTn(ui32Module)->CR; + pState->sRegState.regIFLS = UARTn(ui32Module)->IFLS; + pState->sRegState.regIER = UARTn(ui32Module)->IER; + pState->sRegState.bValid = true; + + AM_CRITICAL_END + } // - // Turn off the UART. + // Clear all interrupts before sleeping as having a pending UART + // interrupt burns power. // - case AM_HAL_SYSCTRL_NORMALSLEEP: - case AM_HAL_SYSCTRL_DEEPSLEEP: - if (bRetainState) - { - AM_CRITICAL_BEGIN - - pState->sRegState.regILPR = UARTn(ui32Module)->ILPR; - pState->sRegState.regIBRD = UARTn(ui32Module)->IBRD; - pState->sRegState.regFBRD = UARTn(ui32Module)->FBRD; - pState->sRegState.regLCRH = UARTn(ui32Module)->LCRH; - pState->sRegState.regCR = UARTn(ui32Module)->CR; - pState->sRegState.regIFLS = UARTn(ui32Module)->IFLS; - pState->sRegState.regIER = UARTn(ui32Module)->IER; - pState->sRegState.bValid = true; - - AM_CRITICAL_END - } - - // - // Clear all interrupts before sleeping as having a pending UART - // interrupt burns power. - // - am_hal_uart_interrupt_clear(pState, 0xFFFFFFFF); + am_hal_uart_interrupt_clear(pState, 0xFFFFFFFF); - // - // Disable power control. - // - am_hal_pwrctrl_periph_disable(eUARTPowerModule); - break; + // + // Disable power control. + // + am_hal_pwrctrl_periph_disable(eUARTPowerModule); + break; - default: - return AM_HAL_STATUS_INVALID_ARG; + default: + return AM_HAL_STATUS_INVALID_ARG; } // @@ -360,7 +357,7 @@ am_hal_uart_power_control(void *pHandle, uint32_t am_hal_uart_configure(void *pHandle, const am_hal_uart_config_t *psConfig) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; uint32_t ui32ErrorStatus; @@ -404,7 +401,7 @@ am_hal_uart_configure(void *pHandle, const am_hal_uart_config_t *psConfig) // Set the baud rate. // ui32ErrorStatus = config_baudrate(ui32Module, psConfig->ui32BaudRate, - &(pState->ui32BaudRate)); + &(pState->ui32BaudRate)); RETURN_ON_ERROR(ui32ErrorStatus); @@ -417,9 +414,9 @@ am_hal_uart_configure(void *pHandle, const am_hal_uart_config_t *psConfig) UARTn(ui32Module)->IFLS = psConfig->ui32FifoLevels; - UARTn(ui32Module)->LCRH = (psConfig->ui32DataBits | - psConfig->ui32Parity | - psConfig->ui32StopBits | + UARTn(ui32Module)->LCRH = (psConfig->ui32DataBits | + psConfig->ui32Parity | + psConfig->ui32StopBits | AM_HAL_UART_FIFO_ENABLE); // @@ -454,7 +451,7 @@ static uint32_t buffer_configure(void *pHandle, uint8_t *pui8TxBuffer, uint32_t ui32TxBufferSize, uint8_t *pui8RxBuffer, uint32_t ui32RxBufferSize) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32ErrorStatus; // @@ -519,7 +516,7 @@ buffer_configure(void *pHandle, uint8_t *pui8TxBuffer, uint32_t ui32TxBufferSize // Set Baud Rate based on the UART clock frequency. // //***************************************************************************** -#define BAUDCLK (16) // Number of UART clocks needed per bit. +#define BAUDCLK (16) // Number of UART clocks needed per bit. static uint32_t config_baudrate(uint32_t ui32Module, uint32_t ui32DesiredBaudrate, uint32_t *pui32ActualBaud) { @@ -535,40 +532,40 @@ config_baudrate(uint32_t ui32Module, uint32_t ui32DesiredBaudrate, uint32_t *pui // if (APOLLO3_A1) { - if (ui32DesiredBaudrate > AM_HAL_UART_MAXIMUM_BAUDRATE_A1) - { - return AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE; - } + if (ui32DesiredBaudrate > AM_HAL_UART_MAXIMUM_BAUDRATE_A1) + { + return AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE; + } } if (APOLLO3_GE_B0) { - if (ui32DesiredBaudrate > AM_HAL_UART_MAXIMUM_BAUDRATE_B0) - { - return AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE; - } + if (ui32DesiredBaudrate > AM_HAL_UART_MAXIMUM_BAUDRATE_B0) + { + return AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE; + } } - switch ( UARTn(ui32Module)->CR_b.CLKSEL ) + switch (UARTn(ui32Module)->CR_b.CLKSEL) { - case UART0_CR_CLKSEL_24MHZ: - ui32UartClkFreq = 24000000; - break; + case UART0_CR_CLKSEL_24MHZ: + ui32UartClkFreq = 24000000; + break; - case UART0_CR_CLKSEL_12MHZ: - ui32UartClkFreq = 12000000; - break; + case UART0_CR_CLKSEL_12MHZ: + ui32UartClkFreq = 12000000; + break; - case UART0_CR_CLKSEL_6MHZ: - ui32UartClkFreq = 6000000; - break; + case UART0_CR_CLKSEL_6MHZ: + ui32UartClkFreq = 6000000; + break; - case UART0_CR_CLKSEL_3MHZ: - ui32UartClkFreq = 3000000; - break; + case UART0_CR_CLKSEL_3MHZ: + ui32UartClkFreq = 3000000; + break; - default: - *pui32ActualBaud = 0; - return AM_HAL_UART_STATUS_CLOCK_NOT_CONFIGURED; + default: + *pui32ActualBaud = 0; + return AM_HAL_UART_STATUS_CLOCK_NOT_CONFIGURED; } // @@ -617,7 +614,7 @@ uart_fifo_read(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t ui32ReadData; uint32_t ui32ErrorStatus = AM_HAL_STATUS_SUCCESS; - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; // @@ -629,7 +626,7 @@ uart_fifo_read(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, // If the fifo is empty, return with the number of bytes we read. // Otherwise, read the data into the provided buffer. // - if ( UARTn(ui32Module)->FR_b.RXFE ) + if (UARTn(ui32Module)->FR_b.RXFE) { break; } @@ -643,9 +640,9 @@ uart_fifo_read(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, if (ui32ReadData & (_VAL2FLD(UART0_DR_OEDATA, UART0_DR_OEDATA_ERR) | _VAL2FLD(UART0_DR_BEDATA, UART0_DR_BEDATA_ERR) | _VAL2FLD(UART0_DR_PEDATA, UART0_DR_PEDATA_ERR) | - _VAL2FLD(UART0_DR_FEDATA, UART0_DR_FEDATA_ERR)) ) + _VAL2FLD(UART0_DR_FEDATA, UART0_DR_FEDATA_ERR))) { - ui32ErrorStatus = AM_HAL_UART_STATUS_BUS_ERROR; + ui32ErrorStatus = AM_HAL_UART_STATUS_BUS_ERROR; break; } else @@ -674,7 +671,7 @@ uart_fifo_write(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, { uint32_t i = 0; - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; // @@ -686,7 +683,7 @@ uart_fifo_write(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, // If the TX FIFO is full, break out of the loop. We've sent everything // we can. // - if ( UARTn(ui32Module)->FR_b.TXFF ) + if (UARTn(ui32Module)->FR_b.TXFF) { break; } @@ -720,7 +717,7 @@ read_nonblocking(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t ui32BytesTransferred; uint32_t ui32ErrorStatus = AM_HAL_STATUS_SUCCESS; - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; // // Check to make sure this is a valid handle. @@ -757,8 +754,7 @@ read_nonblocking(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, ui32BufferData = am_hal_queue_data_left(&pState->sRxQueue); - ui32BytesTransferred = (ui32NumBytes < ui32BufferData ? - ui32NumBytes : ui32BufferData); + ui32BytesTransferred = (ui32NumBytes < ui32BufferData ? ui32NumBytes : ui32BufferData); am_hal_queue_item_get(&pState->sRxQueue, pui8Data, ui32BytesTransferred); } @@ -796,7 +792,7 @@ write_nonblocking(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t ui32BufferSpace; uint32_t ui32BytesTransferred; - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; // // Check to make sure this is a valid handle. @@ -831,8 +827,7 @@ write_nonblocking(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, // ui32BufferSpace = am_hal_queue_space_left(&pState->sTxQueue); - ui32BytesTransferred = (ui32NumBytes < ui32BufferSpace ? - ui32NumBytes : ui32BufferSpace); + ui32BytesTransferred = (ui32NumBytes < ui32BufferSpace ? ui32NumBytes : ui32BufferSpace); am_hal_queue_item_add(&pState->sTxQueue, pui8Data, ui32BytesTransferred); @@ -874,7 +869,7 @@ read_timeout(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t *pui32NumBytesRead, uint32_t ui32TimeoutMs) { uint32_t ui32Status, ui32BytesRead, ui32RemainingBytes, - ui32TimeSpent, i; + ui32TimeSpent, i; // // If we don't have a timeout, just pass this directly to the nonblocking @@ -953,7 +948,7 @@ write_timeout(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t *pui32NumBytesWritten, uint32_t ui32TimeoutMs) { uint32_t ui32Status, ui32BytesWritten, ui32RemainingBytes, - ui32TimeSpent, i; + ui32TimeSpent, i; i = 0; ui32RemainingBytes = ui32NumBytes; @@ -1060,7 +1055,7 @@ am_hal_uart_transfer(void *pHandle, const am_hal_uart_transfer_t *pTransfer) uint32_t am_hal_uart_tx_flush(void *pHandle) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; // @@ -1077,7 +1072,7 @@ am_hal_uart_tx_flush(void *pHandle) // // Wait for the TX busy bit to go low. // - while ( UARTn(ui32Module)->FR_b.BUSY ) + while (UARTn(ui32Module)->FR_b.BUSY) { ONE_BYTE_DELAY(pState); } @@ -1093,7 +1088,7 @@ am_hal_uart_tx_flush(void *pHandle) uint32_t am_hal_uart_flags_get(void *pHandle, uint32_t *ui32Flags) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; // @@ -1104,7 +1099,12 @@ am_hal_uart_flags_get(void *pHandle, uint32_t *ui32Flags) return AM_HAL_STATUS_INVALID_HANDLE; } - return UARTn(ui32Module)->FR; + //Correct code + *ui32Flags = (uint32_t)UARTn(ui32Module)->FR; + return AM_HAL_STATUS_SUCCESS; + + //return UARTn(ui32Module)->FR; //Incorrect code? + } // am_hal_uart_flags_get() //***************************************************************************** @@ -1115,7 +1115,7 @@ am_hal_uart_flags_get(void *pHandle, uint32_t *ui32Flags) static uint32_t rx_queue_update(void *pHandle) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint8_t pui8Data[AM_HAL_UART_FIFO_MAX]; uint32_t ui32BytesTransferred; @@ -1154,7 +1154,7 @@ rx_queue_update(void *pHandle) static uint32_t tx_queue_update(void *pHandle) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; uint8_t pui8Data; @@ -1166,7 +1166,7 @@ tx_queue_update(void *pHandle) // // Loop as long as the TX fifo isn't full yet. // - while ( !UARTn(ui32Module)->FR_b.TXFF ) + while (!UARTn(ui32Module)->FR_b.TXFF) { // // Attempt to grab an item from the queue, and add it to the fifo. @@ -1203,7 +1203,7 @@ tx_queue_update(void *pHandle) uint32_t am_hal_uart_interrupt_service(void *pHandle, uint32_t ui32Status, uint32_t *pui32UartTxIdle) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; uint32_t ui32ErrorStatus; @@ -1250,13 +1250,13 @@ am_hal_uart_interrupt_service(void *pHandle, uint32_t ui32Status, uint32_t *pui3 // if (pState->bEnableTxQueue) { - if ( am_hal_queue_empty(&(pState->sTxQueue) ) && - ( UARTn(ui32Module)->FR_b.BUSY == false ) ) + if (am_hal_queue_empty(&(pState->sTxQueue)) && + (UARTn(ui32Module)->FR_b.BUSY == false)) { *pui32UartTxIdle = true; } } - else if ( UARTn(ui32Module)->FR_b.BUSY == false ) + else if (UARTn(ui32Module)->FR_b.BUSY == false) { *pui32UartTxIdle = true; } @@ -1276,7 +1276,7 @@ am_hal_uart_interrupt_service(void *pHandle, uint32_t ui32Status, uint32_t *pui3 uint32_t am_hal_uart_interrupt_enable(void *pHandle, uint32_t ui32IntMask) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; if (!AM_HAL_UART_CHK_HANDLE(pHandle)) @@ -1297,7 +1297,7 @@ am_hal_uart_interrupt_enable(void *pHandle, uint32_t ui32IntMask) uint32_t am_hal_uart_interrupt_disable(void *pHandle, uint32_t ui32IntMask) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; if (!AM_HAL_UART_CHK_HANDLE(pHandle)) @@ -1318,7 +1318,7 @@ am_hal_uart_interrupt_disable(void *pHandle, uint32_t ui32IntMask) uint32_t am_hal_uart_interrupt_clear(void *pHandle, uint32_t ui32IntMask) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; if (!AM_HAL_UART_CHK_HANDLE(pHandle)) @@ -1339,7 +1339,7 @@ am_hal_uart_interrupt_clear(void *pHandle, uint32_t ui32IntMask) uint32_t am_hal_uart_interrupt_status_get(void *pHandle, uint32_t *pui32Status, bool bEnabledOnly) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; uint32_t ui32Module = pState->ui32Module; if (!AM_HAL_UART_CHK_HANDLE(pHandle)) From 98bee29ff100bb435c2b3bb5367830f23581d13c Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 2 Dec 2019 12:01:08 -0700 Subject: [PATCH 03/11] Sends characters if TX is empty. Buffers the rest. TX interrupts working. --- cores/arduino/ard_sup/uart/ap3_uart.cpp | 30 ++++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/cores/arduino/ard_sup/uart/ap3_uart.cpp b/cores/arduino/ard_sup/uart/ap3_uart.cpp index ac96aac7..44e34fbf 100644 --- a/cores/arduino/ard_sup/uart/ap3_uart.cpp +++ b/cores/arduino/ard_sup/uart/ap3_uart.cpp @@ -122,40 +122,38 @@ size_t Uart::write(const uint8_t *buffer, size_t size) //FIFO on Apollo3 is 32 bytes //If TX UART is sitting idle, load it. This will start the ISR TX handler as well. - uint32_t uartFlags = 0; + uint32_t uartFlags; am_hal_uart_flags_get(_handle, &uartFlags); - - // am_hal_uart_tx_flush(_handle); if (uartFlags & AM_HAL_UART_FR_TX_EMPTY) - //if (1) { uint32_t amtToSend = size; if (amtToSend > AM_HAL_UART_FIFO_MAX) amtToSend = AM_HAL_UART_FIFO_MAX; + size -= amtToSend; + //Transfer to local buffer uint8_t tempTX[AM_HAL_UART_FIFO_MAX]; for (int x = 0; x < amtToSend; x++) - tempTX[x] = _tx_buffer.read_char(); + tempTX[x] = buffer[x]; const am_hal_uart_transfer_t sUartWrite = { .ui32Direction = AM_HAL_UART_WRITE, - .pui8Data = (uint8_t *)buffer, - .ui32NumBytes = size, - .ui32TimeoutMs = 0, //Use non-blocking xfer + .pui8Data = (uint8_t *)tempTX, + .ui32NumBytes = amtToSend, + // .ui32TimeoutMs = 0, //Use non-blocking xfer + .ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER, .pui32BytesTransferred = (uint32_t *)&ui32BytesWritten, }; am_hal_uart_transfer(_handle, &sUartWrite); } - else - { - //UART is already sending bytes so load the ring buffer instead - for (int x = 0; x < size; x++) - _tx_buffer.store_char(buffer[x]); - ui32BytesWritten = size; - } - return ui32BytesWritten; + + //Transfer any remaining bytes into ring buffer + for (int x = 0; x < size; x++) + _tx_buffer.store_char(buffer[x]); + + return ui32BytesWritten; //Return number of bytes pushed to UART hardware } // Stop Bits From 38f7fca6c4c8f616ac39e12ea03eaf21f902949c Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 2 Dec 2019 12:32:42 -0700 Subject: [PATCH 04/11] Add blocking delay if the TX ring buffer is full --- cores/arduino/ard_sup/uart/ap3_uart.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cores/arduino/ard_sup/uart/ap3_uart.cpp b/cores/arduino/ard_sup/uart/ap3_uart.cpp index 44e34fbf..b907d9cc 100644 --- a/cores/arduino/ard_sup/uart/ap3_uart.cpp +++ b/cores/arduino/ard_sup/uart/ap3_uart.cpp @@ -151,7 +151,12 @@ size_t Uart::write(const uint8_t *buffer, size_t size) //Transfer any remaining bytes into ring buffer for (int x = 0; x < size; x++) + { + //If TX ring buffer is full, begin blocking + while (_tx_buffer.availableForStore() == 0) + delay(1); _tx_buffer.store_char(buffer[x]); + } return ui32BytesWritten; //Return number of bytes pushed to UART hardware } From b9507127452884072d3a370c0b7a98a5c28dc3b6 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 2 Dec 2019 12:38:27 -0700 Subject: [PATCH 05/11] Fix availableForWrite --- cores/arduino/ard_sup/uart/ap3_uart.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cores/arduino/ard_sup/uart/ap3_uart.cpp b/cores/arduino/ard_sup/uart/ap3_uart.cpp index b907d9cc..03a77d25 100644 --- a/cores/arduino/ard_sup/uart/ap3_uart.cpp +++ b/cores/arduino/ard_sup/uart/ap3_uart.cpp @@ -90,8 +90,7 @@ int Uart::available() int Uart::availableForWrite() { - // return _tx_buffer.availableForStore(); - return 127; // todo: + return _tx_buffer.availableForStore(); } int Uart::peek() From 3855222262ebe67a4e51fc99889d150edf31fec0 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 2 Dec 2019 12:45:15 -0700 Subject: [PATCH 06/11] Remove old/dead code --- cores/arduino/ard_sup/ap3_uart.h | 20 -------------------- cores/arduino/ard_sup/uart/ap3_uart.cpp | 1 - 2 files changed, 21 deletions(-) diff --git a/cores/arduino/ard_sup/ap3_uart.h b/cores/arduino/ard_sup/ap3_uart.h index 2331e3f2..5f7a671c 100644 --- a/cores/arduino/ard_sup/ap3_uart.h +++ b/cores/arduino/ard_sup/ap3_uart.h @@ -86,26 +86,6 @@ class Uart : public HardwareSerial ap3_err_t set_config(HardwareSerial_Config_e HWSconfig); ap3_err_t _begin(void); // call once all members + config structure are set up - - // ap3_err_t initialize( void ); - - // SERCOM *sercom; - // RingBuffer rxBuffer; - // RingBuffer txBuffer; - - // uint8_t uc_pinRX; - // uint8_t uc_pinTX; - // SercomRXPad uc_padRX; - // SercomUartTXPad uc_padTX; - // uint8_t uc_pinRTS; - // volatile uint32_t* pul_outsetRTS; - // volatile uint32_t* pul_outclrRTS; - // uint32_t ul_pinMaskRTS; - // uint8_t uc_pinCTS; - - // SercomNumberStopBit extractNbStopBit(uint16_t config); - // SercomUartCharSize extractCharSize(uint16_t config); - // SercomParityMode extractParity(uint16_t config); }; #endif // _AP3_UART_H_ \ No newline at end of file diff --git a/cores/arduino/ard_sup/uart/ap3_uart.cpp b/cores/arduino/ard_sup/uart/ap3_uart.cpp index 03a77d25..d6c690ec 100644 --- a/cores/arduino/ard_sup/uart/ap3_uart.cpp +++ b/cores/arduino/ard_sup/uart/ap3_uart.cpp @@ -141,7 +141,6 @@ size_t Uart::write(const uint8_t *buffer, size_t size) .ui32Direction = AM_HAL_UART_WRITE, .pui8Data = (uint8_t *)tempTX, .ui32NumBytes = amtToSend, - // .ui32TimeoutMs = 0, //Use non-blocking xfer .ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER, .pui32BytesTransferred = (uint32_t *)&ui32BytesWritten, }; From 56c10d21ae15ee68be1ee1b5d111a6a58c0bacc5 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 2 Dec 2019 13:20:11 -0700 Subject: [PATCH 07/11] Fix bug: Start buffering where initial TX loading left off --- cores/arduino/ard_sup/uart/ap3_uart.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cores/arduino/ard_sup/uart/ap3_uart.cpp b/cores/arduino/ard_sup/uart/ap3_uart.cpp index d6c690ec..59b7e3b7 100644 --- a/cores/arduino/ard_sup/uart/ap3_uart.cpp +++ b/cores/arduino/ard_sup/uart/ap3_uart.cpp @@ -117,6 +117,7 @@ size_t Uart::write(const uint8_t data) size_t Uart::write(const uint8_t *buffer, size_t size) { uint32_t ui32BytesWritten = 0; + uint32_t remaining = size; //FIFO on Apollo3 is 32 bytes @@ -125,11 +126,11 @@ size_t Uart::write(const uint8_t *buffer, size_t size) am_hal_uart_flags_get(_handle, &uartFlags); if (uartFlags & AM_HAL_UART_FR_TX_EMPTY) { - uint32_t amtToSend = size; + uint32_t amtToSend = remaining; if (amtToSend > AM_HAL_UART_FIFO_MAX) amtToSend = AM_HAL_UART_FIFO_MAX; - size -= amtToSend; + remaining -= amtToSend; //Transfer to local buffer uint8_t tempTX[AM_HAL_UART_FIFO_MAX]; @@ -148,7 +149,7 @@ size_t Uart::write(const uint8_t *buffer, size_t size) } //Transfer any remaining bytes into ring buffer - for (int x = 0; x < size; x++) + for (int x = size - remaining; x < size; x++) { //If TX ring buffer is full, begin blocking while (_tx_buffer.availableForStore() == 0) From 86d4cd1558c104e9d2205c1c3bb4beb2bb502801 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Tue, 3 Dec 2019 11:52:59 -0700 Subject: [PATCH 08/11] Change name of ISR --- cores/arduino/ard_sup/ap3_uart.h | 2 +- cores/arduino/ard_sup/uart/ap3_uart.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cores/arduino/ard_sup/ap3_uart.h b/cores/arduino/ard_sup/ap3_uart.h index 5f7a671c..d983267d 100644 --- a/cores/arduino/ard_sup/ap3_uart.h +++ b/cores/arduino/ard_sup/ap3_uart.h @@ -67,7 +67,7 @@ class Uart : public HardwareSerial uint32_t printf(const char *pcFmt, ...); using Print::write; // pull in write(str) and write(buf, size) from Print - void rx_isr(void); + void uart_isr(void); operator bool() { return true; } // todo: wait for a serial terminal to be open... probably depends on RTS or CTS... diff --git a/cores/arduino/ard_sup/uart/ap3_uart.cpp b/cores/arduino/ard_sup/uart/ap3_uart.cpp index 59b7e3b7..f7f196eb 100644 --- a/cores/arduino/ard_sup/uart/ap3_uart.cpp +++ b/cores/arduino/ard_sup/uart/ap3_uart.cpp @@ -514,7 +514,7 @@ ap3_err_t ap3_uart_pad_funcsel(uint8_t instance, ap3_uart_pad_type_e type, ap3_g // Interrupt handler for the UART. // //***************************************************************************** -inline void Uart::rx_isr(void) +inline void Uart::uart_isr(void) { uint32_t ui32Status; @@ -579,7 +579,7 @@ extern "C" void am_uart_isr(void) { if (ap3_uart_handles[0] != NULL) { - ap3_uart_handles[0]->rx_isr(); + ap3_uart_handles[0]->uart_isr(); } } @@ -587,6 +587,6 @@ extern "C" void am_uart1_isr(void) { if (ap3_uart_handles[1] != NULL) { - ap3_uart_handles[1]->rx_isr(); + ap3_uart_handles[1]->uart_isr(); } } From 15da778a61dff07d7d27bdeb9bb8a69fdc666d71 Mon Sep 17 00:00:00 2001 From: Owen L - SFE Date: Tue, 3 Dec 2019 12:06:51 -0700 Subject: [PATCH 09/11] clarify changes to HAL --- .../am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c | 161 +++++++++--------- 1 file changed, 83 insertions(+), 78 deletions(-) diff --git a/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c b/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c index d6023173..0b5a241f 100644 --- a/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c +++ b/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c @@ -15,24 +15,24 @@ // // Copyright (c) 2019, Ambiq Micro // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the copyright holder nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. -// +// // Third party software included in this distribution is subject to the // additional license terms as defined in the /docs/licenses directory. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -58,11 +58,11 @@ // UART magic number for handle verification. // //***************************************************************************** -#define AM_HAL_MAGIC_UART 0xEA9E06 +#define AM_HAL_MAGIC_UART 0xEA9E06 -#define AM_HAL_UART_CHK_HANDLE(h) \ - ((h) && \ - ((am_hal_handle_prefix_t *)(h))->s.bInit && \ +#define AM_HAL_UART_CHK_HANDLE(h) \ + ((h) && \ + ((am_hal_handle_prefix_t *)(h))->s.bInit && \ (((am_hal_handle_prefix_t *)(h))->s.magic == AM_HAL_MAGIC_UART)) //***************************************************************************** @@ -70,10 +70,10 @@ // Convenience macro for passing errors. // //***************************************************************************** -#define RETURN_ON_ERROR(x) \ - if ((x) != AM_HAL_STATUS_SUCCESS) \ - { \ - return (x); \ +#define RETURN_ON_ERROR(x) \ + if ((x) != AM_HAL_STATUS_SUCCESS) \ + { \ + return (x); \ }; //***************************************************************************** @@ -81,8 +81,8 @@ // Baudrate to byte-time in microseconds with a little extra margin. // //***************************************************************************** -#define ONE_BYTE_US(baudrate) (12000000 / (baudrate)) -#define ONE_BYTE_DELAY(handle) \ +#define ONE_BYTE_US(baudrate) (12000000/(baudrate)) +#define ONE_BYTE_DELAY(handle) \ am_hal_flash_delay(FLASH_CYCLES_US(ONE_BYTE_US((handle)->ui32BaudRate))) //***************************************************************************** @@ -100,7 +100,8 @@ typedef struct uint32_t regCR; uint32_t regIFLS; uint32_t regIER; -} am_hal_uart_register_state_t; +} +am_hal_uart_register_state_t; //***************************************************************************** // @@ -121,7 +122,8 @@ typedef struct am_hal_queue_t sRxQueue; uint32_t ui32BaudRate; -} am_hal_uart_state_t; +} +am_hal_uart_state_t; //***************************************************************************** // @@ -167,7 +169,7 @@ am_hal_uart_initialize(uint32_t ui32Module, void **ppHandle) // // Check that the request module is in range. // - if (ui32Module >= AM_REG_UART_NUM_MODULES) + if (ui32Module >= AM_REG_UART_NUM_MODULES ) { return AM_HAL_STATUS_OUT_OF_RANGE; } @@ -249,11 +251,12 @@ am_hal_uart_power_control(void *pHandle, am_hal_sysctrl_power_state_e ePowerState, bool bRetainState) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; - am_hal_pwrctrl_periph_e eUARTPowerModule = ((am_hal_pwrctrl_periph_e)(AM_HAL_PWRCTRL_PERIPH_UART0 + - ui32Module)); + am_hal_pwrctrl_periph_e eUARTPowerModule = ((am_hal_pwrctrl_periph_e) + (AM_HAL_PWRCTRL_PERIPH_UART0 + + ui32Module)); // // Check to make sure this is a valid handle. @@ -357,7 +360,7 @@ am_hal_uart_power_control(void *pHandle, uint32_t am_hal_uart_configure(void *pHandle, const am_hal_uart_config_t *psConfig) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; uint32_t ui32ErrorStatus; @@ -401,7 +404,7 @@ am_hal_uart_configure(void *pHandle, const am_hal_uart_config_t *psConfig) // Set the baud rate. // ui32ErrorStatus = config_baudrate(ui32Module, psConfig->ui32BaudRate, - &(pState->ui32BaudRate)); + &(pState->ui32BaudRate)); RETURN_ON_ERROR(ui32ErrorStatus); @@ -414,9 +417,9 @@ am_hal_uart_configure(void *pHandle, const am_hal_uart_config_t *psConfig) UARTn(ui32Module)->IFLS = psConfig->ui32FifoLevels; - UARTn(ui32Module)->LCRH = (psConfig->ui32DataBits | - psConfig->ui32Parity | - psConfig->ui32StopBits | + UARTn(ui32Module)->LCRH = (psConfig->ui32DataBits | + psConfig->ui32Parity | + psConfig->ui32StopBits | AM_HAL_UART_FIFO_ENABLE); // @@ -451,7 +454,7 @@ static uint32_t buffer_configure(void *pHandle, uint8_t *pui8TxBuffer, uint32_t ui32TxBufferSize, uint8_t *pui8RxBuffer, uint32_t ui32RxBufferSize) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32ErrorStatus; // @@ -516,7 +519,7 @@ buffer_configure(void *pHandle, uint8_t *pui8TxBuffer, uint32_t ui32TxBufferSize // Set Baud Rate based on the UART clock frequency. // //***************************************************************************** -#define BAUDCLK (16) // Number of UART clocks needed per bit. +#define BAUDCLK (16) // Number of UART clocks needed per bit. static uint32_t config_baudrate(uint32_t ui32Module, uint32_t ui32DesiredBaudrate, uint32_t *pui32ActualBaud) { @@ -532,40 +535,40 @@ config_baudrate(uint32_t ui32Module, uint32_t ui32DesiredBaudrate, uint32_t *pui // if (APOLLO3_A1) { - if (ui32DesiredBaudrate > AM_HAL_UART_MAXIMUM_BAUDRATE_A1) - { - return AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE; - } + if (ui32DesiredBaudrate > AM_HAL_UART_MAXIMUM_BAUDRATE_A1) + { + return AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE; + } } if (APOLLO3_GE_B0) { - if (ui32DesiredBaudrate > AM_HAL_UART_MAXIMUM_BAUDRATE_B0) - { - return AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE; - } + if (ui32DesiredBaudrate > AM_HAL_UART_MAXIMUM_BAUDRATE_B0) + { + return AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE; + } } - switch (UARTn(ui32Module)->CR_b.CLKSEL) + switch ( UARTn(ui32Module)->CR_b.CLKSEL ) { - case UART0_CR_CLKSEL_24MHZ: - ui32UartClkFreq = 24000000; - break; + case UART0_CR_CLKSEL_24MHZ: + ui32UartClkFreq = 24000000; + break; - case UART0_CR_CLKSEL_12MHZ: - ui32UartClkFreq = 12000000; - break; + case UART0_CR_CLKSEL_12MHZ: + ui32UartClkFreq = 12000000; + break; - case UART0_CR_CLKSEL_6MHZ: - ui32UartClkFreq = 6000000; - break; + case UART0_CR_CLKSEL_6MHZ: + ui32UartClkFreq = 6000000; + break; - case UART0_CR_CLKSEL_3MHZ: - ui32UartClkFreq = 3000000; - break; + case UART0_CR_CLKSEL_3MHZ: + ui32UartClkFreq = 3000000; + break; - default: - *pui32ActualBaud = 0; - return AM_HAL_UART_STATUS_CLOCK_NOT_CONFIGURED; + default: + *pui32ActualBaud = 0; + return AM_HAL_UART_STATUS_CLOCK_NOT_CONFIGURED; } // @@ -614,7 +617,7 @@ uart_fifo_read(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t ui32ReadData; uint32_t ui32ErrorStatus = AM_HAL_STATUS_SUCCESS; - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; // @@ -626,7 +629,7 @@ uart_fifo_read(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, // If the fifo is empty, return with the number of bytes we read. // Otherwise, read the data into the provided buffer. // - if (UARTn(ui32Module)->FR_b.RXFE) + if ( UARTn(ui32Module)->FR_b.RXFE ) { break; } @@ -640,9 +643,9 @@ uart_fifo_read(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, if (ui32ReadData & (_VAL2FLD(UART0_DR_OEDATA, UART0_DR_OEDATA_ERR) | _VAL2FLD(UART0_DR_BEDATA, UART0_DR_BEDATA_ERR) | _VAL2FLD(UART0_DR_PEDATA, UART0_DR_PEDATA_ERR) | - _VAL2FLD(UART0_DR_FEDATA, UART0_DR_FEDATA_ERR))) + _VAL2FLD(UART0_DR_FEDATA, UART0_DR_FEDATA_ERR)) ) { - ui32ErrorStatus = AM_HAL_UART_STATUS_BUS_ERROR; + ui32ErrorStatus = AM_HAL_UART_STATUS_BUS_ERROR; break; } else @@ -671,7 +674,7 @@ uart_fifo_write(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, { uint32_t i = 0; - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; // @@ -683,7 +686,7 @@ uart_fifo_write(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, // If the TX FIFO is full, break out of the loop. We've sent everything // we can. // - if (UARTn(ui32Module)->FR_b.TXFF) + if ( UARTn(ui32Module)->FR_b.TXFF ) { break; } @@ -717,7 +720,7 @@ read_nonblocking(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t ui32BytesTransferred; uint32_t ui32ErrorStatus = AM_HAL_STATUS_SUCCESS; - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; // // Check to make sure this is a valid handle. @@ -754,7 +757,8 @@ read_nonblocking(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, ui32BufferData = am_hal_queue_data_left(&pState->sRxQueue); - ui32BytesTransferred = (ui32NumBytes < ui32BufferData ? ui32NumBytes : ui32BufferData); + ui32BytesTransferred = (ui32NumBytes < ui32BufferData ? + ui32NumBytes : ui32BufferData); am_hal_queue_item_get(&pState->sRxQueue, pui8Data, ui32BytesTransferred); } @@ -792,7 +796,7 @@ write_nonblocking(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t ui32BufferSpace; uint32_t ui32BytesTransferred; - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; // // Check to make sure this is a valid handle. @@ -827,7 +831,8 @@ write_nonblocking(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, // ui32BufferSpace = am_hal_queue_space_left(&pState->sTxQueue); - ui32BytesTransferred = (ui32NumBytes < ui32BufferSpace ? ui32NumBytes : ui32BufferSpace); + ui32BytesTransferred = (ui32NumBytes < ui32BufferSpace ? + ui32NumBytes : ui32BufferSpace); am_hal_queue_item_add(&pState->sTxQueue, pui8Data, ui32BytesTransferred); @@ -869,7 +874,7 @@ read_timeout(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t *pui32NumBytesRead, uint32_t ui32TimeoutMs) { uint32_t ui32Status, ui32BytesRead, ui32RemainingBytes, - ui32TimeSpent, i; + ui32TimeSpent, i; // // If we don't have a timeout, just pass this directly to the nonblocking @@ -948,7 +953,7 @@ write_timeout(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t *pui32NumBytesWritten, uint32_t ui32TimeoutMs) { uint32_t ui32Status, ui32BytesWritten, ui32RemainingBytes, - ui32TimeSpent, i; + ui32TimeSpent, i; i = 0; ui32RemainingBytes = ui32NumBytes; @@ -1055,7 +1060,7 @@ am_hal_uart_transfer(void *pHandle, const am_hal_uart_transfer_t *pTransfer) uint32_t am_hal_uart_tx_flush(void *pHandle) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; // @@ -1072,7 +1077,7 @@ am_hal_uart_tx_flush(void *pHandle) // // Wait for the TX busy bit to go low. // - while (UARTn(ui32Module)->FR_b.BUSY) + while ( UARTn(ui32Module)->FR_b.BUSY ) { ONE_BYTE_DELAY(pState); } @@ -1088,7 +1093,7 @@ am_hal_uart_tx_flush(void *pHandle) uint32_t am_hal_uart_flags_get(void *pHandle, uint32_t *ui32Flags) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; // @@ -1115,7 +1120,7 @@ am_hal_uart_flags_get(void *pHandle, uint32_t *ui32Flags) static uint32_t rx_queue_update(void *pHandle) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint8_t pui8Data[AM_HAL_UART_FIFO_MAX]; uint32_t ui32BytesTransferred; @@ -1154,7 +1159,7 @@ rx_queue_update(void *pHandle) static uint32_t tx_queue_update(void *pHandle) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; uint8_t pui8Data; @@ -1166,7 +1171,7 @@ tx_queue_update(void *pHandle) // // Loop as long as the TX fifo isn't full yet. // - while (!UARTn(ui32Module)->FR_b.TXFF) + while ( !UARTn(ui32Module)->FR_b.TXFF ) { // // Attempt to grab an item from the queue, and add it to the fifo. @@ -1203,7 +1208,7 @@ tx_queue_update(void *pHandle) uint32_t am_hal_uart_interrupt_service(void *pHandle, uint32_t ui32Status, uint32_t *pui32UartTxIdle) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; uint32_t ui32ErrorStatus; @@ -1250,13 +1255,13 @@ am_hal_uart_interrupt_service(void *pHandle, uint32_t ui32Status, uint32_t *pui3 // if (pState->bEnableTxQueue) { - if (am_hal_queue_empty(&(pState->sTxQueue)) && - (UARTn(ui32Module)->FR_b.BUSY == false)) + if ( am_hal_queue_empty(&(pState->sTxQueue) ) && + ( UARTn(ui32Module)->FR_b.BUSY == false ) ) { *pui32UartTxIdle = true; } } - else if (UARTn(ui32Module)->FR_b.BUSY == false) + else if ( UARTn(ui32Module)->FR_b.BUSY == false ) { *pui32UartTxIdle = true; } @@ -1276,7 +1281,7 @@ am_hal_uart_interrupt_service(void *pHandle, uint32_t ui32Status, uint32_t *pui3 uint32_t am_hal_uart_interrupt_enable(void *pHandle, uint32_t ui32IntMask) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; if (!AM_HAL_UART_CHK_HANDLE(pHandle)) @@ -1297,7 +1302,7 @@ am_hal_uart_interrupt_enable(void *pHandle, uint32_t ui32IntMask) uint32_t am_hal_uart_interrupt_disable(void *pHandle, uint32_t ui32IntMask) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; if (!AM_HAL_UART_CHK_HANDLE(pHandle)) @@ -1339,7 +1344,7 @@ am_hal_uart_interrupt_clear(void *pHandle, uint32_t ui32IntMask) uint32_t am_hal_uart_interrupt_status_get(void *pHandle, uint32_t *pui32Status, bool bEnabledOnly) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; if (!AM_HAL_UART_CHK_HANDLE(pHandle)) From 03a1aa615d33f05fa11b7602852889a67a07e4da Mon Sep 17 00:00:00 2001 From: Owen L - SFE Date: Tue, 3 Dec 2019 12:10:39 -0700 Subject: [PATCH 10/11] more clarity --- .../am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c | 126 +++++++++--------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c b/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c index 0b5a241f..d6aacf56 100644 --- a/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c +++ b/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c @@ -271,79 +271,79 @@ am_hal_uart_power_control(void *pHandle, // switch (ePowerState) { - // - // Turn on the UART. - // - case AM_HAL_SYSCTRL_WAKE: - // - // Make sure we don't try to restore an invalid state. - // - if (bRetainState && !pState->sRegState.bValid) - { - return AM_HAL_STATUS_INVALID_OPERATION; - } - // - // Enable power control. + // Turn on the UART. // - am_hal_pwrctrl_periph_enable(eUARTPowerModule); - - if (bRetainState) - { + case AM_HAL_SYSCTRL_WAKE: // - // Restore UART registers + // Make sure we don't try to restore an invalid state. // - AM_CRITICAL_BEGIN - - UARTn(ui32Module)->ILPR = pState->sRegState.regILPR; - UARTn(ui32Module)->IBRD = pState->sRegState.regIBRD; - UARTn(ui32Module)->FBRD = pState->sRegState.regFBRD; - UARTn(ui32Module)->LCRH = pState->sRegState.regLCRH; - UARTn(ui32Module)->CR = pState->sRegState.regCR; - UARTn(ui32Module)->IFLS = pState->sRegState.regIFLS; - UARTn(ui32Module)->IER = pState->sRegState.regIER; - - pState->sRegState.bValid = false; + if (bRetainState && !pState->sRegState.bValid) + { + return AM_HAL_STATUS_INVALID_OPERATION; + } - AM_CRITICAL_END - } - break; + // + // Enable power control. + // + am_hal_pwrctrl_periph_enable(eUARTPowerModule); - // - // Turn off the UART. - // - case AM_HAL_SYSCTRL_NORMALSLEEP: - case AM_HAL_SYSCTRL_DEEPSLEEP: - if (bRetainState) - { - AM_CRITICAL_BEGIN - - pState->sRegState.regILPR = UARTn(ui32Module)->ILPR; - pState->sRegState.regIBRD = UARTn(ui32Module)->IBRD; - pState->sRegState.regFBRD = UARTn(ui32Module)->FBRD; - pState->sRegState.regLCRH = UARTn(ui32Module)->LCRH; - pState->sRegState.regCR = UARTn(ui32Module)->CR; - pState->sRegState.regIFLS = UARTn(ui32Module)->IFLS; - pState->sRegState.regIER = UARTn(ui32Module)->IER; - pState->sRegState.bValid = true; - - AM_CRITICAL_END - } + if (bRetainState) + { + // + // Restore UART registers + // + AM_CRITICAL_BEGIN + + UARTn(ui32Module)->ILPR = pState->sRegState.regILPR; + UARTn(ui32Module)->IBRD = pState->sRegState.regIBRD; + UARTn(ui32Module)->FBRD = pState->sRegState.regFBRD; + UARTn(ui32Module)->LCRH = pState->sRegState.regLCRH; + UARTn(ui32Module)->CR = pState->sRegState.regCR; + UARTn(ui32Module)->IFLS = pState->sRegState.regIFLS; + UARTn(ui32Module)->IER = pState->sRegState.regIER; + + pState->sRegState.bValid = false; + + AM_CRITICAL_END + } + break; // - // Clear all interrupts before sleeping as having a pending UART - // interrupt burns power. + // Turn off the UART. // - am_hal_uart_interrupt_clear(pState, 0xFFFFFFFF); + case AM_HAL_SYSCTRL_NORMALSLEEP: + case AM_HAL_SYSCTRL_DEEPSLEEP: + if (bRetainState) + { + AM_CRITICAL_BEGIN + + pState->sRegState.regILPR = UARTn(ui32Module)->ILPR; + pState->sRegState.regIBRD = UARTn(ui32Module)->IBRD; + pState->sRegState.regFBRD = UARTn(ui32Module)->FBRD; + pState->sRegState.regLCRH = UARTn(ui32Module)->LCRH; + pState->sRegState.regCR = UARTn(ui32Module)->CR; + pState->sRegState.regIFLS = UARTn(ui32Module)->IFLS; + pState->sRegState.regIER = UARTn(ui32Module)->IER; + pState->sRegState.bValid = true; + + AM_CRITICAL_END + } - // - // Disable power control. - // - am_hal_pwrctrl_periph_disable(eUARTPowerModule); - break; + // + // Clear all interrupts before sleeping as having a pending UART + // interrupt burns power. + // + am_hal_uart_interrupt_clear(pState, 0xFFFFFFFF); - default: - return AM_HAL_STATUS_INVALID_ARG; + // + // Disable power control. + // + am_hal_pwrctrl_periph_disable(eUARTPowerModule); + break; + + default: + return AM_HAL_STATUS_INVALID_ARG; } // @@ -1323,7 +1323,7 @@ am_hal_uart_interrupt_disable(void *pHandle, uint32_t ui32IntMask) uint32_t am_hal_uart_interrupt_clear(void *pHandle, uint32_t ui32IntMask) { - am_hal_uart_state_t *pState = (am_hal_uart_state_t *)pHandle; + am_hal_uart_state_t *pState = (am_hal_uart_state_t *) pHandle; uint32_t ui32Module = pState->ui32Module; if (!AM_HAL_UART_CHK_HANDLE(pHandle)) From 3eacc3ba329cfe3db94191f4255185e922d6e31a Mon Sep 17 00:00:00 2001 From: Owen L - SFE Date: Tue, 3 Dec 2019 12:12:33 -0700 Subject: [PATCH 11/11] modify whitespace --- cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c b/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c index d6aacf56..e7797a97 100644 --- a/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c +++ b/cores/arduino/am_sdk_ap3/mcu/apollo3/hal/am_hal_uart.c @@ -81,7 +81,7 @@ // Baudrate to byte-time in microseconds with a little extra margin. // //***************************************************************************** -#define ONE_BYTE_US(baudrate) (12000000/(baudrate)) +#define ONE_BYTE_US(baudrate) (12000000/(baudrate)) #define ONE_BYTE_DELAY(handle) \ am_hal_flash_delay(FLASH_CYCLES_US(ONE_BYTE_US((handle)->ui32BaudRate))) @@ -299,9 +299,9 @@ am_hal_uart_power_control(void *pHandle, UARTn(ui32Module)->IBRD = pState->sRegState.regIBRD; UARTn(ui32Module)->FBRD = pState->sRegState.regFBRD; UARTn(ui32Module)->LCRH = pState->sRegState.regLCRH; - UARTn(ui32Module)->CR = pState->sRegState.regCR; + UARTn(ui32Module)->CR = pState->sRegState.regCR; UARTn(ui32Module)->IFLS = pState->sRegState.regIFLS; - UARTn(ui32Module)->IER = pState->sRegState.regIER; + UARTn(ui32Module)->IER = pState->sRegState.regIER; pState->sRegState.bValid = false; @@ -322,9 +322,9 @@ am_hal_uart_power_control(void *pHandle, pState->sRegState.regIBRD = UARTn(ui32Module)->IBRD; pState->sRegState.regFBRD = UARTn(ui32Module)->FBRD; pState->sRegState.regLCRH = UARTn(ui32Module)->LCRH; - pState->sRegState.regCR = UARTn(ui32Module)->CR; + pState->sRegState.regCR = UARTn(ui32Module)->CR; pState->sRegState.regIFLS = UARTn(ui32Module)->IFLS; - pState->sRegState.regIER = UARTn(ui32Module)->IER; + pState->sRegState.regIER = UARTn(ui32Module)->IER; pState->sRegState.bValid = true; AM_CRITICAL_END