$ git clone https://github.com/spiriou/incubator-nuttx-apps apps $ git clone https://github.com/apache/incubator-nuttx $ cd apps $ git checkout -b iotjs origin/iotjs Branch 'iotjs' set up to track remote branch 'iotjs' from 'origin'. Switched to a new branch 'iotjs' $ cd ../incubator-nuttx Config: CONFIG_ARCH_FPU is not set CONFIG_NSH_ARGCAT is not set CONFIG_NSH_CMDOPT_HEXDUMP is not set CONFIG_NSH_CMDPARMS is not set CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="stm32f4discovery" CONFIG_ARCH_BOARD_STM32F4_DISCOVERY=y CONFIG_ARCH_BUTTONS=y CONFIG_ARCH_CHIP="stm32" CONFIG_ARCH_CHIP_STM32=y CONFIG_ARCH_CHIP_STM32F407VG=y CONFIG_ARCH_SETJMP_H=y CONFIG_ARCH_STACKDUMP=y CONFIG_BOARD_LATE_INITIALIZE=y CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BUILTIN=y CONFIG_EXAMPLES_HELLO=y CONFIG_FS_FAT=y CONFIG_FS_PROCFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INTELHEX_BINARY=y CONFIG_IOTJS=y CONFIG_LIBUV=y CONFIG_LIBUV_FS=y CONFIG_LIBUV_TCP=y CONFIG_LIBUV_TIMER=y CONFIG_LIBUV_WQ=y CONFIG_MAX_TASKS=16 CONFIG_MM_REGIONS=2 CONFIG_NET=y CONFIG_NETDEV_LATEINIT=y CONFIG_NET_SOCKOPTS=y CONFIG_NET_TCP=y CONFIG_NET_TCPBACKLOG=y CONFIG_NET_TCP_KEEPALIVE=y CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_LINELEN=64 CONFIG_NSH_READLINE=y CONFIG_PREALLOC_TIMERS=4 CONFIG_RAM_SIZE=114688 CONFIG_RAM_START=0x20000000 CONFIG_RAW_BINARY=y CONFIG_RR_INTERVAL=200 CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y CONFIG_START_DAY=6 CONFIG_START_MONTH=12 CONFIG_START_YEAR=2011 CONFIG_STM32_JTAG_SW_ENABLE=y CONFIG_STM32_PWR=y CONFIG_STM32_SPI1=y CONFIG_STM32_USART2=y CONFIG_SYSTEM_NSH=y CONFIG_USART2_RXBUFSIZE=128 CONFIG_USART2_SERIAL_CONSOLE=y CONFIG_USART2_TXBUFSIZE=128 CONFIG_USER_ENTRYPOINT="nsh_main" $ make $ sudo openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000" Create the RAMDISK: nsh> mkrd 64 nsh> mkfatfs /dev/ram0 nsh> mount -t vfat /dev/ram0 /mnt Create the sample file: nsh> echo "var fs = require('fs');" > /mnt/index.js nsh> echo "console.log('Hello World');" >> /mnt/index.js Confirm it is correct: nsh> cat /mnt/index.js var fs = require('fs'); console.log('Hello World'); Is iotjs here? nsh> ? help usage: help [-v] [] . cd exec ifdown mkrd pwd time [ cp exit ifup mh rm true ? cmp false kill mount rmdir uname arp dirname free ls mv set umount basename dd help mb mw sleep unset break df hexdump mkdir nslookup source usleep cat echo ifconfig mkfatfs ps test xd Builtin Apps: iotjs sh hello nsh All right, run it: nsh> iotjs /mnt/index.js Hello World nsh>
Month: August 2020
How to use RAMDISK as filesystem on NuttX
NuttX is evolving all the time and although I created a video tutorial at NuttX Channel explaining how to create a RAMDISK, that information is already outdated.
Let’s do it again using the current NuttX version (9.1)
First select the needed options at menuconfig:
Device Drivers ---> [*] RAM disk wrapper (mkrd) Board Selection ---> [*] Enable boardctl() interface [*] Enable application space creation of RAM disks File Systems ---> [*] FAT file system
Compile it and run these commands when NuttX’s nsh show up on serial console:
NuttShell (NSH) NuttX-9.1.0 nsh> ? help usage: help [-v] [] . cd echo hexdump mkrd pwd test usleep [ cp exec kill mh rm time xd ? cmp exit ls mount rmdir true basename dirname false mb mv set uname break dd free mkdir mw sleep umount cat df help mkfatfs ps source unset Builtin Apps: sh nsh nsh> mkrd 64 nsh> ls /dev /dev: console null ram0 <--- ttyS0 nsh> mkfatfs /dev/ram0 nsh> mount -t vfat /dev/ram0 /mnt nsh> echo "This is a file in RAMDISK" > /mnt/file.txt nsh> cat /mnt/file.txt This is a file in RAMDISK nsh>
Dieharder: A Random Number Test Suite
This is the test suite used to verify the randomness of (True) RNG algorithms or hardware.
How to save GMail emails in bulk
I was looking for a way to save all the emails returned after searching for some word.
There is not an direct way to do it, so this is a workaround:
- After the search returned the list of emails, just select them (mark the checkbox)
- Click in the (…) and select the option: Forward as attachment
- Go to Sent folder, click on email that you just sent and click on (…) and Download email
Thanks user Dave Thompson 8260 for this tip: https://support.google.com/mail/thread/9010168?hl=en
Getting the SDCard of iMXRT1050-EVK working on NuttX
I decided to test the SDCard support on iMXRT1050-EVK board, but go these errors:
CC: chip/imxrt_lowputc.c chip/imxrt_lowputc.c: In function 'imxrt_lpuart_configure': chip/imxrt_lowputc.c:559:2: warning: #warning missing logic [-Wcpp] 559 | #warning missing logic | ^ CC: chip/imxrt_idle.c CC: chip/imxrt_timerisr.c chip/imxrt_timerisr.c:63:2: warning: #warning REVISIT these clock settings [-Wcpp] 63 | #warning REVISIT these clock settings | ^ CC: chip/imxrt_usdhc.c chip/imxrt_usdhc.c:100:4: error: #error "CONFIG_SDIO_BLOCKSETUP is mandatory for this driver" 100 | # error "CONFIG_SDIO_BLOCKSETUP is mandatory for this driver" | ^ In file included from chip/imxrt_usdhc.c:60: chip/imxrt_usdhc.c: In function 'imxrt_usdhc_initialize': chip/imxrt_usdhc.c:3144:25: error: 'GPIO_USDHC1_DATA0' undeclared (first use in this function); did you mean 'GPIO_USDHC1_DATA0_1'? 3144 | imxrt_config_gpio(PIN_USDHC1_D0); | ^ chip/imxrt_usdhc.c:3144:25: note: each undeclared identifier is reported only once for each function it appears in chip/imxrt_usdhc.c:3145:25: error: 'GPIO_USDHC1_CLK' undeclared (first use in this function); did you mean 'GPIO_USDHC1_CLK_1'? 3145 | imxrt_config_gpio(PIN_USDHC1_DCLK); | ^ chip/imxrt_usdhc.c:3146:25: error: 'GPIO_USDHC1_CMD' undeclared (first use in this function); did you mean 'GPIO_USDHC1_CMD_1'? 3146 | imxrt_config_gpio(PIN_USDHC1_CMD); | ^ make[1]: *** [Makefile:151: imxrt_usdhc.o] Error 1
The first error as easy to fix: just run “make menuconfig” press the key “/” and search for “CONFIG_SDIO_BLOCKSETUP” you will find the:
Prompt: SDIO block setup
Just press 1 do go directly to it and then enable it:
[*] SDIO block setup
After trying to compile again you will see that the pins definition still missing: PIN_USDHC1_D0, PIN_USDHC1_DCLK, PIN_USDHC1_CMD. Just like we did for SPI in the previous post, you need to start looking the schematics.
First let see the SDCard slot:
So, let search for these pins: SD1_CLK, SD1_CMD, SD1_D0, SD1_D1, SD1_SD2, SD1_D3 and SD_CD_SW:
So, we have:
SD1_CMD = GPIO_SD_B0_00
SD1_CLK = GPIO_SD_B0_01
SD1_D0 = GPIO_SD_B0_02
SD1_D1 = GPIO_SD_B0_03
SD1_D2 = GPIO_SD_B0_04
SD1_D3 = GPIO_SD_B0_05
SD_CD_SW = GPIO_B1_12
And like we did for the SPI, let’s to look at arch/arm/src/imxrt/hardware/rt105x/imxrt105x_pinmux.h for these GPIO_SD_* pins definition:
#define GPIO_USDHC1_CMD_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_00_INDEX))
#define GPIO_USDHC1_CLK_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_01_INDEX))
#define GPIO_USDHC1_DATA0_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_02_INDEX))
#define GPIO_USDHC1_DATA1_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_03_INDEX))
#define GPIO_USDHC1_DATA2_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_04_INDEX))
#define GPIO_USDHC1_DATA3_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_05_INDEX))
#define GPIO_GPIO2_IO28_1 (GPIO_PERIPH | GPIO_ALT5 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_B1_12_INDEX))
So, we need to include the missing SD1 pins pointing to these defines names at boards/arm/imxrt/imxrt1050-evk/include/board.h this way:
/* MMC/SD SD1 */ #define PIN_USDHC1_DCLK GPIO_USDHC1_CLK_1 #define PIN_USDHC1_CMD GPIO_USDHC1_CMD_1 #define PIN_USDHC1_D0 GPIO_USDHC1_DATA0_1
Ok, after defining these pins the compilation finished correctly. But the fact of the USDHC driver is only failing because DATA0 rings a bell! Probably it is using SD Card with 1-bit interface, we need to enable 4-bits interface:
$ make menuconfig
System Type ->
USDHC Configuration ->
Bus width for USDHC1 (Four bit)
Perfect, now the compilation is failing, this is exactly what I was waiting for:
CC: chip/imxrt_usdhc.c
In file included from chip/imxrt_usdhc.c:60:
chip/imxrt_usdhc.c: In function 'imxrt_usdhc_initialize':
chip/imxrt_usdhc.c:3138:25: error: 'GPIO_USDHC1_DATA1' undeclared (first use in this function); did you mean 'GPIO_USDHC1_DATA2_1'?
3138 | imxrt_config_gpio(PIN_USDHC1_D1);
| ^
chip/imxrt_usdhc.c:3138:25: note: each undeclared identifier is reported only once for each function it appears in
chip/imxrt_usdhc.c:3139:25: error: 'GPIO_USDHC1_DATA2' undeclared (first use in this function); did you mean 'GPIO_USDHC1_DATA2_1'?
3139 | imxrt_config_gpio(PIN_USDHC1_D2);
| ^
chip/imxrt_usdhc.c:3140:25: error: 'GPIO_USDHC1_DATA3' undeclared (first use in this function); did you mean 'GPIO_USDHC1_DATA3_1'?
3140 | imxrt_config_gpio(PIN_USDHC1_D3);
| ^
make[1]: *** [Makefile:151: imxrt_usdhc.o] Error 1
make[1]: Leaving directory '/comum/workspace/Consultancy/iDTech/NuttX/nuttx/arch/arm/src'
make: *** [tools/LibTargets.mk:155: arch/arm/src/libarch.a] Error 2
You already know what to do, right? Just insert all the pins to board.h :
/* MMC/SD */
#define PIN_USDHC1_DCLK GPIO_USDHC1_CLK_1
#define PIN_USDHC1_CMD GPIO_USDHC1_CMD_1
#define PIN_USDHC1_D0 GPIO_USDHC1_DATA0_1
#define PIN_USDHC1_D1 GPIO_USDHC1_DATA1_1
#define PIN_USDHC1_D2 GPIO_USDHC1_DATA2_1
#define PIN_USDHC1_D3 GPIO_USDHC1_DATA3_1
Excellent! Now it is compiling with 4-bit SDCard interface.
But wait! What about the SDCard insertion pin (SD_CD_SW)? If you look at arch/arm/src/imxrt/imxrt_usdhc.c you will see that it is waiting for a pin named PIN_USDHC1_CD_GPIO, so let to declare it pointing to our pin:
#define PIN_USDHC1_CD_GPIO (IOMUX_VSD_DEFAULT | \ GPIO_PORT2 | GPIO_PIN28)
With everything in place, compile, flash, put a SDCard in the board’s slot and VoilĂ :
NuttShell (NSH) NuttX-9.1.0 nsh> uname -a NuttX 9.1.0 74c16e8d6d-dirty Aug 9 2020 12:58:00 arm imxrt1050-evk nsh> ls /dev /dev: console mmcsd0 null numdisp0 ttyS0 nsh> mount -t vfat /dev/mmcsd0 /mnt nsh> ls /mnt /mnt: LOST.DIR/ Android/ .android_secure/ nsh>
Using LPSPI on iMXRT1050-EVKB with NuttX
I decided to document the steps needed to get the Low Power SPI working on iMXRT1050-EVKB and I hope it could be useful for other people using this board. But the basic idea apply to any other board supported by NuttX.
Everything starts with the schematic, you need to spot the SPI pins that you want to use and which SPI Port it belongs to.
Right, so we found the SPI pins and its MCU pins:
D10/SPI_CS -> GPIO_SD_B0_01
D11/OC2A/PWM/SPI_MOSI -> GPIO_SD_B0_02
D12/SPI_MISO -> GPIO_SD_B0_03
D13/SPI_CLK -> GPIO_SD_B0_00
Now we can find these pins definition on NuttX looking at the file arch/arm/src/imxrt/hardware/rt105x/imxrt105x_pinmux.h :
#define GPIO_LPSPI1_PCS0_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_01_INDEX)) #define GPIO_LPSPI1_SDO_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_02_INDEX)) #define GPIO_LPSPI1_SDI_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_03_INDEX)) #define GPIO_LPSPI1_SCK_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_SD_B0_00_INDEX))
Perfect, but here you need to know an important information about NuttX: normally the NuttX SPI drivers don’t use the native CS (Chip Select) pin, instead it use ordinary GPIO pins to work as CS. The reason behind it is because normally the SPI Hardware has a limited number os HW CS pins (normally 4 pins). So instead of limiting the user to only 4 devices (CS), NuttX allow you to use how many CS pins as you wish.
Now we need to see in the LPSPI driver what is the name of pins it uses, so we will associate these pins to those from the pinmux header file.
Just open the file arch/arm/src/imxrt/imxrt_lpspi.c and search for imxrt_config_gpio(), this is the function used to configure the pins on iMXRT10xx chips.
imxrt_config_gpio(GPIO_LPSPI1_SCK); imxrt_config_gpio(GPIO_LPSPI1_MISO); imxrt_config_gpio(GPIO_LPSPI1_MOSI);
All we need to do is to point these pins to our SPI pins (that we found in the pinmux.h).
You can do it adding these line to boards/arm/imxrt/imxrt1050-evk/include/board.h file:
#define GPIO_LPSPI1_SCK (GPIO_LPSPI1_SCK_2|IOMUX_LPSPI_DEFAULT) #define GPIO_LPSPI1_MISO (GPIO_LPSPI1_SDI_2|IOMUX_LPSPI_DEFAULT) #define GPIO_LPSPI1_MOSI (GPIO_LPSPI1_SDO_2|IOMUX_LPSPI_DEFAULT)
Ok, but where is the the Chip Select pin?
Don’t worry, if you look at iMXRT1050 Datasheet you will see that this CS pin (GPIO_SD_B0_01) is the GPIO3.IO[13] and it is already defined at boards/arm/imxrt/imxrt1050-evk/src/imxrt1050-evk.h this way:
#define GPIO_LPSPI1_CS (GPIO_OUTPUT | GPIO_OUTPUT_ONE | \ GPIO_PORT3 | GPIO_PIN13 | IOMUX_LPSPI1_CS)
So, with the basic configuration in place, now we can start defining our SPI device initialization. Let me think what SPI device we could you. Well, since I want you to “see” the SPI working, let’s to use the MAX7219 7-segment numeric display! đ
Fortunately we have the boards/arm/stm32/stm32f4discovery/src/stm32_max7219_leds.c as example to initialize our MAX7219 display.
We can copy it and modify to become an iMXRT file:
$ cp boards/arm/stm32/stm32f4discovery/src/stm32_max7219_leds.c boards/arm/imxrt/imxrt1050-evk/src/imxrt_max7219_leds.c
Replace all references to stm32f4discovery with imxrt1050-evk and all stm32 with imxrt!
You need to take care with some functions name replacement, ie:
stm32_spibus_initialize(MAX7219_SPI_PORTNO);
will become:
imxrt_lpspibus_initialize(MAX7219_SPI_PORTNO);
We are almost done, but we need to define this file to be compiled and we need to call its initialization function to register the display device.
To compile this file we just need to edit the file boards/arm/imxrt/imxrt1050-evk/src/Makefile and add these lines:
ifeq ($(CONFIG_LEDS_MAX7219),y)
CSRCS += imxrt_max7219_leds.c
endif
And to call the initialization we just add these lines to boards/arm/imxrt/imxrt1050-evk/src/imxrt_bringup.c inside imxrt_bringup() function:
#ifdef CONFIG_LEDS_MAX7219
ret = imxtrt_max7219init("/dev/numdisp0");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: max7219_leds_register failed: %d\n", ret);
}
#endif
After everything is in place you can configure your iMXRT1050-EVK board, enter in the menuconfig and select:
System Type -> i.MX RT Peripheral Selection -> LPSPI Peripherals -> [*] LPSPI1
Device Drivers -> [*] SPI Driver Support
Device Drivers -> LED Support -> [*] MAX7219 Numeric Display
Save and Exit. Just type “make” to compile.
When the compilation finish you can look at the System.map file and search for max7219, you should see these symbols:
6000f954 T imxrt_max7219init
6000f974 t max7219_open
6000f978 t max7219_read
6000f97e t max7219_write16.isra.0
6000f9f4 t max7219_write
6000fb4e t max7219_close
6000fb52 T max7219_leds_register
Flash the firmware in the board (with SW7 1-off 2-on 3-on 4-off I just dropped the nuttx.hex in the disk), open the /dev/ttyACM0 and reset the board, you show see:
NuttShell (NSH) NuttX-9.1.0 nsh> uname -a NuttX 9.1.0 9a1391d36b-dirty Aug 8 2020 12:23:10 arm imxrt1050-evk nsh> ls /dev /dev: console null numdisp0 ttyS0 nsh>
As you can see our /dev/numdisp0 is there!
Note: you need to solder the resistors R281, R279, R278 and R280 to get LPSPI1 working.