Category: Dicas

Accessing Internet from NuttX PPP Connection

As you know I was facing some issues to get PPPD connection working:

https://acassis.wordpress.com/2019/02/10/debugging-pppd-using-quectel-m95-on-samd21-board/

Then I received a comment from Vladimir Novikov (thank you!) at that post commenting the issues was introduced some time ago at this commit:

https://bitbucket.org/nuttx/apps/commits/cddfda99f0a519681b894b7a12560406c4372cfb

And he suggested me adding this line to lcp.c:

          tptr = bptr;
+          bptr += 4;
          error = 0;

Before testing this suggestion I received an email from Quectel Brasil support (thanks Micael Lisboa) suggesting run this AT cmd:

AT+QACCM=0,0

Micael’s suggestion worked fine.

But I decided to contact the author of the modification (Xiao Xiang) and he explained that the bptr was already increased by 4 compared to original code. And in fact he was correct.

Anyway I decided to test Vladimir’s suggestion that also worked. So we need to investigate it in more details to understand what is happening.

BTW since the AT command was working for me I decided to follow with my tests.

After PPPD connection was established it was getting IP:

nsh> ifconfig
ppp0    Link encap:TUN at UP
        inet addr:100.75.210.38 DRaddr:192.168.254.254 Mask:0.0.0.0

But ping command was crashing:

nsh> ping 8.8.8.8

PINGup_assert: Assertion failed at file:armv6-m/up_hardfault.c line: 139
up_registerdump: R0: 20000a78 00000000 00000000 00004a64 20000819
20006f8c 20000a78 00000000
up_registerdump: R8: 00000000 00000000 00000000 00000000 20000414
20003fa0 0000b54f 00009dd6
up_registerdump: xPSR: 21000000 PRIMASK: 00000000
up_dumpstate: sp:         20003ee8
up_dumpstate: stack base: 20004040
up_dumpstate: stack size: 000007e4
up_stackdump: 20003ee0: 2000385c 000009c5 00000000 00000000 00000000
20000414 20003fa0 0000b54f
up_stackdump: 20003f00: 00009dd6 00000000 00013437 00000000 00000000
00000000 20000000 00000018
up_stackdump: 20003f20: 00000003 20003f58 00000000 00000c03 00000018
000010e3 20001e5c 00000ab9
up_stackdump: 20003f40: 00000000 00000000 00000000 20000a78 00000000
000002ab 20003fa0 00000000
up_stackdump: 20003f60: 20000819 20006f8c 20000a78 00000000 00000000
00000000 00000000 00000000
up_stackdump: 20003f80: 20000a78 00000000 00000000 00004a64 20000414
0000b54f 00009dd6 21000000
up_stackdump: 20003fa0: 20000a78 00004000 20006f8c 00004000 2000077c
00009d5d 00000000 0000b54f
up_stackdump: 20003fc0: 00000000 20000a78 00004000 00000000 20000a78
0000fd1d 20001f2c 0000b7f1
up_stackdump: 20003fe0: 00000000 0000b34b 200007f0 20000a74 00000000
0000ff3f 200007f8 00001ee9
up_stackdump: 20004000: 00000000 00001bcf ffffffff 00000000 20001de8
00020000 00000000 00000101
up_stackdump: 20004020: 00000000 00000000 00000000 0000144b 00000101
0000140f 00000000 00000000

After much debugging and with Greg’s help I noticed the “srcipaddr” was not aligned:

(gdb)
194       net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
(gdb) p &ipv4->srcipaddr
$1 = (uint16_t (*)[2]) 0x20000c41 
(gdb) p &dev->d_ipaddr
$2 = (in_addr_t *) 0x20000eac 

See, it was at 0x20000c41 that is an odd address position.

Almost instantly Greg found the source of this issue: it was the TUN/TAP driver that was defining the read_buf at odd position:

 142   bool              read_wait;
 143
 144   uint8_t           read_buf[CONFIG_NET_TUN_PKTSIZE];
 145   size_t            read_d_len;
 146   uint8_t           write_buf[CONFIG_NET_TUN_PKTSIZE];

Moving the “size_t read_d_len;” to the line above read_buf[] fixed the issue!

Now ping is not crashing and I was able to ping the Google’s DNS 8.8.8.8:

