From 86e74c00ba46d5151b98a424ca8fd43e9dfb3d26 Mon Sep 17 00:00:00 2001 From: dexter93 Date: Sat, 1 Jun 2024 23:24:27 +0300 Subject: [PATCH] sn32: implement UART LLD (#402) --- os/hal/ports/SN32/LLD/SN32F2xx/UART/UART.h | 184 ------ os/hal/ports/SN32/LLD/SN32F2xx/UART/UART0.c | 250 -------- os/hal/ports/SN32/LLD/SN32F2xx/UART/UART1.c | 253 -------- os/hal/ports/SN32/LLD/SN32F2xx/UART/UART2.c | 253 -------- os/hal/ports/SN32/LLD/SN32F2xx/UART/driver.mk | 13 + .../SN32/LLD/SN32F2xx/UART/hal_serial_lld.c | 527 +++++++++++++++++ .../SN32/LLD/SN32F2xx/UART/hal_serial_lld.h | 245 ++++++++ .../SN32/LLD/SN32F2xx/UART/hal_uart_lld.c | 554 ++++++++++++++++++ .../SN32/LLD/SN32F2xx/UART/hal_uart_lld.h | 353 +++++++++++ .../ports/SN32/LLD/SN32F2xx/UART/sn32_uart.h | 322 ++++++++++ os/hal/ports/SN32/SN32F240B/platform.mk | 1 + os/hal/ports/SN32/SN32F260/platform.mk | 1 + 12 files changed, 2016 insertions(+), 940 deletions(-) delete mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/UART.h delete mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/UART0.c delete mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/UART1.c delete mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/UART2.c create mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/driver.mk create mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.c create mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.h create mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.c create mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.h create mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/UART/sn32_uart.h diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART.h b/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART.h deleted file mode 100644 index cd33abbe31..0000000000 --- a/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART.h +++ /dev/null @@ -1,184 +0,0 @@ -#ifndef __SN32F2XX_UART_H -#define __SN32F2XX_UART_H - - -/*_____ I N C L U D E S ____________________________________________________*/ -#include - -/*_____ D E F I N I T I O N S ______________________________________________*/ -/* -Base Address: 0x4001 6000 (UART0) - 0x4001 4000 (UART1) - 0x4001 2000 (UART1) -*/ -#define UART0_CLK_EN (0x01<<16) -#define UART1_CLK_EN (0x01<<17) -#define UART2_CLK_EN (0x01<<18) - -/**************Line Control Define******/ -#define UART_CHARACTER_LEN5BIT (0x00) -#define UART_CHARACTER_LEN6BIT (0x01) -#define UART_CHARACTER_LEN7BIT (0x02) -#define UART_CHARACTER_LEN8BIT (0x03) -/***********************/ -#define UART_STOPBIT_1BIT (0x0<<2) -#define UART_STOPBIT_2BIT (0x1<<2) -/***********************/ -#define UART_PARITY_BIT_DISEN (0x0<<3) -#define UART_PARITY_BIT_EN (0x1<<3) -/***********************/ -#define UART_PARITY_SELECTODD (0x00<<4) -#define UART_PARITY_SELECTEVEN (0x01<<4) -#define UART_PARITY_SELECTFORC1 (0x02<<4) -#define UART_PARITY_SELECTFORC0 (0x03<<4) -/***********************/ -#define UART_BREAK_DISEN (0x0<<6) -#define UART_BREAK_EN (0x1<<6) -/***********************/ -#define UART_DIVISOR_DISEN (0x0<<7) -#define UART_DIVISOR_EN (0x1<<7) - -#define UART_OVER_SAMPLE_16 (0x0<<8) -#define UART_OVER_SAMPLE_8 (0x1<<8) -/***Baud rate pre-scaler multilier = MULVAL+1***/ -#define UART_MULVAL_0 (0x0000<<4) -#define UART_MULVAL_1 (0x0001<<4) -#define UART_MULVAL_2 (0x0002<<4) -#define UART_MULVAL_3 (0x0003<<4) -#define UART_MULVAL_4 (0x0004<<4) -#define UART_MULVAL_5 (0x0005<<4) -#define UART_MULVAL_6 (0x0006<<4) -#define UART_MULVAL_7 (0x0007<<4) -#define UART_MULVAL_8 (0x0008<<4) -#define UART_MULVAL_9 (0x0009<<4) -#define UART_MULVAL_10 (0x000A<<4) -#define UART_MULVAL_11 (0x000B<<4) -#define UART_MULVAL_12 (0x000C<<4) -#define UART_MULVAL_13 (0x000D<<4) -#define UART_MULVAL_14 (0x000E<<4) -#define UART_MULVAL_15 (0x000F<<4) -/***Buad rate pre-scaler divisor value********/ -#define UART_DIVADDVAL_0 (0x000) -#define UART_DIVADDVAL_1 (0x001) -#define UART_DIVADDVAL_2 (0x002) -#define UART_DIVADDVAL_3 (0x003) -#define UART_DIVADDVAL_4 (0x004) -#define UART_DIVADDVAL_5 (0x005) -#define UART_DIVADDVAL_6 (0x006) -#define UART_DIVADDVAL_7 (0x007) -#define UART_DIVADDVAL_8 (0x008) -#define UART_DIVADDVAL_9 (0x009) -#define UART_DIVADDVAL_10 (0x00A) -#define UART_DIVADDVAL_11 (0x00B) -#define UART_DIVADDVAL_12 (0x00C) -#define UART_DIVADDVAL_13 (0x00D) -#define UART_DIVADDVAL_14 (0x00E) -#define UART_DIVADDVAL_15 (0x00F) -/***UART divisor latch MSB reg[7:0]. determines the baud rate***/ - - -/***UART divisor latch LSB reg[7:0]. determines the baud rate***/ - - -#define UART_FIFO_ENABLE (0x01) -#define UART_RXFIFO_RESET (0x01<<1) -#define UART_TXFIFO_RESET (0x01<<2) - -#define UART_RXTRIGGER_LEVEL1 (0x00<<6) - - -/***UART Interrupt Enable register***/ -#define UART_ABTOIE_EN (0x01<<9) //auto-buad time out INT -#define UART_ABEOIE_EN (0x01<<8) //End of auto-buad INT -#define UART_TEMTIE_EN (0x01<<4) //Transmitter empty flag -#define UART_RLSIE_EN (0x01<<2) //Rx Receive line status(RLS) INT -#define UART_THREIE_EN (0x01<<1) //Transmitter holding register empty flag INT -#define UART_RDAIE_EN (0x01) //character receive(RDA) time-out INT - -/*** UARTn_CTRL************/ -#define UART_EN (0x01) -#define UART_RX_EN (0x01<<6) -#define UART_TX_EN (0x01<<7) -#define UART_CTRL_EN 1 -#define UART_CTRL_DIS 0 -#define UART_FIFOCTRL_RESET 1 - -/*** UARTn_ABCCTRL************/ -#define UART_ABCCTRL_START (0x01) //START:1(Auto-baud is running), START:0(Auto-baud is not running) -#define UART_ABCCTRL_MODE0 (0x00<<1) -#define UART_ABCCTRL_MODE1 (0x01<<1) -#define UART_ABCCTRL_RESTART (0x01<<2) -#define UART_ABEO_EN (0x01<<8) -#define UART_ABTO_EN (0x01<<9) - -/*** Line status register************/ -#define UART_LS_RDR (0x01) //receiver data ready flag -#define UART_LS_OE (0x01<<1) //overrun error flag -#define UART_LS_PE (0x01<<2) //parity error flag -#define UART_LS_FE (0x01<<3) //framing error flag -#define UART_LS_BI (0x01<<4) //break interrupt flag -#define UART_LS_THRE (0x01<<5) //transmitter holding register empty flag -#define UART_LS_TEMT (0x01<<6) //transmitter empty flag -#define UART_LS_RXFE (0x01<<7) //error in RX FIFO flag -#define mskUART_LS_RDR (0x01) -#define mskUART_LS_OE (0x01<<1) -#define mskUART_LS_PE (0x01<<2) -#define mskUART_LS_FE (0x01<<3) -#define mskUART_LS_BI (0x01<<4) -#define mskUART_LS_THRE (0x01<<5) -#define mskUART_LS_TEMT (0x01<<6) -#define mskUART_LS_RXFE (0x01<<7) - -/*** Interrupt Identification register************/ -#define UART_RLS 3 -#define UART_RDA 2 -#define UART_THRE 1 -#define UART_TEMT 7 -#define UART_II_STATUS 0 //the INTstatus can be determined by UARTn_II[3:1] -#define UART_II_ABEOIF (0x01<<8) //end of auto-baud interrupt flag -#define UART_II_ABTOIF (0x01<<9) //auto-baud time-out interrupt flag -#define mskUART_INTID_STATUS 7 //interrupt corresponding to the UARTn RX FIFO -#define mskUART_II_STATUS (0x01) -#define mskUART_II_ABEOIF (0x01<<8) -#define mskUART_II_ABTOIF (0x01<<9) - - -/*_____ M A C R O S ________________________________________________________*/ - - -/*_____ D E C L A R A T I O N S ____________________________________________*/ -extern uint32_t GulNum; -extern uint8_t bUART0_RecvFIFO[]; -extern uint32_t GulNum1; -extern uint8_t bUART1_RecvFIFO[]; -extern uint32_t GulNum2; -extern uint8_t bUART2_RecvFIFO[]; -extern volatile uint8_t bUART0_RecvNew; -extern volatile uint8_t bUART1_RecvNew; -extern volatile uint8_t bUART2_RecvNew; - - -/*_____ D E C L A R A T I O N S ____________________________________________*/ -extern void UART0_Init(void); -extern void UART0_SendByte (uint8_t ucDat); -extern void UART0_Enable(void); -extern void UART0_Disable(void); -extern void UART0_InterruptEnable(void); -extern void UART0_AutoBaudrateInit(void); - -extern void UART1_Init(void); -extern void UART1_SendByte (uint8_t ucDat); -extern void UART1_Enable(void); -extern void UART1_Disable(void); -extern void UART1_InterruptEnable(void); -extern void UART1_AutoBaudrateInit(void); - -void UART2_Init(void); -void UART2_SendByte (uint8_t ucDat); -void UART2_Enable(void); -void UART2_Disable(void); -void UART2_InterruptEnable(void); -void UART2_AutoBaudrateInit(void); - -#endif /*__SN32F2XX_UART_H*/ - diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART0.c b/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART0.c deleted file mode 100644 index 960affc674..0000000000 --- a/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART0.c +++ /dev/null @@ -1,250 +0,0 @@ -/******************** (C) COPYRIGHT 2017 SONiX ******************************* -* COMPANY: SONiX -* DATE: 2017/07 -* AUTHOR: SA1 -* IC: SN32F240B -* DESCRIPTION: UART0 related functions. -*____________________________________________________________________________ -* REVISION Date User Description -* 1.0 2017/07/07 SA1 First release -* -*____________________________________________________________________________ -* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS TIME TO MARKET. -* SONiX SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL -* DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE -* AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN -* IN CONNECTION WITH THEIR PRODUCTS. -*****************************************************************************/ - -/*_____ I N C L U D E S ____________________________________________________*/ -#include -#include "UART.h" - -/*_____ D E C L A R A T I O N S ____________________________________________*/ -volatile uint8_t bUART0_RecvNew; -uint32_t GulNum; -uint8_t bUART0_RecvFIFO[56]; - - -/*_____ D E F I N I T I O N S ______________________________________________*/ - - -/*_____ M A C R O S ________________________________________________________*/ - - -/*_____ F U N C T I O N S __________________________________________________*/ - -/***************************************************************************** -* Function : UART0_IRQHandler -* Description : UART0 interrupt service routine -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -__irq void UART0_IRQHandler (void) -{ - uint32_t II_Buf, LS_Buf; - volatile uint32_t Null_Buf; - - II_Buf = SN_UART0->II; - while ((II_Buf & mskUART_II_STATUS) == UART_II_STATUS) //check interrupt status, the INT can be determined by USARTn_II[3:1] - { - switch ((II_Buf>>1) & mskUART_INTID_STATUS) - { - case UART_RLS: //Receive Line Status - LS_Buf = SN_UART0->LS; - if((LS_Buf & mskUART_LS_OE) == UART_LS_OE) //Overrun Error - { } - if((LS_Buf & mskUART_LS_RXFE) == UART_LS_RXFE)//RX FIFO Error - { - if((LS_Buf & mskUART_LS_PE) == UART_LS_PE)//Parity Error - Null_Buf = SN_UART0->RB; //Clear interrupt - if((LS_Buf & mskUART_LS_FE) == UART_LS_FE) //Framing Error - Null_Buf = SN_UART0->RB; //Clear interrupt - if((LS_Buf & mskUART_LS_BI) == UART_LS_BI) //Break Interrupt - Null_Buf = SN_UART0->RB; //Clear interrupt - } - break; - - case UART_RDA: //Receive Data Available - LS_Buf = SN_UART0->LS; - bUART0_RecvNew = 1; - if((LS_Buf & mskUART_LS_RDR) == UART_LS_RDR)//Receiver Data Ready - { - bUART0_RecvFIFO[GulNum] = SN_UART0->RB; - GulNum++; - } - if(GulNum == 56) - GulNum = 0; - break; - - case UART_THRE: //THRE interrupt - LS_Buf = SN_UART0->LS; - if((LS_Buf & mskUART_LS_THRE) == UART_LS_THRE)//THRE empty - { //SN_UART0->TH = Null_Buf; //Clear interrupt - } - break; - - case UART_TEMT: //TEMT interrupt - LS_Buf = SN_UART0->LS; - if((LS_Buf & mskUART_LS_TEMT) == UART_LS_TEMT) - { //SN_UART0->TH = Null_Buf; //Clear interrupt - } - break; - - default: - break; - } //end switch ((II_Buf>>1) & mskUART_INTID_STATUS) - - II_Buf = SN_UART0->II; - } //end while ((II_Buf&0x01) == mskUART_II_STATUS) - - if ((II_Buf & mskUART_II_ABEOIF) == UART_II_ABEOIF) //Auto Baud interrupt - SN_UART0->ABCTRL |= UART_ABEO_EN; - else if((II_Buf & mskUART_II_ABTOIF) == UART_II_ABTOIF) //Auto Baud time-out interrupt - SN_UART0->ABCTRL |= UART_ABTO_EN; -} - - -/***************************************************************************** -* Function : UART0_Init -* Description : Initialization of UART0 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART0_Init (void) -{ - SN_SYS1->AHBCLKEN |= UART0_CLK_EN; //Enables clock for UART0 - - //===Line Control=== - //setting character Word length(5/6/7/8 bit) - SN_UART0->LC = (UART_CHARACTER_LEN8BIT //8bit character length. - | UART_STOPBIT_1BIT //stop bit of 1 bit - | UART_PARITY_BIT_DISEN //parity bit is disable - | UART_PARITY_SELECTODD //parity bit is odd - | UART_BREAK_DISEN //Break Transmission control disable - | UART_DIVISOR_EN); //Divisor Latch Access enable - - //===Baud Rate Calculation=== - //UART PCLK = 12MHz, Baud rate = 115200 - SN_UART0->FD = (UART_OVER_SAMPLE_16|UART_MULVAL_7|UART_DIVADDVAL_5); - SN_UART0->DLM = 0; - SN_UART0->DLL = 4; - /* - //UART PCLK = 12MHz, Baud rate = 57600 - SN_UART0->FD = (OVER_SAMPLE_16|UART_MULVAL_7|UART_DIVADDVAL_5); - SN_UART0->DLM = 0; - SN_UART0->DLL = 8; - */ - SN_UART0->LC &= ~(UART_DIVISOR_EN); //Disable divisor latch - - //===Auto Baud Rate=== - //UART0_Autobaudrate_Init(); //Auto buad rate initial - - //===FIFO Control=== - SN_UART0->FIFOCTRL =(UART_FIFO_ENABLE //Enable USART FIFOs - | UART_RXFIFO_RESET //RX FIFO Reset - | UART_TXFIFO_RESET //TX FIFO Reset - | UART_RXTRIGGER_LEVEL1); //RX Trigger Level(1 characters) - - //===Oversampling=== - //SN_UART0->FD |= UART_OVER_SAMPLE_8; //OVER8(Oversampling Value), 1:Oversampling by 8. 0:Oversampling by 16 - - //===Half-duplex=== - //SN_UART0->HDEN = 1; //Half-duplex mode enable - - //===Interrupt Enable=== - UART0_InterruptEnable(); - - //===UART Control=== - SN_UART0->CTRL =(UART_EN //Enable USART0 - | UART_RX_EN //Enable RX - | UART_TX_EN); //Enable TX - //===NVIC=== - NVIC_EnableIRQ(UART0_IRQn); //Enable USART0 INT - -} - -/***************************************************************************** -* Function : UART0_SendByte -* Description : MCU sends Byte through UTXD0 -* Input : ucDat - data to be sent -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART0_SendByte (uint8_t ucDat) -{ - SN_UART0->TH = ucDat; - while ((SN_UART0->LS & 0x40) == 0); -} - -/***************************************************************************** -* Function : UART0_AutoBaudrateInit -* Description : Initialization of UART0 Auto baud rate. -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART0_AutoBaudrateInit(void) -{ - SN_UART0->ABCTRL =(UART_ABTO_EN //Clear Auto Baud Time-out interrupt - | UART_ABEO_EN //Clear Auto Baud interrupt - | UART_ABCCTRL_RESTART //Restart in case of time-out - | UART_ABCCTRL_MODE1 //Auto Baud mode, 0:mode 0, 1:mode 1 - | UART_ABCCTRL_START); //Auto Baud start, 0:stop(not running), 1:start(running) -} - -/***************************************************************************** -* Function : UART0_Enable -* Description : Enable UART0 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART0_Enable(void) -{ - //Enable HCLK for UART0 - SN_SYS1->AHBCLKEN |= UART0_CLK_EN; //Enables clock for UART0 - SN_UART0->CTRL_b.UARTEN = UART_CTRL_EN; //UART enable bit -} - -/***************************************************************************** -* Function : UART0_Disable -* Description : Disable UART0 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART0_Disable(void) -{ - SN_UART0->CTRL_b.UARTEN = UART_CTRL_DIS; //UART disable - //Disable HCLK for UART0 - SN_SYS1->AHBCLKEN &= ~(UART0_CLK_EN); //Disable clock for UART0 -} - -/***************************************************************************** -* Function : UART0_InterruptEnable -* Description : Interrupt Enable -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART0_InterruptEnable(void) -{ - SN_UART0->IE =(UART_RDAIE_EN //Enables the Receive Data Available(RDA) interrupt - | UART_THREIE_EN //Enable THRE interrupt - | UART_RLSIE_EN //Enable Receive Line Status(RLS) interrupt - | UART_TEMTIE_EN //Enable TEMT interrupt - | UART_ABEOIE_EN //Enable Auto Baud interrupt - | UART_ABTOIE_EN); //Enable Auto Baud time-out interrupt -} - diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART1.c b/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART1.c deleted file mode 100644 index 18a55c5ead..0000000000 --- a/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART1.c +++ /dev/null @@ -1,253 +0,0 @@ -/******************** (C) COPYRIGHT 2017 SONiX ******************************* -* COMPANY: SONiX -* DATE: 2017/07 -* AUTHOR: SA1 -* IC: SN32F240B -* DESCRIPTION: UART1 related functions. -*____________________________________________________________________________ -* REVISION Date User Description -* 1.0 2017/07/07 SA1 First release -* -*____________________________________________________________________________ -* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS TIME TO MARKET. -* SONiX SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL -* DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE -* AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN -* IN CONNECTION WITH THEIR PRODUCTS. -*****************************************************************************/ - -/*_____ I N C L U D E S ____________________________________________________*/ -#include -#include "UART.h" - -/*_____ D E C L A R A T I O N S ____________________________________________*/ -volatile uint8_t bUART1_RecvNew; -uint32_t GulNum1; -uint8_t bUART1_RecvFIFO[56]; - - -/*_____ D E F I N I T I O N S ______________________________________________*/ - - -/*_____ M A C R O S ________________________________________________________*/ - - -/*_____ F U N C T I O N S __________________________________________________*/ - -/***************************************************************************** -* Function : UART1_IRQHandler -* Description : UART1 interrupt service routine -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -__irq void UART1_IRQHandler (void) -{ - uint32_t II_Buf, LS_Buf; - volatile uint32_t Null_Buf; - - II_Buf = SN_UART1->II; - while ((II_Buf & mskUART_II_STATUS) == UART_II_STATUS) //check interrupt status, the INT can be determined by UARTn_II[3:1] - { - switch ((II_Buf>>1) & mskUART_INTID_STATUS) - { - case UART_RLS: //Receive Line Status - LS_Buf = SN_UART1->LS; - if((LS_Buf & mskUART_LS_OE) == UART_LS_OE) //Overrun Error - { } - if((LS_Buf & mskUART_LS_RXFE) == UART_LS_RXFE)//RX FIFO Error - { - if((LS_Buf & mskUART_LS_PE) == UART_LS_PE)//Parity Error - Null_Buf = SN_UART1->RB; //Clear interrupt - if((LS_Buf & mskUART_LS_FE) == UART_LS_FE) //Framing Error - Null_Buf = SN_UART1->RB; //Clear interrupt - if((LS_Buf & mskUART_LS_BI) == UART_LS_BI) //Break Interrupt - Null_Buf = SN_UART1->RB; //Clear interrupt - } - break; - - case UART_RDA: //Receive Data Available - LS_Buf = SN_UART1->LS; - bUART1_RecvNew = 1; - if((LS_Buf & mskUART_LS_RDR) == UART_LS_RDR)//Receiver Data Ready - { - bUART1_RecvFIFO[GulNum1] = SN_UART1->RB; - GulNum1++; - } - if(GulNum1 == 56) - GulNum1 = 0; - break; - - case UART_THRE: //THRE interrupt - LS_Buf = SN_UART1->LS; - if((LS_Buf & mskUART_LS_THRE) == UART_LS_THRE)//THRE empty - { //SN_UART1->TH = Null_Buf; //Clear interrupt - } - break; - - case UART_TEMT: //TEMT interrupt - LS_Buf = SN_UART1->LS; - if((LS_Buf & mskUART_LS_TEMT) == UART_LS_TEMT) - { //SN_UART1->TH = Null_Buf; //Clear interrupt - } - break; - - default: - break; - } //end switch ((II_Buf>>1) & mskUART_INTID_STATUS) - - II_Buf = SN_UART1->II; - } //end while ((II_Buf&0x01) == mskUART_II_STATUS) - - if ((II_Buf & mskUART_II_ABEOIF) == UART_II_ABEOIF) //Auto Baud interrupt - SN_UART1->ABCTRL |= UART_ABEO_EN; - else if((II_Buf & mskUART_II_ABTOIF) == UART_II_ABTOIF) //Auto Baud time-out interrupt - SN_UART1->ABCTRL |= UART_ABTO_EN; -} - - -/***************************************************************************** -* Function : UART1_Init -* Description : Initialization of UART1 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART1_Init (void) -{ - SN_SYS1->AHBCLKEN |= UART1_CLK_EN; //Enables clock for UART1 - - //===Line Control=== - //setting character Word length(5/6/7/8 bit) - SN_UART1->LC = (UART_CHARACTER_LEN8BIT //8bit character length. - | UART_STOPBIT_1BIT //stop bit of 1 bit - | UART_PARITY_BIT_DISEN //parity bit is disable - | UART_PARITY_SELECTODD //parity bit is odd - | UART_BREAK_DISEN //Break Transmission control disable - | UART_DIVISOR_EN); //Divisor Latch Access enable - - //===Baud Rate Calculation=== - //UART PCLK = 12MHz, Baud rate = 115200 - SN_UART1->FD = (UART_OVER_SAMPLE_16|UART_MULVAL_7|UART_DIVADDVAL_5); - SN_UART1->DLM = 0; - SN_UART1->DLL = 4; - /* - //UART PCLK = 12MHz, Baud rate = 57600 - SN_UART1->FD = (OVER_SAMPLE_16|UART_MULVAL_7|UART_DIVADDVAL_5); - SN_UART1->DLM = 0; - SN_UART1->DLL = 8; - */ - SN_UART1->LC &= ~(UART_DIVISOR_EN); //Disable divisor latch - - //===Auto Baud Rate=== - //UART1_Autobaudrate_Init(); //Auto buad rate initial - - //===FIFO Control=== - SN_UART1->FIFOCTRL =(UART_FIFO_ENABLE //Enable UART FIFOs - | UART_RXFIFO_RESET //RX FIFO Reset - | UART_TXFIFO_RESET //TX FIFO Reset - | UART_RXTRIGGER_LEVEL1); //RX Trigger Level(1/4/8/14 characters) - - //===Scratch Pad=== - //SN_UART1->SP = 0; //A readable, writable byte - - //===Oversampling=== - //SN_UART1->FD |= UART_OVER_SAMPLE_8; //OVER8(Oversampling Value), 1:Oversampling by 8. 0:Oversampling by 16 - - //===Half-duplex=== - //SN_UART1->HDEN = 1; //Half-duplex mode enable - - //===Interrupt Enable=== - UART1_InterruptEnable(); - - //===UART Control=== - SN_UART1->CTRL =(UART_EN //Enable UART0 - | UART_RX_EN //Enable RX - | UART_TX_EN); //Enable TX - //===NVIC=== - NVIC_EnableIRQ(UART1_IRQn); //Enable UART1 INT - -} - -/***************************************************************************** -* Function : UART1_SendByte -* Description : MCU sends Byte through UTXD1 -* Input : ucDat - data to be sent -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART1_SendByte (uint8_t ucDat) -{ - SN_UART1->TH = ucDat; - while ((SN_UART1->LS & 0x40) == 0); -} - -/***************************************************************************** -* Function : UART1_AutoBaudrateInit -* Description : Initialization of UART1 Auto baud rate. -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART1_AutoBaudrateInit(void) -{ - SN_UART1->ABCTRL =(UART_ABTO_EN //Clear Auto Baud Time-out interrupt - | UART_ABEO_EN //Clear Auto Baud interrupt - | UART_ABCCTRL_RESTART //Restart in case of time-out - | UART_ABCCTRL_MODE1 //Auto Baud mode, 0:mode 0, 1:mode 1 - | UART_ABCCTRL_START); //Auto Baud start, 0:stop(not running), 1:start(running) -} - -/***************************************************************************** -* Function : UART1_Enable -* Description : Enable UART1 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART1_Enable(void) -{ - //Enable HCLK for UART1 - SN_SYS1->AHBCLKEN |= UART1_CLK_EN; //Enables clock for UART1 - SN_UART1->CTRL_b.UARTEN = UART_CTRL_EN; //UART enable bit -} - -/***************************************************************************** -* Function : UART1_Disable -* Description : Disable UART1 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART1_Disable(void) -{ - SN_UART1->CTRL_b.UARTEN = UART_CTRL_DIS; //UART disable - //Disable HCLK for UART1 - SN_SYS1->AHBCLKEN &= ~(UART1_CLK_EN); //Disable clock for UART1 -} - -/***************************************************************************** -* Function : UART1_InterruptEnable -* Description : Interrupt Enable -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART1_InterruptEnable(void) -{ - SN_UART1->IE =(UART_RDAIE_EN //Enables the Receive Data Available(RDA) interrupt - | UART_THREIE_EN //Enable THRE interrupt - | UART_RLSIE_EN //Enable Receive Line Status(RLS) interrupt - | UART_TEMTIE_EN //Enable TEMT interrupt - | UART_ABEOIE_EN //Enable Auto Baud interrupt - | UART_ABTOIE_EN); //Enable Auto Baud time-out interrupt -} - diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART2.c b/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART2.c deleted file mode 100644 index f46091b6f6..0000000000 --- a/os/hal/ports/SN32/LLD/SN32F2xx/UART/UART2.c +++ /dev/null @@ -1,253 +0,0 @@ -/******************** (C) COPYRIGHT 2017 SONiX ******************************* -* COMPANY: SONiX -* DATE: 2017/07 -* AUTHOR: SA1 -* IC: SN32F240B -* DESCRIPTION: UART2 related functions. -*____________________________________________________________________________ -* REVISION Date User Description -* 1.0 2017/07/07 SA1 First release -* -*____________________________________________________________________________ -* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS TIME TO MARKET. -* SONiX SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL -* DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE -* AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN -* IN CONNECTION WITH THEIR PRODUCTS. -*****************************************************************************/ - -/*_____ I N C L U D E S ____________________________________________________*/ -#include -#include "UART.h" - -/*_____ D E C L A R A T I O N S ____________________________________________*/ -volatile uint8_t bUART2_RecvNew; -uint32_t GulNum2; -uint8_t bUART2_RecvFIFO[56]; - - -/*_____ D E F I N I T I O N S ______________________________________________*/ - - -/*_____ M A C R O S ________________________________________________________*/ - - -/*_____ F U N C T I O N S __________________________________________________*/ - -/***************************************************************************** -* Function : UART2_IRQHandler -* Description : UART2 interrupt service routine -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -__irq void UART2_IRQHandler (void) -{ - uint32_t II_Buf, LS_Buf; - volatile uint32_t Null_Buf; - - II_Buf = SN_UART2->II; - while ((II_Buf & mskUART_II_STATUS) == UART_II_STATUS) //check interrupt status, the INT can be determined by UARTn_II[3:1] - { - switch ((II_Buf>>1) & mskUART_INTID_STATUS) - { - case UART_RLS: //Receive Line Status - LS_Buf = SN_UART2->LS; - if((LS_Buf & mskUART_LS_OE) == UART_LS_OE) //Overrun Error - { } - if((LS_Buf & mskUART_LS_RXFE) == UART_LS_RXFE)//RX FIFO Error - { - if((LS_Buf & mskUART_LS_PE) == UART_LS_PE)//Parity Error - Null_Buf = SN_UART2->RB; //Clear interrupt - if((LS_Buf & mskUART_LS_FE) == UART_LS_FE) //Framing Error - Null_Buf = SN_UART2->RB; //Clear interrupt - if((LS_Buf & mskUART_LS_BI) == UART_LS_BI) //Break Interrupt - Null_Buf = SN_UART2->RB; //Clear interrupt - } - break; - - case UART_RDA: //Receive Data Available - LS_Buf = SN_UART2->LS; - bUART2_RecvNew = 1; - if((LS_Buf & mskUART_LS_RDR) == UART_LS_RDR)//Receiver Data Ready - { - bUART2_RecvFIFO[GulNum2] = SN_UART2->RB; - GulNum2++; - } - if(GulNum2 == 56) - GulNum2 = 0; - break; - - case UART_THRE: //THRE interrupt - LS_Buf = SN_UART2->LS; - if((LS_Buf & mskUART_LS_THRE) == UART_LS_THRE)//THRE empty - { //SN_UART2->TH = Null_Buf; //Clear interrupt - } - break; - - case UART_TEMT: //TEMT interrupt - LS_Buf = SN_UART2->LS; - if((LS_Buf & mskUART_LS_TEMT) == UART_LS_TEMT) - { //SN_UART2->TH = Null_Buf; //Clear interrupt - } - break; - - default: - break; - } //end switch ((II_Buf>>1) & mskUART_INTID_STATUS) - - II_Buf = SN_UART2->II; - } //end while ((II_Buf&0x01) == mskUART_II_STATUS) - - if ((II_Buf & mskUART_II_ABEOIF) == UART_II_ABEOIF) //Auto Baud interrupt - SN_UART2->ABCTRL |= UART_ABEO_EN; - else if((II_Buf & mskUART_II_ABTOIF) == UART_II_ABTOIF) //Auto Baud time-out interrupt - SN_UART2->ABCTRL |= UART_ABTO_EN; -} - - -/***************************************************************************** -* Function : UART2_Init -* Description : Initialization of UART2 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART2_Init (void) -{ - SN_SYS1->AHBCLKEN |= UART2_CLK_EN; //Enables clock for UART2 - - //===Line Control=== - //setting character Word length(5/6/7/8 bit) - SN_UART2->LC = (UART_CHARACTER_LEN8BIT //8bit character length. - | UART_STOPBIT_1BIT //stop bit of 1 bit - | UART_PARITY_BIT_DISEN //parity bit is disable - | UART_PARITY_SELECTODD //parity bit is odd - | UART_BREAK_DISEN //Break Transmission control disable - | UART_DIVISOR_EN); //Divisor Latch Access enable - - //===Baud Rate Calculation=== - //UART PCLK = 12MHz, Baud rate = 115200 - SN_UART2->FD = (UART_OVER_SAMPLE_16|UART_MULVAL_7|UART_DIVADDVAL_5); - SN_UART2->DLM = 0; - SN_UART2->DLL = 4; - /* - //UART PCLK = 12MHz, Baud rate = 57600 - SN_UART2->FD = (OVER_SAMPLE_16|UART_MULVAL_7|UART_DIVADDVAL_5); - SN_UART2->DLM = 0; - SN_UART2->DLL = 8; - */ - SN_UART2->LC &= ~(UART_DIVISOR_EN); //Disable divisor latch - - //===Auto Baud Rate=== - //UART2_Autobaudrate_Init(); //Auto buad rate initial - - //===FIFO Control=== - SN_UART2->FIFOCTRL =(UART_FIFO_ENABLE //Enable UART FIFOs - | UART_RXFIFO_RESET //RX FIFO Reset - | UART_TXFIFO_RESET //TX FIFO Reset - | UART_RXTRIGGER_LEVEL1); //RX Trigger Level(1/4/8/14 characters) - - //===Scratch Pad=== - //SN_UART2->SP = 0; //A readable, writable byte - - //===Oversampling=== - //SN_UART2->FD |= UART_OVER_SAMPLE_8; //OVER8(Oversampling Value), 1:Oversampling by 8. 0:Oversampling by 16 - - //===Half-duplex=== - //SN_UART2->HDEN = 1; //Half-duplex mode enable - - //===Interrupt Enable=== - UART2_InterruptEnable(); - - //===UART Control=== - SN_UART2->CTRL =(UART_EN //Enable UART0 - | UART_RX_EN //Enable RX - | UART_TX_EN); //Enable TX - //===NVIC=== - NVIC_EnableIRQ(UART2_IRQn); //Enable UART2 INT - -} - -/***************************************************************************** -* Function : UART2_SendByte -* Description : MCU sends Byte through UTXD1 -* Input : ucDat - data to be sent -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART2_SendByte (uint8_t ucDat) -{ - SN_UART2->TH = ucDat; - while ((SN_UART2->LS & 0x40) == 0); -} - -/***************************************************************************** -* Function : UART2_AutoBaudrateInit -* Description : Initialization of UART2 Auto baud rate. -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART2_AutoBaudrateInit(void) -{ - SN_UART2->ABCTRL =(UART_ABTO_EN //Clear Auto Baud Time-out interrupt - | UART_ABEO_EN //Clear Auto Baud interrupt - | UART_ABCCTRL_RESTART //Restart in case of time-out - | UART_ABCCTRL_MODE1 //Auto Baud mode, 0:mode 0, 1:mode 1 - | UART_ABCCTRL_START); //Auto Baud start, 0:stop(not running), 1:start(running) -} - -/***************************************************************************** -* Function : UART2_Enable -* Description : Enable UART2 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART2_Enable(void) -{ - //Enable HCLK for UART2 - SN_SYS1->AHBCLKEN |= UART2_CLK_EN; //Enables clock for UART2 - SN_UART2->CTRL_b.UARTEN = UART_CTRL_EN; //UART enable bit -} - -/***************************************************************************** -* Function : UART2_Disable -* Description : Disable UART2 -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART2_Disable(void) -{ - SN_UART2->CTRL_b.UARTEN = UART_CTRL_DIS; //UART disable - //Disable HCLK for UART2 - SN_SYS1->AHBCLKEN &= ~(UART2_CLK_EN); //Disable clock for UART2 -} - -/***************************************************************************** -* Function : UART2_InterruptEnable -* Description : Interrupt Enable -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void UART2_InterruptEnable(void) -{ - SN_UART2->IE =(UART_RDAIE_EN //Enables the Receive Data Available(RDA) interrupt - | UART_THREIE_EN //Enable THRE interrupt - | UART_RLSIE_EN //Enable Receive Line Status(RLS) interrupt - | UART_TEMTIE_EN //Enable TEMT interrupt - | UART_ABEOIE_EN //Enable Auto Baud interrupt - | UART_ABTOIE_EN); //Enable Auto Baud time-out interrupt -} - diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/driver.mk b/os/hal/ports/SN32/LLD/SN32F2xx/UART/driver.mk new file mode 100644 index 0000000000..fb9381a036 --- /dev/null +++ b/os/hal/ports/SN32/LLD/SN32F2xx/UART/driver.mk @@ -0,0 +1,13 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),) +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.c +endif +ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),) +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.c +endif +else +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.c +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.c +endif + +PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/UART diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.c b/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.c new file mode 100644 index 0000000000..3c3748ed2a --- /dev/null +++ b/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.c @@ -0,0 +1,527 @@ +/* + Copyright (C) 2024 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file UART/hal_serial_lld.c + * @brief SN32 low level serial driver code. + * + * @addtogroup SERIAL + * @{ + */ + +#include "hal.h" +#include "matrix.h" +#include "print.h" +#include +#if HAL_USE_SERIAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief UART0 serial driver identifier.*/ +#if SN32_SERIAL_USE_UART0 || defined(__DOXYGEN__) +SerialDriver SD0; +#endif + +/** @brief UART1 serial driver identifier.*/ +#if SN32_SERIAL_USE_UART1 || defined(__DOXYGEN__) +SerialDriver SD1; +#endif + +/** @brief UART2 serial driver identifier.*/ +#if SN32_SERIAL_USE_UART2 || defined(__DOXYGEN__) +SerialDriver SD2; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/* Driver default configuration.*/ +static const SerialConfig default_config = {SERIAL_DEFAULT_BITRATE, + UART_WordLength_8b, + UART_StopBits_One, + UART_Parity_None, + (UART_FIFO_Enable | UART_RxFIFOThreshold_1), + UART_AutoBaudControl_None, + UART_Oversample_16, + UART_FullDuplexEnable}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ +void UART_divisor_CAL(uint32_t baudrate,uint32_t UART_PCLK,uint8_t Oversampling,uint8_t *dlm,uint8_t *dll,uint8_t *d_divaddval,uint8_t *d_mulval) +{ + float expected_val; + uint8_t divaddval[2],mulval[2]; + uint8_t divider_Index = 0; + uint8_t f_divider_new=0; + uint16_t divisor=0; + float divider_plus,divider_minus,divider_expected; + uint32_t i,j,k; + + //Init + for(i=0;i<2;i++) { + mulval[i] = 0; + divaddval[i] = 0; + } + + expected_val = (float)(UART_PCLK/Oversampling/baudrate); + + if((int)expected_val == expected_val) { + divisor = expected_val; + // no fractional divider needed + divaddval[0] = 0; + mulval[0] = 1; + } else { + // we have to use the fractional divider + // generate a lookup table + uint8_t mulval_limit = 16; + uint8_t divaddval_limit =15; + float tab_D_div_M[mulval_limit][divaddval_limit]; + for (uint8_t i = 0; i < mulval_limit; i++) { + for (uint8_t j = 0; j < divaddval_limit; j++) { + tab_D_div_M[i][j] = (float)j / (i + 1); + } + } + // go through the table until we have a match + for(i=expected_val/2;ik) { + if(tab_D_div_M[j][k]>divider_minus && tab_D_div_M[j][k]>8)&0xff; + *dll = divisor&0xff; + *d_mulval = mulval[0]; + *d_divaddval = divaddval[0]; + } +} +/** + * @brief UART initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] config the architecture-dependent serial driver configuration + */ +static void uart_init(SerialDriver *sdp, const SerialConfig *config) { + uint32_t apbclock; + uint8_t dlm, dll, divaddval, mulval, oversampling; + sn32_uart_t *u = sdp->uart; + + // Default to oversampling by 16 + oversampling = (config->UART_Oversampling == UART_Oversample_8) ? 8 : 16; + apbclock = (SN32_HCLK); + + // Calculate divider + UART_divisor_CAL(config->speed,apbclock,oversampling,&dlm,&dll,&divaddval,&mulval); + + // Update the registers + u->LC = UART_Divisor_Latch_Access_Enable; + u->LC |= (config->UART_WordLength + | config->UART_StopBits + | config->UART_Parity + | UART_Break_Control_Disable); + + u->FD_b.MULVAL = mulval; + u->FD_b.DIVADDVAL = divaddval; + u->FD_b.OVER8 = (oversampling == 8) ? 1 : 0; + u->DLM = dlm; + u->DLL = dll; + + u->LC &= ~(UART_Divisor_Latch_Access_Enable); + // Disable AutoBaud for serial - not useful + u->ABCTRL = UART_AutoBaudControl_None; + + // Configure full or half duplex mode + u->HDEN = config->UART_HalfDuplexMode; + + // Reset FIFO and enable + // Set RX trigger level + u->FIFOCTRL = (UART_FIFO_Enable + | UART_RxFIFO_Reset + | UART_TxFIFO_Reset + | config->UART_FIFOControl); + + /* Enable Interrupts*/ + u->IE = (UART_ReceiveDataAvailable | UART_ReceiveLine); + + // Enable UART + u->CTRL = (UART_Enable| UART_RxEnable | UART_TxEnable); +} + +/** + * @brief UART de-initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] u pointer to an UART I/O block + */ +static void uart_deinit(sn32_uart_t *u) { + // disable FIFOs + u->FIFOCTRL_b.FIFOEN =0; + // disable interrupts + u->IE =0; + // disable UART peripheral + u->CTRL =0; +} + +/** + * @brief Error handling routine. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] ls UART LS register value +*/ +static void set_error(SerialDriver *sdp, uint8_t ls) { + eventflags_t sts = 0; + + if(ls & UART_LineStatus_BI) + sts |= SD_BREAK_DETECTED; + if (ls & UART_LineStatus_PE) + sts |= SD_PARITY_ERROR; + if (ls & UART_LineStatus_FE) + sts |= SD_FRAMING_ERROR; + + osalSysLockFromISR(); + chnAddFlagsI(sdp, sts); + osalSysUnlockFromISR(); +} + +/** + * @brief Common IRQ handler. + * + * @param[in] sdp communication channel associated to the UART + */ +static void serve_interrupt(SerialDriver *sdp) { + #define UART_LS_STATUS (UART_LineStatus_PE | UART_LineStatus_FE | UART_LineStatus_BI | UART_LineStatus_RxError) + sn32_uart_t *u = sdp->uart; + uint32_t ii=u->II; + + while ((ii & UART_Interrupt_Status) == UART_Interrupt_Pending) { + uint32_t ls = u->LS; + if (ls & UART_LineStatus_BI) { + set_error(sdp,UART_LineStatus_BI); + u-> IE &= ~(UART_ReceiveLine); + (void)u->RB; + ii=u->II; + break; + } + + if(ls & UART_LS_STATUS) set_error(sdp, ls); + + while (ls & UART_LineStatus_RDR) { + osalSysLockFromISR(); + if (iqIsEmptyI(&sdp->iqueue)) + chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); + osalSysUnlockFromISR(); + osalSysLockFromISR(); + if (iqPutI(&sdp->iqueue, u->RB) < MSG_OK) + chnAddFlagsI(sdp, SD_OVERRUN_ERROR); + osalSysUnlockFromISR(); + ls = u->LS; + } + uint32_t ie = u->IE; + + if (ie & UART_TransmitterHoldingEmpty) { + while (ls & UART_LineStatus_THRE) { + msg_t b; + + osalSysLockFromISR(); + b = oqGetI(&sdp->oqueue); + osalSysUnlockFromISR(); + if (b < MSG_OK) { + osalSysLockFromISR(); + chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); + osalSysUnlockFromISR(); + u->IE &= ~(UART_TransmitterHoldingEmpty); + break; + } + u->TH = b; + osalSysUnlockFromISR(); + ls = u->LS; + } + } + + if ((ie & UART_TransmitterEmpty) && (ls & UART_LineStatus_TEMT)) { + osalSysLockFromISR(); + if (oqIsEmptyI(&sdp->oqueue)) { + chnAddFlagsI(sdp, CHN_TRANSMISSION_END); + u->IE &= ~(UART_TransmitterEmpty); + } + osalSysUnlockFromISR(); + } + ii=u->II; + } +} + +static void load(SerialDriver *sdp) { + sn32_uart_t *u = sdp->uart; + if (u->LS & UART_LineStatus_THRE) { + osalSysLock(); + msg_t b = oqGetI(&sdp->oqueue); + osalSysUnlock(); + if (b < MSG_OK) { + osalSysLock(); + chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); + osalSysUnlock(); + return; + } + u->TH = b; + } + u->IE |= (UART_TransmitterHoldingEmpty | UART_TransmitterEmpty); +} +#if SN32_SERIAL_USE_UART0 || defined(__DOXYGEN__) +static void notify0(io_queue_t *qp) { + + (void)qp; + load(&SD0); +} +#endif + +#if SN32_SERIAL_USE_UART1 || defined(__DOXYGEN__) +static void notify1(io_queue_t *qp) { + + (void)qp; + load(&SD1); +} +#endif + +#if SN32_SERIAL_USE_UART2 || defined(__DOXYGEN__) +static void notify2(io_queue_t *qp) { + + (void)qp; + load(&SD2); +} +#endif +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if SN32_SERIAL_USE_UART0 || defined(__DOXYGEN__) +#if !defined(SN32_UART0_HANDLER) +#error "SN32_UART0_HANDLER not defined" +#endif +/** + * @brief UART0 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(SN32_UART0_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_interrupt(&SD0); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if SN32_SERIAL_USE_UART1 || defined(__DOXYGEN__) +#if !defined(SN32_UART1_HANDLER) +#error "SN32_UART1_HANDLER not defined" +#endif +/** + * @brief UART1 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(SN32_UART1_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_interrupt(&SD1); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if SN32_SERIAL_USE_UART2 || defined(__DOXYGEN__) +#if !defined(SN32_UART2_HANDLER) +#error "SN32_UART2_HANDLER not defined" +#endif +/** + * @brief UART2 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(SN32_UART2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_interrupt(&SD2); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level serial driver initialization. + * + * @notapi + */ +void sd_lld_init(void) { + +#if SN32_SERIAL_USE_UART0 + sdObjectInit(&SD0, NULL, notify0); + SD0.uart = SN32_UART0; +#endif + +#if SN32_SERIAL_USE_UART1 + sdObjectInit(&SD1, NULL, notify1); + SD1.uart = SN32_UART1; +#endif + +#if SN32_SERIAL_USE_UART2 + sdObjectInit(&SD2, NULL, notify2); + SD2.uart = SN32_UART2; +#endif +} + +/** + * @brief Low level serial driver configuration and (re)start. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] config the architecture-dependent serial driver configuration. + * If this parameter is set to @p NULL then a default + * configuration is used. + * + * @notapi + */ +void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { + + if (config == NULL) + config = &default_config; + + if (sdp->state == SD_STOP) { +#if SN32_SERIAL_USE_UART0 + if (&SD0 == sdp) { + /* UART0 clock enable.*/ + sys1EnableUART0(); + uart_init(sdp, config); + nvicEnableVector(SN32_UART0_NUMBER, SN32_SERIAL_UART0_PRIORITY); + } +#endif +#if SN32_SERIAL_USE_UART1 + if (&SD1 == sdp) { + /* UART1 clock enable.*/ + sys1EnableUART1(); + uart_init(sdp, config); + nvicEnableVector(SN32_UART1_NUMBER, SN32_SERIAL_UART1_PRIORITY); + } +#endif +#if SN32_SERIAL_USE_UART2 + if (&SD2 == sdp) { + /* UART2 clock enable.*/ + sys1EnableUART2(); + uart_init(sdp, config); + nvicEnableVector(SN32_UART2_NUMBER, SN32_SERIAL_UART2_PRIORITY); + } +#endif + } +} + +/** + * @brief Low level serial driver stop. + * @details De-initializes the UART, stops the associated clock, resets the + * interrupt vector. + * + * @param[in] sdp pointer to a @p SerialDriver object + * + * @notapi + */ +void sd_lld_stop(SerialDriver *sdp) { + + if (sdp->state == SD_READY) { + uart_deinit(sdp->uart); +#if SN32_SERIAL_USE_UART0 + if (&SD0 == sdp) { + /* UART0 DeInit.*/ + sys1DisableUART0(); + nvicDisableVector(SN32_UART0_NUMBER); + return; + } +#endif +#if SN32_SERIAL_USE_UART1 + if (&SD1 == sdp) { + /* UART1 DeInit.*/ + sys1DisableUART1(); + nvicDisableVector(SN32_UART1_NUMBER); + return; + } +#endif +#if SN32_SERIAL_USE_UART2 + if (&SD2 == sdp) { + /* UART2 DeInit.*/ + sys1DisableUART2(); + nvicDisableVector(SN32_UART2_NUMBER); + return; + } +#endif + } +} + +#endif /* HAL_USE_SERIAL */ + +/** @} */ diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.h b/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.h new file mode 100644 index 0000000000..ec37948f2f --- /dev/null +++ b/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_serial_lld.h @@ -0,0 +1,245 @@ +/* + Copyright (C) 2024 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file UART/hal_serial_lld.h + * @brief SN32 low level serial driver header. + * + * @addtogroup SERIAL + * @{ + */ + +#ifndef HAL_SERIAL_LLD_H +#define HAL_SERIAL_LLD_H + +#if HAL_USE_SERIAL || defined(__DOXYGEN__) + +#include "sn32_uart.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief UART0 driver enable switch. + * @details If set to @p TRUE the support for UART0 is included. + * @note The default is @p FALSE. + */ +#if !defined(SN32_SERIAL_USE_UART0) || defined(__DOXYGEN__) +#define SN32_SERIAL_USE_UART0 FALSE +#endif + +/** + * @brief UART1 driver enable switch. + * @details If set to @p TRUE the support for UART1 is included. + * @note The default is @p FALSE. + */ +#if !defined(SN32_SERIAL_USE_UART1) || defined(__DOXYGEN__) +#define SN32_SERIAL_USE_UART1 FALSE +#endif + +/** + * @brief UART2 driver enable switch. + * @details If set to @p TRUE the support for UART2 is included. + * @note The default is @p FALSE. + */ +#if !defined(SN32_SERIAL_USE_UART2) || defined(__DOXYGEN__) +#define SN32_SERIAL_USE_UART2 FALSE +#endif + +/** + * @brief UART0 interrupt priority level setting. + */ +#if !defined(SN32_SERIAL_UART0_PRIORITY) || defined(__DOXYGEN__) +#define SN32_SERIAL_UART0_PRIORITY 3 +#endif + +/** + * @brief UART1 interrupt priority level setting. + */ +#if !defined(SN32_SERIAL_UART1_PRIORITY) || defined(__DOXYGEN__) +#define SN32_SERIAL_UART1_PRIORITY 3 +#endif + +/** + * @brief UART2 interrupt priority level setting. + */ +#if !defined(SN32_SERIAL_UART2_PRIORITY) || defined(__DOXYGEN__) +#define SN32_SERIAL_UART2_PRIORITY 3 +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if SN32_SERIAL_USE_UART0 && !SN32_HAS_UART0 +#error "UART0 not present in the selected device" +#endif + +#if SN32_SERIAL_USE_UART1 && !SN32_HAS_UART1 +#error "UART1 not present in the selected device" +#endif + +#if SN32_SERIAL_USE_UART2 && !SN32_HAS_UART2 +#error "UART2 not present in the selected device" +#endif + +#if !SN32_SERIAL_USE_UART0 && !SN32_SERIAL_USE_UART1 && \ + !SN32_SERIAL_USE_UART2 +#error "SERIAL driver activated but no UART/UART peripheral assigned" +#endif + +#if SN32_SERIAL_USE_UART0 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(SN32_SERIAL_UART0_PRIORITY) +#error "Invalid IRQ priority assigned to UART0" +#endif + +#if SN32_SERIAL_USE_UART1 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(SN32_SERIAL_UART1_PRIORITY) +#error "Invalid IRQ priority assigned to UART1" +#endif + +#if SN32_SERIAL_USE_UART2 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(SN32_SERIAL_UART2_PRIORITY) +#error "Invalid IRQ priority assigned to UART2" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +#if SN32_HAS_UART0 +#define SN32_UART0_BASE SN_UART0_BASE +#define SN32_UART0 ((sn32_uart_t *)SN_UART0_BASE) +#endif + +#if SN32_HAS_UART1 +#define SN32_UART1_BASE SN_UART1_BASE +#define SN32_UART1 ((sn32_uart_t *)SN_UART1_BASE) +#endif + +#if SN32_HAS_UART2 +#define SN32_UART2_BASE SN_UART2_BASE +#define SN32_UART2 ((sn32_uart_t *)SN_UART2_BASE) +#endif + +/** + * @brief SN32 Serial Driver configuration structure. + * @details An instance of this structure must be passed to @p sdStart() + * in order to configure and start a serial driver operations. + * @note This structure content is architecture dependent, each driver + * implementation defines its own version and the custom static + * initializers. + */ +typedef struct { + /** + * @brief This member configures the UART communication baud rate. + */ + uint32_t speed; + /** + * @brief Specifies the number of data bits transmitted or received in a frame. + * This parameter can be a value of @ref UART_Word_Length + */ + uint8_t UART_WordLength; + /** + * @brief Specifies the number of stop bits transmitted. + * This parameter can be a value of @ref UART_Stop_Bits + */ + uint8_t UART_StopBits; + /** + * @brief Specifies the parity mode. + * This parameter can be a value of @ref UART_Parity + */ + uint8_t UART_Parity; + /** + * @brief Controls the operation of the UART RX and TX FIFOs. + */ + uint32_t UART_FIFOControl; + /** + * @brief Specifies the auto flow control mode and configures functionality. + */ + uint32_t UART_AutoBaudControl; + /** + * @brief Specifies the oversampling rate. + * This parameter can be a value of @ref UART_Oversample + */ + uint16_t UART_Oversampling; + /** + * @brief Enables half-duplex mode. + */ + uint8_t UART_HalfDuplexMode; +} SerialConfig; + +/** + * @brief @p SerialDriver specific data. + */ +#define _serial_driver_data \ + _base_asynchronous_channel_data \ + /* Driver state.*/ \ + sdstate_t state; \ + /* Input queue.*/ \ + input_queue_t iqueue; \ + /* Output queue.*/ \ + output_queue_t oqueue; \ + /* Input circular buffer.*/ \ + uint8_t ib[SERIAL_BUFFERS_SIZE]; \ + /* Output circular buffer.*/ \ + uint8_t ob[SERIAL_BUFFERS_SIZE]; \ + /* End of the mandatory fields.*/ \ + /* Pointer to the UART registers block.*/ \ + sn32_uart_t *uart; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if SN32_SERIAL_USE_UART0 && !defined(__DOXYGEN__) +extern SerialDriver SD0; +#endif +#if SN32_SERIAL_USE_UART1 && !defined(__DOXYGEN__) +extern SerialDriver SD1; +#endif +#if SN32_SERIAL_USE_UART2 && !defined(__DOXYGEN__) +extern SerialDriver SD2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void sd_lld_init(void); + void sd_lld_start(SerialDriver *sdp, const SerialConfig *config); + void sd_lld_stop(SerialDriver *sdp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_SERIAL */ + +#endif /* HAL_SERIAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.c b/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.c new file mode 100644 index 0000000000..1a9caea3af --- /dev/null +++ b/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.c @@ -0,0 +1,554 @@ +/* + Copyright (C) 2024 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file UART/hal_uart_lld.c + * @brief SN32 low level UART driver code. + * + * @addtogroup UART + * @{ + */ + +#include "hal.h" + +#if HAL_USE_UART || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief UART0 UART driver identifier.*/ +#if SN32_UART_USE_UART0 || defined(__DOXYGEN__) +UARTDriver UARTD0; +#endif + +/** @brief UART1 UART driver identifier.*/ +#if SN32_UART_USE_UART1 || defined(__DOXYGEN__) +UARTDriver UARTD1; +#endif + +/** @brief UART2 UART driver identifier.*/ +#if SN32_UART_USE_UART2 || defined(__DOXYGEN__) +UARTDriver UARTD2; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Status bits translation. + * + * @param[in] ls UART LS register value + * + * @return The error flags. + */ +static uartflags_t translate_errors(uint32_t ls) { + uartflags_t sts = 0; + + if (ls & UART_LineStatus_OE) + sts |= UART_OVERRUN_ERROR; + if (ls & UART_LineStatus_PE) + sts |= UART_PARITY_ERROR; + if (ls & UART_LineStatus_FE) + sts |= UART_FRAMING_ERROR; + if (ls & UART_LineStatus_BI) + sts |= UART_BREAK_DETECTED; + if (ls & UART_LineStatus_RDR) + sts |= UART_NOISE_ERROR; + return sts; +} + +/** + * @brief Puts the receiver in the UART_RX_IDLE state. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void uart_enter_rx_idle_loop(UARTDriver *uartp) { + + uartp->xfer.rx_len = 1; + uartp->xfer.rx_buf = (uint8_t *)&uartp->rxbuf; + + uartp->uart->IE |= UART_ReceiveDataAvailable; +} + +/** + * @brief UART de-initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void uart_stop(UARTDriver *uartp) { + + /* Disable the UART Interrupt.*/ + uartp->uart->IE &= ~(0x7FF); +} + +/** + * @brief UART initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void uart_start(UARTDriver *uartp) { + uint32_t divider, apbclock; + uint8_t dlm, dll, divaddval, mulval, oversampling; + sn32_uart_t *u = uartp->uart; + + uart_stop(uartp); + + u->ABCTRL = uartp->config->UART_AutoBaudControl; + + apbclock = SN32_HCLK; + + // Default to oversampling by 16 + oversampling = (config->UART_Oversampling == UART_Oversample_8) ? 8 : 16; + + // Check constraints based on oversampling value + if (oversampling == 8) { + chDbgAssert(oversampling * uartp->config->UART_BaudRate <= apbclock / 8, + "Invalid oversampling configuration for requested baud rate"); + } else if (oversampling == 16) { + chDbgAssert(oversampling * uartp->config->UART_BaudRate <= apbclock / 16, + "Invalid oversampling configuration for requested baud rate"); + } + + // Calculate divider + uint32_t rounded_sum = apbclock + (uartp->config->UART_BaudRate >> 1); + divider = rounded_sum / (uartp->config->UART_BaudRate * oversampling); + + // Calculate DLM and DLL + dlm = (uint8_t)(divider >> 8); + dll = (uint8_t)(divider & 0xFF); + + // Calculate fractional part + uint32_t fractional_part = (rounded_sum % (uartp->config->UART_BaudRate * + oversampling)) * (uartp->config->UART_WordLength + 1) * oversampling; + + // Calculate DIVADDVAL and MULVAL + divaddval = (uint8_t)((fractional_part >> 4) & 0x0F); + mulval = (uint8_t)(fractional_part & 0x0F); + + // Check and adjust DLL value if needed + if (divaddval > 0 && dlm == 0 && dll < 3) { + dll = 3; // Set to the minimum value + } + + // Check and adjust MULVAL if needed + if (mulval - divaddval == 2) { + mulval++; // Adjust mulval to satisfy the condition + } + + // Update the registers + u->LC = UART_Divisor_Latch_Access_Enable; + u->LC |= (config->UART_WordLength + | config->UART_StopBits + | config->UART_Parity + | UART_Break_Control_Disable); + + u->FD_b.MULVAL = mulval; + u->FD_b.DIVADDVAL = divaddval; + u->FD_b.OVER8 = (oversampling == 8) ? 1 : 0; + u->DLM = dlm; + u->DLL = dll; + + u->LC &= ~(UART_Divisor_Latch_Access_Enable); + // Configure full or half duplex mode + u->HDEN = config->UART_HalfDuplexMode; + + // Set RX trigger level + u->FIFOCTRL |= uartp->config->UART_FIFOControl; + + // AutoBaud reset and init + u->ABCTRL |= (UART_AutoBaudControl_Timeout | UART_AutoBaudControl_Timeout | + UART_AutoBaudControl_Restart | UART_AutoBaudControl_Start); + + // Reset FIFO and enable + u->FIFOCTRL |= (UART_TxFIFO_Reset | UART_RxFIFO_Reset | UART_FIFO_Enable); + + // Enable AutoBaud Interrupts + u->IE |= (UART_AutoBaudTimeout | UART_AutoBaudEnd); + + // Enable UART + u->CTRL = (UART_TxEnable | UART_RxEnable | UART_Enable); + + /* Starting the receiver idle loop.*/ + uart_enter_rx_idle_loop(uartp); +} + +/** + * @brief UART common service routine. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void serve_uart_irq(UARTDriver *uartp) { + sn32_uart_t *u = uartp->uart; + uint32_t ls; + uint8_t rbyte; + uint32_t int_ii; + + int_ii = u->II; + // Check for pending interrupts + while((int_ii & UART_Interrupt_Status) == UART_Interrupt_Pending) { + // Check INTID + switch ((int_ii>>1) & UART_InterruptID_Status) { + case UART_InterruptID_RLS: + ls = (uint32_t)u->LS; + if (ls & (UART_LineStatus_PE | UART_LineStatus_FE | UART_LineStatus_OE | + UART_LineStatus_RDR | UART_LineStatus_BI)) { + _uart_rx_error_isr_code(uartp, translate_errors(ls)); + } + break; + case UART_InterruptID_RDA: + /* Receive One Byte.*/ + rbyte = (uint16_t)u->RB; + if (uartp->xfer.rx_len) { + *uartp->xfer.rx_buf = rbyte; + uartp->xfer.rx_buf++; + uartp->xfer.rx_len--; + if (uartp->xfer.rx_len == 0) { + if (uartp->rxstate == UART_RX_IDLE) { + /* Receiver in idle state, a callback is generated, if enabled, + for each received character and then the driver stays in the + same state.*/ + _uart_rx_idle_code(uartp); + } + else { + _uart_rx_complete_isr_code(uartp); + } + } + } + break; + case UART_InterruptID_CTI: + /* FIFO Time out.*/ + while ((u->LS & UART_LineStatus_RDR) == UART_LineStatus_RDR) { + rbyte = (uint16_t)u->RB; + if (uartp->xfer.rx_len) { + *uartp->xfer.rx_buf = rbyte; + uartp->xfer.rx_buf++; + uartp->xfer.rx_len--; + if (uartp->xfer.rx_len == 0) { + if (uartp->rxstate == UART_RX_IDLE) { + /* Receiver in idle state, a callback is generated, + if enabled, for each received character and then the + driver stays in the same state.*/ + _uart_rx_idle_code(uartp); + } + else { + _uart_rx_complete_isr_code(uartp); + } + } + } + } + /* Timeout interrupt sources are only checked if enabled in IE.*/ + _uart_timeout_isr_code(uartp); + break; + case UART_InterruptID_THRE: + /* Send One Byte.*/ + if (uartp->xfer.tx_len) { + u->TH = (uint16_t)*uartp->xfer.tx_buf; + uartp->xfer.tx_buf++; + uartp->xfer.tx_len--; + if (uartp->xfer.tx_len == 0) { + /* A callback is generated, if enabled, after a completed + transfer.*/ + _uart_tx1_isr_code(uartp); + /* End of transmission, a callback is generated.*/ + _uart_tx2_isr_code(uartp); + /* Disable tx interrupt.*/ + u->IE &= ~UART_TransmitterHoldingEmpty; + } + } + break; + case UART_InterruptID_TEMT: + /* Physical transmission end.*/ + /* A callback is generated, if enabled, after a completed + transfer.*/ + _uart_tx1_isr_code(uartp); + /* End of transmission, a callback is generated.*/ + _uart_tx2_isr_code(uartp); + break; + default: + break; + } + // Update II status + int_ii = u->II; + } + // AutoBaud interrupts + if ((int_ii & UART_AutoBaudEnd) == UART_InterruptEnable) + u->ABCTRL |= UART_AutoBaudControl_End; + else if((int_ii & UART_AutoBaudTimeout) == UART_InterruptEnable) + u->ABCTRL |= UART_AutoBaudControl_Timeout; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if SN32_UART_USE_UART0 || defined(__DOXYGEN__) +#if !defined(SN32_UART0_HANDLER) +#error "SN32_UART0_HANDLER not defined" +#endif +/** + * @brief UART0 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(SN32_UART0_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_uart_irq(&UARTD0); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* SN32_UART_USE_UART0 */ + +#if SN32_UART_USE_UART1 || defined(__DOXYGEN__) +#if !defined(SN32_UART1_HANDLER) +#error "SN32_UART0_HANDLER not defined" +#endif +/** + * @brief UART1 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(SN32_UART1_IRQ_VECTOR) { + + OSAL_IRQ_PROLOGUE(); + + serve_uart_irq(&UARTD1); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* SN32_UART_USE_UART1 */ + +#if SN32_UART_USE_UART2 || defined(__DOXYGEN__) +#if !defined(SN32_UART2_HANDLER) +#error "SN32_UART2_HANDLER not defined" +#endif +/** + * @brief UART2 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(SN32_UART2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_uart_irq(&UARTD2); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* SN32_UART_USE_UART2 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level UART driver initialization. + * + * @notapi + */ +void uart_lld_init(void) { + +#if SN32_UART_USE_UART0 + uartObjectInit(&UARTD0); + UARTD0.uart = SN32_UART0; +#endif + +#if SN32_UART_USE_UART1 + uartObjectInit(&UARTD1); + UARTD1.uart = SN32_UART1; +#endif + +#if SN32_UART_USE_UART2 + uartObjectInit(&UARTD2); + UARTD2.uart = SN32_UART2; +#endif +} + +/** + * @brief Configures and activates the UART peripheral. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @notapi + */ +void uart_lld_start(UARTDriver *uartp) { + + if (uartp->state == UART_STOP) { +#if SN32_UART_USE_UART0 + if (&UARTD0 == uartp) { + /* UART0 clock enable.*/ + sys1EnableUART0(); + nvicClearPending(SN32_UART0_NUMBER); + nvicEnableVector(SN32_UART0_NUMBER, SN32_UART_UART0_IRQ_PRIORITY); + } +#endif + +#if SN32_UART_USE_UART1 + if (&UARTD1 == uartp) { + /* UART1 clock enable.*/ + sys1EnableUART1(); + nvicClearPending(SN32_UART1_NUMBER); + nvicEnableVector(SN32_UART1_NUMBER, SN32_UART_UART1_IRQ_PRIORITY); + } +#endif + +#if SN32_UART_USE_UART2 + if (&UARTD2 == uartp) { + /* UART2 clock enable.*/ + sys1EnableUART2(); + nvicClearPending(SN32_UART2_NUMBER); + nvicEnableVector(SN32_UART2_NUMBER, SN32_UART_UART2_IRQ_PRIORITY); + } +#endif + } + uartp->rxstate = UART_RX_IDLE; + uartp->txstate = UART_TX_IDLE; + uart_start(uartp); +} + +/** + * @brief Deactivates the UART peripheral. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @notapi + */ +void uart_lld_stop(UARTDriver *uartp) { + + if (uartp->state == UART_READY) { + uartp->xfer.tx_len = 0; + uartp->xfer.rx_len = 0; + uartp->xfer.tx_buf = NULL; + uartp->xfer.rx_buf = NULL; + uartp->xfer.tx_abrt_source = 0; + + uart_stop(uartp); + +#if SN32_UART_USE_UART0 + if (&UARTD0 == uartp) { + nvicDisableVector(SN32_UART0_NUMBER); + sys1DisableUART0(); + return; + } +#endif + +#if SN32_UART_USE_UART1 + if (&UARTD1 == uartp) { + nvicDisableVector(SN32_UART1_NUMBER); + sys1DisableUART1(); + return; + } +#endif + +#if SN32_UART_USE_UART2 + if (&UARTD2 == uartp) { + nvicDisableVector(SN32_UART2_NUMBER); + sys1DisableUART2(); + return; + } +#endif + } +} + +/** + * @brief Starts a transmission on the UART peripheral. + * @note The buffers are organized as uint8_t arrays for data sizes below + * or equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] n number of data frames to send + * @param[in] txbuf the pointer to the transmit buffer + * + * @notapi + */ +void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { + + uartp->xfer.tx_len = n; + uartp->xfer.tx_buf = txbuf; + + uartp->uart->IE |= UART_TransmitterHoldingEmpty; +} + +/** + * @brief Stops any ongoing transmission. + * @note Stopping a transmission also suppresses the transmission callbacks. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @return The number of data frames not transmitted by the + * stopped transmit operation. + * + * @notapi + */ +size_t uart_lld_stop_send(UARTDriver *uartp) { + + uartp->uart->IE &= ~(UART_TransmitterHoldingEmpty); + + return (size_t)(uartp->xfer.tx_len); +} + +/** + * @brief Starts a receive operation on the UART peripheral. + * @note The buffers are organized as uint8_t arrays for data sizes below + * or equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] n number of data frames to send + * @param[out] rxbuf the pointer to the receive buffer + * + * @notapi + */ +void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { + + uartp->xfer.rx_len = n; + uartp->xfer.rx_buf = rxbuf; + + uartp->uart->IE |= UART_ReceiveDataAvailable; +} + +/** + * @brief Stops any ongoing receive operation. + * @note Stopping a receive operation also suppresses the receive callbacks. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @return The number of data frames not received by the + * stopped receive operation. + * + * @notapi + */ +size_t uart_lld_stop_receive(UARTDriver *uartp) { + uartp->uart->IE &= ~(UART_ReceiveDataAvailable); + + return (size_t)(uartp->xfer.rx_len); +} + +#endif /* HAL_USE_UART */ + +/** @} */ \ No newline at end of file diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.h b/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.h new file mode 100644 index 0000000000..608515fa65 --- /dev/null +++ b/os/hal/ports/SN32/LLD/SN32F2xx/UART/hal_uart_lld.h @@ -0,0 +1,353 @@ +/* + Copyright (C) 2024 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file UART/hal_uart_lld.h + * @brief SN32 low level UART driver header. + * + * @addtogroup UART + * @{ + */ + +#ifndef HAL_UART_LLD_H +#define HAL_UART_LLD_H + +#if HAL_USE_UART || defined(__DOXYGEN__) + +#include "sn32_uart.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief UART driver on UART0 enable switch. + * @details If set to @p TRUE the support for UART0 is included. + * @note The default is @p FALSE. + */ +#if !defined(SN32_UART_USE_UART0) || defined(__DOXYGEN__) +#define SN32_UART_USE_UART0 FALSE +#endif + +/** + * @brief UART driver on UART1 enable switch. + * @details If set to @p TRUE the support for UART1 is included. + * @note The default is @p FALSE. + */ +#if !defined(SN32_UART_USE_UART1) || defined(__DOXYGEN__) +#define SN32_UART_USE_UART1 FALSE +#endif + +/** + * @brief UART driver on UART2 enable switch. + * @details If set to @p TRUE the support for UART2 is included. + * @note The default is @p FALSE. + */ +#if !defined(SN32_UART_USE_UART2) || defined(__DOXYGEN__) +#define SN32_UART_USE_UART2 FALSE +#endif + +/** + * @brief UART0 interrupt priority level setting. + */ +#if !defined(SN32_UART_UART0_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SN32_UART_UART0_IRQ_PRIORITY 3 +#endif + +/** + * @brief UART1 interrupt priority level setting. + */ +#if !defined(SN32_UART_UART1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SN32_UART_UART1_IRQ_PRIORITY 3 +#endif + +/** + * @brief UART2 interrupt priority level setting. + */ +#if !defined(SN32_UART_UART2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SN32_UART_UART2_IRQ_PRIORITY 3 +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if SN32_UART_USE_UART0 && !SN32_HAS_UART0 +#error "UART0 not present in the selected device" +#endif + +#if SN32_UART_USE_UART1 && !SN32_HAS_UART1 +#error "UART1 not present in the selected device" +#endif + +#if SN32_UART_USE_UART2 && !SN32_HAS_UART2 +#error "UART2 not present in the selected device" +#endif + +#if !SN32_UART_USE_UART0 && !SN32_UART_USE_UART1 && \ + !SN32_UART_USE_UART2 +#error "UART driver activated but no UART/UART peripheral assigned" +#endif + +#if SN32_UART_USE_UART0 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(SN32_UART_UART0_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART0" +#endif + +#if SN32_UART_USE_UART1 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(SN32_UART_UART1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART1" +#endif + +#if SN32_UART_USE_UART2 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(SN32_UART_UART2_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART2" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +#if SN32_HAS_UART0 +#define SN32_UART0_BASE SN_UART0_BASE +#define SN32_UART0 ((sn32_uart_t *)SN_UART0_BASE) +#endif + +#if SN32_HAS_UART1 +#define SN32_UART1_BASE SN_UART1_BASE +#define SN32_UART1 ((sn32_uart_t *)SN_UART1_BASE) +#endif + +#if SN32_HAS_UART2 +#define SN32_UART2_BASE SN_UART2_BASE +#define SN32_UART2 ((sn32_uart_t *)SN_UART2_BASE) +#endif + +/** + * @brief UART driver condition flags type. + */ +typedef uint32_t uartflags_t; + +/** + * @brief Structure representing an UART driver. + */ +typedef struct UARTDriver UARTDriver; + +/** + * @brief Generic UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +typedef void (*uartcb_t)(UARTDriver *uartp); + +/** + * @brief Character received UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] c received character + */ +typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c); + +/** + * @brief Receive error UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] e receive error mask + */ +typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e); + +typedef struct { + const uint8_t *tx_buf; + volatile uint32_t tx_len; + uint8_t *rx_buf; + volatile uint32_t rx_len; + uint32_t tx_abrt_source; +} uart_xfer_info_t; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief End of transmission buffer callback. + */ + uartcb_t txend1_cb; + /** + * @brief Physical end of transmission callback. + */ + uartcb_t txend2_cb; + /** + * @brief Receive buffer filled callback. + */ + uartcb_t rxend_cb; + /** + * @brief Character received while out if the @p UART_RECEIVE state. + */ + uartccb_t rxchar_cb; + /** + * @brief Receive error callback. + */ + uartecb_t rxerr_cb; + /* End of the mandatory fields.*/ + /** + * @brief Receiver timeout callback. + * @details Handles idle interrupts depending on configured + * flags in CR registers and supported hardware features. + */ + uartcb_t timeout_cb; + /** + * @brief Controls the clock prescaler for baud rate generation. + */ + uint32_t UART_BaudRate; + /** + * @brief Specifies the number of data bits transmitted or received in a frame. + * This parameter can be a value of @ref UART_Word_Length + */ + uint8_t UART_WordLength; + /** + * @brief Specifies the number of stop bits transmitted. + * This parameter can be a value of @ref UART_Stop_Bits + */ + uint8_t UART_StopBits; + /** + * @brief Specifies the parity mode. + * This parameter can be a value of @ref UART_Parity + */ + uint8_t UART_Parity; + /** + * @brief Controls the operation of the UART RX and TX FIFOs. + */ + uint32_t UART_FIFOControl; + /** + * @brief Specifies the auto flow control mode and configures functionality. + */ + uint32_t UART_AutoBaudControl; + /** + * @brief Specifies the oversampling rate. + * This parameter can be a value of @ref UART_Oversample + */ + uint16_t UART_Oversampling; + /** + * @brief Enables half-duplex mode. + */ + uint8_t UART_HalfDuplexMode; +} UARTConfig; + +/** + * @brief Structure representing an UART driver. + */ +struct UARTDriver { + /** + * @brief Driver state. + */ + uartstate_t state; + /** + * @brief Transmitter state. + */ + uarttxstate_t txstate; + /** + * @brief Receiver state. + */ + uartrxstate_t rxstate; + /** + * @brief Current configuration data. + */ + const UARTConfig *config; +#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__) + /** + * @brief Synchronization flag for transmit operations. + */ + bool early; + /** + * @brief Waiting thread on RX. + */ + thread_reference_t threadrx; + /** + * @brief Waiting thread on TX. + */ + thread_reference_t threadtx; +#endif /* UART_USE_WAIT */ +#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the peripheral. + */ + mutex_t mutex; +#endif /* UART_USE_MUTUAL_EXCLUSION */ +#if defined(UART_DRIVER_EXT_FIELDS) + UART_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the UART registers block. + */ + sn32_uart_t *uart; + /** + * @brief Default receive buffer while into @p UART_RX_IDLE state. + */ + volatile uint16_t rxbuf; + uart_xfer_info_t xfer; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if SN32_UART_USE_UART0 && !defined(__DOXYGEN__) +extern UARTDriver UARTD0; +#endif + +#if SN32_UART_USE_UART1 && !defined(__DOXYGEN__) +extern UARTDriver UARTD1; +#endif + +#if SN32_UART_USE_UART2 && !defined(__DOXYGEN__) +extern UARTDriver UARTD2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void uart_lld_init(void); + void uart_lld_start(UARTDriver *uartp); + void uart_lld_stop(UARTDriver *uartp); + void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf); + size_t uart_lld_stop_send(UARTDriver *uartp); + void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf); + size_t uart_lld_stop_receive(UARTDriver *uartp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_UART */ + +#endif /* HAL_UART_LLD_H */ + +/** @} */ \ No newline at end of file diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/UART/sn32_uart.h b/os/hal/ports/SN32/LLD/SN32F2xx/UART/sn32_uart.h new file mode 100644 index 0000000000..ab3c75af16 --- /dev/null +++ b/os/hal/ports/SN32/LLD/SN32F2xx/UART/sn32_uart.h @@ -0,0 +1,322 @@ +/* + Copyright (C) 2024 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef SN32_UART_H +# define SN32_UART_H + +typedef struct { + union { + union { + __IM uint32_t RB; + + struct { + __IM uint32_t RB : 8; + } RB_b; + }; + + union { + __OM uint32_t TH; + + struct { + __OM uint32_t TH : 8; + } TH_b; + }; + + union { + __IOM uint32_t DLL; + + struct { + __IOM uint32_t DLL : 8; + } DLL_b; + }; + }; + + union { + union { + __IOM uint32_t DLM; + + struct { + __IOM uint32_t DLM : 8; + } DLM_b; + }; + + union { + __IOM uint32_t IE; + + struct { + __IOM uint32_t RDAIE : 1; + __IOM uint32_t THREIE : 1; + __IOM uint32_t RLSIE : 1; + __IM uint32_t : 1; + __IOM uint32_t TEMTIE : 1; + __IM uint32_t : 3; + __IOM uint32_t ABEOIE : 1; + __IOM uint32_t ABTOIE : 1; + } IE_b; + }; + }; + + union { + union { + __IM uint32_t II; + + struct { + __IM uint32_t INTSTATUS : 1; + __IM uint32_t INTID : 3; + __IM uint32_t : 2; + __IM uint32_t FIFOEN : 2; + __IM uint32_t ABEOIF : 1; + __IM uint32_t ABTOIF : 1; + } II_b; + }; + + union { + __OM uint32_t FIFOCTRL; + + struct { + __OM uint32_t FIFOEN : 1; + __IM uint32_t : 5; + __OM uint32_t RXTL : 2; + } FIFOCTRL_b; + }; + }; + + union { + __IOM uint32_t LC; + + struct { + __IOM uint32_t WLS : 2; + __IOM uint32_t SBS : 1; + __IOM uint32_t PE : 1; + __IOM uint32_t PS : 2; + __IOM uint32_t BC : 1; + __IOM uint32_t DLAB : 1; + } LC_b; + }; + __IM uint32_t RESERVED; + + union { + __IM uint32_t LS; + + struct { + __IM uint32_t RDR : 1; + __IM uint32_t OE : 1; + __IM uint32_t PE : 1; + __IM uint32_t FE : 1; + __IM uint32_t BI : 1; + __IM uint32_t THRE : 1; + __IM uint32_t TEMT : 1; + __IM uint32_t RXFE : 1; + } LS_b; + }; + __IM uint32_t RESERVED1; + + union { + __IOM uint32_t SP; + + struct { + __IOM uint32_t PAD : 8; + } SP_b; + }; + + union { + __IOM uint32_t ABCTRL; + + struct { + __IOM uint32_t START : 1; + __IOM uint32_t MODE : 1; + __IOM uint32_t AUTORESTART : 1; + __IM uint32_t : 5; + __OM uint32_t ABEOIFC : 1; + __OM uint32_t ABTOIFC : 1; + } ABCTRL_b; + }; + __IM uint32_t RESERVED2; + + union { + __IOM uint32_t FD; + + struct { + __IOM uint32_t DIVADDVAL : 4; + __IOM uint32_t MULVAL : 4; + __IOM uint32_t OVER8 : 1; + } FD_b; + }; + __IM uint32_t RESERVED3; + + union { + __IOM uint32_t CTRL; + + struct { + __IOM uint32_t UARTEN : 1; + __IOM uint32_t MODE : 3; + __IM uint32_t : 2; + __IOM uint32_t RXEN : 1; + __IOM uint32_t TXEN : 1; + } CTRL_b; + }; + + union { + __IOM uint32_t HDEN; + + struct { + __IOM uint32_t HDEN : 1; + } HDEN_b; + }; +} sn32_uart_t; + +/** @defgroup UART_Exported_Constants + * @{ + */ + +/** @defgroup UART_LineControl + * @{ + */ +#define UART_Break_Control_Disable (0x0<<6) +#define UART_Break_Control_Enable (0x1<<6) +#define UART_Divisor_Latch_Access_Disable (0x0<<7) +#define UART_Divisor_Latch_Access_Enable (0x1<<7) +#define UART_Parity_None (0x0<<3) +#define UART_Parity_Enable (0x1<<3) +#define UART_Parity_Odd (0x00<<4) +#define UART_Parity_Even (0x01<<4) +#define UART_Parity_Mark (0x02<<4) +#define UART_Parity_Space (0x03<<4) +#define UART_StopBits_One (0x0<<2) +#define UART_StopBits_Two (0x1<<2) +#define UART_WordLength_5b (0x00) +#define UART_WordLength_6b (0x01) +#define UART_WordLength_7b (0x02) +#define UART_WordLength_8b (0x03) +/** + * @} + */ + + +/** @defgroup UART_AutoBaudControl + * @{ + */ +#define UART_AutoBaudControl_None 0 +#define UART_AutoBaudControl_Start (0x01) +#define UART_AutoBaudControl_Restart (UART_AutoBaudControl_Start <<2) +#define UART_AutoBaudControl_End (UART_AutoBaudControl_Start <<8) +#define UART_AutoBaudControl_Timeout (UART_AutoBaudControl_Start <<9) +#define UART_ABCTRL_MODE(x) ((0x00 + x) << 1) +/** + * @} + */ + + +/** @defgroup UART_FIFOControl + * @{ + */ +#define UART_FIFO_Enable (0x01) +#define UART_RxFIFO_Reset (0x01<<1) +#define UART_TxFIFO_Reset (0x01<<2) +#define UART_RxFIFOThreshold_1 (0x00<<6) +#define UART_RxFIFOThreshold_4 (0x01<<6) +#define UART_RxFIFOThreshold_8 (0x02<<6) +#define UART_RxFIFOThreshold_14 (0x03<<6) +/** + * @} + */ + + +/** @defgroup UART_FractionalDivider + * @{ + */ +#define UART_Oversample_8 (0x1<<8) +#define UART_Oversample_16 (0x0<<8) +#define UART_FD_MULVAL(x) (((0x0000 + x) - 1) << 4) +#define UART_FD_DIVADDVAL(x) (0x000 +x) +/** + * @} + */ + +/** @defgroup UART_InterruptEnable + * @{ + */ +#define UART_InterruptEnable (0x01) +#define UART_TxError (UART_InterruptEnable <<10) +#define UART_AutoBaudTimeout (UART_InterruptEnable <<9) +#define UART_AutoBaudEnd (UART_InterruptEnable <<8) +#define UART_TransmitterEmpty (UART_InterruptEnable <<4) +#define UART_ModemStatus (UART_InterruptEnable <<3) +#define UART_ReceiveLine (UART_InterruptEnable <<2) +#define UART_TransmitterHoldingEmpty (UART_InterruptEnable <<1) +#define UART_ReceiveDataAvailable (UART_InterruptEnable <<0) +/** + * @} + */ + +/** @defgroup UART_InterruptIdentification + * @{ + */ +#define UART_Interrupt_Pending 0 +#define UART_InterruptID_THRE 1 +#define UART_InterruptID_RDA 2 +#define UART_InterruptID_RLS 3 +#define UART_InterruptID_CTI 6 +#define UART_InterruptID_TEMT 7 +#define UART_Interrupt_TxError (0x01<<10) +#define UART_Interrupt_ABTO (0x01<<9) +#define UART_Interrupt_ABEO (0x01<<8) +#define UART_Interrupt_Status (0x01) +#define UART_InterruptID_Status 7 + +/** + * @} + */ + +/** @defgroup UART_LineStatus + * @{ + */ +#define UART_LineStatus_TxError (0x01<<8) +#define UART_LineStatus_RxError (0x01<<7) +#define UART_LineStatus_TEMT (0x01<<6) +#define UART_LineStatus_THRE (0x01<<5) +#define UART_LineStatus_BI (0x01<<4) +#define UART_LineStatus_FE (0x01<<3) +#define UART_LineStatus_PE (0x01<<2) +#define UART_LineStatus_OE (0x01<<1) +#define UART_LineStatus_RDR (0x01) + +/** + * @} + */ + +/** @defgroup UART_Control + * @{ + */ +#define UART_Enable (0x01) +#define UART_RxEnable (UART_Enable <<6) +#define UART_TxEnable (UART_Enable <<7) +/** + * @} + */ + +/** @defgroup UART_HalfDuplexMode + * @{ + */ +#define UART_HalfDuplexEnable (0x01) +#define UART_FullDuplexEnable 0 +/** + * @} + */ + +#endif /* SN32_UART_H */ + +/** @} */ diff --git a/os/hal/ports/SN32/SN32F240B/platform.mk b/os/hal/ports/SN32/SN32F240B/platform.mk index 24ad660945..62710aa7e4 100644 --- a/os/hal/ports/SN32/SN32F240B/platform.mk +++ b/os/hal/ports/SN32/SN32F240B/platform.mk @@ -27,6 +27,7 @@ include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/SysTick/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/SPI/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/I2C/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/WDT/driver.mk +include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/UART/driver.mk # Shared variables ALLCSRC += $(PLATFORMSRC_CONTRIB) diff --git a/os/hal/ports/SN32/SN32F260/platform.mk b/os/hal/ports/SN32/SN32F260/platform.mk index 1b8774133b..1c0e8cc196 100644 --- a/os/hal/ports/SN32/SN32F260/platform.mk +++ b/os/hal/ports/SN32/SN32F260/platform.mk @@ -27,6 +27,7 @@ include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/SysTick/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/SPI/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/I2C/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/WDT/driver.mk +include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/UART/driver.mk # Shared variables ALLCSRC += $(PLATFORMSRC_CONTRIB)