diff --git a/source/hal/driver/Luat/Air105/CMakeLists.txt b/source/hal/driver/Luat/Air105/CMakeLists.txt index ee84be6d0..0c601be85 100644 --- a/source/hal/driver/Luat/Air105/CMakeLists.txt +++ b/source/hal/driver/Luat/Air105/CMakeLists.txt @@ -2,3 +2,6 @@ vsf_add_sources( driver.c startup_Air105.c ) + +add_subdirectory(usb) +add_subdirectory(uart) diff --git a/source/hal/driver/Luat/Air105/device.h b/source/hal/driver/Luat/Air105/device.h index 09263d9b2..da73df398 100644 --- a/source/hal/driver/Luat/Air105/device.h +++ b/source/hal/driver/Luat/Air105/device.h @@ -65,6 +65,9 @@ .reg = (void *)0x40000C00, \ .irqn = 1, +#define VSF_HW_USART_COUNT 4 +#define VSF_HW_USART_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) + /*============================ MACROFIED FUNCTIONS ===========================*/ /*============================ TYPES =========================================*/ /*============================ GLOBAL VARIABLES ==============================*/ diff --git a/source/hal/driver/Luat/Air105/driver.h b/source/hal/driver/Luat/Air105/driver.h index 55e1ddd21..7e7175574 100644 --- a/source/hal/driver/Luat/Air105/driver.h +++ b/source/hal/driver/Luat/Air105/driver.h @@ -29,6 +29,7 @@ # include "hal/vsf_hal_cfg.h" # include "./device.h" +# include "./uart/uart.h" # include "./usb/usb.h" /*============================ MACROFIED FUNCTIONS ===========================*/ @@ -37,6 +38,22 @@ /*============================ TYPES =========================================*/ /*============================ INCLUDES ======================================*/ +#if VSF_HAL_USE_USART == ENABLED +# define VSF_USART_CFG_REIMPLEMENT_TYPE_MODE ENABLED +# define VSF_USART_CFG_REIMPLEMENT_TYPE_IRQ_MASK ENABLED +# include "hal/driver/common/template/vsf_template_usart.h" + +# define VSF_USART_CFG_DEC_INSTANCE_PREFIX __vsf_hw +# define VSF_USART_CFG_DEC_PREFIX vsf_hw +# define VSF_USART_CFG_DEC_UPCASE_PREFIX VSF_HW +# include "hal/driver/common/usart/usart_template.h" + +# define VSF_USART_CFG_DEC_INSTANCE_PREFIX vsf_hw +# define VSF_FIFO2REQ_USART_COUNT VSF_HW_USART_COUNT +# define VSF_FIFO2REQ_USART_MASK VSF_HW_USART_MASK +# include "hal/driver/common/usart/fifo2req_usart.h" +#endif + # endif // __HAL_DRIVER_LUAT_AIR05_H__ #endif // __VSF_HEADER_ONLY_SHOW_ARCH_INFO__ /* EOF */ diff --git a/source/hal/driver/Luat/Air105/startup_Air105.c b/source/hal/driver/Luat/Air105/startup_Air105.c index b5234192f..1c2e8d2fd 100644 --- a/source/hal/driver/Luat/Air105/startup_Air105.c +++ b/source/hal/driver/Luat/Air105/startup_Air105.c @@ -89,6 +89,10 @@ __imp_unprocessed_weak_handler(SWI6_Handler) __imp_unprocessed_weak_handler(SWI7_Handler) __imp_unprocessed_weak_handler(SWI8_Handler) __imp_unprocessed_weak_handler(USB_OTG0_Handler) +__imp_unprocessed_weak_handler(UART0_Handler) +__imp_unprocessed_weak_handler(UART1_Handler) +__imp_unprocessed_weak_handler(UART2_Handler) +__imp_unprocessed_weak_handler(UART3_Handler) /*---------------------------------------------------------------------------- Exception / Interrupt Vector table @@ -123,8 +127,8 @@ ROOT const pFunc __VECTOR_TABLE[] ALIGN(512) = { ISR_GlobalHandler, ISR_GlobalHandler, ISR_GlobalHandler, - ISR_GlobalHandler, - ISR_GlobalHandler, + UART0_Handler, + UART1_Handler, ISR_GlobalHandler, ISR_GlobalHandler, ISR_GlobalHandler, @@ -150,8 +154,8 @@ ROOT const pFunc __VECTOR_TABLE[] ALIGN(512) = { ISR_GlobalHandler, SWI1_Handler, SWI2_Handler, - ISR_GlobalHandler, - ISR_GlobalHandler, + UART2_Handler, + UART3_Handler, SWI3_Handler, ISR_GlobalHandler, ISR_GlobalHandler, diff --git a/source/hal/driver/Luat/Air105/uart/CMakeLists.txt b/source/hal/driver/Luat/Air105/uart/CMakeLists.txt new file mode 100644 index 000000000..f4185ce0e --- /dev/null +++ b/source/hal/driver/Luat/Air105/uart/CMakeLists.txt @@ -0,0 +1,3 @@ +vsf_add_sources( + uart.c +) diff --git a/source/hal/driver/Luat/Air105/uart/uart.c b/source/hal/driver/Luat/Air105/uart/uart.c new file mode 100644 index 000000000..10fc22e05 --- /dev/null +++ b/source/hal/driver/Luat/Air105/uart/uart.c @@ -0,0 +1,310 @@ +/***************************************************************************** + * Copyright(C)2009-2022 by VSF Team * + * * + * 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. * + * * + ****************************************************************************/ + +/*============================ INCLUDES ======================================*/ + +#include "../driver.h" + +#if VSF_HAL_USE_USART == ENABLED + +#include "hal/vsf_hal.h" + +#ifdef FALSE +# undef FALSE +#endif +#ifdef TRUE +# undef TRUE +#endif +#include "air105.h" + +/*============================ MACROS ========================================*/ + +#ifndef VSF_HW_USART_CFG_MULTI_CLASS +# define VSF_HW_USART_CFG_MULTI_CLASS VSF_USART_CFG_MULTI_CLASS +#endif + +/*============================ MACROFIED FUNCTIONS ===========================*/ +/*============================ TYPES =========================================*/ + +typedef struct vsf_hw_usart_const_t { + IRQn_Type irqn; + UART_TypeDef *reg; + uint8_t periph_idx; +} vsf_hw_usart_const_t; + +typedef struct vsf_hw_usart_t { +#if VSF_HW_USART_CFG_MULTI_CLASS == ENABLED + vsf_usart_t vsf_usart; +#endif + const vsf_hw_usart_const_t *usart_const; + + vsf_usart_isr_t isr; +} vsf_hw_usart_t; + +/*============================ IMPLEMENTATION ================================*/ + +vsf_err_t vsf_hw_usart_init(vsf_hw_usart_t *hw_usart_ptr, vsf_usart_cfg_t *cfg_ptr) +{ + VSF_HAL_ASSERT(NULL != hw_usart_ptr); + const vsf_hw_usart_const_t *usart_const = hw_usart_ptr->usart_const; + VSF_HAL_ASSERT(NULL != usart_const); + UART_TypeDef *reg = usart_const->reg; + VSF_HAL_ASSERT(NULL != reg); + + SYSCTRL->SOFT_RST1 = 1 << usart_const->periph_idx; + while (SYSCTRL->SOFT_RST1 & (1 << usart_const->periph_idx)); + + { + extern uint32_t SystemCoreClock; + uint32_t tmp_baud_div = (SystemCoreClock >> 6) / cfg_ptr->baudrate; + reg->LCR |= UART_LCR_DLAB; + reg->OFFSET_0.DLL = (tmp_baud_div >> 0) & 0x00FF; + reg->OFFSET_4.DLH = (tmp_baud_div >> 8) & 0x00FF; + reg->LCR &= ~UART_LCR_DLAB; + } + + reg->LCR = cfg_ptr->mode & AIR105_USART_MODE_ALL_BITS_MASK; + reg->SFE |= UART_SFE_SFE; + + vsf_usart_isr_t *isr_ptr = &cfg_ptr->isr; + hw_usart_ptr->isr = *isr_ptr; + + if (isr_ptr->handler_fn != NULL) { + NVIC_SetPriority(usart_const->irqn, (uint32_t)isr_ptr->prio); + NVIC_EnableIRQ(usart_const->irqn); + } else { + NVIC_DisableIRQ(usart_const->irqn); + } + + return VSF_ERR_NONE; +} + +void vsf_hw_usart_fini(vsf_hw_usart_t *hw_usart_ptr) +{ + VSF_HAL_ASSERT(hw_usart_ptr != NULL); +} + +vsf_usart_capability_t vsf_hw_usart_capability(vsf_hw_usart_t *hw_usart_ptr) +{ + VSF_HAL_ASSERT(NULL != hw_usart_ptr); + const vsf_hw_usart_const_t *usart_const = hw_usart_ptr->usart_const; + VSF_HAL_ASSERT(NULL != usart_const); + + extern uint32_t SystemCoreClock; + vsf_usart_capability_t usart_capability = { + .irq_mask = AIR105_USART_MODE_ALL_BITS_MASK, + .max_baudrate = (SystemCoreClock >> 6) / (16 * 1), + .min_baudrate = (SystemCoreClock >> 6) / (16 * 65535), + .min_data_bits = 5, + .max_data_bits = 8, + .max_tx_fifo_counter = 16, + .max_rx_fifo_counter = 16, + .support_rx_timeout = 0, + }; + + return usart_capability; +} + +fsm_rt_t vsf_hw_usart_enable(vsf_hw_usart_t *hw_usart_ptr) +{ + return fsm_rt_cpl; +} + +fsm_rt_t vsf_hw_usart_disable(vsf_hw_usart_t *hw_usart_ptr) +{ + return fsm_rt_cpl; +} + +void vsf_hw_usart_irq_enable(vsf_hw_usart_t *hw_usart_ptr, vsf_usart_irq_mask_t irq_mask) +{ + VSF_HAL_ASSERT(NULL != hw_usart_ptr); + const vsf_hw_usart_const_t *usart_const = hw_usart_ptr->usart_const; + VSF_HAL_ASSERT(NULL != usart_const); + VSF_HAL_ASSERT(NULL != usart_const->reg); + VSF_HAL_ASSERT((irq_mask & ~AIR105_USART_IRQ_MASK) == 0); + + usart_const->reg->OFFSET_4.IER |= irq_mask; +} + +void vsf_hw_usart_irq_disable(vsf_hw_usart_t *hw_usart_ptr, vsf_usart_irq_mask_t irq_mask) +{ + VSF_HAL_ASSERT(NULL != hw_usart_ptr); + const vsf_hw_usart_const_t *usart_const = hw_usart_ptr->usart_const; + VSF_HAL_ASSERT(NULL != usart_const); + VSF_HAL_ASSERT(NULL != usart_const->reg); + VSF_HAL_ASSERT((irq_mask & ~AIR105_USART_IRQ_MASK) == 0); + + usart_const->reg->OFFSET_4.IER &= ~irq_mask; +} + +static bool __hw_usart_read_fifo_is_empty(vsf_hw_usart_t *hw_usart_ptr) +{ + return !(hw_usart_ptr->usart_const->reg->USR & UART_USR_RFNE); +} + +static bool __hw_usart_write_fifo_is_full(vsf_hw_usart_t *hw_usart_ptr) +{ + return !(hw_usart_ptr->usart_const->reg->USR & UART_USR_TFNF); +} + +vsf_usart_status_t vsf_hw_usart_status(vsf_hw_usart_t *hw_usart_ptr) +{ + VSF_HAL_ASSERT(NULL != hw_usart_ptr); + + vsf_usart_status_t status = { + .is_busy = !!(hw_usart_ptr->usart_const->reg->USR & UART_USR_BUSY), + }; + + return status; +} + +uint_fast16_t vsf_hw_usart_rxfifo_get_data_count(vsf_hw_usart_t *hw_usart_ptr) +{ + return hw_usart_ptr->usart_const->reg->RFL & UART_RFL_RFL; +} + +uint_fast16_t vsf_hw_usart_rxfifo_read(vsf_hw_usart_t *hw_usart_ptr, void *buffer_ptr, uint_fast16_t count) +{ + VSF_HAL_ASSERT(NULL != hw_usart_ptr); + const vsf_hw_usart_const_t *usart_const = hw_usart_ptr->usart_const; + VSF_HAL_ASSERT(NULL != usart_const); + UART_TypeDef *reg = usart_const->reg; + VSF_HAL_ASSERT(NULL != reg); + + uint8_t *buf_ptr = (uint8_t *)buffer_ptr; + VSF_HAL_ASSERT(NULL != buf_ptr); + + uint_fast16_t i = 0; + while (i < count) { + if (__hw_usart_read_fifo_is_empty(hw_usart_ptr)) { + break; + } + buf_ptr[i++] = reg->OFFSET_0.RBR; + } + return i; +} + +uint_fast16_t vsf_hw_usart_txfifo_get_free_count(vsf_hw_usart_t *hw_usart_ptr) +{ + return 16 - (hw_usart_ptr->usart_const->reg->TFL & UART_TFL_TFL); +} + +uint_fast16_t vsf_hw_usart_txfifo_write(vsf_hw_usart_t *hw_usart_ptr, void *buffer_ptr, uint_fast16_t count) +{ + VSF_HAL_ASSERT(NULL != hw_usart_ptr); + const vsf_hw_usart_const_t *usart_const = hw_usart_ptr->usart_const; + VSF_HAL_ASSERT(NULL != usart_const); + UART_TypeDef *reg = usart_const->reg; + VSF_HAL_ASSERT(NULL != reg); + + uint8_t *buf_ptr = (uint8_t *) buffer_ptr; + VSF_HAL_ASSERT(NULL != buf_ptr); + + uint_fast16_t i = 0; + while (i < count) { + if (__hw_usart_write_fifo_is_full(hw_usart_ptr)) { + break; + } + reg->OFFSET_0.THR = buf_ptr[i++]; + } + return i; +} + +static vsf_usart_irq_mask_t __get_uart_irq_mask(vsf_hw_usart_t *hw_usart_ptr) +{ + VSF_HAL_ASSERT(NULL != hw_usart_ptr); + const vsf_hw_usart_const_t *usart_const = hw_usart_ptr->usart_const; + VSF_HAL_ASSERT(NULL != usart_const); + UART_TypeDef *reg = usart_const->reg; + VSF_HAL_ASSERT(NULL != reg); + + uint32_t value; + uint32_t irq_type = reg->OFFSET_8.IIR & UART_IIR_IID; + + switch (irq_type) { + case 0x0000: // Modem Status Interrupt + value = reg->MSR; + (void)value; + return 0; + + case 0x0001: // No interrupt + return 0; + + case 0x0010: // Tx FIFO Empty + return VSF_USART_IRQ_MASK_TX; + + case 0x0100: // Rx FIFO valid + return VSF_USART_IRQ_MASK_RX; + + case 0x0110: // Line status interrupt + value = reg->LSR; + (void)value; + return 0; + + case 0x1100: // Rx timeout interrupt + return VSF_USART_IRQ_MASK_RX_TIMEOUT; + + default: + VSF_HAL_ASSERT(0); + return (vsf_usart_irq_mask_t)0; + } +} + +static void __vsf_hw_usart_irq_handler(vsf_hw_usart_t *hw_usart_ptr) +{ + vsf_usart_irq_mask_t irq_mask = __get_uart_irq_mask(hw_usart_ptr); + if (irq_mask & VSF_USART_IRQ_ALL_BITS_MASK) { + if (NULL != hw_usart_ptr->isr.handler_fn) { + hw_usart_ptr->isr.handler_fn(hw_usart_ptr->isr.target_ptr, (vsf_usart_t *)hw_usart_ptr, irq_mask); + } + } +} + +/*============================ INCLUDES ======================================*/ + +#define VSF_USART_CFG_IMP_INSTANCE_PREFIX __vsf_hw +#define VSF_USART_CFG_IMP_PREFIX vsf_hw +#define VSF_USART_CFG_IMP_UPCASE_PREFIX VSF_HW +#define VSF_USART_CFG_IMP_FIFO_TO_REQUEST ENABLED +#define VSF_USART_CFG_IMP_LV0(__COUNT, __HAL_OP) \ + static const vsf_hw_usart_const_t __vsf_hw_usart ## __COUNT ## _clock = { \ + .reg = UART ## __COUNT, \ + .irqn = UART ## __COUNT ## _IRQn, \ + .periph_idx = __COUNT, \ + }; \ + vsf_hw_usart_t __vsf_hw_usart ## __COUNT = { \ + .usart_const = &__vsf_hw_usart ## __COUNT ## _clock, \ + __HAL_OP \ + }; \ + void UART ## __COUNT ## _Handler(void) \ + { \ + uintptr_t ctx = vsf_hal_irq_enter(); \ + __vsf_hw_usart_irq_handler(&__vsf_hw_usart ## __COUNT); \ + vsf_hal_irq_leave(ctx); \ + } +#include "hal/driver/common/usart/usart_template.inc" + +#define VSF_USART_CFG_IMP_INSTANCE_PREFIX vsf_hw +#define VSF_USART_CFG_IMP_PREFIX vsf_fifo2req +#define VSF_USART_CFG_IMP_UPCASE_PREFIX VSF_FIFO2REQ +#define VSF_FIFO2REQ_USART_COUNT VSF_HW_USART_COUNT +#define VSF_FIFO2REQ_USART_MASK VSF_HW_USART_MASK +#define VSF_USART_CFG_IMP_LV0(__COUNT, __HAL_OP) \ + describe_fifo2req_usart(vsf_hw_usart ## __COUNT, __vsf_hw_usart ## __COUNT) +#include "hal/driver/common/usart/usart_template.inc" + +#endif // VSF_HAL_USE_USART diff --git a/source/hal/driver/Luat/Air105/uart/uart.h b/source/hal/driver/Luat/Air105/uart/uart.h new file mode 100644 index 000000000..9732bcfa6 --- /dev/null +++ b/source/hal/driver/Luat/Air105/uart/uart.h @@ -0,0 +1,115 @@ +/***************************************************************************** + * Copyright(C)2009-2022 by VSF Team * + * * + * 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 __HAL_DRIVER_LUAT_AIR105_UART_H__ +#define __HAL_DRIVER_LUAT_AIR105_UART_H__ + +/*============================ INCLUDES ======================================*/ + +#include "hal/vsf_hal_cfg.h" + +#if VSF_HAL_USE_USART == ENABLED +#include "../__device.h" + +/*============================ MACROS ========================================*/ + +#define VSF_USART_CFG_REIMPLEMENT_TYPE_MODE ENABLED +#define VSF_USART_CFG_REIMPLEMENT_TYPE_IRQ_MASK ENABLED + +/*============================ MACROFIED FUNCTIONS ===========================*/ +/*============================ TYPES =========================================*/ + +typedef enum vsf_usart_mode_t { + // hardware + VSF_USART_8_BIT_LENGTH = (0x3ul << 0), + VSF_USART_7_BIT_LENGTH = (0x2ul << 0), + VSF_USART_6_BIT_LENGTH = (0x1ul << 0), + VSF_USART_5_BIT_LENGTH = (0x0ul << 0), + + + VSF_USART_1_STOPBIT = (0x0ul << 2), + VSF_USART_2_STOPBIT = (0x1ul << 2), + VSF_USART_1_5_STOPBIT = (0x1ul << 2), // for VSF_USART_5_BIT_LENGTH only + + + VSF_USART_NO_PARITY = (0x0ul << 3), + VSF_USART_ODD_PARITY = (0x1ul << 3), + VSF_USART_EVEN_PARITY = (0x3ul << 3), + + // Not hardware, just keep for build + VSF_USART_9_BIT_LENGTH = (0x1ul << 24), + + VSF_USART_FORCE_0_PARITY = (0x1ul << 25), + VSF_USART_FORCE_1_PARITY = (0x2ul << 25), + + VSF_USART_NO_HWCONTROL = (0x0ul << 28), + VSF_USART_RTS_HWCONTROL = (0x1ul << 28), + VSF_USART_CTS_HWCONTROL = (0x2ul << 28), + VSF_USART_RTS_CTS_HWCONTROL = (0x3ul << 28), + + VSF_USART_TX_ENABLE = (0x1ul << 30), + VSF_USART_TX_DISABLE = (0x0ul << 30), + + VSF_USART_RX_ENABLE = (0x1ul << 31), + VSF_USART_RX_DISABLE = (0x0ul << 31), + + AIR105_VSF_USART_BIT_LENGTH_MASK = VSF_USART_8_BIT_LENGTH | + VSF_USART_7_BIT_LENGTH | + VSF_USART_6_BIT_LENGTH | + VSF_USART_5_BIT_LENGTH, + AIR105_VSF_USART_STOPBIT_MASK = VSF_USART_1_STOPBIT | + VSF_USART_2_STOPBIT, + AIR105_VSF_USART_PARITY_MASK = VSF_USART_NO_PARITY | + VSF_USART_ODD_PARITY | + VSF_USART_EVEN_PARITY, + AIR105_USART_MODE_ALL_BITS_MASK = AIR105_VSF_USART_BIT_LENGTH_MASK | + AIR105_VSF_USART_STOPBIT_MASK | + AIR105_VSF_USART_PARITY_MASK, +} vsf_usart_mode_t; + +typedef enum vsf_usart_irq_mask_t { + // usart fifo interrupt + VSF_USART_IRQ_MASK_RX = (1 << 0), + VSF_USART_IRQ_MASK_TX = (1 << 1), + + AIR105_USART_IRQ_MASK_FIFO = VSF_USART_IRQ_MASK_RX | VSF_USART_IRQ_MASK_TX, + + VSF_USART_IRQ_MASK_RX_TIMEOUT = (1 << 8), + + // usart request interrupt + VSF_USART_IRQ_MASK_RX_CPL = (0x1ul << 26), + VSF_USART_IRQ_MASK_TX_CPL = (0x1ul << 27), + + // usart error interrupt + VSF_USART_IRQ_MASK_FRAME_ERR = (0x1ul << 28), + VSF_USART_IRQ_MASK_PARITY_ERR = (0x1ul << 29), + VSF_USART_IRQ_MASK_BREAK_ERR = (0x1ul << 30), + VSF_USART_IRQ_MASK_OVERFLOW_ERR = (0x1ul << 31), + + AIR105_USART_IRQ_MASK = VSF_USART_IRQ_MASK_RX | + VSF_USART_IRQ_MASK_TX, +} vsf_usart_irq_mask_t; + +/*============================ INCLUDES ======================================*/ +/*============================ GLOBAL VARIABLES ==============================*/ +/*============================ INCLUDES ======================================*/ +/*============================ PROTOTYPES ====================================*/ +/*============================ IMPLEMENTATION ================================*/ + +#endif +#endif +/* EOF */