I2C, Serial, SPI experiments with Zephyr on Giga

Thanks, I sort of figured as such...
But then wondered if I am still not better off running this under
WSL Ubuntu 24.04 instead of the mingw64... stuff

Note: the bootstrap.sh takes a long while to install everything...
Still chugging now...

I am currently doing the shell manually as it did not like the .sh file.
Maybe it has windows line ending...

I've never used WSL (I have a real Linux machine ready at hand when I need one and I try to avoid using any of the Windows stuff from Microsoft other than what you get from a minimal Windows installation) so I can't say whether it would be superior in any way. But I can say that I use Git Bash constantly, running scripts written by Linux and macOS users who don't even know that Git Bash exists and would tell you that their script can't be used on Windows if asked. It is extremely rare that I experience any problems (and usually when I do they are something expected, as in the example of a script that uses apt I mentioned above, which would even fail on some Linux distros).

1 Like

Thanks,

I may try that later.

WSL, sets up a hardware supported virtual processor, and installs the real Ubuntu or others that they have setup, so I have had pretty good luck with it. Sometimes it gets difficult if you want that machine to have access to certain hardware, but...

And I am guessing that the first script probably does a lot of apt stuff...
At least it was failing in the same way as some of my apt stuff on my machine not liking using HTTP

1 Like

I was able to build with the changes, but other wire objects still don't show up.

My guess is changes needed to Wire.h...

But now off to food...

Was looking at wire.h and the only thing I see that defines object is this:

#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), i2cs) && (DT_PROP_LEN(DT_PATH(zephyr_user), i2cs) > 1)
#define ARDUINO_WIRE_DEFINED_0 1
#define DECL_EXTERN_WIRE_0(i)  extern arduino::ZephyrI2C Wire;
#define DECL_EXTERN_WIRE_N(i)  extern arduino::ZephyrI2C Wire##i;
#define DECLARE_EXTERN_WIRE_N(n, p, i)                                                             \
	COND_CODE_1(ARDUINO_WIRE_DEFINED_##i, (DECL_EXTERN_WIRE_0(i)), (DECL_EXTERN_WIRE_N(i)))

/* Declare Wire, Wire1, Wire2, ... */
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), i2cs, DECLARE_EXTERN_WIRE_N)

#undef DECLARE_EXTERN_WIRE_N
#undef DECL_EXTERN_WIRE_N
#undef DECL_EXTERN_WIRE_0
#undef ARDUINO_WIRE_DEFINED_0
#else
extern arduino::ZephyrI2C Wire;
#endif

and this in wire.cpp


#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), i2cs)
#if (DT_PROP_LEN(DT_PATH(zephyr_user), i2cs) > 1)
#define ARDUINO_WIRE_DEFINED_0 1
#define DECL_WIRE_0(n, p, i)   arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i)));
#define DECL_WIRE_N(n, p, i)   arduino::ZephyrI2C Wire##i(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i)));
#define DECLARE_WIRE_N(n, p, i)                                                                    \
	COND_CODE_1(ARDUINO_WIRE_DEFINED_##i, (DECL_WIRE_0(n, p, i)), (DECL_WIRE_N(n, p, i)))

/* Declare Wire, Wire1, Wire2, ... */
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), i2cs, DECLARE_WIRE_N)

#undef DECLARE_WIRE_N
#undef DECL_WIRE_N
#undef DECL_WIRE_0
#undef ARDUINO_WIRE_DEFINED_0
#elif (DT_PROP_LEN(DT_PATH(zephyr_user), i2cs) == 1)
/* When PROP_LEN(i2cs) == 1, DT_FOREACH_PROP_ELEM work not correctly. */
arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), i2cs, 0)));
#endif // HAS_PORP(i2cs)
/* If i2cs node is not defined, tries to use arduino_i2c */
#elif DT_NODE_EXISTS(DT_NODELABEL(arduino_i2c))
arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_NODELABEL(arduino_i2c)));
#endif

Looks the number of wire objects is defined by i2cs but not working for some reason with more that 1 wire oject

Yep - there is that iterator:
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), i2cs, DECLARE_WIRE_N)

But I have not gone through to figure out how it works.
Figure that is something for tomorrow.

