Author: acassis

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:

  1. After the search returned the list of emails, just select them (mark the checkbox)
  2. Click in the (…) and select the option: Forward as attachment
  3. 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.

Just a resume of my experience with iMXRT1060-EVK

I was trying to run NuttX RTOS on iMXRT1060_EVK board (it has an
external 8MiB QSPI Flash), but because my JLink EDU is version V8 it
doesn’t supports Cortex-M7.

Using the DAPLink drag-and-drop I can copy small nuttx firmwares
(i.e.: up to 73KB worked), but when I compile NuttX to PROTECTED Mode
it doesn’t work. Because the kernel is at the beginning of the flash
and the userspace is at offset +2MB. Then during the copy it reports
timeout.

Then I tried to use OpenOCD. I got it working for debugging, but it
doesn’t have support to flash the QSPI for NXP chips, only for
STMicro.

While searching for a solution I found this post:

https://community.nxp.com/thread/518836

“You can actually run the LPC-Link2 firmware on the onboard debug
probe of the RT1064-EVK board, in place of the default DAP-Link
firmware. For more details see:”

That points to this post:
https://community.nxp.com/community/mcuxpresso/mcuxpresso-ide/blog/2019/01/23/overview-of-using-the-mimxrt1060-evk-with-mcuxpresso-ide

Reading this PDF I discovered that if I wire the jumper J42 near the
LPC4322, the firmware will work as a native LPC-Link2, instead of a
DAPLink.

It is strange because in the User’s Guide there is nothing about this
jumper: https://www.avnet.com/opasdata/d120001/medias/docus/192/NXP-MIMXRT1060-EVK-User-Guide.PDF

And in fact it works as DFU mode:

[ 638.833516] usb 1-1: new high-speed USB device number 9 using xhci_hcd
[ 638.982422] usb 1-1: New USB device found, idVendor=1fc9,
idProduct=000c, bcdDevice= 1.00
[ 638.982428] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 638.982434] usb 1-1: Product: LPC
[ 638.982436] usb 1-1: Manufacturer: NXP
[ 638.982439] usb 1-1: SerialNumber: ABCD
$ sudo dfu-util -d 0x1fc9:0x000c -l
dfu-util 0.9


Found DFU: [1fc9:000c] ver=0100, devnum=9, cfg=1, intf=0, path="1-1",
alt=0, name="DFU", serial="ABCD"

But I need to find the .hdr file to implement the LPCScrypt for this
iMXRT1060 chip, like I did some time ago for LPC43:

https://acassis.wordpress.com/2017/03/28/using-lpcscrypt-to-flash-firmware-on-bambino-board/

I have a LPCXpresso54628 board here, then I thought about the idea of
using its LPC-Link2 to program the iMXRT1060. But that should be more complicated.

While searching for a solution I found this post:

https://community.nxp.com/thread/518836

“You can actually run the LPC-Link2 firmware on the onboard debug
probe of the RT1064-EVK board, in place of the default DAP-Link
firmware. For more details see:”

That points to this post:
https://community.nxp.com/community/mcuxpresso/mcuxpresso-ide/blog/2019/01/23/overview-of-using-the-mimxrt1060-evk-with-mcuxpresso-ide

Reading this PDF I discovered that if I wire the jumper J42 near the
LPC4322, the firmware will work as a native LPC-Link2, instead of a
DAPLink.

It is strange because in the User’s Guide there is nothing about this
jumper: https://www.avnet.com/opasdata/d120001/medias/docus/192/NXP-MIMXRT1060-EVK-User-Guide.PDF

JLinkExe Flash failing to STM32L496RE

Found SW-DP with ID 0x2BA01477
Unknown DP version. Assuming DPv0
Scanning AP map to find all available APs
AP[1]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU
ROMTbl[0][5]: E0041000, CID: B105900D, PID: 000BB925 ETM
Cortex-M4 identified.
J-Link>loadbin nuttx.bin, 0
Halting CPU for downloading file.
Downloading file [nuttx.bin]

Writing target memory failed.
J-Link>erase
Erasing device

J-Link: Flash download: Only internal flash banks will be erased.
To enable erasing of other flash banks like QSPI or CFI, it needs to be enabled via "exec EnableEraseAllFlashBanks"
Erasing flash [100%] Done.
Error: Failed to erase chip @ address 0x08000000 (Algo87: Unspecified error #1)
Failed to erase chip.
Failed to execute RAMCode for chip erase!
J-Link: Flash download: Total time needed: 0.105s (Prepare: 0.064s, Compare: 0.000s, Erase: 0.001s, Program: 0.000s, Verify: 0.000s, Restore: 0.038s)
ERROR: Erase returned with error code -5.
J-Link>

Strange, after resetting the board and writing a .hex instead of a .bin worked…

Creating a VIM macro to align variable definition on header files

I was looking for a way to align registers definitions like these:

#define REGISTER_XYZ 0x0001
#define REGISTER_A 0x0002

And I found this nice tip:

qa -- Record a macro in hotkey a
0 -- Go to the beginning of the line
f= -- Go to the first equals sign
100i <Esc> -- (There's a single space after the i, and the <Esc> means press escape, don't type "<Esc>".) Insert 100 spaces
8| -- Go to the 8th column (sorry, you'll have to manually figure out which column to align to)
dw -- Delete until the next non-space character
j -- Go to the next line
q -- Stop recording.

In my case I just replaced the “f=” with “f0” and “8|” with “33|”

Source: https://stackoverflow.com/questions/6154306/how-to-insert-spaces-up-to-column-x-to-line-up-things-in-columns

Tips when booting with NSH

If you want to start your application on NuttX directly without using the NSH you can setup your “app_main” in the ENTRYPOINT, although you will see that some drivers will not start anymore.

You can fix it enabling the “Board Late Init” in the menuconfig:

RTOS Features ---> RTOS hooks ---> [*] Custom board late initialization

Also you need to disable the architecture-specific initialization:

Application Configuration ---> NSH Library ---> Have architecture-specific initialization

Using NuttX as library once again

If you follow this blog you know that I already show how to use NuttX as a library to avoid compiling it all the time using the build system. But unfortunately I did it more than 3 years ago and NuttX changed a lot since that time.

So, let’s to start configuring the STM32F429IDISCOVERY board.

Create the nuttxspace directory and clone the nuttx and apps:

$ mkdir ~/nuttxspace
$ cd ~/nuttxspace
$ git clone https://github.com/apache/incubator-nuttx nuttx
$ git clone https://github.com/apache/incubator-nuttx-apps apps

Configure the NuttX to the STM32F429IDISCOVERY board and ‘nsh’ profile:

$ cd ~/nuttxspace
$ cd nuttx
$ make distclean
$ ./tools/configure.sh stm32f429i-disco:nsh
$ make menuconfig

Select HELLO application and use USER_ENTRYPOINT = hello_main

Exit menuconfig and run:

$ make export

If everything worked fine it should have created a nuttx-export file:

$ ls -l nuttx-export*
-rw-rw-r-- 1 alan alan 4396597 Jun 28 09:49 nuttx-export-9.0.0.zip

Now create your hello world directory and copy this export file to there

$ mkdir ~/hello
$ cp nuttx-export-9.0.0.zip ~/hello
$ cd ~/hello
$ unzip nuttx-export-9.0.0.zip
$ cd nuttx-export-9.0.0

Finally create your hello.c file:

#include <stdio.h>

int hello_main(void)
{
        printf("Hello World from my App!\n");
        return 0;
}

Compile it:

$ arm-none-eabi-gcc -c -fno-builtin -Wall -Wstrict-prototypes -Wshadow -Wundef -g -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -I. -isystem ./include   -pipe -I "./include" -I "./arch/chip" hello.c -o  hello.o

We just need to link again all libs to generate our nuttx ELF:

$ arm-none-eabi-ld --entry=__start -nostartfiles -nodefaultlibs -T./scripts/ld.script -L./libs hello.o -o nuttx.elf --start-group -lc -larch -lbinfmt -lboard -lboards -ldrivers -lfs -lmm -lsched -lxx "/usr/lib/gcc/arm-none-eabi/9.2.1/thumb/v7e-m/nofp/libgcc.a" --end-group

Finally convert the ELF to BIN to flash into the board:

$ arm-none-eabi-objcopy -S -O binary nuttx.elf nuttx.bin

Time to flash it:

$ sudo openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000"

Open the minicom and reset the board, you should see: