Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

drivers/hd44780: fix potential hardfault during initialization #12634

Merged
merged 3 commits into from
Nov 6, 2019

Conversation

aabadie
Copy link
Contributor

@aabadie aabadie commented Nov 3, 2019

Contribution description

This PR fixes a hardfault when running the tests/driver_hd44780 application on samr21-xpro, when built with LLVM, as reported in #12487 (comment).

In fact, the test application also crashes when run on arduino-zero/samr30-xpro if built GCC or LLVM.

Since the data pins array param is stored on flash memory and the driver is accessing it in loops for initializing/setting/clearing the pins. I thought that there was something with this that could cause a crash so this PR is just adding a extra array in RAM for and use it in the driver instead of the param array. It seems to work, at least it doesn't crash anymore.

Surprisingly, there's no RAM increase, just 24 extra bytes on ROM.

There might be something else, related to SAM0 platforms since it works well on the other platforms I tested (STM32, nRF), but I have no idea what it could be.

Testing procedure

  • Run
    $ make BOARD=samr21-xpro -C tests/driver_hd44780 flash test
    $ TOOLCHAIN=llvm make BOARD=samr21-xpro -C tests/driver_hd44780 flash test
    
    on master and with this PR the first one works but the second one only works with this PR.
    Changing BOARD for arduino-zero or samr30-xpro none of the 2 commands works on master but both are fixed by this PR.

Issues/PRs references

Fixes the issue reported in #12487 (comment)

@aabadie aabadie added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR labels Nov 3, 2019
Copy link
Contributor

@MrKevinWeiss MrKevinWeiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running on the CI to be sure but it seems to fix the failure that murdock found.

if (dev->p.data[i] != GPIO_UNDEF) {
++count_pins;
}
dev->data[i] = dev->p.data[i];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason no memcpy(dev->data, dev.p.data, ARRAY_SIZE((dev->data)); (I don't know if that is the proper array size macro but you get the idea)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried memcpy and noticed a bigger code size on ROM, that's why I kept the for loop version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, lets me run it through the test.

@benpicco
Copy link
Contributor

benpicco commented Nov 4, 2019

Hm, I'd like to understand where this bug comes from before working around it - it works in GCC and I don't see anything obviously wrong with it. After all gpio_t is just a uint32_t, it shouldn't matter where it resides.

How did you set up the llvm tookchain? I couldn't find anything in the Wiki.

@aabadie
Copy link
Contributor Author

aabadie commented Nov 4, 2019

it works in GCC and I don't see anything obviously wrong with it. After all gpio_t is just a uint32_t, it shouldn't matter where it resides.

While working on it, I discovered that saml21 based boards are broken with GCC, same for Arduino-Zero (samd21). So there's something wrong with sam0 boards in general, it's just that samr21 is less affected I would say. On the other architectures I tested (STM32, nRF51) the test is working.

How did you set up the llvm tookchain?

Just installed llvm locally but you can also use this toolchain from within docker.

@benpicco
Copy link
Contributor

benpicco commented Nov 4, 2019

I can't even build with TOOLCHAIN=llvm when I select BOARD=same54-xpro:

/home/benpicco/dev/RIOT/cpu/cortexm_common/thread_arch.c:309:6: error: instruction requires: VFP2
    "vstmdbeq r0!, {s16-s31}          \n" /* save FPU registers if FPU is used */
     ^
<inline asm>:5:1: note: instantiated into assembly here
vstmdbeq r0!, {s16-s31}          
^
/home/benpicco/dev/RIOT/cpu/cortexm_common/thread_arch.c:311:6: error: incorrect condition in IT block; got 'al', but expected 'eq'
    "stmdb  r0!,{r4-r11}              \n" /* save regs */
     ^
<inline asm>:6:6: note: instantiated into assembly here
stmdb  r0!,{r4-r11}              
     ^
/home/benpicco/dev/RIOT/cpu/cortexm_common/thread_arch.c:360:6: error: instruction requires: VFP2
    "vldmiaeq r1!, {s16-s31}          \n" /* load FPU registers if saved */
     ^
<inline asm>:12:1: note: instantiated into assembly here
vldmiaeq r1!, {s16-s31}          
^
/home/benpicco/dev/RIOT/cpu/cortexm_common/thread_arch.c:362:6: error: incorrect condition in IT block; got 'al', but expected 'eq'
    "msr    psp, r1                   \n" /* restore user mode SP to PSP reg */
     ^
<inline asm>:13:4: note: instantiated into assembly here
msr    psp, r1                   
   ^
4 errors generated.

When I use BOARD=samr21-xpro the build succeeds oO

@aabadie
Copy link
Contributor Author

aabadie commented Nov 4, 2019

I had the same issue with nrf52. Maybe the toolchain just doesn't support M4 ?

@MrKevinWeiss
Copy link
Contributor

A few boards have failed though I don't know if we should expect failures for this test since the boards don't have the driver connected... Maybe some GPIO pins are not valid in the boards or something:

ek-lm4f120xl
make RIOT_CI_BUILD=1 CC_NOCOLOR=1 --no-print-directory -C ./tests/driver_hd44780 test
/srv/ilab-builds/workspace/jobs/experimental-pull-request-tests/dist/tools/pyterm/pyterm -p "/dev/riot/tty-ek-lm4f120xl" -b "115200" --noprefix --no-repeat-command-on-empty-line
Twisted not available, please install it if you want to use pyterm's JSON capabilities
Connect to serial port /dev/riot/tty-ek-lm4f120xl
Welcome to pyterm!
Type '/exit' to exit.
main(): This is RIOT! (Version: buildtest)
[START]

Context before hardfault:
   r0: 0x00000000
   r1: 0x00000000
   r2: 0x40004000
   r3: 0x00004000
  r12: 0x00000000
   lr: 0x000014fb
   pc: 0x000014fa
  psr: 0x41000000

FSR/FAR:
 CFSR: 0x00000400
 HFSR: 0x40000000
 DFSR: 0x00000008
 AFSR: 0x00000000
Misc
EXC_RET: 0xfffffffd
Attempting to reconstruct state for debugging...
In GDB:
  set $pc=0x14fa
  frame 0
  bt

ISR stack overflowed by at least 16 bytes.
Timeout in expect script at "child.expect_exact("[SUCCESS]")" (tests/driver_hd44780/tests/01-run.py:16)

/srv/ilab-builds/workspace/jobs/experimental-pull-request-tests/tests/driver_hd44780/../../Makefile.include:710: recipe for target 'test' failed
make: *** [test] Error 1

Return value: 2
stm32f3discovery - I think just a uart problem though
make RIOT_CI_BUILD=1 CC_NOCOLOR=1 --no-print-directory -C ./tests/driver_hd44780 test
/srv/ilab-builds/workspace/jobs/experimental-pull-request-tests/dist/tools/pyterm/pyterm -p "/dev/riot/tty-stm32f3discovery" -b "115200" --noprefix --no-repeat-command-on-empty-line
Twisted not available, please install it if you want to use pyterm's JSON capabilities
Connect to serial port /dev/riot/tty-stm32f3discovery
Welcome to pyterm!
Type '/exit' to exit.
\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00main(): This is RIOT! (Version: buildtest)
[START]
Timeout in expect script at "child.expect_exact("[SUCCESS]")" (tests/driver_hd44780/tests/01-run.py:16)

/srv/ilab-builds/workspace/jobs/experimental-pull-request-tests/tests/driver_hd44780/../../Makefile.include:710: recipe for target 'test' failed
make: *** [test] Error 1

Return value: 2
esp32-wroom32
make RIOT_CI_BUILD=1 CC_NOCOLOR=1 --no-print-directory -C ./tests/driver_hd44780 test
ESP32_SDK_DIR should be defined as /path/to/esp-idf directory
ESP32_SDK_DIR is set by default to /opt/esp/esp-idf
/srv/ilab-builds/workspace/jobs/experimental-pull-request-tests/dist/tools/pyterm/pyterm -p "/dev/riot/tty-esp32-wroom-32" -b "115200" --noprefix --no-repeat-command-on-empty-line
Twisted not available, please install it if you want to use pyterm's JSON capabilities
Connect to serial port /dev/riot/tty-esp32-wroom-32
Welcome to pyterm!
Type '/exit' to exit.
ets Jun  8 2016 00:22:57

rst:0x7 (TG0WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DOUT, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5632
ho 0 tail 12 room 4
load:0x40078000,len:0
load:0x40078000,len:14868
entry 0x40078628
�[0;33mW (30) boot: PRO CPU has been reset by WDT.�[0m
�[0;33mW (31) boot: WDT reset info: PRO CPU PC=0x4008175f�[0m
�[0;33mW (31) boot: WDT reset info: APP CPU PC=0x73794bdd�[0m
�[0;32mI (37) boot: ESP-IDF v3.1-dev-961-ga255622 2nd stage bootloader�[0m
�[0;32mI (43) boot: compile time 12:38:02�[0m
�[0;32mI (47) boot: Enabling RNG early entropy source...�[0m
�[0;32mI (53) boot: SPI Speed      : 40MHz�[0m
�[0;32mI (57) boot: SPI Mode       : DOUT�[0m
�[0;32mI (61) boot: SPI Flash Size : 4MB�[0m
�[0;32mI (65) boot: Partition Table:�[0m
�[0;32mI (69) boot: ## Label            Usage          Type ST Offset   Length�[0m
�[0;32mI (76) boot:  0 nvs              WiFi data        01 02 00009000 00006000�[0m
�[0;32mI (83) boot:  1 phy_init         RF data          01 01 0000f000 00001000�[0m
�[0;32mI (91) boot:  2 factory          factory app      00 00 00010000 00018ad0�[0m
�[0;32mI (98) boot: End of partition table�[0m
�[0;32mI (103) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x01920 (  6432) map�[0m
�[0;32mI (114) esp_image: segment 1: paddr=0x00011948 vaddr=0x3ffb0000 size=0x01198 (  4504) load�[0m
�[0;32mI (122) esp_image: segment 2: paddr=0x00012ae8 vaddr=0x40080000 size=0x00400 (  1024) load�[0m
�[0;32mI (130) esp_image: segment 3: paddr=0x00012ef0 vaddr=0x40080400 size=0x0467c ( 18044) load�[0m
�[0;32mI (146) esp_image: segment 4: paddr=0x00017574 vaddr=0x00000000 size=0x08a9c ( 35484) �[0m
�[0;32mI (160) esp_image: segment 5: paddr=0x00020018 vaddr=0x400d0018 size=0x08a8c ( 35468) map�[0m
�[0;32mI (176) boot: Loaded app from partition at offset 0x10000�[0m
�[0;32mI (176) boot: Disabling RNG early entropy source...�[0m

Starting ESP32 with ID: 1730aea4d34600

Current clocks in Hz: CPU=80000000 APB=80000000 XTAL=40000000 SLOW=150000
PRO cpu is up (single core mode, only PRO cpu is used)
PRO cpu starts user code
Used clocks in Hz: CPU=80000000 APB=80000000 XTAL
Board configuration:
	UART_DEV(0)	txd=1 rxd=3
	UART_DEV(1)	txd=10 rxd=9
	LED		pins=[ ]
	BUTTONS		pins=[ 0 ]

Starting RIOT kernel on PRO cpu
I (13630) [main_trampoline]: main(): This is RIOT! (Version: buildtest)
[START]
EXCEPTION!! exccause=0 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (EXCEPTION!! exccause=28 (ets Jun  8 2016 00:22:57

rst:0x7 (TG0WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DOUT, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5632
ho 0 tail 12 room 4
load:0x40078000,len:0
load:0x40078000,len:14868
entry 0x40078628
�[0;33mW (30) boot: PRO CPU has been reset by WDT.�[0m
�[0;33mW (31) boot: WDT reset info: PRO CPU PC=0x4008175f�[0m
�[0;33mW (31) boot: WDT reset info: APP CPU PC=0x73794bdd�[0m
�[0;32mI (37) boot: ESP-IDF v3.1-dev-961-ga255622 2nd stage bootloader�[0m
�[0;32mI (43) boot: compile time 12:38:02�[0m
�[0;32mI (47) boot: Enabling RNG early entropy source...�[0m
�[0;32mI (53) boot: SPI Speed      : 40MHz�[0m
�[0;32mI (57) boot: SPI Mode       : DOUT�[0m
�[0;32mI (61) boot: SPI Flash Size : 4MB�[0m
�[0;32mI (65) boot: Partition Table:�[0m
�[0;32mI (69) boot: ## Label            Usage          Type ST Offset   Length�[0m
�[0;32mI (76) boot:  0 nvs              WiFi data        01 02 00009000 00006000�[0m
�[0;32mI (83) boot:  1 phy_init         RF data          01 01 0000f000 00001000�[0m
�[0;32mI (91) boot:  2 factory          factory app      00 00 00010000 00018ad0�[0m
�[0;32mI (98) boot: End of partition table�[0m
�[0;32mI (103) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x01920 (  6432) map�[0m
�[0;32mI (114) esp_image: segment 1: paddr=0x00011948 vaddr=0x3ffb0000 size=0x01198 (  4504) load�[0m
�[0;32mI (122) esp_image: segment 2: paddr=0x00012ae8 vaddr=0x40080000 size=0x00400 (  1024) load�[0m
�[0;32mI (130) esp_image: segment 3: paddr=0x00012ef0 vaddr=0x40080400 size=0x0467c ( 18044) load�[0m
�[0;32mI (146) esp_image: segment 4: paddr=0x00017574 vaddr=0x00000000 size=0x08a9c ( 35484) �[0m
�[0;32mI (160) esp_image: segment 5: paddr=0x00020018 vaddr=0x400d0018 size=0x08a8c ( 35468) map�[0m
�[0;32mI (176) boot: Loaded app from partition at offset 0x10000�[0m
�[0;32mI (176) boot: Disabling RNG early entropy source...�[0m

Starting ESP32 with ID: 1730aea4d34600

Current clocks in Hz: CPU=80000000 APB=80000000 XTAL=40000000 SLOW=150000
PRO cpu is up (single core mode, only PRO cpu is used)
PRO cpu starts user code
Used clocks in Hz: CPU=80000000 APB=80000000 XTAL
Board configuration:
	UART_DEV(0)	txd=1 rxd=3
	UART_DEV(1)	txd=10 rxd=9
	LED		pins=[ ]
	BUTTONS		pins=[ 0 ]

Starting RIOT kernel on PRO cpu
I (20318) [main_trampoline]: main(): This is RIOT! (Version: buildtest)
[START]
Timeout in expect script at "child.expect_exact("[SUCCESS]")" (tests/driver_hd44780/tests/01-run.py:16)

/srv/ilab-builds/workspace/jobs/experimental-pull-request-tests/tests/driver_hd44780/../../Makefile.include:710: recipe for target 'test' failed
make: *** [test] Error 1

Return value: 2

@MrKevinWeiss
Copy link
Contributor

I can build the same54-xpro with llvm:

TOOLCHAIN=llvm make BOARD=same54-xpro -C tests/driver_hd44780 all
make: Entering directory '/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780'
Building application "tests_driver_hd44780" for "same54-xpro" with MCU "samd5x".

"make" -C /home/kevinweiss/WorkingDirectory/RIOT/boards/same54-xpro
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/core
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/samd5x
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/cortexm_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/cortexm_common/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/sam0_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/sam0_common/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/samd5x/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers/hd44780
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers/periph_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/auto_init
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/div
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/newlib_syscalls_default
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/pm_layered
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/stdio_uart
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/xtimer
   text	   data	    bss	    dec	    hex	filename
  12084	    120	   2576	  14780	   39bc	/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780/bin/same54-xpro/tests_driver_hd44780.elf
make: Leaving directory '/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780'

@aabadie
Copy link
Contributor Author

aabadie commented Nov 6, 2019

@MrKevinWeiss are the failing boards also failing on master (and eventually the latest release version) ?
Does it work on same54-xpro with LLVM ?

@MrKevinWeiss
Copy link
Contributor

Probably good to point that out... Yup failing in master too so maybe we don't worry about it, yet.

@MrKevinWeiss
Copy link
Contributor

For the same54 I seem to have some flashing problems, looking into it.

TOOLCHAIN=llvm make BOARD=same54-xpro -C tests/driver_hd44780 flash test
make: Entering directory '/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780'
Building application "tests_driver_hd44780" for "same54-xpro" with MCU "samd5x".

"make" -C /home/kevinweiss/WorkingDirectory/RIOT/boards/same54-xpro
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/core
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/samd5x
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/cortexm_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/cortexm_common/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/sam0_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/sam0_common/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/samd5x/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers/hd44780
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers/periph_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/auto_init
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/div
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/newlib_syscalls_default
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/pm_layered
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/stdio_uart
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/xtimer
   text	   data	    bss	    dec	    hex	filename
  12084	    120	   2576	  14780	   39bc	/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780/bin/same54-xpro/tests_driver_hd44780.elf
/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/edbg  --target atmel_cm4v2 --verbose --file /home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780/bin/same54-xpro/tests_driver_hd44780.bin --verify || /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/edbg  --target atmel_cm4v2 --verbose --file /home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780/bin/same54-xpro/tests_driver_hd44780.bin --verify --program
Error: unknown target type (atmel_cm4v2); use '-t' option
Error: unknown target type (atmel_cm4v2); use '-t' option
/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780/../../Makefile.include:650: recipe for target 'flash' failed
make: *** [flash] Error 1
make: Leaving directory '/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780'

@MrKevinWeiss
Copy link
Contributor

Bumped the version of edbg and cleared out the binary in dist/tools/edbg and reran. It passes.

make BOARD=same54-xpro -C tests/driver_hd44780 all flash test
make: Entering directory '/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780'
Building application "tests_driver_hd44780" for "same54-xpro" with MCU "samd5x".

"make" -C /home/kevinweiss/WorkingDirectory/RIOT/boards/same54-xpro
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/core
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/samd5x
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/cortexm_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/cortexm_common/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/sam0_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/sam0_common/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/cpu/samd5x/periph
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers/hd44780
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/drivers/periph_common
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/auto_init
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/div
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/newlib_syscalls_default
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/pm_layered
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/stdio_uart
"make" -C /home/kevinweiss/WorkingDirectory/RIOT/sys/xtimer
   text	   data	    bss	    dec	    hex	filename
  11292	    120	   2576	  13988	   36a4	/home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780/bin/same54-xpro/tests_driver_hd44780.elf
[INFO] edbg binary not found - building it from source now
CC= CFLAGS= make -C /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg
rm -Rf /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin
mkdir -p /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin
/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/git/git-cache clone "https://github.com/ataradov/edbg" "4f5d490bfffc7fd10855e513e6e88be5a9a3f789" "/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin"
Cloning into '/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin'...
remote: Enumerating objects: 29, done.
remote: Counting objects: 100% (29/29), done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 558 (delta 12), reused 14 (delta 5), pack-reused 529
Receiving objects: 100% (558/558), 232.10 KiB | 0 bytes/s, done.
Resolving deltas: 100% (354/354), done.
Checking connectivity... done.
HEAD is now at 4f5d490... Moved initial reset into target-specific code
touch /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin/.git-downloaded
if [ 4f5d490bfffc7fd10855e513e6e88be5a9a3f789 != 4f5d490bfffc7fd10855e513e6e88be5a9a3f789 ] ; then \
	git -C /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin clean -xdff ; \
	git -C /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin fetch "https://github.com/ataradov/edbg" "4f5d490bfffc7fd10855e513e6e88be5a9a3f789" ; \
	git -C /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin checkout -f 4f5d490bfffc7fd10855e513e6e88be5a9a3f789 ; \
	touch /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin/.git-downloaded ; \
fi
env -i PATH="/home/kevinweiss/esp/esptool-esp8266-rtos-sdk-v3:/home/kevinweiss/esp/xtensa-esp8266-elf/bin:/home/kevinweiss/opt/gnu-mcu-eclipse/openocd/0.10.0-12-20190422-2015/bin/:/home/kevinweiss/bin:/home/kevinweiss/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/kevinweiss/opt/gcc-arm-none-eabi-7-2017-q4-major/bin:/home/kevinweiss/opt/dfu-util/src:/home/kevinweiss/tmp/pic32prog:/home/kevinweiss/esp/xtensa-esp32-elf/bin" TERM="xterm-256color" "make" -C "/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin"
make: Entering directory '/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin'
gcc -W -Wall -Wextra -O2 -std=gnu11 dap.c edbg.c target.c target_atmel_cm0p.c target_atmel_cm3.c target_atmel_cm4.c target_atmel_cm7.c target_atmel_cm4v2.c target_mchp_cm23.c  dbg_lin.c -ludev -o edbg
make: Leaving directory '/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin'
mv /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/bin/edbg .
[INFO] edbg binary successfully built!
/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/edbg  --target atmel_cm4v2 --verbose --file /home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780/bin/same54-xpro/tests_driver_hd44780.bin --verify || /home/kevinweiss/WorkingDirectory/RIOT/dist/tools/edbg/edbg  --target atmel_cm4v2 --verbose --file /home/kevinweiss/WorkingDirectory/RIOT/tests/driver_hd44780/bin/same54-xpro/tests_driver_hd44780.bin --verify --program
Debugger: ATMEL EDBG CMSIS-DAP ATML2748051800004069 03.25.01B6 (S)
Clock frequency: 16.0 MHz
Target: SAM E54P20A (Rev A)
Verification...
at address 0x0 expected 0x00, read 0xf0
Error: verification failed
Debugger: ATMEL EDBG CMSIS-DAP ATML2748051800004069 03.25.01B6 (S)
Clock frequency: 16.0 MHz
Target: SAM E54P20A (Rev A)
Programming..... done.
Verification.......................... done.
/home/kevinweiss/WorkingDirectory/RIOT/dist/tools/pyterm/pyterm -p "/dev/ttyACM0" -b "115200" --noprefix --no-repeat-command-on-empty-line
Twisted not available, please install it if you want to use pyterm's JSON capabilities
Connect to serial port /dev/ttyACM0
Welcome to pyterm!
Type '/exit' to exit.
main(): This is RIOT! (Version: 2020.01-devel-443-g0c18788-tstxxx/12634)
[START]
[SUCCESS]

MrKevinWeiss
MrKevinWeiss previously approved these changes Nov 6, 2019
Copy link
Contributor

@MrKevinWeiss MrKevinWeiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a bugfix and it only affects the driver I think it should be in sooner than later. I tested and it fixes the bugs and does not introduce any new ones. I will ACK, @benpicco @kaspar030 if you have any objections now it the time.

Copy link
Contributor

@benpicco benpicco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff --git a/drivers/hd44780/hd44780.c b/drivers/hd44780/hd44780.c
index 73b2a6072..26b0ec341 100644
--- a/drivers/hd44780/hd44780.c
+++ b/drivers/hd44780/hd44780.c
@@ -110,20 +110,16 @@ int hd44780_init(hd44780_t *dev, const hd44780_params_t *params)
         LOG_ERROR("hd44780_init: invalid LCD size!\n");
         return -1;
     }
-    uint8_t count_pins = 0;
-    /* check which pins are used */
-    for (unsigned i = 0; i < HD44780_MAX_PINS; ++i) {
-        if (dev->p.data[i] != GPIO_UNDEF) {
-            ++count_pins;
-        }
-    }
-    /* set mode depending on configured pins */
-    if (count_pins < HD44780_MAX_PINS) {
-        dev->flag |= HD44780_4BITMODE;
+
+    /* set mode depending on configured pins:
+        if 4th pin is set, use 8bit mode, else use 4bit mode*/
+    if (dev->p.data[4] != GPIO_UNDEF) {
+        dev->flag |= HD44780_8BITMODE;
     }
     else {
-        dev->flag |= HD44780_8BITMODE;
+        dev->flag |= HD44780_4BITMODE;
     }
+
     /* set flag for 1 or 2 row mode, 4 rows are 2 rows split half */
     if (dev->p.rows > 1) {
         dev->flag |= HD44780_2LINE;

This part of the patch is enough to fix the bug.

@benpicco benpicco dismissed their stale review November 6, 2019 14:25

oops, no - the TOOLCHAIN=llvm slipped though

Copy link
Contributor

@benpicco benpicco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the patch is much simpler:

diff --git a/drivers/hd44780/hd44780.c b/drivers/hd44780/hd44780.c
index 73b2a6072..8bdb83c40 100644
--- a/drivers/hd44780/hd44780.c
+++ b/drivers/hd44780/hd44780.c
@@ -117,6 +117,8 @@ int hd44780_init(hd44780_t *dev, const hd44780_params_t *params)
             ++count_pins;
         }
     }
+
+    dev->flag = 0;
     /* set mode depending on configured pins */
     if (count_pins < HD44780_MAX_PINS) {
         dev->flag |= HD44780_4BITMODE;

flags is uninitialized so the HD44780_8BITMODE is erroneously set.
And since sam0 stores the address of the GPIO port inside gpio_t, calling gpio_set(-1) does not fare well.

And HD44780_4BITMODE is never used, only set - I'd suggest to remove it so we can't set HD44780_4BITMODE and HD44780_8BITMODE at the same time - an unset HD44780_8BITMODE should indicate 4 Bit mode.

@aabadie
Copy link
Contributor Author

aabadie commented Nov 6, 2019

Thanks @benpicco! That was it. Good catch!

@aabadie
Copy link
Contributor Author

aabadie commented Nov 6, 2019

Another solution is to declare the device descriptor static in the test application.

Co-authored-by Benjamin Valentin <benpicco@googlemail.com>
@aabadie aabadie force-pushed the pr/drivers/hd44780_fix_sam0 branch from 0c18788 to c7fac09 Compare November 6, 2019 15:14
@aabadie
Copy link
Contributor Author

aabadie commented Nov 6, 2019

Another solution is to declare the device descriptor static in the test application.

I agree this is not nice. But it is showing the potential initialization difference between structures initialized on the stack and structures defined statically.

@aabadie
Copy link
Contributor Author

aabadie commented Nov 6, 2019

I reworked the PR with the simple fix proposed by @benpicco. AFAICT, everything works locally with this patch.

@benpicco
Copy link
Contributor

benpicco commented Nov 6, 2019

I still liked the change to just check if the 4th pin is set instead of counting the pins.
The driver only works for consecutive sets of 4 or 8 pins after all.

@aabadie
Copy link
Contributor Author

aabadie commented Nov 6, 2019

The driver only works for consecutive sets of 4 or 8 pins after all.

Indeed. And it was saving some memory on ROM. I'll push a commit for this.

The driver can only be used with either 4 or 8 bit modes. Checking if the 5th pin is set in the configuration is enough the determine if 8bit mode should be used or not
@aabadie
Copy link
Contributor Author

aabadie commented Nov 6, 2019

Done. With this we save 16B on ROM for Arduino-Zero, not that much but better than before.

Copy link
Contributor

@benpicco benpicco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this the driver doesn't crash anymore on samr21 when build with LLVM.

@aabadie aabadie merged commit 08e1cf2 into RIOT-OS:master Nov 6, 2019
@aabadie aabadie deleted the pr/drivers/hd44780_fix_sam0 branch November 6, 2019 16:18
benpicco added a commit to benpicco/RIOT that referenced this pull request Nov 7, 2019
This reverts commit cf01c74.

Adding an unexplained delay seemed wrong in the first place, but it fixed
the display on the MCB2388.

Turns out the display was erroneously operating in 8-bit mode due to the
uninitialized flag register.
Why the delay helped here I don't know.

But with RIOT-OS#12634 fixing this, this hack is not needed anymore.
@fjmolinas fjmolinas added this to the Release 2020.01 milestone Dec 13, 2019
gdoffe pushed a commit to gdoffe/RIOT that referenced this pull request Dec 17, 2019
This reverts commit cf01c74.

Adding an unexplained delay seemed wrong in the first place, but it fixed
the display on the MCB2388.

Turns out the display was erroneously operating in 8-bit mode due to the
uninitialized flag register.
Why the delay helped here I don't know.

But with RIOT-OS#12634 fixing this, this hack is not needed anymore.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants