summaryrefslogtreecommitdiff
path: root/bsp/smartfusion2/drivers
diff options
context:
space:
mode:
authorwhik <[email protected]>2020-07-07 17:17:45 +0800
committerwhik <[email protected]>2020-07-07 17:17:45 +0800
commit1731a6cd99f6da326cd2ff18e65e65619d90669d (patch)
treeb4b206a7eb45806acc3b30c6629dee93f6704c70 /bsp/smartfusion2/drivers
parent02c6c92a19976b5b5269e23026bae99a82c8fab0 (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.c434
-rw-r--r--bsp/smartfusion2/drivers/drv_gpio.h8
-rw-r--r--bsp/smartfusion2/drivers/drv_uart.c180
-rw-r--r--bsp/smartfusion2/drivers/drv_uart.h11
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