nsh> ping 8.8.8.8
PING 8.8.8.8 56 bytes of data
56 bytes from 8.8.8.8: icmp_seq=0 time=1010 ms
56 bytes from 8.8.8.8: icmp_seq=2 time=1260 ms
56 bytes from 8.8.8.8: icmp_seq=2 time=370 ms
56 bytes from 8.8.8.8: icmp_seq=4 time=1080 ms
56 bytes from 8.8.8.8: icmp_seq=4 time=490 ms
56 bytes from 8.8.8.8: icmp_seq=5 time=870 ms
56 bytes from 8.8.8.8: icmp_seq=6 time=560 ms
56 bytes from 8.8.8.8: icmp_seq=7 time=930 ms
56 bytes from 8.8.8.8: icmp_seq=8 time=640 ms
56 bytes from 8.8.8.8: icmp_seq=9 time=1010 ms
10 packets transmitted, 10 received, 0% packet loss, time 10100 ms

How to use git behind proxy

I was willing to use git behind company proxy.

Then I found these tips:

https://stackoverflow.com/questions/2088156/git-through-digest-proxy-authentication

Unfortunately just adding it didn’t work:

git config --global http.proxy "http://USERNAME:PASSWORD@IP:PORT"
git config --global https.proxy "https://USERNAME:PASSWORD@IP:PORT"

Searching a little bit more I found the final piece:

https://askubuntu.com/questions/1061945/not-able-to-connect-to-github-via-proxy

git config --global http.proxyAuthMethod 'basic'

Learning the new NuttX PPPD/CHAT script

Probably you already know it, but I will reinforce the idea: “Changing is the only constant thing!”

So we need to change and to adapt all the time.

Why am I saying these “non-sense” words? Let me explain…

This is a sample of the old NuttX PPPD/Chat script:

static struct chat_script_s connect_script =
{
  .timeout = 30,
  .lines =
  {
    {"AT",                                 "OK"},
    {"AT+CGDCONT = 1,\"IP\",\"internet\"", "OK"},
    {"ATD*99***1#",                        "CONNECT"},
    {0, 0}
  },
};

static struct chat_script_s disconnect_script =
{
  .timeout = 30,
  .lines =
  {
    {"ATZ",                                "OK"},
    {0, 0}
  },
};

Very easy to understand, don’t you think? Basically you have the AT command and the expected result.

But it had a drawback, you had a structure with internal parameters fields (i.e. timeout) and AT commands strings.

Now the new script is basically a sequence of string lines, or basically a single string:

static FAR const char connect_script[] =
  "ECHO ON "
  "TIMEOUT 30 "
  "\"\" ATE1 "
  "OK AT+CGDCONT=1,\\\"IP\\\",\\\"internet\\\" "
  "OK ATD*99***1# "
  "CONNECT \\c";

static FAR const char disconnect_script[] =
  "\"\" ATZ "
  "OK \\c";

Unfortunately this is not that simple: we have internal commands: “ECHO”, “TIMEOUT”, etc and AT string commands. And internal commands don’t expect a return string as AT commands do.

So, what should be the expected result string of ATE1 command? If you think it is an empty string “”, using the original script logic, you are wrong. The expect result is in the below line “OK AT+CGDCONT=1…”, yes “ATE1” expects an “OK” that is in the below line.

Same way “ATD*99***1#” doesn’t expect an “OK”, but a “CONNECT” that is in the next line.

It is a little bit complex, it should exist a documentation explaining how it works. At least this post make a brief introduction to this subject.

Using MODBUS RTU with NuttX

MODBUS is an old protocol used on industrial automation. Although it is an “old” protocol, it still used on many industrial devices.

There are many articles about this protocol in the Internet, but most are very shallow. This guy has a fair introduction about MODBUS:

https://www.lammertbies.nl/comm/info/modbus.html

I spent some time (few days) to get it working on NuttX. First I implemented the DIR pin control for SAMD21 microcontroller and submitted to mainline: https://bitbucket.org/nuttx/nuttx/commits/a34c9733bcac707be803a27c91fec7406bda310b and also fixed a serial issue that was preventing the serial driver from working: https://bitbucket.org/nuttx/nuttx/commits/db0b9b7c34ddcf098059bb51d73d03d45b3f69b7

