MPyATE_Firmware/src/app_uart.c

160 lines
4.9 KiB
C

/* SDK drivers */
#include "fsl_clock.h"
#include "fsl_usart.h"
/* App */
#include "app_uart.h"
#define APP_UART_REG_OFFSET_CFG (0x00U)
#define APP_UART_REG_OFFSET_STAT (0x01U)
#define APP_UART_REG_OFFSET_FIFO (0x02U)
#define APP_UART_REG_CFG_EN_Pos (15U)
#define APP_UART_REG_CFG_EN_Msk (1U << APP_UART_REG_CFG_EN_Pos)
#define APP_UART_REG_CFG_BAUD_Pos (0U)
#define APP_UART_REG_CFG_BAUD_Msk (0x0FU << APP_UART_REG_CFG_BAUD_Pos)
typedef struct {
uint8_t mul;
uint8_t osr;
uint8_t brg;
} app_uart_clk_preset_t;
typedef enum {
APP_UART_BAUD_2400 = 0U,
APP_UART_BAUD_4800,
APP_UART_BAUD_9600,
APP_UART_BAUD_19200,
APP_UART_BAUD_38400,
APP_UART_BAUD_57600,
APP_UART_BAUD_115200,
APP_UART_BAUD_230400,
APP_UART_BAUD_460800,
APP_UART_BAUD_921600,
APP_UART_BAUD_END,
} app_uart_baud_t;
/* Script generated, do not edit. */
static const app_uart_clk_preset_t s_clk_preset[] = {
[APP_UART_BAUD_2400] = {.mul = 0xaa, .osr = 0x0e, .brg = 0xf9}, /* Actual: 2400.00 baud/s, err: 0.00% */
[APP_UART_BAUD_4800] = {.mul = 0xaa, .osr = 0x0e, .brg = 0x7c}, /* Actual: 4800.00 baud/s, err: 0.00% */
[APP_UART_BAUD_9600] = {.mul = 0x08, .osr = 0x0e, .brg = 0x64}, /* Actual: 9599.82 baud/s, err: 0.00% */
[APP_UART_BAUD_19200] = {.mul = 0xcb, .osr = 0x0e, .brg = 0x1c}, /* Actual: 19198.92 baud/s, err: 0.01% */
[APP_UART_BAUD_38400] = {.mul = 0xcc, .osr = 0x06, .brg = 0x1e}, /* Actual: 38402.46 baud/s, err: -0.01% */
[APP_UART_BAUD_57600] = {.mul = 0xcb, .osr = 0x04, .brg = 0x1c}, /* Actual: 57596.75 baud/s, err: 0.01% */
[APP_UART_BAUD_115200] = {.mul = 0x18, .osr = 0x06, .brg = 0x10}, /* Actual: 115207.37 baud/s, err: -0.01% */
[APP_UART_BAUD_230400] = {.mul = 0xa0, .osr = 0x09, .brg = 0x03}, /* Actual: 230421.69 baud/s, err: -0.01% */
[APP_UART_BAUD_460800] = {.mul = 0xa0, .osr = 0x09, .brg = 0x01}, /* Actual: 460843.37 baud/s, err: -0.01% */
[APP_UART_BAUD_921600] = {.mul = 0xa0, .osr = 0x09, .brg = 0x00}, /* Actual: 921686.75 baud/s, err: -0.01% */
};
static volatile app_uart_baud_t s_cfg_baud; /* Register interface configuration */
static volatile uint8_t s_rx_fifo[16];
static volatile uint8_t s_rx_fifo_w_ptr; /* Incremented by USART RXDAT read */
static volatile uint8_t s_rx_fifo_r_ptr; /* Incremented by I2C RX FIFO read */
static volatile uint8_t s_tx_fifo[16];
static volatile uint8_t s_tx_fifo_w_ptr; /* Incremented by I2C TX FIFO write */
static volatile uint8_t s_tx_fifo_r_ptr; /* Incremented by USART TXDAT write */
static inline void app_uart_apply_clock_preset(const app_uart_clk_preset_t *preset);
static inline uint16_t app_uart_read_reg_cfg(void);
static inline void app_uart_write_reg_cfg(uint16_t data);
static inline uint16_t app_uart_read_reg_stat(void);
void app_uart_init(void) {
/* Main Clock -> FRG -> USART0 */
CLOCK_Select(kFRG0_Clk_From_MainClk);
CLOCK_Select(kUART0_Clk_From_Frg0Clk);
CLOCK_EnableClock(kCLOCK_Uart0);
RESET_PeripheralReset(kUART0_RST_N_SHIFT_RSTn);
s_cfg_baud = APP_UART_BAUD_115200;
s_rx_fifo_r_ptr = 0x00U;
s_rx_fifo_w_ptr = 0x00U;
s_tx_fifo_r_ptr = 0x00U;
s_tx_fifo_w_ptr = 0x00U;
USART0->CFG = USART_CFG_DATALEN(1); /* 8N1, No parity, No HW FC */
USART0->CTL = 0x00U;
app_uart_apply_clock_preset(&s_clk_preset[s_cfg_baud]);
}
uint16_t app_uart_module_reg_read(uint8_t addr) {
uint16_t ret = 0x5555U;
switch (addr) {
case APP_UART_REG_OFFSET_CFG:
ret = app_uart_read_reg_cfg();
break;
case APP_UART_REG_OFFSET_STAT:
ret = app_uart_read_reg_stat();
break;
default:
break;
}
return ret;
}
void app_uart_module_reg_write(uint8_t addr, uint16_t data) {
switch (addr) {
case APP_UART_REG_OFFSET_CFG:
app_uart_write_reg_cfg(data);
break;
default:
break;
}
}
static inline void app_uart_apply_clock_preset(const app_uart_clk_preset_t *preset) {
SYSCON->FRG[0].FRGDIV = 0xFFU;
SYSCON->FRG[0].FRGMULT = preset->mul;
USART0->BRG = preset->brg;
USART0->OSR = preset->osr;
}
static inline uint16_t app_uart_read_reg_cfg(void) {
/* CFG register fields:
* EN: [15]
* BAUD: [3:0]
*/
uint16_t ret = 0x0000;
ret |= (s_cfg_baud << APP_UART_REG_CFG_BAUD_Pos) & APP_UART_REG_CFG_BAUD_Msk;
return ret;
}
static inline void app_uart_write_reg_cfg(uint16_t data) {
app_uart_baud_t baud = (data & APP_UART_REG_CFG_BAUD_Msk) >> APP_UART_REG_CFG_BAUD_Pos;
bool uart_en = (data & APP_UART_REG_CFG_EN_Msk) >> APP_UART_REG_CFG_EN_Pos;
if (uart_en) {
/* -- TODO: Enable UART -- */
return;
}
/* Baud rate can't be changed when UART is enabled */
if (baud >= APP_UART_BAUD_END) {
return;
}
app_uart_apply_clock_preset(&s_clk_preset[baud]);
s_cfg_baud = baud;
}
static inline uint16_t app_uart_read_reg_stat(void) {
uint16_t ret = 0x0000;
return ret;
}