From ade57e4cd8b1c061d9e3c7996dbd083e76b0b13d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 6 May 2014 11:07:10 -0600 Subject: [PATCH] Nucleo-F401RE: With these changes and the changes from previous commits, the basic Nucleo-F401RE NSH configuration is working. --- arch/arm/src/stm32/stm32_serial.c | 44 ++++---- arch/arm/src/stm32/stm32_uart.h | 4 + configs/nucleo-f401re/README.txt | 138 ++++++++++++++++---------- configs/nucleo-f401re/include/board.h | 26 ++--- 4 files changed, 120 insertions(+), 92 deletions(-) diff --git a/arch/arm/src/stm32/stm32_serial.c b/arch/arm/src/stm32/stm32_serial.c index c392896ceae..ef624b8703d 100644 --- a/arch/arm/src/stm32/stm32_serial.c +++ b/arch/arm/src/stm32/stm32_serial.c @@ -992,7 +992,11 @@ static struct up_dev_s g_uart8priv = }; #endif -/* This table lets us iterate over the configured USARTs */ +/* This table lets us iterate over the configured USARTs. + * + * REVISIT: The following logic is not valid for the STM32F401 which + * supports 3 USARTS: USART1, USART2, and USART6. + */ static struct up_dev_s *uart_devs[STM32_NUSART] = { @@ -1153,7 +1157,7 @@ static int up_dma_nextrx(struct up_dev_s *priv) #ifndef CONFIG_SUPPRESS_UART_CONFIG static void up_set_format(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; uint32_t regval; #ifdef CONFIG_STM32_STM32F30XX @@ -1315,7 +1319,7 @@ static void up_set_format(struct uart_dev_s *dev) static int up_setup(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; #ifndef CONFIG_SUPPRESS_UART_CONFIG uint32_t regval; @@ -1418,7 +1422,7 @@ static int up_setup(struct uart_dev_s *dev) #ifdef SERIAL_HAVE_DMA static int up_dma_setup(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; int result; uint32_t regval; @@ -1479,7 +1483,7 @@ static int up_dma_setup(struct uart_dev_s *dev) static void up_shutdown(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; uint32_t regval; /* Disable all interrupts */ @@ -1505,7 +1509,7 @@ static void up_shutdown(struct uart_dev_s *dev) #ifdef SERIAL_HAVE_DMA static void up_dma_shutdown(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; /* Perform the normal UART shutdown */ @@ -1539,7 +1543,7 @@ static void up_dma_shutdown(struct uart_dev_s *dev) static int up_attach(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; int ret; /* Attach and enable the IRQ */ @@ -1568,7 +1572,7 @@ static int up_attach(struct uart_dev_s *dev) static void up_detach(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; up_disable_irq(priv->irq); irq_detach(priv->irq); } @@ -1713,7 +1717,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) struct uart_dev_s *dev = inode->i_private; #endif #ifdef CONFIG_SERIAL_TERMIOS - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; #endif int ret = OK; @@ -1722,7 +1726,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) #ifdef CONFIG_SERIAL_TIOCSERGSTRUCT case TIOCSERGSTRUCT: { - struct up_dev_s *user = (struct up_dev_s*)arg; + struct up_dev_s *user = (struct up_dev_s *)arg; if (!user) { ret = -EINVAL; @@ -1910,7 +1914,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) #ifndef SERIAL_HAVE_ONLY_DMA static int up_receive(struct uart_dev_s *dev, uint32_t *status) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; uint32_t rdr; /* Get the Rx byte */ @@ -1939,7 +1943,7 @@ static int up_receive(struct uart_dev_s *dev, uint32_t *status) #ifndef SERIAL_HAVE_ONLY_DMA static void up_rxint(struct uart_dev_s *dev, bool enable) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; irqstate_t flags; uint16_t ie; @@ -1997,7 +2001,7 @@ static void up_rxint(struct uart_dev_s *dev, bool enable) #ifndef SERIAL_HAVE_ONLY_DMA static bool up_rxavailable(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; return ((up_serialin(priv, STM32_USART_SR_OFFSET) & USART_SR_RXNE) != 0); } #endif @@ -2015,7 +2019,7 @@ static bool up_rxavailable(struct uart_dev_s *dev) #ifdef SERIAL_HAVE_DMA static int up_dma_receive(struct uart_dev_s *dev, uint32_t *status) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; int c = 0; if (up_dma_nextrx(priv) != priv->rxdmanext) @@ -2044,7 +2048,7 @@ static int up_dma_receive(struct uart_dev_s *dev, uint32_t *status) #ifdef SERIAL_HAVE_DMA static void up_dma_rxint(struct uart_dev_s *dev, bool enable) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; /* En/disable DMA reception. * @@ -2069,7 +2073,7 @@ static void up_dma_rxint(struct uart_dev_s *dev, bool enable) #ifdef SERIAL_HAVE_DMA static bool up_dma_rxavailable(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; /* Compare our receive pointer to the current DMA pointer, if they * do not match, then there are bytes to be received. @@ -2089,7 +2093,7 @@ static bool up_dma_rxavailable(struct uart_dev_s *dev) static void up_send(struct uart_dev_s *dev, int ch) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; #ifdef HAVE_RS485 if (priv->rs485_dir_gpio != 0) stm32_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); @@ -2107,7 +2111,7 @@ static void up_send(struct uart_dev_s *dev, int ch) static void up_txint(struct uart_dev_s *dev, bool enable) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; irqstate_t flags; /* USART transmit interrupts: @@ -2167,7 +2171,7 @@ static void up_txint(struct uart_dev_s *dev, bool enable) static bool up_txready(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; return ((up_serialin(priv, STM32_USART_SR_OFFSET) & USART_SR_TXE) != 0); } @@ -2247,7 +2251,7 @@ static int up_interrupt_uart8(int irq, void *context) #ifdef SERIAL_HAVE_DMA static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg) { - struct up_dev_s *priv = (struct up_dev_s*)arg; + struct up_dev_s *priv = (struct up_dev_s *)arg; if (priv->rxenable && up_dma_rxavailable(&priv->dev)) { diff --git a/arch/arm/src/stm32/stm32_uart.h b/arch/arm/src/stm32/stm32_uart.h index e776196dffc..07422cd3dfc 100644 --- a/arch/arm/src/stm32/stm32_uart.h +++ b/arch/arm/src/stm32/stm32_uart.h @@ -63,6 +63,10 @@ ************************************************************************************/ /* Make sure that we have not enabled more U[S]ARTs than are support by * the device. + * + * REVISIT: These should be replaced with the CONFIG_STM32_HAVE_USARTn now generated + * by the Kconfig file. The following logic is not valid for the STM32F401 which + * supports 3 USARTS: USART1, USART2, and USART6. */ #if STM32_NUSART < 8 diff --git a/configs/nucleo-f401re/README.txt b/configs/nucleo-f401re/README.txt index 88a6d6bb1ad..4177733d157 100644 --- a/configs/nucleo-f401re/README.txt +++ b/configs/nucleo-f401re/README.txt @@ -342,6 +342,18 @@ Serial Consoles TXD: PA10 CN9 pin 3, CN10 pin 33 PB6 CN5 pin 3, CN10 pin 17 + NOTE: You may need to edit the include/board.h to select different USART1 + pin selections. + + TTL to RS-232 converter connection: + + Nucleo CN10 STM32F401RE + ----------- ------------ + Pin 21 PA9 USART2_RX + Pin 33 PA10 USART2_TX + Pin 20 GND + Pin 8 U5V + To configure USART1 as the console: CONFIG_STM32_USART1=y @@ -363,9 +375,9 @@ Serial Consoles TXD: PA2 CN9 pin 2(See SB13, 14, 62, 63). CN10 pin 35 PD5 - If you have a 3.3 V TTL to RS-232 converter then this is the most convenient - serial console to use. UART2 is the default in all of these - configurations. + UART2 is the default in all of these configurations. + + TTL to RS-232 converter connection: Nucleo CN9 STM32F401RE ----------- ------------ @@ -462,78 +474,94 @@ Shields Configurations ============== - Composite: The composite is a super set of all the functions in nsh, - usbserial, usbmsc. (usbnsh has not been rung out). + nsh: + --- + Configures the NuttShell (nsh) located at apps/examples/nsh. The + Configuration enables the serial interfaces on UART2. Support for + builtin applications is enabled, but in the base configuration no + builtin applications are selected (see NOTES below). - Build it with + NOTES: - make distclean;(cd tools;./configure.sh nucleo-f401re/nsh) + 1. This configuration uses the mconf-based configuration tool. To + change this configuration using that tool, you should: - then run make menuconfig if you wish to customize things. + a. Build and install the kconfig-mconf tool. See nuttx/README.txt + and misc/tools/ - or + b. Execute 'make menuconfig' in nuttx/ in order to start the + reconfiguration process. - $ make qconfig + 2. By default, this configuration uses the CodeSourcery toolchain + for Linux. That can easily be reconfigured, of course. - N.B. Memory is tight, both Flash and RAM are taxed. If you enable - debugging you will need to add -Os following the line -g in the line: + CONFIG_HOST_LINUX=y : Builds under Linux + CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL=y : CodeSourcery for Linux - ifeq ($(CONFIG_DEBUG_SYMBOLS),y) - ARCHOPTIMIZATION = -g + 3. Although the default console is USART2 (which would correspond to + the Virtual COM port) I have done all testing with the console + device configured for USART1 (see instruction above under "Serial + Consoles). I have been using a TTL-to-RS-232 converted connected + as shown below: - in the top level Make.degs or the code will not fit. + Nucleo CN10 STM32F401RE + ----------- ------------ + Pin 21 PA9 USART2_RX + Pin 33 PA10 USART2_TX + Pin 20 GND + Pin 8 U5V - Stack space has been hand optimized using the stack coloring by enabling - "Stack usage debug hooks" (CONFIG_DEBUG_STACK) in Build Setup-> Debug - Options. I have selected values that have 8-16 bytes of headroom with - network debugging on. If you enable more debugging and get a hard fault - or any weirdness like commands hanging. Then the Idle, main or Interrupt - stack my be too small. Stop the target and have a look a memory for a - blown stack: No DEADBEEF at the lowest address of a given stack. + cc3000: + ------ + This configuration adds support for the CC3000 Shield. - Given the RAM memory constraints it is not possible to be running the - network and USB CDC/ACM and MSC at the same time. But on the bright - side, you can export the FLASH memory to the PC. Write files on the - Flash. Reboot and mount the FAT FS and run network code that will have - access the files. + Build it with - You can use the scripts/cdc-acm.inf file to install the windows - composite device. + make distclean;(cd tools;./configure.sh nucleo-f401re/nsh) - Network control is facilitated by running the c3b (cc3000basic) application. + then run make menuconfig if you wish to customize things. - Run c3b from the nsh prompt. + or - +-------------------------------------------+ - | Nuttx CC3000 Demo Program | - +-------------------------------------------+ + $ make qconfig - 01 - Initialize the CC3000 - 02 - Show RX & TX buffer sizes, & free RAM - 03 - Start Smart Config - 04 - Manually connect to AP - 05 - Manually add connection profile - 06 - List access points - 07 - Show CC3000 information - 08 - Telnet + You can use the scripts/cdc-acm.inf file to install the windows + composite device. - Type 01-07 to select above option: + Network control is facilitated by running the c3b (cc3000basic) application. - Select 01. Then use 03 and the TI Smart config application running on an - IOS or Android device to configure join your network. + Run c3b from the nsh prompt. - Use 07 to see the IP address of the device. + +-------------------------------------------+ + | Nuttx CC3000 Demo Program | + +-------------------------------------------+ - (On the next reboot running c3b 01 the CC3000 will automaticaly rejoin the - network after the 01 give it a few seconds and enter 07 or 08) + 01 - Initialize the CC3000 + 02 - Show RX & TX buffer sizes, & free RAM + 03 - Start Smart Config + 04 - Manually connect to AP + 05 - Manually add connection profile + 06 - List access points + 07 - Show CC3000 information + 08 - Telnet - Use 08 to start Telnet. Then you can connect to the device using the - address listed in command 07. + Type 01-07 to select above option: - qq will exit the c3b with the telnet deamon running (if started) + Select 01. Then use 03 and the TI Smart config application running on an + IOS or Android device to configure join your network. - Slow.... You will be thinking 300 bps. This is because of packet sizes and - how the select thread runs in the telnet session. Telnet is not the best - showcase for the CC3000, but simply a proof of network connectivity. + Use 07 to see the IP address of the device. - http POST and GET should be more efficient. + (On the next reboot running c3b 01 the CC3000 will automaticaly rejoin the + network after the 01 give it a few seconds and enter 07 or 08) + + Use 08 to start Telnet. Then you can connect to the device using the + address listed in command 07. + + qq will exit the c3b with the telnet deamon running (if started) + + Slow.... You will be thinking 300 bps. This is because of packet sizes and + how the select thread runs in the telnet session. Telnet is not the best + showcase for the CC3000, but simply a proof of network connectivity. + + http POST and GET should be more efficient. diff --git a/configs/nucleo-f401re/include/board.h b/configs/nucleo-f401re/include/board.h index 3c9b57410b5..d582d34704c 100644 --- a/configs/nucleo-f401re/include/board.h +++ b/configs/nucleo-f401re/include/board.h @@ -228,14 +228,19 @@ /* Alternate function pin selections ************************************************/ /* USART1: - * RXD: PA11 CN10 pin 14 + * RXD: PA10 CN9 pin 3, CN10 pin 33 * PB7 CN7 pin 21 - * TXD: PA10 CN9 pin 3, CN10 pin 33 + * TXD: PA9 CN5 pin 1, CN10 pin 21 * PB6 CN5 pin 3, CN10 pin 17 */ -#define GPIO_USART1_RX GPIO_USART1_RX_1 /* PA10 */ -#define GPIO_USART1_TX GPIO_USART1_TX_2 /* PA9 */ +#if 1 +# define GPIO_USART1_RX GPIO_USART1_RX_1 /* PA10 */ +# define GPIO_USART1_TX GPIO_USART1_TX_1 /* PA9 */ +#else +# define GPIO_USART1_RX GPIO_USART1_RX_2 /* PB7 */ +# define GPIO_USART1_TX GPIO_USART1_TX_2 /* PB6 */ +#endif /* USART2: * RXD: PA3 CN9 pin 1 (See SB13, 14, 62, 63). CN10 pin 37 @@ -259,24 +264,11 @@ #define GPIO_USART6_RX GPIO_USART6_RX_1 /* PC7 */ #define GPIO_USART6_TX GPIO_USART6_TX_1 /* PC6 */ -/* UART8 has no alternate pin config */ - /* UART RX DMA configurations */ #define DMAMAP_USART1_RX DMAMAP_USART1_RX_2 #define DMAMAP_USART6_RX DMAMAP_USART6_RX_2 -/* CAN - * - * CAN1 is routed to the onboard transceiver. - * CAN2 is routed to the expansion connector. - */ - -#define GPIO_CAN1_RX GPIO_CAN1_RX_3 -#define GPIO_CAN1_TX GPIO_CAN1_TX_3 -#define GPIO_CAN2_RX GPIO_CAN2_RX_1 -#define GPIO_CAN2_TX GPIO_CAN2_TX_2 - /* I2C * * The optional _GPIO configurations allow the I2C driver to manually