Then after spending many hours trying to get my computer communicating with SAMD21 board I discovered that the guilt was the USB/RS485 Dongle I was using.

Replacing it with a common USB/Serial (CP2102) and with a MAX485 module, like this: https://www.aliexpress.com/item/2PCS-MAX485-module-RS-485-module-TTL-to-RS-485-module/2055143247.html , solved the issue.

I connected this way:

+-----------------------------------------+
| USB/Serial (CP2102)   |   MAX485 Module |
+-----------------------+-----------------+
|          RXD          |       RO        |
|          TXD          |       DI        |
|          RTS          |     DE + RE     |
|          GND          |       GND       |
|          +5V          |       VCC       |
+-----------------------+-----------------+

This is the listing of features enabled on NuttX:

Serial SERCOM5 Config:

CONFIG_SAMD2L2_SERCOM5_ISUSART=y
CONFIG_USART5_RS485MODE=y
CONFIG_USART5_RS485_DIR_POLARITY=1

We need support to POLL (so don’t select the disable POLL)

# CONFIG_DISABLE_POLL is not set

FreeModbus config:

CONFIG_MODBUS=y
CONFIG_MB_FUNC_HANDLERS_MAX=16
CONFIG_MODBUS_SLAVE=y
CONFIG_MB_ASCII_ENABLED=y
CONFIG_MB_RTU_ENABLED=y
# CONFIG_MB_TCP_ENABLED is not set
CONFIG_MB_ASCII_TIMEOUT_SEC=1
CONFIG_MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0
CONFIG_MB_FUNC_OTHER_REP_SLAVEID_BUF=32
CONFIG_MB_FUNC_OTHER_REP_SLAVEID_ENABLED=y
CONFIG_MB_FUNC_READ_INPUT_ENABLED=y
CONFIG_MB_FUNC_READ_HOLDING_ENABLED=y
CONFIG_MB_FUNC_WRITE_HOLDING_ENABLED=y
CONFIG_MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED=y
CONFIG_MB_FUNC_READ_COILS_ENABLED=y
CONFIG_MB_FUNC_WRITE_COIL_ENABLED=y
CONFIG_MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED=y
CONFIG_MB_FUNC_READ_DISCRETE_INPUTS_ENABLED=y
CONFIG_MB_FUNC_READWRITE_HOLDING_ENABLED=y
# CONFIG_MODBUS_MASTER is not set

Modbus example:

CONFIG_EXAMPLES_MODBUS=y
CONFIG_EXAMPLES_MODBUS_PORT=0
CONFIG_EXAMPLES_MODBUS_BAUD=38400
CONFIG_EXAMPLES_MODBUS_PARITY=2
CONFIG_EXAMPLES_MODBUS_REG_INPUT_START=1000
CONFIG_EXAMPLES_MODBUS_REG_INPUT_NREGS=4
CONFIG_EXAMPLES_MODBUS_REG_HOLDING_START=2000
CONFIG_EXAMPLES_MODBUS_REG_HOLDING_NREGS=130

After compiling and flashing the nuttx.bin, run the modbus:

NuttShell (NSH)
nsh> modbus -e

From computer side I used the “mbpoll” program:

$ mbpoll -a 10 -b 38400 -t 3 -r 1000 -c 4 /dev/ttyUSB0 -R
mbpoll 1.4-11 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright © 2015-2019 Pascal JEAN, https://github.com/epsilonrt/mbpoll
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'mbpoll -w' for details.

Protocol configuration: Modbus RTU
Slave configuration...: address = [10]
start reference = 1000, count = 4
Communication.........: /dev/ttyUSB0,      38400-8E1
t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, input register table

-- Polling slave 10... Ctrl-C to stop)
[1000]: 	40122 (-25414)
[1001]: 	0
[1002]: 	0
[1003]: 	0
-- Polling slave 10... Ctrl-C to stop)
[1000]: 	832
[1001]: 	0
[1002]: 	0
[1003]: 	0
-- Polling slave 10... Ctrl-C to stop)
[1000]: 	24996
[1001]: 	0
[1002]: 	0
[1003]: 	0
-- Polling slave 10... Ctrl-C to stop)
[1000]: 	3747
[1001]: 	0
[1002]: 	0
[1003]: 	0

This is an image of pulseview sniffing the bus:

That is it, very easy after you get it working.

Thanks Daniel Carvalho for the help and suggestions to fix the issue.

I used this online tool to check my modbus packets:

http://modbus.rapidscada.net

Checking the CRC-8 PEC byte of MLX90614

I am creating a NuttX device driver for Melexis MLX90614 and it is a nice adventure.

First I downloaded the adafruit lib and tested it on Arduino Uno just to confirm the sensor was working, but I didn’t look the source code because I always prefer to read the datasheet and implement the driver from scratch.

All things fine, the mlxtest example worked correctly and I got the ambient temperature and the object temperature printed correctly.

Then I created the driver and decided to test it on STM32F103, but discovered that I2C_TRANSFER() for STM32F103 is broken. No problem, let to test it on STM32F4Discovery board:

nsh> dd if=/dev/thermo0 of=/dev/null bs=2 count=1
mlx90614_read_word: value[0]: 0xDF | value[1]: 0x3A | value[2]: 0xCF | ret: 0

Let see in the logic analyzer to confirm:

Very good! But how to check if CRC-8 PEC field (third received byte: 0xCF) is correct?

I found this nice online CRC calculator:

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

But putting all values as suggested in the datasheet didn’t work:

0x5A 0x06 0x5A 0xDF 0x3A
Result CRC value: 0x2F

Then just web searching for: MLX90614 PEC CRC-8 example

Returned me this thread:

https://stackoverflow.com/questions/20554869/implementing-crc8-on-arduino-to-write-to-mlx90614

The “thb” guy saved me:

“I haven’t checked your CRC implementation but there is a mistake in the MLX datasheet or at least it’s badly written. You have to include all the I2C frame’s data for the PEC’s calculation not just the replied data. For a read word command you have to include [SA_W, Command, SA_R, LSB, MSB] and for a write word command [SA_W, Command, LSB, MSB]. So, for their first example the calculation must be made on [ 0xB4, 0x07, 0xB5, 0xD2, 0x3A ] and not just on [ 0xD2, 0x3A ] and this way you get the expected 0x30.”

What this guy is saying is: we need to include all the bits of the Slave Address, the address needs to be seen as 8-bit including the the less significant bit Write or Read. So I2C Write at address 0x5A is seen as 0xB4 and I2C Read is seen as 0xB5 (pay attention at bits over the “5A” in the logic analyzer image above).

So, let to try his idea:

0xB4 0x06 0xB5 0xDF 0x3A
Result CRC value: 0xCF

Bingo!

the moon… beautiful! oh yeah!

Today I decided to test the Lua (the programming language, it means Moon in Portuguese) with FLTK. There is a project called lua-fltk4lua.

Unfortunately the project doesn’t explain how to compile it from source code and it expects the developer uses the “luarocks” package manager to install it.

Although initially I was getting some issues like:

No rule to make target “moon/moon.h”
No rule to make target “compat-5.3/c-api/compat-5.3.h”

I figured out how to get it compiled and working easily, find the steps below:

$ sudo apt-get install lua5.2

$ sudo apt-get install liblua5.2-dev

$ sudo apt-get install libfltk1.3-dev

$ git clone https://github.com/siffiejoe/lua-fltk4lua

$ cd lua-fltk4lua

$ git clone https://github.com/siffiejoe/lua-moon moon

$ git clone https://github.com/keplerproject/lua-compat-5.3 compat-5.3

$ make

$ sudo make install

This is a nice Hello World to see it working, just create a hello.lua file with it:

local fl = require( "fltk4lua" )
local window = fl.Window( 340, 180, "Hello" )
local box = fl.Box( 20, 40, 300, 100, "Hello World!" )
box.box = "FL_UP_BOX"
box.labelfont = "FL_HELVETICA_BOLD_ITALIC"
box.labelsize = 36
box.labeltype = "FL_SHADOW_LABEL"
window:end_group()
window:show( arg )
fl.run()

And run:

$ lua hello.lua

Just it!

Using FAT32 long file names on NuttX

NuttX supports FAT32 with long file names, but there is some details that you need to know to get it working. I will share here the issues that I was facing and how I fixed it.

The original FAT uses 8.3 (8 chars for name and 3 chars for extension), but it can supports files with up to 255 characters (including the extension).

To use it we need to enable long file name support in the menuconfig:

 File Systems  --->
     [*] FAT file system
     [*]   FAT upper/lower names
     [*]   FAT long file names             -------->  (CONFIG_FAT_LFN=y)
     (255)   FAT maximum file name size    -------->  (CONFIG_FAT_MAXFNAME=255)

Initially I will mount an empty SDCard to do my tests:

NuttShell (NSH)

nsh> mount -t vfat /dev/mmcsd0 /mnt

nsh> ls /mnt
/mnt:

nsh>

Let’s to create a small 8.3 file that will be renamed:

nsh> echo "Small file" > /mnt/tinyfile.txt
nsh> ls -l /mnt/tinyfile.txt
 -rw-rw-rw-      12 /mnt/tinyfile.txt
nsh>

Now I will try to rename it to a file with a long name:

nsh> mv /mnt/tinyfile.txt /mnt/this_is_a_file_with_a_long_name_jnsh>

Strange, while I was typing “this_is_a_file_with_a_long_name_just_for_test.txt” the typing was interrupted and the nsh> appeared.

Let see if the file was renamed:

nsh> ls /mnt
/mnt:
 this_is_a_file_with_a_long_name_

Then I remembered that the max line size of NSH was just 60 (CONFIG_NSH_LINELEN=60), I will increase it to 300 characters:

Application Configuration  --->
    NSH Library  --->
          Command Line Configuration  --->
              (300) Max command line length    -------->  (CONFIG_NSH_LINELEN=300)

I will create a tinyfile.txt again and try to rename it:

nsh> mv /mnt/tinyfile.txt /mnt/this_is_a_file_with_a_long_name_just_for_test.txt
nsh> 

Right, now the nsh prompt accept the enter the name, but let see if the file was created correctly:

nsh> ls /mnt
/mnt:
 this_is_a_file_with_a_long_name_
 this_is_a_file_with_a_long_name_

Whoa, it created two files with same name? How it is possible? Don’t worry, these files are different. Opening the SDCard in the Linux I can see:

this_is_a_file_with_a_long_name_j
this_is_a_file_with_a_long_name_just_for_test.txt

So, the LS command is showing only 32 characters. After some investigation I discovered that CONFIG_NAME_MAX=32 was the issue. Let to increase it to 255:

RTOS Features  --->
    Files and I/O  --->
        (255) Maximum size of a file name    -------->  (CONFIG_NAME_MAX=255)

Now I can see the files:

nsh> ls /mnt
/mnt:
 this_is_a_file_with_a_long_name_j
 this_is_a_file_with_a_long_name_just_for_test.txt

My next step is to create a file with 255 characters, like this:

this_file_will_have_a_big_filename_to_verify_how_to_work_with_files_with_long_names_our_test_need_to_have_the_max_filename_size_supported_by_fat32_that_means_it_could_have_up_to_255_characters_including_the_extension_in_the_filename_so_here_we_arrived.txt

nsh> echo "Test" > /mnt/this_file_will_have_a_big_filename_to_verify_how_to_work_with_files_with_long_names_our_test_need_to_have_the_max_filename_size_supported_by_fat32_that_means_it_could_have_up_to_255_characters_including_the_extension_in_the_filename_so_here_we_arrived.txt
nsh> ls /mnt
/mnt:
 this_file_will_have_a_big_filename_to_verify_how_to_work_with_files_with_long_names_our_test_need_to_have_the_max_filename_size_supported_by_fat32_that_means_it_could_have_up_to_255_characters_including_the_extension_in_the_filename_so_here_we_arrived.txt
nsh> 

Very nice! It worked correctly.

As you can see NuttX is similar to Linux kernel, many features depends on other features’ configuration. They are inter-dependent.

Fashing a bad firmware can drive your crazy

I put by XMC4500 in a state where OpenOCD was unable the communicate with it:

