From 3c1cf090d5709f3900426084a1615e489974963a Mon Sep 17 00:00:00 2001 From: Sihyung Woo <75494566+sihyung-maxim@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:40:24 -0500 Subject: [PATCH] fix(PeriphDrivers): Add UART Clock Setter API for all parts using UART RevB Drivers (#1113) Co-authored-by: sihyung-maxim --- .../PeriphDrivers/Include/MAX32572/uart.h | 14 +- .../PeriphDrivers/Include/MAX32655/uart.h | 9 + .../PeriphDrivers/Include/MAX32662/uart.h | 9 + .../PeriphDrivers/Include/MAX32690/uart.h | 7 + .../PeriphDrivers/Include/MAX78000/uart.h | 9 + .../PeriphDrivers/Include/MAX78002/uart.h | 7 + .../PeriphDrivers/Source/UART/uart_ai85.c | 162 +++++++++++------ .../PeriphDrivers/Source/UART/uart_me12.c | 97 +++++++--- .../PeriphDrivers/Source/UART/uart_me17.c | 169 +++++++++++------- .../PeriphDrivers/Source/UART/uart_me55.c | 82 +++++++-- 10 files changed, 410 insertions(+), 155 deletions(-) diff --git a/Libraries/PeriphDrivers/Include/MAX32572/uart.h b/Libraries/PeriphDrivers/Include/MAX32572/uart.h index 19dbd02252..ce9e84fd4f 100644 --- a/Libraries/PeriphDrivers/Include/MAX32572/uart.h +++ b/Libraries/PeriphDrivers/Include/MAX32572/uart.h @@ -78,14 +78,9 @@ typedef enum { /** * @brief Clock settings */ typedef enum { - /*For UART3 APB clock source is the 8MHz clock*/ MXC_UART_APB_CLK = 0, - MXC_UART_EXT_CLK = 1, - /*IBRO and ERFO clock can only be used for UART 0, 1 & 2*/ MXC_UART_IBRO_CLK = 2, MXC_UART_ERFO_CLK = 3, - /*ERTCO clock can only be used for UART3*/ - MXC_UART_ERTCO_CLK = 4, } mxc_uart_clock_t; /** @@ -254,6 +249,15 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt */ int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock); +/** + * @brief Gets the clock source used for the UART instance + * + * @param uart Pointer to UART registers (selects the UART block used.) + * + * @return The selected clock source for the UART instance + */ +mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ diff --git a/Libraries/PeriphDrivers/Include/MAX32655/uart.h b/Libraries/PeriphDrivers/Include/MAX32655/uart.h index 91d743d129..92f1fcfc2b 100644 --- a/Libraries/PeriphDrivers/Include/MAX32655/uart.h +++ b/Libraries/PeriphDrivers/Include/MAX32655/uart.h @@ -257,6 +257,15 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt */ int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock); +/** + * @brief Gets the clock source used for the UART instance + * + * @param uart Pointer to UART registers (selects the UART block used.) + * + * @return The selected clock source for the UART instance + */ +mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ diff --git a/Libraries/PeriphDrivers/Include/MAX32662/uart.h b/Libraries/PeriphDrivers/Include/MAX32662/uart.h index cce341c712..120def82e0 100644 --- a/Libraries/PeriphDrivers/Include/MAX32662/uart.h +++ b/Libraries/PeriphDrivers/Include/MAX32662/uart.h @@ -256,6 +256,15 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt */ int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock); +/** + * @brief Gets the clock source used for the UART instance + * + * @param uart Pointer to UART registers (selects the UART block used.) + * + * @return The selected clock source for the UART instance + */ +mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ diff --git a/Libraries/PeriphDrivers/Include/MAX32690/uart.h b/Libraries/PeriphDrivers/Include/MAX32690/uart.h index a390290e04..cd5fcf9e77 100644 --- a/Libraries/PeriphDrivers/Include/MAX32690/uart.h +++ b/Libraries/PeriphDrivers/Include/MAX32690/uart.h @@ -255,6 +255,13 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt */ int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock); +/** + * @brief Gets the clock source used for the UART instance + * + * @param uart Pointer to UART registers (selects the UART block used.) + * + * @return The selected clock source for the UART instance + */ mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart); /** diff --git a/Libraries/PeriphDrivers/Include/MAX78000/uart.h b/Libraries/PeriphDrivers/Include/MAX78000/uart.h index 2d280e8011..212cc6190c 100644 --- a/Libraries/PeriphDrivers/Include/MAX78000/uart.h +++ b/Libraries/PeriphDrivers/Include/MAX78000/uart.h @@ -252,6 +252,15 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt */ int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock); +/** + * @brief Gets the clock source used for the UART instance + * + * @param uart Pointer to UART registers (selects the UART block used.) + * + * @return The selected clock source for the UART instance + */ +mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ diff --git a/Libraries/PeriphDrivers/Include/MAX78002/uart.h b/Libraries/PeriphDrivers/Include/MAX78002/uart.h index 7fa3faaac4..49a0865bd8 100644 --- a/Libraries/PeriphDrivers/Include/MAX78002/uart.h +++ b/Libraries/PeriphDrivers/Include/MAX78002/uart.h @@ -244,6 +244,13 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt */ int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock); +/** + * @brief Gets the clock source used for the UART instance + * + * @param uart Pointer to UART registers (selects the UART block used.) + * + * @return The selected clock source for the UART instance + */ mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart); /** diff --git a/Libraries/PeriphDrivers/Source/UART/uart_ai85.c b/Libraries/PeriphDrivers/Source/UART/uart_ai85.c index 8a10a82604..d0e07fd820 100644 --- a/Libraries/PeriphDrivers/Source/UART/uart_ai85.c +++ b/Libraries/PeriphDrivers/Source/UART/uart_ai85.c @@ -47,24 +47,10 @@ int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clo int retval; retval = MXC_UART_Shutdown(uart); - if (retval) { return retval; } - switch (clock) { - case MXC_UART_ERTCO_CLK: - MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO); - break; - - case MXC_UART_IBRO_CLK: - MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); - break; - - default: - break; - } - switch (MXC_UART_GET_IDX(uart)) { case 0: MXC_GPIO_Config(&gpio_cfg_uart0); @@ -90,6 +76,11 @@ int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clo return E_BAD_PARAM; } + retval = MXC_UART_SetClockSource(uart, clock); + if (retval != E_NO_ERROR) { + return retval; + } + return MXC_UART_RevB_Init((mxc_uart_revb_regs_t *)uart, baud, clock); } @@ -130,59 +121,53 @@ int MXC_UART_ReadyForSleep(mxc_uart_regs_t *uart) int MXC_UART_SetFrequency(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clock) { - int frequency, clkDiv = 0, mod = 0; + int freq; + uint32_t clock_freq = 0; + if (MXC_UART_GET_IDX(uart) < 0) { return E_BAD_PARAM; } - // check if the uart is LPUART - if (uart == MXC_UART3) { - // OSR default value - uart->osr = 5; - - switch (clock) { - case MXC_UART_APB_CLK: - case MXC_UART_IBRO_CLK: - clkDiv = ((IBRO_FREQ) / baud); - mod = ((IBRO_FREQ) % baud); - break; + switch (clock) { + case MXC_UART_APB_CLK: + clock_freq = SystemCoreClock / 2; + break; - case MXC_UART_ERTCO_CLK: - uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_EXTERNAL_CLOCK; - uart->ctrl |= MXC_F_UART_CTRL_FDM; - clkDiv = ((ERTCO_FREQ * 2) / baud); - mod = ((ERTCO_FREQ * 2) % baud); - - if (baud > 2400) { - uart->osr = 0; - } else { - uart->osr = 1; - } - break; + case MXC_UART_IBRO_CLK: + clock_freq = IBRO_FREQ; + break; - default: + case MXC_UART_ERTCO_CLK: + // Only UART3 (LPUART0) supports ERTCO clock source. + if (uart != MXC_UART3) { return E_BAD_PARAM; } - if (!clkDiv || mod > (baud / 2)) { - clkDiv++; - } - uart->clkdiv = clkDiv; - frequency = MXC_UART_GetFrequency(uart); - } else { - if (clock == MXC_UART_ERTCO_CLK) { - return E_BAD_PARAM; + + uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_EXTERNAL_CLOCK; + uart->ctrl |= MXC_F_UART_CTRL_FDM; + + if (baud > 2400) { + uart->osr = 0; + } else { + uart->osr = 1; } - frequency = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, baud, clock); + clock_freq = ERTCO_FREQ * 2; // x2 to account for FDM. + break; + + default: + return E_BAD_PARAM; } - if (frequency > 0) { + freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, clock_freq, baud); + + if (freq > 0) { // Enable baud clock and wait for it to become ready. uart->ctrl |= MXC_F_UART_CTRL_BCLKEN; while (((uart->ctrl & MXC_F_UART_CTRL_BCLKRDY) >> MXC_F_UART_CTRL_BCLKRDY_POS) == 0) {} } - return frequency; + return freq; } int MXC_UART_GetFrequency(mxc_uart_regs_t *uart) @@ -251,7 +236,82 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock) { - return MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, clock); + int error = E_NO_ERROR; + + switch (MXC_UART_GET_IDX(uart)) { + case 0: + case 1: + case 2: + // UART0-2 support PCLK and IBRO + switch (clock) { + case MXC_UART_APB_CLK: + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 0); + break; + + case MXC_UART_IBRO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 2); + break; + + default: + return E_BAD_PARAM; + } + break; + + case 3: + // UART3 (LPUART0) supports IBRO and ERTCO + switch (clock) { + case MXC_UART_IBRO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 2); + break; + + case MXC_UART_ERTCO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 3); + break; + + default: + return E_BAD_PARAM; + } + break; + + default: + return E_BAD_PARAM; + } + + return error; +} + +mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart) +{ + unsigned int clock_option = MXC_UART_RevB_GetClockSource((mxc_uart_revb_regs_t *)uart); + switch (MXC_UART_GET_IDX(uart)) { + case 0: + case 1: + case 2: + switch (clock_option) { + case 0: + return MXC_UART_APB_CLK; + case 2: + return MXC_UART_IBRO_CLK; + default: + return E_BAD_STATE; + } + break; + case 3: + switch (clock_option) { + case 0: + return MXC_UART_IBRO_CLK; + case 1: + return MXC_UART_ERTCO_CLK; + default: + return E_BAD_STATE; + } + break; + default: + return E_BAD_PARAM; + } } int MXC_UART_GetActive(mxc_uart_regs_t *uart) diff --git a/Libraries/PeriphDrivers/Source/UART/uart_me12.c b/Libraries/PeriphDrivers/Source/UART/uart_me12.c index d010911bd5..23d9f751db 100644 --- a/Libraries/PeriphDrivers/Source/UART/uart_me12.c +++ b/Libraries/PeriphDrivers/Source/UART/uart_me12.c @@ -47,28 +47,10 @@ int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clo int retval; retval = MXC_UART_Shutdown(uart); - if (retval) { return retval; } - switch (clock) { - case MXC_UART_EXT_CLK: - MXC_GPIO_Config(&gpio_cfg_hf_extclk); - break; - - case MXC_UART_IBRO_CLK: - MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); - break; - - case MXC_UART_ERFO_CLK: - MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERFO); - break; - - default: - break; - } - if (uart == MXC_UART0) { if (map == MAP_B) { MXC_GPIO_Config(&gpio_cfg_uart0b); @@ -86,6 +68,11 @@ int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clo (void)map; #endif // MSDK_NO_GPIO_CLK_INIT + retval = MXC_UART_SetClockSource(uart, clock); + if (retval != E_NO_ERROR) { + return retval; + } + return MXC_UART_RevB_Init((mxc_uart_revb_regs_t *)uart, baud, clock); } @@ -117,12 +104,34 @@ int MXC_UART_ReadyForSleep(mxc_uart_regs_t *uart) int MXC_UART_SetFrequency(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clock) { int freq; + uint32_t clock_freq; if (MXC_UART_GET_IDX(uart) < 0) { return E_BAD_PARAM; } - freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, baud, clock); + switch (clock) { + case MXC_UART_APB_CLK: + clock_freq = SystemCoreClock / 2; + break; + + case MXC_UART_EXT_CLK: + clock_freq = HF_EXTCLK_FREQ; + break; + + case MXC_UART_IBRO_CLK: + clock_freq = IBRO_FREQ; + break; + + case MXC_UART_ERFO_CLK: + clock_freq = ERFO_FREQ; + break; + + default: + return E_BAD_PARAM; + } + + freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, clock_freq, baud); if (freq > 0) { // Enable baud clock and wait for it to become ready. @@ -192,7 +201,55 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock) { - return MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, clock); + int error = E_NO_ERROR; + + if (MXC_UART_GET_IDX(uart) < 0 || MXC_UART_GET_IDX(uart) > 1) { + return E_BAD_PARAM; + } + + // The following interprets table 12-1 from the MAX78002 UG. + switch (clock) { + case MXC_UART_APB_CLK: + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 0); + break; + + case MXC_UART_EXT_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_EXTCLK); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 1); + break; + + case MXC_UART_IBRO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 2); + break; + + case MXC_UART_ERFO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERFO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 3); + break; + + default: + return E_BAD_PARAM; + } + + return error; +} + +mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart) +{ + unsigned int clock_option = MXC_UART_RevB_GetClockSource((mxc_uart_revb_regs_t *)uart); + switch (clock_option) { + case 0: + return MXC_UART_APB_CLK; + case 1: + return MXC_UART_EXT_CLK; + case 2: + return MXC_UART_IBRO_CLK; + case 3: + return MXC_UART_ERFO_CLK; + default: + return E_BAD_PARAM; + } } int MXC_UART_GetActive(mxc_uart_regs_t *uart) diff --git a/Libraries/PeriphDrivers/Source/UART/uart_me17.c b/Libraries/PeriphDrivers/Source/UART/uart_me17.c index 3344a6e217..49308eef8a 100644 --- a/Libraries/PeriphDrivers/Source/UART/uart_me17.c +++ b/Libraries/PeriphDrivers/Source/UART/uart_me17.c @@ -48,26 +48,10 @@ int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clo int retval; retval = MXC_UART_Shutdown(uart); - if (retval) { return retval; } - switch (clock) { -#if TARGET_NUM != 32680 - case MXC_UART_ERTCO_CLK: - MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO); - break; -#endif - - case MXC_UART_IBRO_CLK: - MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); - break; - - default: - break; - } - switch (MXC_UART_GET_IDX(uart)) { case 0: MXC_GPIO_Config(&gpio_cfg_uart0); @@ -94,7 +78,12 @@ int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clo } #endif // MSDK_NO_GPIO_CLK_INIT - return MXC_UART_RevB_Init((mxc_uart_revb_regs_t *)uart, baud, clock); + retval = MXC_UART_SetClockSource(uart, clock); + if (retval != E_NO_ERROR) { + return retval; + } + + return MXC_UART_RevB_Init((mxc_uart_revb_regs_t *)uart, baud, MXC_UART_GetClockSource(uart)); } int MXC_UART_Shutdown(mxc_uart_regs_t *uart) @@ -135,66 +124,45 @@ int MXC_UART_ReadyForSleep(mxc_uart_regs_t *uart) int MXC_UART_SetFrequency(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clock) { int freq; - unsigned mod = 0; - unsigned clkDiv = 0; + uint32_t clock_freq = 0; if (MXC_UART_GET_IDX(uart) < 0) { return E_BAD_PARAM; } - // check if the uart is LPUART - if (uart == MXC_UART3) { - // OSR default value - uart->osr = 5; - - switch (clock) { - case MXC_UART_IBRO_CLK: - uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_PERIPHERAL_CLOCK; - clkDiv = ((IBRO_FREQ) / baud); - mod = ((IBRO_FREQ) % baud); - break; + switch (clock) { + case MXC_UART_APB_CLK: + clock_freq = SystemCoreClock / 2; + break; - case MXC_UART_ERTCO_CLK: - // Only supports up to 9600 baud with ERTCO clock. - if (baud > 9600) { - return E_NOT_SUPPORTED; - } - - uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_EXTERNAL_CLOCK; - uart->ctrl |= MXC_F_UART_CTRL_FDM; - if (baud == 9600) { - clkDiv = 7; - mod = 0; - } else { - clkDiv = ((ERTCO_FREQ * 2) / baud); - mod = ((ERTCO_FREQ * 2) % baud); - } - - if (baud > 2400) { - uart->osr = 0; - } else { - uart->osr = 1; - } - break; + case MXC_UART_IBRO_CLK: + clock_freq = IBRO_FREQ; + break; - default: + case MXC_UART_ERTCO_CLK: + // Only UART3 (LPUART0) supports ERTCO clock source. + if (uart != MXC_UART3) { return E_BAD_PARAM; } - if (!clkDiv || mod > (baud / 2)) { - clkDiv++; - } - uart->clkdiv = clkDiv; + uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_EXTERNAL_CLOCK; + uart->ctrl |= MXC_F_UART_CTRL_FDM; - freq = MXC_UART_GetFrequency(uart); - } else { - if (clock == MXC_UART_ERTCO_CLK) { - return E_BAD_PARAM; + if (baud > 2400) { + uart->osr = 0; + } else { + uart->osr = 1; } - freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, baud, clock); + clock_freq = ERTCO_FREQ * 2; // x2 to account for FDM. + break; + + default: + return E_BAD_PARAM; } + freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, clock_freq, baud); + if (freq > 0) { // Enable baud clock and wait for it to become ready. uart->ctrl |= MXC_F_UART_CTRL_BCLKEN; @@ -287,7 +255,82 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock) { - return MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, clock); + int error = E_NO_ERROR; + + switch (MXC_UART_GET_IDX(uart)) { + case 0: + case 1: + case 2: + // UART0-2 support PCLK and IBRO + switch (clock) { + case MXC_UART_APB_CLK: + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 0); + break; + + case MXC_UART_IBRO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 2); + break; + + default: + return E_BAD_PARAM; + } + break; + + case 3: + // UART3 (LPUART0) supports IBRO and ERTCO + switch (clock) { + case MXC_UART_IBRO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 2); + break; + + case MXC_UART_ERTCO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 3); + break; + + default: + return E_BAD_PARAM; + } + break; + + default: + return E_BAD_PARAM; + } + + return error; +} + +mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart) +{ + unsigned int clock_option = MXC_UART_RevB_GetClockSource((mxc_uart_revb_regs_t *)uart); + switch (MXC_UART_GET_IDX(uart)) { + case 0: + case 1: + case 2: + switch (clock_option) { + case 0: + return MXC_UART_APB_CLK; + case 2: + return MXC_UART_IBRO_CLK; + default: + return E_BAD_STATE; + } + break; + case 3: + switch (clock_option) { + case 0: + return MXC_UART_IBRO_CLK; + case 1: + return MXC_UART_ERTCO_CLK; + default: + return E_BAD_STATE; + } + break; + default: + return E_BAD_PARAM; + } } int MXC_UART_GetActive(mxc_uart_regs_t *uart) diff --git a/Libraries/PeriphDrivers/Source/UART/uart_me55.c b/Libraries/PeriphDrivers/Source/UART/uart_me55.c index de15b76f0e..d04def93cf 100644 --- a/Libraries/PeriphDrivers/Source/UART/uart_me55.c +++ b/Libraries/PeriphDrivers/Source/UART/uart_me55.c @@ -46,24 +46,10 @@ int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clo int retval; retval = MXC_UART_Shutdown(uart); - if (retval) { return retval; } - switch (clock) { - case MXC_UART_ERTCO_CLK: - MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO); - break; - - case MXC_UART_IBRO_CLK: - MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); - break; - - default: - break; - } - switch (MXC_UART_GET_IDX(uart)) { case 0: MXC_GPIO_Config(&gpio_cfg_uart0); @@ -89,6 +75,11 @@ int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clo return E_BAD_PARAM; } + retval = MXC_UART_SetClockSource(uart, clock); + if (retval != E_NO_ERROR) { + return retval; + } + return MXC_UART_RevB_Init((mxc_uart_revb_regs_t *)uart, baud, clock); } @@ -130,12 +121,30 @@ int MXC_UART_ReadyForSleep(mxc_uart_regs_t *uart) int MXC_UART_SetFrequency(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clock) { int freq; + uint32_t clock_freq; if (MXC_UART_GET_IDX(uart) < 0) { return E_BAD_PARAM; } - freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, baud, clock); + switch (clock) { + case MXC_UART_APB_CLK: + clock_freq = SystemCoreClock / 2; + break; + + case MXC_UART_IBRO_CLK: + clock_freq = IBRO_FREQ; + break; + + case MXC_UART_ERFO_CLK: + clock_freq = ERFO_FREQ; + break; + + default: + return E_BAD_PARAM; + } + + freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, clock_freq, baud); if (freq > 0) { // Enable baud clock and wait for it to become ready. @@ -221,7 +230,48 @@ int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rt int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock) { - return MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, clock); + int error = E_NO_ERROR; + + if (MXC_UART_GET_IDX(uart) < 0 || MXC_UART_GET_IDX(uart) > 3) { + return E_BAD_PARAM; + } + + // The following interprets table 12-1 from the MAX78002 UG. + switch (clock) { + case MXC_UART_APB_CLK: + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 0); + break; + + case MXC_UART_IBRO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 2); + break; + + case MXC_UART_ERFO_CLK: + error = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERFO); + MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, 3); + break; + + default: + return E_BAD_PARAM; + } + + return error; +} + +mxc_uart_clock_t MXC_UART_GetClockSource(mxc_uart_regs_t *uart) +{ + unsigned int clock_option = MXC_UART_RevB_GetClockSource((mxc_uart_revb_regs_t *)uart); + switch (clock_option) { + case 0: + return MXC_UART_APB_CLK; + case 2: + return MXC_UART_IBRO_CLK; + case 3: + return MXC_UART_ERFO_CLK; + default: + return E_BAD_PARAM; + } } int MXC_UART_GetActive(mxc_uart_regs_t *uart)