@ptillisch - one thing I ran into using today's nightly build.
Noticed many things pulled in.

I am trying to build the Teensy version of wire scanner.
Wire/examples/Scanner at master ยท PaulStoffregen/Wire

WIth the zephyr version of GIGA...
And I had to define a forward reference:
extern void printKnownChips(byte address);
in the INO file as it said this function was not defined, although it was farther down in the INO file.

EDIT: I also hacked it to tell it, there are three Wire objects

Have not tried it on Teensy yet...

But thought I would mention in case it is a regression and you are close to releasing 2.3.4

1 Like

@KurtE and I were poking around this morning and found that you also need to be looking at the Zephyr repo in the Arduino repos. Any we noticed that the m7.dts file had this defined:

&i2c1 {
	status = "disabled";
	pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>;
	pinctrl-names = "default";
	clock-frequency = <I2C_BITRATE_FAST>;
};

&i2c2 {
	status = "disabled";
	pinctrl-0 = <&i2c2_scl_ph4 &i2c2_sda_pb11>;
	pinctrl-names = "default";
	clock-frequency = <I2C_BITRATE_FAST>;
};

by copying that over to the _m7.overlay file but with status showing ok was able to read the Wire1, also had to add i2cs = <&i2c2>, <&i2c4>, <&i2c1>;

But it works. Wire2 works but takes long time to scan through devices (this is an update).

Scanning Wire...
Device found at address 0x1C  (LIS3MDL)
Device found at address 0x68  (DS1307,DS3231,MPU6050,MPU9050,MPU9250,ITG3200,ITG3701,LSM9DS0,L3G4200D)
done

Scanning Wire1...
Device found at address 0x60  (MPL3115,MCP4725,MCP4728,TEA5767,Si5351)
Device found at address 0x68  (DS1307,DS3231,MPU6050,MPU9050,MPU9250,ITG3200,ITG3701,LSM9DS0,L3G4200D)
Device found at address 0x76  (MS5607,MS5611,MS5637,BMP280)
done

Yeah I modified the PJRC scanner as well.

UPDATE: Wanted to mention to get it to compile and upload correctly have to put it into boot mode by double pressing the rst button other on complile it complains about Wire1.

1 Like

:smiley: progress

I have been playing around with Serial code, devices.

@facchinm @ptillisch others? - Wondering if this is a good place to discuss some of this,
or elsewhere? I noticed that the main tree of information is in the zephyr project with your fork:

kurte@kurte-750-435st:~/github/zephyr$ git remote -v
arduino	https://github.com/facchinm/zephyr (fetch)
arduino	https://github.com/facchinm/zephyr (push)

Right now I am experimenting try to setup Serial1-4 to match the MBED objects. Current github, has Serial1 and Serial2 defined, but I believe Serial1 is same, and Serial2 is Serial4 on MBED builds...

Looks like you might have something defined for the usart used for MBED Serial2 as for the M4...

I have it building and uploading for Serial1-4, but my test program hangs. So debugging with just Serail1 used.

Things I found in test program so far:
a) unrelate: pinMode(LED_BUILTIN, OUTPUT);
will initialize with the LED on, I believe it is off on MBED builds...

b) Serial.read() appears to not return -1, when queue is empty. That is:

void wait_for_user_input() {
  Serial.println("Waiting...");
#if 1
  while (!Serial.available()) {}
  while (Serial.available()) {Serial.read();}
#else
  while (Serial.read() == -1) {};
  while (Serial.read() != -1) {};
#endif
}

That is the above code works, the else clause which was the code hangs

c) Serial(X) - availableForWrite returns 0 - not surprising as was also not implemented on MBED. But at least it looks like the writes might be buffered.

Question again is, should things like that be reported here?, issues (or maybe better yet) PRs?

Thanks.

Now back to debugging

I did make some changes, and for at least a place holder I created a Pull request:

I fixed SerialX.read() to return -1 if queue is empty (ditto for peek )
Implemented SerialX.availableForWrite
Updated the begin method to reset the rx queue. There appeared to be garbage in it.
Changes to Overlay to have Serial1-4 same as GIGA

Test sketch and picture showing the GIGA with jumpers... Mostly working.

