From 0e142aeee19b76c271ccef3a533d2b56ae4d69d0 Mon Sep 17 00:00:00 2001 From: DisruptiveNL Date: Sun, 8 Apr 2018 07:30:19 -0600 Subject: [PATCH] DisruptiveNL --- configs/nucleo-l476rg/include/board.h | 14 +- configs/nucleo-l476rg/src/Makefile | 10 + configs/nucleo-l476rg/src/nucleo-l476rg.h | 48 +++- configs/nucleo-l476rg/src/stm32_appinit.c | 28 +- configs/nucleo-l476rg/src/stm32_can.c | 109 +++++++ configs/nucleo-l476rg/src/stm32_gpio.c | 336 ++++++++++++++++++++++ 6 files changed, 542 insertions(+), 3 deletions(-) create mode 100644 configs/nucleo-l476rg/src/stm32_can.c create mode 100644 configs/nucleo-l476rg/src/stm32_gpio.c diff --git a/configs/nucleo-l476rg/include/board.h b/configs/nucleo-l476rg/include/board.h index f1625efdf8..184c78d7f5 100644 --- a/configs/nucleo-l476rg/include/board.h +++ b/configs/nucleo-l476rg/include/board.h @@ -1,7 +1,7 @@ /************************************************************************************ * configs/nucleo-l476rg/include/board.h * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -81,6 +81,18 @@ /* Alternate function pin selections ************************************************/ +/* CAN1: (added 31-03 -- Ben vd Veen (DisruptiveNL) + * RXD: PA11 + * PB8 + * PD0 + * TXD: PA12 + * PB9 + * PD1 + */ + +#define GPIO_CAN1_RX GPIO_CAN1_RX_2 /* PA11 - AF9 */ +#define GPIO_CAN1_TX GPIO_CAN1_TX_2 /* PA12 - AF9 */ + /* USART1: * RXD: PA10 CN9 pin 3, CN10 pin 33 * PB7 CN7 pin 21 diff --git a/configs/nucleo-l476rg/src/Makefile b/configs/nucleo-l476rg/src/Makefile index cfa6ae2baf..61049202bd 100644 --- a/configs/nucleo-l476rg/src/Makefile +++ b/configs/nucleo-l476rg/src/Makefile @@ -59,6 +59,16 @@ CSRCS += stm32_ajoystick.c endif endif +# Ben vd Veen (DisruptiveNL) -- 31-03-2018 +ifeq ($(CONFIG_DEV_GPIO),y) + CSRCS += stm32_gpio.c +endif + +# Ben vd Veen (DisruptiveNL) -- 31-03-2018 +ifeq ($(CONFIG_CAN),y) + CSRCS += stm32_can.c +endif + ifeq ($(CONFIG_SENSORS_QENCODER),y) CSRCS += stm32_qencoder.c endif diff --git a/configs/nucleo-l476rg/src/nucleo-l476rg.h b/configs/nucleo-l476rg/src/nucleo-l476rg.h index 4921bdd08d..7b91f5ea15 100644 --- a/configs/nucleo-l476rg/src/nucleo-l476rg.h +++ b/configs/nucleo-l476rg/src/nucleo-l476rg.h @@ -50,6 +50,7 @@ /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ + /* Configuration ********************************************************************/ #define HAVE_PROC 1 @@ -119,7 +120,6 @@ * D7=PA_8 I2C1_SCL=D15=PB_8 WIFI Probe * * mostly from: https://mbed.org/platforms/ST-Nucleo-F401RE/ - * */ /* SPI1 off */ @@ -243,6 +243,26 @@ #define GPIO_FIRE GPIO_BUTTON_2 #define GPIO_JUMP GPIO_BUTTON_3 +/* GPIO pins used by the GPIO Subsystem + * Added by: Ben vd Veen (DisruptiveNL) -- www.nuttx.nl + */ + +#define BOARD_NGPIOIN 1 /* Amount of GPIO Input pins */ +#define BOARD_NGPIOOUT 1 /* Amount of GPIO Output pins */ +#define BOARD_NGPIOINT 1 /* Amount of GPIO Input w/ Interruption pins */ + +/* This was really something to find out! But the GPIOA Port was causing + * conflicts with the nsh console. So thats why I have chosen GPIOB + * + * Author: Ben vd Veen (DisruptiveNL) -- www.nuttx.nl + * https://www.youtube.com/watch?v=VXsTLzI6idA -- Original video GPIO + */ + +#define GPIO_IN1 (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTB | GPIO_PIN0) +#define GPIO_OUT1 (GPIO_OUTPUT | GPIO_OUTPUT | GPIO_SPEED_50MHz | \ + GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN1) +#define GPIO_INT1 (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTB | GPIO_PIN2) + /************************************************************************************ * Public Data ************************************************************************************/ @@ -283,6 +303,32 @@ void stm32l4_spiinitialize(void); void stm32l4_usbinitialize(void); +/**************************************************************************** + * Name: stm32_gpio_initialize + * + * Description: + * Initialize GPIO drivers for use with /apps/examples/gpio + * Added by: Ben vd Veen (DisruptiveNL) -- www.nuttx.nl + * + ****************************************************************************/ + +#ifdef CONFIG_DEV_GPIO +int stm32l4_gpio_initialize(void); +#endif + +/************************************************************************************ + * Name: stm32l4_can_setup -- DisruptiveNL + * + * Description: + * Initialize CAN and register the CAN device. + * Added by: Ben vd Veen (DisruptiveNL) -- www.nuttx.nl + * + ************************************************************************************/ + +#ifdef CONFIG_CAN +int stm32l4_can_setup(void); +#endif + /************************************************************************************ * Name: stm32l4_pwm_setup * diff --git a/configs/nucleo-l476rg/src/stm32_appinit.c b/configs/nucleo-l476rg/src/stm32_appinit.c index b9a8b2d9ec..abba0e482a 100644 --- a/configs/nucleo-l476rg/src/stm32_appinit.c +++ b/configs/nucleo-l476rg/src/stm32_appinit.c @@ -1,7 +1,7 @@ /**************************************************************************** * configs/nucleo-l476rg/src/stm32l4_appinit.c * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -196,6 +196,19 @@ int board_app_initialize(uintptr_t arg) } #endif +/* Initialize CAN and register the CAN driver. + * Added by: Ben vd Veen (DisruptiveNL) -- www.nuttx.nl + */ + +#ifdef CONFIG_CAN + ret = stm32l4_can_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32l4_can_setup failed: %d\n", ret); + return ret; + } +#endif + #ifdef CONFIG_AJOYSTICK /* Initialize and register the joystick driver */ @@ -300,6 +313,19 @@ int board_app_initialize(uintptr_t arg) #endif #endif /* CONFIG_SENSORS_QENCODER */ +/* Initialize CAN and register the CAN driver. + * Added by: Ben vd Veen (DisruptiveNL) -- www.nuttx.nl + */ + +#ifdef CONFIG_DEV_GPIO + ret = stm32l4_gpio_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret); + return ret; + } +#endif + #ifdef CONFIG_WL_CC1101 /* Initialize and register the cc1101 radio */ diff --git a/configs/nucleo-l476rg/src/stm32_can.c b/configs/nucleo-l476rg/src/stm32_can.c new file mode 100644 index 0000000000..c1a1948b31 --- /dev/null +++ b/configs/nucleo-l476rg/src/stm32_can.c @@ -0,0 +1,109 @@ +/************************************************************************************ + * configs/stm3220g-eval/src/stm32_can.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* Added by: Ben vd Veen (DisruptiveNL) -- www.nuttx.nl */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "stm32l4_can.h" +#include "nucleo-l476rg.h" + +#ifdef CONFIG_CAN + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_STM32L4_CAN1) +# warning "Both CAN1 and CAN2 are enabled. Only CAN1 is connected." +#endif + +#ifdef CONFIG_STM32L4_CAN1 +# define CAN_PORT 1 +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_can_setup + * + * Description: + * Initialize CAN and register the CAN device + * + ****************************************************************************/ + +int stm32l4_can_setup(void) +{ +#ifdef CONFIG_STM32L4_CAN1 + struct can_dev_s *can; + int ret; + + /* Call stm32_caninitialize() to get an instance of the CAN interface */ + + can = stm32l4can_initialize(CAN_PORT); + if (can == NULL) + { + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; + } + + /* Register the CAN driver at "/dev/can0" */ + + ret = can_register("/dev/can0", can); + if (ret < 0) + { + canerr("ERROR: can_register failed: %d\n", ret); + return ret; + } + + return OK; +#else + return -ENODEV; +#endif +} + +#endif /* CONFIG_CAN */ \ No newline at end of file diff --git a/configs/nucleo-l476rg/src/stm32_gpio.c b/configs/nucleo-l476rg/src/stm32_gpio.c new file mode 100644 index 0000000000..c8ff89fe22 --- /dev/null +++ b/configs/nucleo-l476rg/src/stm32_gpio.c @@ -0,0 +1,336 @@ +/**************************************************************************** + * configs/nucleo-l476rg/src/stm32_gpio.c + * + * Copyright (C) 2017-2018 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * Based on: configs/sim/src/sim_gpio.c + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Added by: Ben vd Veen (DisruptiveNL) -- www.nuttx.nl */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" + +#include +#include "nucleo-l476rg.h" + +#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32gpio_dev_s +{ + struct gpio_dev_s gpio; + uint8_t id; +}; + +struct stm32gpint_dev_s +{ + struct stm32gpio_dev_s stm32gpio; + pin_interrupt_t callback; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int gpin_read(FAR struct gpio_dev_s *dev, FAR bool *value); +static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value); +static int gpout_write(FAR struct gpio_dev_s *dev, bool value); +static int gpint_read(FAR struct gpio_dev_s *dev, FAR bool *value); +static int gpint_attach(FAR struct gpio_dev_s *dev, + pin_interrupt_t callback); +static int gpint_enable(FAR struct gpio_dev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct gpio_operations_s gpin_ops = +{ + .go_read = gpin_read, + .go_write = NULL, + .go_attach = NULL, + .go_enable = NULL, +}; + +static const struct gpio_operations_s gpout_ops = +{ + .go_read = gpout_read, + .go_write = gpout_write, + .go_attach = NULL, + .go_enable = NULL, +}; + +static const struct gpio_operations_s gpint_ops = +{ + .go_read = gpint_read, + .go_write = NULL, + .go_attach = gpint_attach, + .go_enable = gpint_enable, +}; + +#if BOARD_NGPIOIN > 0 +/* This array maps the GPIO pins used as INPUT */ + +static const uint32_t g_gpioinputs[BOARD_NGPIOIN] = +{ + GPIO_IN1, +}; + +static struct stm32gpio_dev_s g_gpin[BOARD_NGPIOIN]; +#endif + +#if BOARD_NGPIOOUT +/* This array maps the GPIO pins used as OUTPUT */ + +static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] = +{ + GPIO_OUT1, +}; + +static struct stm32gpio_dev_s g_gpout[BOARD_NGPIOOUT]; +#endif + +#if BOARD_NGPIOINT > 0 +/* This array maps the GPIO pins used as INTERRUPT INPUTS */ + +static const uint32_t g_gpiointinputs[BOARD_NGPIOINT] = +{ + GPIO_INT1, +}; + +static struct stm32gpint_dev_s g_gpint[BOARD_NGPIOINT]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int stm32gpio_interrupt(int irq, void *context, void *arg) +{ + FAR struct stm32gpint_dev_s *stm32gpint = (FAR struct stm32gpint_dev_s *)arg; + + DEBUGASSERT(stm32gpint != NULL && stm32gpint->callback != NULL); + gpioinfo("Interrupt! callback=%p\n", stm32gpint->callback); + + stm32gpint->callback(&stm32gpint->stm32gpio.gpio); + return OK; +} + +static int gpin_read(FAR struct gpio_dev_s *dev, FAR bool *value) +{ + FAR struct stm32gpio_dev_s *stm32gpio = (FAR struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL && value != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOIN); + gpioinfo("Reading...\n"); + + *value = stm32l4_gpioread(g_gpioinputs[stm32gpio->id]); + return OK; +} + +static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value) +{ + FAR struct stm32gpio_dev_s *stm32gpio = (FAR struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL && value != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOOUT); + gpioinfo("Reading...\n"); + + *value = stm32l4_gpioread(g_gpiooutputs[stm32gpio->id]); + return OK; +} + +static int gpout_write(FAR struct gpio_dev_s *dev, bool value) +{ + FAR struct stm32gpio_dev_s *stm32gpio = (FAR struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOOUT); + gpioinfo("Writing %d\n", (int)value); + + stm32l4_gpiowrite(g_gpiooutputs[stm32gpio->id], value); + return OK; +} + +static int gpint_read(FAR struct gpio_dev_s *dev, FAR bool *value) +{ + FAR struct stm32gpint_dev_s *stm32gpint = (FAR struct stm32gpint_dev_s *)dev; + + DEBUGASSERT(stm32gpint != NULL && value != NULL); + DEBUGASSERT(stm32gpint->stm32gpio && stm32gpint->stm32gpio.id < BOARD_NGPIOINT); + gpioinfo("Reading int pin...\n"); + + *value = stm32l4_gpioread(g_gpiointinputs[stm32gpint->stm32gpio.id]); + return OK; +} + +static int gpint_attach(FAR struct gpio_dev_s *dev, + pin_interrupt_t callback) +{ + FAR struct stm32gpint_dev_s *stm32gpint = (FAR struct stm32gpint_dev_s *)dev; + + gpioinfo("Attaching the callback\n"); + + /* Make sure the interrupt is disabled */ + + (void)stm32l4_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], false, + false, false, NULL, NULL); + + gpioinfo("Attach %p\n", callback); + stm32gpint->callback = callback; + return OK; +} + +static int gpint_enable(FAR struct gpio_dev_s *dev, bool enable) +{ + FAR struct stm32gpint_dev_s *stm32gpint = (FAR struct stm32gpint_dev_s *)dev; + + if (enable) + { + if (stm32gpint->callback != NULL) + { + gpioinfo("Enabling the interrupt\n"); + + /* Configure the interrupt for rising edge */ + + (void)stm32l4_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], + true, false, false, stm32gpio_interrupt, + &g_gpint[stm32gpint->stm32gpio.id]); + } + } + else + { + gpioinfo("Disable the interrupt\n"); + + (void)stm32l4_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], + false, false, false, NULL, NULL); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_gpio_initialize + * + * Description: + * Initialize GPIO drivers for use with /apps/examples/gpio + * + ****************************************************************************/ + +int stm32l4_gpio_initialize(void) +{ + int pincount = 0; + int i; + +#if BOARD_NGPIOIN > 0 + for (i = 0; i < BOARD_NGPIOIN; i++) + { + /* Setup and register the GPIO pin */ + + g_gpin[i].gpio.gp_pintype = GPIO_INPUT_PIN; + g_gpin[i].gpio.gp_ops = &gpin_ops; + g_gpin[i].id = i; + (void)gpio_pin_register(&g_gpin[i].gpio, pincount); + + /* Configure the pin that will be used as input */ + + stm32l4_configgpio(g_gpioinputs[i]); + + pincount++; + } +#endif + +#if BOARD_NGPIOOUT > 0 + for (i = 0; i < BOARD_NGPIOOUT; i++) + { + /* Setup and register the GPIO pin */ + + g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN; + g_gpout[i].gpio.gp_ops = &gpout_ops; + g_gpout[i].id = i; + (void)gpio_pin_register(&g_gpout[i].gpio, pincount); + + /* Configure the pin that will be used as output */ + + stm32l4_gpiowrite(g_gpiooutputs[i], 0); + stm32l4_configgpio(g_gpiooutputs[i]); + + pincount++; + } +#endif + +#if BOARD_NGPIOINT > 0 + for (i = 0; i < BOARD_NGPIOINT; i++) + { + /* Setup and register the GPIO pin */ + + g_gpint[i].stm32gpio.gpio.gp_pintype = GPIO_INTERRUPT_PIN; + g_gpint[i].stm32gpio.gpio.gp_ops = &gpint_ops; + g_gpint[i].stm32gpio.id = i; + (void)gpio_pin_register(&g_gpint[i].stm32gpio.gpio, pincount); + + /* Configure the pin that will be used as interrupt input */ + + stm32l4_configgpio(g_gpiointinputs[i]); + + pincount++; + } +#endif + + return 0; +} +#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */