diff options
| author | whik <[email protected]> | 2020-07-07 17:17:45 +0800 |
|---|---|---|
| committer | whik <[email protected]> | 2020-07-07 17:17:45 +0800 |
| commit | 1731a6cd99f6da326cd2ff18e65e65619d90669d (patch) | |
| tree | b4b206a7eb45806acc3b30c6629dee93f6704c70 /bsp/smartfusion2/drivers | |
| parent | 02c6c92a19976b5b5269e23026bae99a82c8fab0 (diff) | |
1.Modify project directory structure
2.Add support for GPIO and UART peripherals
3.Add pin and serial device driver support
4.Put pictures in local folder
5.Modify README file
Diffstat (limited to 'bsp/smartfusion2/drivers')
| -rw-r--r-- | bsp/smartfusion2/drivers/drv_gpio.c | 434 | ||||
| -rw-r--r-- | bsp/smartfusion2/drivers/drv_gpio.h | 8 | ||||
| -rw-r--r-- | bsp/smartfusion2/drivers/drv_uart.c | 180 | ||||
| -rw-r--r-- | bsp/smartfusion2/drivers/drv_uart.h | 11 |
4 files changed, 633 insertions, 0 deletions
diff --git a/bsp/smartfusion2/drivers/drv_gpio.c b/bsp/smartfusion2/drivers/drv_gpio.c new file mode 100644 index 0000000000..af2ad4ce7e --- /dev/null +++ b/bsp/smartfusion2/drivers/drv_gpio.c @@ -0,0 +1,434 @@ +#include <rtthread.h> +#include <rtdevice.h> +#include <rthw.h> + +#include "mss_gpio.h" +#include "drv_gpio.h" + +#ifdef BSP_USING_GPIO + +static struct rt_pin_irq_hdr sf2_pin_irq_hdr_tab[] = +{ + /* pin, hdr, mode, args */ + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, +}; + +/* configure an individual GPIO port */ +static void sf2_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) +{ + uint32_t config; + switch (mode) + { + case PIN_MODE_OUTPUT: + config = MSS_GPIO_OUTPUT_MODE; + break; + case PIN_MODE_INPUT: + config = MSS_GPIO_INPUT_MODE; + break; + default: + config = MSS_GPIO_INOUT_MODE; + break; + } + MSS_GPIO_config((mss_gpio_id_t )pin, config); +} + +static int sf2_pin_read(rt_device_t dev, rt_base_t pin) +{ + uint32_t value; + value = MSS_GPIO_get_inputs() & (1<<pin); + return ((value) ? PIN_HIGH : PIN_LOW); +} + +static void sf2_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) +{ + if (value == PIN_HIGH) + MSS_GPIO_set_output((mss_gpio_id_t )pin, 1); + else + MSS_GPIO_set_output((mss_gpio_id_t )pin, 0); +} + +static rt_err_t sf2_pin_attach_irq(struct rt_device *device, rt_int32_t pin, + rt_uint32_t mode, void (*hdr)(void *args), void *args) +{ + rt_base_t level; + + level = rt_hw_interrupt_disable(); + + if (sf2_pin_irq_hdr_tab[pin].pin == pin && + sf2_pin_irq_hdr_tab[pin].hdr == hdr && + sf2_pin_irq_hdr_tab[pin].mode == mode && + sf2_pin_irq_hdr_tab[pin].args == args) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + if (sf2_pin_irq_hdr_tab[pin].pin != -1) + { + rt_hw_interrupt_enable(level); + return -RT_EBUSY; + } + sf2_pin_irq_hdr_tab[pin].pin = pin; + sf2_pin_irq_hdr_tab[pin].hdr = hdr; + sf2_pin_irq_hdr_tab[pin].mode = mode; + sf2_pin_irq_hdr_tab[pin].args = args; + + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +static rt_err_t sf2_pin_detach_irq(struct rt_device *device, rt_int32_t pin) +{ + rt_base_t level; + + level = rt_hw_interrupt_disable(); + + if (sf2_pin_irq_hdr_tab[pin].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + + sf2_pin_irq_hdr_tab[pin].pin = -1; + sf2_pin_irq_hdr_tab[pin].hdr = RT_NULL; + sf2_pin_irq_hdr_tab[pin].mode = 0; + sf2_pin_irq_hdr_tab[pin].args = RT_NULL; + + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +static rt_err_t sf2_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) +{ + uint32_t mode; + rt_base_t level; + + if (enabled == PIN_IRQ_ENABLE) + { + level = rt_hw_interrupt_disable(); + if (sf2_pin_irq_hdr_tab[pin].pin == -1) + { + rt_hw_interrupt_enable(level); + return -RT_ENOSYS; + } + switch(sf2_pin_irq_hdr_tab[pin].mode) + { + case PIN_IRQ_MODE_RISING : + mode = MSS_GPIO_IRQ_EDGE_POSITIVE; + break; + case PIN_IRQ_MODE_FALLING : + mode = MSS_GPIO_IRQ_EDGE_NEGATIVE; + break; + case PIN_IRQ_MODE_RISING_FALLING: + mode = MSS_GPIO_IRQ_EDGE_BOTH; + break; + case PIN_IRQ_MODE_HIGH_LEVEL : + mode = MSS_GPIO_IRQ_LEVEL_HIGH; + break; + case PIN_IRQ_MODE_LOW_LEVEL: + mode = MSS_GPIO_IRQ_LEVEL_LOW; + break; + } + MSS_GPIO_config((mss_gpio_id_t )pin, MSS_GPIO_INPUT_MODE | mode); + MSS_GPIO_enable_irq((mss_gpio_id_t )pin); + + rt_hw_interrupt_enable(level); + } + else if (enabled == PIN_IRQ_DISABLE) + { + MSS_GPIO_config((mss_gpio_id_t )pin, MSS_GPIO_INPUT_MODE); + MSS_GPIO_disable_irq((mss_gpio_id_t )pin); + } + else + return -RT_ENOSYS; + + return RT_EOK; +} + +static const struct rt_pin_ops sf2_pin_ops = +{ + sf2_pin_mode, + sf2_pin_write, + sf2_pin_read, + sf2_pin_attach_irq, + sf2_pin_detach_irq, + sf2_pin_irq_enable +}; + + +int rt_hw_pin_init(void) +{ + rt_err_t result = RT_EOK; + MSS_GPIO_init(); + result = rt_device_pin_register("pin", &sf2_pin_ops, RT_NULL); + RT_ASSERT(result == RT_EOK); + return result; +} +INIT_BOARD_EXPORT(rt_hw_pin_init); + +rt_inline void pin_irq_hdr(int pin) +{ + MSS_GPIO_clear_irq((mss_gpio_id_t )pin); + + if (sf2_pin_irq_hdr_tab[pin].hdr) + sf2_pin_irq_hdr_tab[pin].hdr(sf2_pin_irq_hdr_tab[pin].args); +} + +void GPIO0_IRQHandler( void ) +{ + /* enter interrupt */ + rt_interrupt_enter(); + pin_irq_hdr(0); + /* leave interrupt */ + rt_interrupt_leave(); +} + +void GPIO1_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(1); + rt_interrupt_leave(); +} + +void GPIO2_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(2); + rt_interrupt_leave(); +} + +void GPIO3_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(3); + rt_interrupt_leave(); +} + +void GPIO4_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(4); + rt_interrupt_leave(); +} + +void GPIO5_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(5); + rt_interrupt_leave(); +} + +void GPIO6_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(6); + rt_interrupt_leave(); +} +void GPIO7_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(7); + rt_interrupt_leave(); +} + +void GPIO8_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(8); + rt_interrupt_leave(); +} + +void GPIO9_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(9); + rt_interrupt_leave(); +} + +void GPIO10_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(10); + rt_interrupt_leave(); +} + +void GPIO11_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(11); + rt_interrupt_leave(); +} + +void GPIO12_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(12); + rt_interrupt_leave(); +} + +void GPIO13_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(13); + rt_interrupt_leave(); +} + +void GPIO14_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(14); + rt_interrupt_leave(); +} + +void GPIO15_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(15); + rt_interrupt_leave(); +} + +void GPIO16_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(16); + rt_interrupt_leave(); +} + +void GPIO17_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(17); + rt_interrupt_leave(); +} + +void GPIO18_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(18); + rt_interrupt_leave(); +} + +void GPIO19_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(19); + rt_interrupt_leave(); +} + +void GPIO20_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(20); + rt_interrupt_leave(); +} + +void GPIO21_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(21); + rt_interrupt_leave(); +} + +void GPIO22_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(22); + rt_interrupt_leave(); +} + +void GPIO23_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(23); + rt_interrupt_leave(); +} + +void GPIO24_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(24); + rt_interrupt_leave(); +} + +void GPIO25_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(25); + rt_interrupt_leave(); +} + +void GPIO26_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(26); + rt_interrupt_leave(); +} + +void GPIO27_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(27); + rt_interrupt_leave(); +} + +void GPIO28_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(28); + rt_interrupt_leave(); +} + +void GPIO29_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(29); + rt_interrupt_leave(); +} + +void GPIO30_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(30); + rt_interrupt_leave(); +} + +void GPIO31_IRQHandler( void ) +{ + rt_interrupt_enter(); + pin_irq_hdr(31); + rt_interrupt_leave(); +} + +#endif diff --git a/bsp/smartfusion2/drivers/drv_gpio.h b/bsp/smartfusion2/drivers/drv_gpio.h new file mode 100644 index 0000000000..8ebcb4e861 --- /dev/null +++ b/bsp/smartfusion2/drivers/drv_gpio.h @@ -0,0 +1,8 @@ +#ifndef __DRV_GPIO_H__ +#define __DRV_GPIO_H__ + +int rt_hw_pin_init(void); + +#endif + + diff --git a/bsp/smartfusion2/drivers/drv_uart.c b/bsp/smartfusion2/drivers/drv_uart.c new file mode 100644 index 0000000000..5a32efabe8 --- /dev/null +++ b/bsp/smartfusion2/drivers/drv_uart.c @@ -0,0 +1,180 @@ +#include <rthw.h> +#include <rtthread.h> +#include <rtdevice.h> + +#include "drv_uart.h" + +struct sf2_uart +{ + mss_uart_instance_t *uart; + IRQn_Type irq; +}; + +struct sf2_uart uart0= +{ + &g_mss_uart0, + UART0_IRQn, +}; +struct rt_serial_device serial0; + +void uart0_rx_handler(mss_uart_instance_t *this_uart) +{ + /* enter interrupt */ + rt_interrupt_enter(); + rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND); + /* leave interrupt */ + rt_interrupt_leave(); +} + +struct sf2_uart uart1= +{ + &g_mss_uart1, + UART1_IRQn, +}; + +struct rt_serial_device serial1; +void uart1_rx_handler(mss_uart_instance_t *this_uart) +{ + /* enter interrupt */ + rt_interrupt_enter(); + rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND); + /* leave interrupt */ + rt_interrupt_leave(); +} +static rt_err_t sf2_uart_configure(struct rt_serial_device *serial, + struct serial_configure *cfg) +{ + uint32_t baudRate; + uint8_t datBits, parity, stopBits; + uint8_t config; + struct sf2_uart *uart; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart = (struct sf2_uart *)serial->parent.user_data; + + switch(cfg->data_bits) + { + case DATA_BITS_5: datBits = MSS_UART_DATA_5_BITS; break; + case DATA_BITS_6: datBits = MSS_UART_DATA_6_BITS; break; + case DATA_BITS_7: datBits = MSS_UART_DATA_7_BITS; break; + case DATA_BITS_8: datBits = MSS_UART_DATA_8_BITS; break; + default: datBits = MSS_UART_DATA_8_BITS; break; + } + switch(cfg->parity) + { + case PARITY_NONE: parity = MSS_UART_NO_PARITY; break; + case PARITY_EVEN: parity = MSS_UART_EVEN_PARITY; break; + case PARITY_ODD : parity = MSS_UART_ODD_PARITY; break; + default : parity = MSS_UART_NO_PARITY; break; + } + switch(cfg->stop_bits) + { + case STOP_BITS_1: stopBits = MSS_UART_ONE_STOP_BIT; break; + case STOP_BITS_2: stopBits = MSS_UART_TWO_STOP_BITS; break; + case STOP_BITS_3: stopBits = MSS_UART_ONEHALF_STOP_BIT; break; + default : stopBits = MSS_UART_ONE_STOP_BIT; + } + + baudRate = cfg->baud_rate; + config = datBits | parity | stopBits; + + MSS_UART_init(uart->uart, baudRate, config); + if(uart->uart == &g_mss_uart0) + MSS_UART_set_rx_handler(uart->uart, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE); + else + MSS_UART_set_rx_handler(uart->uart, uart1_rx_handler, MSS_UART_FIFO_SINGLE_BYTE); + + return RT_EOK; +} + +static rt_err_t sf2_uart_control(struct rt_serial_device *serial, + int cmd, void *arg) +{ + struct sf2_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct sf2_uart*)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + NVIC_DisableIRQ(uart->irq); + break; + case RT_DEVICE_CTRL_SET_INT: + NVIC_EnableIRQ(uart->irq); + break; + } + + return RT_EOK; +} + +static int sf2_uart_putc(struct rt_serial_device *serial, char c) +{ + struct sf2_uart* uart; + uint32_t tx_ready; + + RT_ASSERT(serial != RT_NULL); + + uart = (struct sf2_uart*)serial->parent.user_data; + + do { + tx_ready = uart->uart->hw_reg->LSR & 0x20u; + } while(!tx_ready); + uart->uart->hw_reg->THR = c; + + return 1; +} + +static int sf2_uart_getc(struct rt_serial_device *serial) +{ + int ch = -1; + uint8_t err_status; + struct sf2_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct sf2_uart*)serial->parent.user_data; + + err_status = MSS_UART_get_rx_status(uart->uart); + if(MSS_UART_NO_ERROR == err_status) + MSS_UART_get_rx(uart->uart, (uint8_t *)&ch, 1); + + return ch; +} + +static const struct rt_uart_ops sf2_uart_ops = +{ + sf2_uart_configure, + sf2_uart_control, + sf2_uart_putc, + sf2_uart_getc, +}; + + +int rt_hw_uart_init(void) +{ + rt_err_t result = RT_EOK; + struct sf2_uart* uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + +#ifdef BSP_USING_UART0 + uart = &uart0; + serial0.ops = &sf2_uart_ops; + /* default config: 115200, 8, no, 1 */ + serial0.config = config; + result = rt_hw_serial_register(&serial0, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); + RT_ASSERT(result == RT_EOK); +#endif + +#ifdef BSP_USING_UART1 + uart = &uart1; + serial1.ops = &sf2_uart_ops; + /* default config: 115200, 8, no, 1 */ + serial1.config = config; + result = rt_hw_serial_register(&serial1, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); + RT_ASSERT(result == RT_EOK); +#endif + return result; +} +INIT_BOARD_EXPORT(rt_hw_uart_init); diff --git a/bsp/smartfusion2/drivers/drv_uart.h b/bsp/smartfusion2/drivers/drv_uart.h new file mode 100644 index 0000000000..e0d731d58e --- /dev/null +++ b/bsp/smartfusion2/drivers/drv_uart.h @@ -0,0 +1,11 @@ +#ifndef __DRV_UART_H__ +#define __DRV_UART_H__ + +#include "mss_uart.h" +void uart_rx_handler(mss_uart_instance_t *this_uart); + +void uart0_rx_handler(mss_uart_instance_t * this_uart); +void uart1_rx_handler(mss_uart_instance_t * this_uart); +int rt_hw_uart_init(void); + +#endif |