Serial (USB) appears to have a problem, maybe others as well?
The end of the setup function in sketch:

  Serial.println("Test all Serials");
  Serial.print("Baud rate: ");
  Serial.println(SPD, DEC);
  wait_for_user_input();
  Serial1.begin(SPD);
  Serial1.println("Serial1 started");
#ifdef USE_SERIAL2
  //wait_for_user_input();
  Serial2.begin(SPD);
  Serial2.println("Serial2 started");
#endif
#ifdef USE_SERIAL3
  //wait_for_user_input();
  Serial3.begin(SPD);
  Serial3.println("Serial3 started");
#endif
#ifdef USE_SERIAL4
  //wait_for_user_input();
  Serial4.begin(SPD);
  Serial4.println("Serial4 started");
#endif
  wait_for_user_input();
}

But notice the order of the output in the Serial monitor:

Test all Serials
Baud rate: 9600
Waiting...
Waiting...
Serial4 started
Serial3 started
Serial2 started
Serial1 started
abcdefg
Check buffers: 
  9 (9)
  77 (17,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) ** counts different **
	61 62 63 64 65 66 67 0D 0A 
	 a  b  c  d  e  f  g        
	53 65 72 69 61 6C 34 20 73 74 61 72 74 65 64 0D 0A 53 65 72 69 61 6C 33 20 73 74 61 72 74 65 64 0D 0A 53 65 72 69 61 6C 32 20 73 74 61 72 74 65 64 0D 0A 53 65 72 69 61 6C 31 20 73 74 61 72 74 65 64 0D 0A 61 62 63 64 65 66 67 0D 0A 
	 S  e  r  i  a  l  4     s  t  a  r  t  e  d        S  e  r  i  a  l  3     s  t  a  r  t  e  d        S  e  r  i  a  l  2     s  t  a  r  t  e  d        S  e  r  i  a  l  1     s  t  a  r  t  e  d        a  b  c  d  e  f  g        
  26 (17,1,1,1,1,1,1,1,1,1) ** counts different **
	61 62 63 64 65 66 67 0D 0A 
	 a  b  c  d  e  f  g        
	53 65 72 69 61 6C 31 20 73 74 61 72 74 65 64 0D 0A 61 62 63 64 65 66 67 0D 0A 
	 S  e  r  i  a  l  1     s  t  a  r  t  e  d        a  b  c  d  e  f  g        
  43 (17,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) ** counts different **
	61 62 63 64 65 66 67 0D 0A 
	 a  b  c  d  e  f  g        
	53 65 72 69 61 6C 32 20 73 74 61 72 74 65 64 0D 0A 53 65 72 69 61 6C 31 20 73 74 61 72 74 65 64 0D 0A 61 62 63 64 65 66 67 0D 0A 
	 S  e  r  i  a  l  2     s  t  a  r  t  e  d        S  e  r  i  a  l  1     s  t  a  r  t  e  d        a  b  c  d  e  f  g        
  60 (17,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) ** counts different **
	61 62 63 64 65 66 67 0D 0A 
	 a  b  c  d  e  f  g        
	53 65 72 69 61 6C 33 20 73 74 61 72 74 65 64 0D 0A 53 65 72 69 61 6C 32 20 73 74 61 72 74 65 64 0D 0A 53 65 72 69 61 6C 31 20 73 74 61 72 74 65 64 0D 0A 61 62 63 64 65 66 67 0D 0A 
	 S  e  r  i  a  l  3     s  t  a  r  t  e  d        S  e  r  i  a  l  2     s  t  a  r  t  e  d        S  e  r  i  a  l  1     s  t  a  r  t  e  d        a  b  c  d  e  f  g        

Think probably done for the day

1 Like

I am wondering that maybe everytime the main overlay setup is updated, that you might have to update the bootloader on the GIGA, to be able to run the sketches.

Could be wrong, but after I made set of changes for USART/UARTs, the sketches were not working. So I figured I fubred it and, more or less deleted everything and redownloaded the github and ruan through the builds... And it still did not work...

Went to the Ubuntu machine and built there and again it did not work, but I then did the burn the bootloader again on the GIGA, and then downloading was much happier... But again maybe just coincidence.

Could be but with me was even happening when I made a change to the sketch without touching the overlay. So would say something strange.

