I am using Arduino ESP32 on a Lilygo T-Beam v1.0 ESP32 (same problem on an older v0.7 T-Beam).
Seems like using VSPI and HSPI concurrently on two different cores fails.
I am using HSPI to communicate with the T-Beam's on-board SX1278 (a task on core 0) and VSPI to communicate with an external 2" ILI9225 TFT display. SX1278 communication is working perfectly while the Arduino main loop (on core 1) is idle in an delay(), but when the Arduinio main loop is communicating with the display using VSPI, all SPI read operation in the SX1278 task return 0 (my measurent means are somewhat limited, but on my analog oscilloscope it seems like the chip select is not pulled to low on the SX1278 while the display is active!?????).
The problem originally arouse in a larger project, but I was able it to reduce it to the following lines of code (arduinio sketch):
Code: Select all
#include <axp20x.h>
#include <SPI.h>
#include <TFT_22_ILI9225.h>
#include <../fonts/FreeSans9pt7b.h>
SPIClass sxspi(HSPI);
SPIClass spiDisp(VSPI);
AXP20X_Class axp;
TFT_22_ILI9225 *tft;
#define REG_OP_MODE 0x01
const uint8_t FSK_SLEEP_MODE = 0x00;
const uint8_t FSK_STANDBY_MODE = 0x01;
#define REG_RSSI_VALUE_FSK 0x11
#define REG_FRF_MSB 0x06
#define REG_FRF_MID 0x07
#define REG_FRF_LSB 0x08
#define REG_OCP 0x0B
#define SX127X_CRYSTAL_FREQ 32000000
#define SX127X_FSTEP (SX127X_CRYSTAL_FREQ*1.0/(1<<19))
#define SX1278_SS SS
class SX1278FSK {
private:
SPIClass _spi;
SPISettings spiset;
public:
void begin(SPIClass &spi) {
spiset = SPISettings(10000000L, MSBFIRST, SPI_MODE0);
pinMode(SX1278_SS, OUTPUT);
digitalWrite(SX1278_SS, HIGH);
_spi = spi;
_spi.begin(SCK, MISO, MOSI, SS);
_spi.setBitOrder(MSBFIRST);
_spi.setClockDivider(SPI_CLOCK_DIV4);
_spi.setDataMode(SPI_MODE0);
delay(100);
int rate = 0x1B;
rate |= B00100000;
writeRegister(REG_OP_MODE, FSK_SLEEP_MODE); // Sleep mode (mandatory to change mode)
writeRegister(REG_OP_MODE, FSK_SLEEP_MODE);
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); // Set FSK Standby mode to write in registers
writeRegister(REG_OCP, rate); // Modifying maximum current supply
int x = readRegister(REG_OP_MODE);
delay(100);
}
byte readRegister(byte address) {
byte value = 0x00;
_spi.beginTransaction(spiset);
digitalWrite(SX1278_SS, LOW);
bitClear(address, 7); // Bit 7 cleared to write in registers
_spi.transfer(address);
value = _spi.transfer(0x00);
digitalWrite(SX1278_SS, HIGH);
_spi.endTransaction();
//Serial.printf("Register %02x reads value %02x\n", address, value);
return value;
}
void writeRegister(byte address, byte data) {
_spi.beginTransaction(spiset);
digitalWrite(SX1278_SS, LOW);
bitSet(address, 7); // Bit 7 set to read from registers
_spi.transfer(address);
_spi.transfer(data);
digitalWrite(SX1278_SS, HIGH);
_spi.endTransaction();
//Serial.printf("Register %02x: writing value %02x\n", address&0x7f, data);
}
uint8_t setFrequency(float freq) {
// set mode to FSK STANDBY
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);
uint32_t frf = freq * 1.0 * (1 << 19) / SX127X_CRYSTAL_FREQ;
writeRegister(REG_FRF_MSB, (frf & 0xff0000) >> 16);
writeRegister(REG_FRF_MID, (frf & 0x00ff00) >> 8);
writeRegister(REG_FRF_LSB, (frf & 0x0000ff));
return 0;
}
float getFrequency() {
uint8_t fmsb = readRegister(REG_FRF_MSB);
uint8_t fmid = readRegister(REG_FRF_MID);
uint8_t flsb = readRegister(REG_FRF_LSB);
return ((fmsb << 16) | (fmid << 8) | flsb) * 1.0 / (1 << 19) * SX127X_CRYSTAL_FREQ;
}
};
SX1278FSK sx1278;
void sx1278Task(void *parameter) {
while (1)
{
sx1278.setFrequency(403300000);
float f = sx1278.getFrequency();
Serial.printf(" freq:%f\n", f);
delay(100);
}
}
void setup()
{
Serial.begin(115200);
// For T-Beam 1.0 => Enable 3.3V on DCDC1 for display
Wire.begin(21, 22);
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) {
Serial.println("AXP192 Begin PASS");
} else {
Serial.println("AXP192 Begin FAIL");
}
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
axp.setDCDC1Voltage(3300);
// setup display
tft = new TFT_22_ILI9225(14, 2, 0, 4, 13, 0, 100);
tft->begin(spiDisp);
tft->setOrientation(1);
tft->clear();
tft->setGFXFont(&FreeSans9pt7b);
// setup sx1278
sx1278.begin(sxspi);
delay(100);
sx1278.setFrequency(403700000);
xTaskCreatePinnedToCore( sx1278Task, "sx1278Task",
10000, /* stack size */
NULL, /* paramter */
1, /* priority */
NULL, 0); /* task handle*/
}
#define XSKIP 14
#define YSKIP 22
void drawString(uint8_t x, uint8_t y, const char *s) {
int16_t w, h;
tft->getGFXTextExtent(s, x * XSKIP, y * YSKIP, &w, &h);
int len = strlen(s);
tft->fillRectangle(x * XSKIP, y * YSKIP + 3, x * XSKIP + len * 14, y * YSKIP + 22, COLOR_BLACK);
tft->drawGFXText(x * XSKIP, (1 + y)*YSKIP, s, COLOR_WHITE);
}
void loop() {
Serial.printf("Mainloop...\n");
for (int i = 0; i < 50; i++) {
char buf[50];
sprintf(buf, "cnt: %d ", i);
drawString(0, 1, buf);
}
Serial.printf("Mainloop delay\n");
delay(1000);
}
The output on the console is the following:
Code: Select all
22:27:52.459 -> Mainloop...
22:27:52.459 -> freq:0.000000
22:27:52.562 -> freq:0.000000
22:27:52.634 -> freq:0.000000
22:27:52.737 -> freq:0.000000
22:27:52.846 -> freq:0.000000
22:27:52.953 -> freq:0.000000
22:27:53.060 -> freq:0.000000
22:27:53.129 -> freq:0.000000
22:27:53.237 -> freq:0.000000
22:27:53.343 -> freq:0.000000
22:27:53.444 -> freq:0.000000
22:27:53.554 -> freq:0.000000
22:27:53.628 -> Mainloop delay
22:27:53.661 -> freq:403300000.000000
22:27:53.734 -> freq:403300000.000000
22:27:53.838 -> freq:403300000.000000
22:27:53.945 -> freq:403300000.000000
22:27:54.052 -> freq:403300000.000000
22:27:54.157 -> freq:403300000.000000
22:27:54.232 -> freq:403300000.000000
22:27:54.339 -> freq:403300000.000000
22:27:54.450 -> freq:403300000.000000
22:27:54.552 -> freq:403300000.000000
22:27:54.628 -> Mainloop...
22:27:54.665 -> freq:0.000000
22:27:54.733 -> freq:0.000000
22:27:54.839 -> freq:403300000.000000
22:27:54.941 -> freq:403300000.000000
22:27:55.045 -> freq:403300000.000000
22:27:55.154 -> freq:0.000000
22:27:55.256 -> freq:0.000000
22:27:55.360 -> freq:0.000000
22:27:55.461 -> freq:0.000000
22:27:55.560 -> freq:0.000000
22:27:55.662 -> freq:0.000000
22:27:55.730 -> freq:0.000000
22:27:55.833 -> Mainloop delay
22:27:55.833 -> freq:403300000.000000
22:27:55.937 -> freq:403300000.000000
22:27:56.040 -> freq:403300000.000000
22:27:56.142 -> freq:403300000.000000
22:27:56.245 -> freq:403300000.000000
22:27:56.346 -> freq:403300000.000000
22:27:56.447 -> freq:403300000.000000
22:27:56.549 -> freq:403300000.000000
22:27:56.651 -> freq:403300000.000000
22:27:56.754 -> freq:403300000.000000