$ sudo openocd -f board/xmc4500-relax.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x0c000000"
Open On-Chip Debugger 0.10.0+dev-00172-g7719e96 (2017-11-12-09:13)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
adapter speed: 4000 kHz
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : No device selected, using first device.
Info : J-Link Lite-XMC4000 Rev.1 compiled Apr  2 2015 18:25:20
Info : Hardware version: 1.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Error: Could not initialize the debug port
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Info : SWD DPIDR 0x2ba01477
Error: Could not initialize the debug port
Error: Target not examined, reset NOT asserted!
in procedure 'reset' 
in procedure 'ocd_bouncer'

What happened?

I just changed BOARD_SYSDIV :

#  define BOARD_SYSDIV              0

But in clockconfig.c it does:

  /* Setup fSYS clock */

  regval  = (BOARD_ENABLE_PLL << SCU_SYSCLKCR_SYSSEL);
  regval |= SCU_SYSCLKCR_SYSDIV(BOARD_SYSDIV);
  putreg32(regval, XMC4_SCU_SYSCLKCR);

SCU_SYSCLKCR_SYSDIV is defined this way:

#  define SCU_SYSCLKCR_SYSDIV(n)    ((uint32_t)((n)-1) << SCU_SYSCLKCR_SYSDIV_SHIFT)

So, it wrote 0xffffffff to SCU_SYSCLKCR register. :-/

Then I tried to flash using JLinkExe from Segger, but it also didn’t work:

$ JLinkExe -if SWD
SEGGER J-Link Commander V6.14h (Compiled May 10 2017 18:39:45)
DLL version V6.14h, compiled May 10 2017 18:39:37

Connecting to J-Link via USB...O.K.
Firmware: J-Link Lite-XMC4000 Rev.1 compiled Apr  2 2015 18:25:20
Hardware version: V1.00
S/N: 551014400
VTref = 3.300V


Type "connect" to establish a target connection, '?' for help
J-Link>connect
Please specify device / core. : XMC4500-1024
Type '?' for selection dialog
Device>
Specify target interface speed [kHz]. : 4000 kHz
Speed>
Device "XMC4500-1024" selected.


Performing XMC4500 connection sequence.
No AP preselected. Assuming that AP[0] is the AHB-AP
AP-IDR: 0x24770011, Type: AHB-AP
AHB-AP ROM: 0xE00FF000 (Base addr. of first ROM table)
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
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
Downloading file [./nuttx.bin]...
Writing target memory failed.

Fortunately the “erase” command worked:

J-Link>erase
Erasing device (XMC4500-1024)...
Comparing flash   [100%] Done.
Erasing flash     [100%] Done.
Verifying flash   [100%] Done.
J-Link: Flash download: Total time needed: 22.650s (Prepare: 0.041s, Compare: 0.000s, Erase: 22.604s, Program: 0.000s, Verify: 0.000s, Restore: 0.004s)
Erasing done.

But even after the flash erase the programming is not working:

J-Link>loadbin ./nuttx.bin 0
Downloading file [./nuttx.bin]...
Writing target memory failed.
J-Link>

Then I decided to try OpenOCD again:

$ sudo openocd -f board/xmc4500-relax.cfg
Open On-Chip Debugger 0.10.0+dev-00172-g7719e96 (2017-11-12-09:13)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
adapter speed: 4000 kHz
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : No device selected, using first device.
Info : J-Link Lite-XMC4000 Rev.1 compiled Apr  2 2015 18:25:20
Info : Hardware version: 1.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : xmc4500.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : accepting 'telnet' connection on tcp/4444

And using telnet I tried to send the reset command:

$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> reset halt
timed out while waiting for target halted
TARGET: xmc4500.cpu - Not halted
in procedure 'reset' 
in procedure 'ocd_bouncer'


Halt timed out, wake up GDB.
> 

At this moment I thought my board could be damaged, but I decided to try to flash it anyway:

> flash write_image erase nuttx.bin 0x0c000000
auto erase enabled
Cannot communicate... target not halted.
auto_probe failed

Hmm, let to test only “halt” instead of “reset halt” :

> halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x41000000 pc: 0x000000e6 msp: 0x2000ff3c

Good, now let to try again:

> flash write_image erase nuttx.bin 0x0c000000
auto erase enabled
Clearing flash status
Clearing flash status
wrote 81920 bytes from file nuttx.bin in 17.523651s (4.565 KiB/s)

Very good, my board is live again!