Now question for me is when @facchinm Zephyr changes are completed and pushed to the main if there are going to other issues or if stuff gets overwritten with the overlay. This is a steep learning curve

1 Like

@KurtE, @facchinm, @ptillisch and others.

This morning while trying to test SPI using an SDCard seems like I can't upload sketches anymore. Even trying the trick of putting the board into boot mode. The upload output says it did it successfully but still runs the previous sketch. Not sure whats going on.

EDIT: Tried reburning the bootloader and not getting red boot light going crazy. Heres the serial output

"C:\Users\Merli\AppData\Local\Arduino15\packages\arduino\tools\dfu-util\0.11.0-arduino5/dfu-util" --device ,0x2341:0x0366 -D "C:\Users\Merli\AppData\Local\Arduino15\packages\arduino\hardware\zephyr\0.1.0/firmwares/zephyr-arduino_giga_r1_m7.bin" -a0 --dfuse-address=0x08040000:leave
dfu-util 0.11-arduino4

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Opening DFU capable USB device...
Device ID 2341:0366
Device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 011a
Device returned transfer size 4096
DfuSe interface name: "Internal Flash  2MB   "
Downloading element to address = 0x08040000, size = 140160

Erase   	[                         ]   0%            0 bytes
Erase   	[                         ]   0%            0 bytes
Erase   	[=                        ]   5%         8192 bytes
Erase   	[==                       ]   8%        12288 bytes
Erase   	[===                      ]  14%        20480 bytes
Erase   	[====                     ]  17%        24576 bytes
Erase   	[=====                    ]  20%        28672 bytes
Erase   	[======                   ]  26%        36864 bytes
Erase   	[=======                  ]  29%        40960 bytes
Erase   	[========                 ]  32%        45056 bytes
Erase   	[=========                ]  37%        53248 bytes
Erase   	[==========               ]  40%        57344 bytes
Erase   	[===========              ]  46%        65536 bytes
Erase   	[============             ]  49%        69632 bytes
Erase   	[=============            ]  52%        73728 bytes
Erase   	[==============           ]  58%        81920 bytes
Erase   	[===============          ]  61%        86016 bytes
Erase   	[================         ]  64%        90112 bytes
Erase   	[=================        ]  70%        98304 bytes
Erase   	[==================       ]  73%       102400 bytes
Erase   	[===================      ]  78%       110592 bytes
Erase   	[====================     ]  81%       114688 bytes
Erase   	[=====================    ]  84%       118784 bytes
Erase   	[======================   ]  90%       126976 bytes
Erase   	[=======================  ]  93%       131072 bytes
Erase   	[======================== ]  96%       135168 bytes
Erase   	[=========================] 100%       140160 bytes
Erase    done.

Download	[                         ]   0%            0 bytes
Download	[=                        ]   5%         8192 bytes
Download	[==                       ]   8%        12288 bytes
Download	[===                      ]  14%        20480 bytes
Download	[====                     ]  17%        24576 bytes
Download	[=====                    ]  20%        28672 bytes
Download	[======                   ]  26%        36864 bytes
Download	[=======                  ]  29%        40960 bytes
Download	[========                 ]  32%        45056 bytes
Download	[=========                ]  37%        53248 bytes
Download	[==========               ]  40%        57344 bytes
Download	[===========              ]  46%        65536 bytes
Download	[============             ]  49%        69632 bytes
Download	[=============            ]  52%        73728 bytes
Download	[==============           ]  58%        81920 bytes
Download	[===============          ]  61%        86016 bytes
Download	[================         ]  64%        90112 bytes
Download	[=================        ]  70%        98304 bytes
Download	[==================       ]  73%       102400 bytes
Download	[===================      ]  78%       110592 bytes
Download	[====================     ]  81%       114688 bytes
Download	[=====================    ]  84%       118784 bytes
Download	[======================   ]  90%       126976 bytes
Download	[=======================  ]  93%       131072 bytes
Download	[======================== ]  96%       135168 bytes
Download	[======================== ]  99%       139264 bytes
Download	[=========================] 100%       140160 bytes
Download done.
File downloaded successfully
Submitting leave request...
Transitioning to dfuMANIFEST state

1 Like

That is what I was seeing when I mentioned:

Try burning the bootloader again from this setup and see what happens...

Still playing with Serial:
I wanted to verify the TX buffer was used and that was pretty sure SerialX.flush() does not
fully work. It only waits until the software TX queue is empty...

void setup() {
  // put your setup code here, to run once:
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  Serial1.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(250);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  Serial1.print("ABCDEFGHIJKLMNOP");
  Serial1.println("qrstuvwxyz");
  digitalWrite(9, LOW);
  Serial1.flush();
  digitalWrite(8, LOW);

}


I think I saw a function that checks for Transmit complete, will try it...

Edit: changed flush to:

void arduino::ZephyrSerial::flush() {
	while (ring_buf_size_get(&tx.ringbuf) > 0) {
		k_yield();
	}
	while (uart_irq_tx_complete(uart) == 0){
		k_yield();
	}
}

Moved it from .h to .cpp as it uses the main device header file... Working better


Will check it in later

@KurtE - @ptillisch
Trying to build now and manually going through .bootstrap.sh. After fixing env issue getting this when trying to install west:

(venv) root@DESKTOP-5R9LQSU:/mnt/d/Github/my_new_zephyr_folder/ArduinoCore-zephyr# pip install west
error: externally-managed-environment

ร— This environment is externally managed
โ•ฐโ”€> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.

    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.

    See /usr/share/doc/python3.12/README.venv for more information.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.

Anyone have an clue.

PS env setup via

`On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

apt install python3.12-venv

EDIT: Got it installed by using installing and using pipx.

2 Likes

Ok spent the morning redoing all installs including ubuntu 24.04 (now on D drive) and putting everything in home directory allows installs and updates to go well without any issues.

After a few false starts updated the overlay file with i2c changes and reflashing new firmware goes well. Output of scanner shows:

I2C Scanner

Scanning Wire...
No I2C devices found

Scanning Wire1...
Device found at address 0x60  (MPL3115,MCP4725,MCP4728,TEA5767,Si5351, BMI150)
done

Scanning Wire2...
Device found at address 0x1C  (LIS3MDL)
Device found at address 0x68  (DS1307,DS3231,MPU6050,MPU9050,BMI270,ITG3200,ITG3701,LSM9DS0,L3G4200D)
done

Now to take a break and then try SDFat.

1 Like

To anyone interested:
Decided to try SPI again and think its broken. Was trying to use SPI1. Tried SDInfo sketch from SDFat and a Nick Gammon test sketch.

With the Nick Gammon test sketch it died on the SPI1.transfer call. So looking at the overlay file again added this:

&spi5 {
	status = "okay";
	pinctrl-0 = <&spi5_nss_pk1 &spi5_sck_ph6
		     &spi5_miso_pj11 &spi5_mosi_pj10>;
	pinctrl-names = "default";
};

recompiled the core and reloaded bootloader and ran the following sketch:


#include <SPI.h>
SPISettings settingsA(3000000, MSBFIRST, SPI_MODE1); 

#define CS 10

void setup (void)
{
  SPI1.begin ();

}

void loop (void)
{

  digitalWrite(CS, HIGH);  // ensure SS stays high
  delay (5000);  // 5 seconds delay to start logic analyser.

  char c;
  SPI1.beginTransaction(settingsA);
  // enable Slave Select
  digitalWrite(CS, LOW);    // SS is pin 10
  // send test string
  for (const char * p = "Giga" ;( c = *p); p++)
    SPI1.transfer (c);
 // disable Slave Select
 digitalWrite(CS, HIGH);
 // turn SPI hardware off
 SPI1.endTransaction();
 
 delay(10);
}

and it seems to work: (Updated LA )

@KurtE - haven't incorporated your changes yet for Serial.

1 Like

To anyone interested:
Can not seem to get SDFat Lib working with Giga with Zephyr - maybe a config issue.

Anyway tried loading the Sdinfo sketch and while it compiles no issues and uploads it seems to hang the Giga, ie, looses the board and port in the ide. Only way to recover is put it into boot mode.

/*
 * This program attempts to initialize an SD card and analyze its structure.
 * The CID and CSD registers are also printed in HEX for use in online
 * decoders like these.
 *
 * https://gurumeditation.org/1342/sd-memory-card-register-decoder/
 * https://archive.goughlui.com/static/multicid.htm
 */
#include "SdFat.h"
#include "sdios.h"
/*
  Set DISABLE_CS_PIN to disable a second SPI device.
  For example, with the Ethernet shield, set DISABLE_CS_PIN
  to 10 to disable the Ethernet controller.
*/
const int8_t DISABLE_CS_PIN = -1;
/*
  Change the value of SD_CS_PIN if you are using SPI
  and your hardware does not use the default value, SS.
  Common values are:
  Arduino Ethernet shield: pin 4
  Sparkfun SD shield: pin 8
  Adafruit SD shields and modules: pin 10
*/
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
const uint8_t SD_CS_PIN = 10;

// Try to select the best SD card configuration.
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(16), &SPI1)
//#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SD_SCK_MHZ(16), &SPI1)


void hexDmp(void* reg, uint8_t size);
//------------------------------------------------------------------------------
SdFs sd;
cid_t cid;
csd_t csd;
scr_t scr;
uint8_t cmd6Data[64];
uint32_t eraseSize;
uint32_t ocr;
static ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
void cidDmp() {
  cout << F("\nManufacturer ID: ");
  cout << uppercase << showbase << hex << int(cid.mid) << dec << endl;
  cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
  cout << F("Product: ");
  for (uint8_t i = 0; i < 5; i++) {
    cout << cid.pnm[i];
  }
  cout << F("\nRevision: ") << cid.prvN() << '.' << cid.prvM() << endl;
  cout << F("Serial number: ") << hex << cid.psn() << dec << endl;
  cout << F("Manufacturing date: ");
  cout << cid.mdtMonth() << '/' << cid.mdtYear() << endl;
  cout << F("CID HEX: ");
  hexDmp(&cid, sizeof(cid));
}
//------------------------------------------------------------------------------
void clearSerialInput() {
  uint32_t m = micros();
  do {
    if (Serial.read() >= 0) {
      m = micros();
    }
  } while (micros() - m < 10000);
}
//------------------------------------------------------------------------------
void csdDmp() {
  eraseSize = csd.eraseSize();
  cout << F("\ncardSize: ") << 0.000512 * csd.capacity();
  cout << F(" MB (MB = 1,000,000 bytes)\n");

  cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n");
  cout << F("eraseSingleBlock: ");
  if (csd.eraseSingleBlock()) {
    cout << F("true\n");
  } else {
    cout << F("false\n");
  }
  cout << F("dataAfterErase: ");
  if (scr.dataAfterErase()) {
    cout << F("ones\n");
  } else {
    cout << F("zeros\n");
  }
  cout << F("CSD HEX: ");
  hexDmp(&csd, sizeof(csd));
}
//------------------------------------------------------------------------------
void errorPrint() {
  if (sd.sdErrorCode()) {
    cout << F("SD errorCode: ") << hex << showbase;
    printSdErrorSymbol(&Serial, sd.sdErrorCode());
    cout << F(" = ") << int(sd.sdErrorCode()) << endl;
    cout << F("SD errorData = ") << int(sd.sdErrorData()) << dec << endl;
  }
}
//------------------------------------------------------------------------------
void hexDmp(void* reg, uint8_t size) {
  uint8_t* u8 = reinterpret_cast<uint8_t*>(reg);
  cout << hex << noshowbase;
  for (size_t i = 0; i < size; i++) {
    cout << setw(2) << setfill('0') << int(u8[i]);
  }
  cout << dec << endl;
}
//------------------------------------------------------------------------------
bool mbrDmp() {
  MbrSector_t mbr;
  bool valid = true;
  if (!sd.card()->readSector(0, (uint8_t*)&mbr)) {
    cout << F("\nread MBR failed.\n");
    errorPrint();
    return false;
  }
  cout << F("\nSD Partition Table\n");
  cout << F("part,boot,bgnCHS[3],type,endCHS[3],start,length\n");
  for (uint8_t ip = 1; ip < 5; ip++) {
    MbrPart_t* pt = &mbr.part[ip - 1];
    if ((pt->boot != 0 && pt->boot != 0X80) ||
        getLe32(pt->relativeSectors) > csd.capacity()) {
      valid = false;
    }
    cout << int(ip) << ',' << uppercase << showbase << hex;
    cout << int(pt->boot) << ',';
    for (int i = 0; i < 3; i++) {
      cout << int(pt->beginCHS[i]) << ',';
    }
    cout << int(pt->type) << ',';
    for (int i = 0; i < 3; i++) {
      cout << int(pt->endCHS[i]) << ',';
    }
    cout << dec << getLe32(pt->relativeSectors) << ',';
    cout << getLe32(pt->totalSectors) << endl;
  }
  if (!valid) {
    cout << F("\nMBR not valid, assuming Super Floppy format.\n");
  }
  return true;
}
//------------------------------------------------------------------------------
void dmpVol() {
  cout << F("\nScanning FAT, please wait.\n");
  int32_t freeClusterCount = sd.freeClusterCount();
  if (sd.fatType() <= 32) {
    cout << F("\nVolume is FAT") << int(sd.fatType()) << endl;
  } else {
    cout << F("\nVolume is exFAT\n");
  }
  cout << F("sectorsPerCluster: ") << sd.sectorsPerCluster() << endl;
  cout << F("fatStartSector:    ") << sd.fatStartSector() << endl;
  cout << F("dataStartSector:   ") << sd.dataStartSector() << endl;
  cout << F("clusterCount:      ") << sd.clusterCount() << endl;
  cout << F("freeClusterCount:  ");
  if (freeClusterCount >= 0) {
    cout << freeClusterCount << endl;
  } else {
    cout << F("failed\n");
    errorPrint();
  }
}
//------------------------------------------------------------------------------
void printCardType() {
  cout << F("\nCard type: ");

  switch (sd.card()->type()) {
    case SD_CARD_TYPE_SD1:
      cout << F("SD1\n");
      break;

    case SD_CARD_TYPE_SD2:
      cout << F("SD2\n");
      break;

    case SD_CARD_TYPE_SDHC:
      if (csd.capacity() < 70000000) {
        cout << F("SDHC\n");
      } else {
        cout << F("SDXC\n");
      }
      break;

    default:
      cout << F("Unknown\n");
  }
}
//------------------------------------------------------------------------------
void printConfig(SdSpiConfig config) {
  if (DISABLE_CS_PIN < 0) {
    cout << F(
        "\nAssuming the SD is the only SPI device.\n"
        "Edit DISABLE_CS_PIN to disable an SPI device.\n");
  } else {
    cout << F("\nDisabling SPI device on pin ");
    cout << int(DISABLE_CS_PIN) << endl;
    pinMode(DISABLE_CS_PIN, OUTPUT);
    digitalWrite(DISABLE_CS_PIN, HIGH);
  }
  cout << F("\nAssuming the SD chip select pin is: ") << int(config.csPin);
  cout << F("\nEdit SD_CS_PIN to change the SD chip select pin.\n");
}
//------------------------------------------------------------------------------
void printConfig(SdioConfig config) {
  (void)config;
  cout << F("Assuming an SDIO interface.\n");
}
//-----------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  // Wait for USB Serial
  while (!Serial) {
    yield();
  }
  cout << F("SdFat version: ") << SD_FAT_VERSION_STR << endl;
  printConfig(SD_CONFIG);
}
//------------------------------------------------------------------------------
void loop() {
  // Read any existing Serial data.
  clearSerialInput();

  // F stores strings in flash to save RAM
  cout << F("\ntype any character to start\n");
  while (!Serial.available()) {
    yield();
  }
  uint32_t t = millis();
  if (!sd.cardBegin(SD_CONFIG)) {
    cout << F(
        "\nSD initialization failed.\n"
        "Do not reformat the card!\n"
        "Is the card correctly inserted?\n"
        "Is there a wiring/soldering problem?\n");
    if (isSpi(SD_CONFIG)) {
      cout << F(
          "Is SD_CS_PIN set to the correct value?\n"
          "Does another SPI device need to be disabled?\n");
    }
    errorPrint();
    return;
  }
  t = millis() - t;
  cout << F("init time: ") << dec << t << " ms" << endl;

  if (!sd.card()->readCID(&cid) || !sd.card()->readCSD(&csd) ||
      !sd.card()->readOCR(&ocr) || !sd.card()->readSCR(&scr)) {
    cout << F("readInfo failed\n");
    errorPrint();
    return;
  }
  printCardType();
  cout << F("sdSpecVer: ") << 0.01 * scr.sdSpecVer() << endl;
  cout << F("HighSpeedMode: ");
  if (scr.sdSpecVer() > 101 && sd.card()->cardCMD6(0X00FFFFFF, cmd6Data) &&
      (2 & cmd6Data[13])) {
    cout << F("true\n");
  } else {
    cout << F("false\n");
  }
  cidDmp();
  csdDmp();
  cout << F("\nOCR: ") << uppercase << showbase;
  cout << hex << ocr << dec << endl;
  if (!mbrDmp()) {
    return;
  }
  if (!sd.volumeBegin()) {
    cout << F("\nvolumeBegin failed. Is the card formatted?\n");
    errorPrint();
    return;
  }
  dmpVol();
}
1 Like

I tried similar with Adafruit_ILI9341 library. Similar issues with it crashing and burning:

Debugging...

EDIT: I keep wondering, if we should for example define the missing objects like spi1, only in overly or should add them to dts file in the zephyr project and refer to it.

EDIT2: Wondering when I build sketches, using the cores generated...
I get message like:

"C:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\zephyr\\tools\\arm-zephyr-eabi\\0.16.8/bin/arm-zephyr-eabi-strip" --strip-debug "C:\\Users\\kurte\\AppData\\Local\\arduino\\sketches\\59A5D9CE3B014BC1329DABB11A4D1E96/ili9341_graphicstest.ino.elf" "-oC:\\Users\\kurte\\AppData\\Local\\arduino\\sketches\\59A5D9CE3B014BC1329DABB11A4D1E96/ili9341_graphicstest.ino.llext"
Bootloader file specified but missing: C:\Users\kurte\Documents\Arduino\hardware\arduino-git\ArduinoCore-zephyr\bootloaders\zephyr-arduino_giga_r1_m7.bin
"C:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\zephyr-post-build-tool\\0.0.2/post_build" "C:\\Users\\kurte\\AppData\\Local\\arduino\\sketches\\59A5D9CE3B014BC1329DABB11A4D1E96/ili9341_graphicstest.ino.llext"
File copied and saved as C:\Users\kurte\AppData\Local\arduino\sketches\59A5D9CE3B014BC1329DABB11A4D1E96/ili9341_graphicstest.ino.llext.dfu

It appears like it builds it into the firmwares directory:

1 Like

SPI killing the board...
Here is simple sketch:

#include "SPI.h"
//#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

// For the Adafruit shield, these are the default.
#define TFT_DC 8
#define TFT_RST 9
#define TFT_CS 10

Adafruit_ILI9341 *ptft = nullptr; 

void step() {
  Serial.println("Waiting...");
  while (Serial.available() == 0) {}
  while (Serial.available() != 0) {Serial.read();}
}

void setup() {
  Serial.begin(115200);
  delay(250);
  Serial.println("After Serial begin");
  SPI1.begin();
  Serial.println("After SPI1 begin");
  SPI1.beginTransaction(SPISettings(3000000, MSBFIRST, SPI_MODE0));
  Serial.println("After begin Transaction");
  step();
  ptft = new Adafruit_ILI9341(&SPI1, TFT_DC, TFT_CS, TFT_RST);
  Serial.println("After new");
  Serial.println("Before tft begin"); Serial.flush(); 
  //ptft->begin(20000000);
  Serial.println("After ptft->begin");
}


void loop() {
  //ptft->fillScreen(ILI9341_RED);
  delay(500);
  //ptft->fillScreen(ILI9341_GREEN);
  delay(500);
  //ptft->fillScreen(ILI9341_BLUE);
  delay(500);
  //ptft->fillScreen(ILI9341_BLACK);
  delay(500);
}

I had all of hte references to the Adafruit library commented out and it runs.
I had it up until this step where I uncommented the new and it still ran
However uncommenting the line:
ptft = new Adafruit_ILI9341(&SPI1, TFT_DC, TFT_CS, TFT_RST);
And it crashes. No serial output at all even though I have it coded up to wait until after it waits for input...

Edit: Meant to say, now to try with different library. I have a version of my own ILI... that I earlier

1 Like