I'm sorry. That is my whole code the reason therefor ist, that if I just extract the IRAM_ATTR TCPulseISR(), calculatepulse() and my "UART Switch" it works fine...
Maybe I should explain what my code is doing: The ESP is used as a slave in an SPI communication. In the first step, it receives 16 bits from the master and in the next transaction, the ESP sends 18x 16 bits back to the master. Since there have already been timing problems with the Chip Select Signal, a workaround was necessary. With this workaround, a continuous CS signal is then generated so that the ESP can send the 18x 16 bits without any problems. After those transactions the master sends a pulse to the ESP, which I would like to measure...
#include <ESP32SPISlave.h>
ESP32SPISlave slave;
#define RXD2 32 //GPIO32
#define TXD2 33 //GPIO33
static constexpr uint8_t BUFFER_SIZE {37};
uint8_t spi_slave_tx_buf[BUFFER_SIZE];
uint8_t spi_slave_rx_buf[BUFFER_SIZE];
uint8_t spi_slave_rx_backup_buf[BUFFER_SIZE];
uint8_t TCMirrorMSB1 = 0;
uint8_t TCMirrorMSB2 = 0;
uint8_t TCMirrorLSB1 = 0;
uint8_t TCMirrorLSB2 = 0;
uint8_t TMData[37] = { 0x0A, 0x0A, 0x10, 0x10, 0x2A, 0x2A, 0x3F, 0x3F, 0x4A, 0x4A, 0x5F, 0x5F, 0x6A, 0x6A, 0x7F, 0x7F, 0x8A, 0x8A, 0x9F, 0x9F, 0xAA, 0xAA, 0xBF, 0xBF, 0xCA, 0xCA, 0xDF, 0xDF, 0 , 0, 0, 0, 0xEA, 0xEA, 0xFF, 0xFF};
uint8_t messageEGSE[15];
uint8_t message[15];
uint8_t sum = 0;
uint8_t previous = 0;
uint8_t j = 0;
uint8_t counterLADU = 0;
int Direction = 17;
uint8_t DirectionSignal = 1;
bool laduCS = true;
bool help = false;
bool addTR = false;
bool pulse = false;
bool printtime = false;
unsigned long starttime = 0;
unsigned long endtime = 0;
unsigned long pulseduration;
uint8_t durationLSB = 0;
uint8_t durationMSB = 0;
uint8_t TCexecuted = 0;
unsigned long startcycle = 0;
unsigned long endcycle = 0;
// ISR for TC Pulse
void IRAM_ATTR TCPulseISR() {
pulse = (GPIO.in >> 4) & 1; //if PIN == HIGH -> pulse = true
if (pulse == true) {
starttime = micros();
TCexecuted = 1;
printtime = false;
} else {
endtime = micros();
printtime = true;
}
}
void IRAM_ATTR laduCSISR() {
laduCS = false;
if (DirectionSignal == HIGH) {
if (help == false) {
GPIO.out_w1tc = 1 << 5;
help = true;
} else {
GPIO.out_w1ts = 1 << 5;
help = false;
addTR = true;
}
}
if (DirectionSignal == LOW) {
if (counterLADU < 36) {
counterLADU = counterLADU + 1;
GPIO.out_w1tc = 1 << 5; // PIN 5 = 0
}
if (counterLADU > 35) {
counterLADU = 0;
GPIO.out_w1ts = 1 << 5; //PIN 5 = 1
laduCS = true; //otherwise laduCS is not updatet due to position of pin query in ISR
}
} //End LOW
} // End ISR
void resetMessage() {
memset(message, 0, 14);
message[0] = 0x24;
message[2] = 0xE;
message[4] = 1;
message[13] = 0x0D;
}
//Build the Checksum of the Message
void checksum() {
previous = message[0] ^ message[1];
for (uint8_t i = 2; i < 11; i++) {
sum = previous ^ message[i];
previous = sum;
}
message[11] = (sum & 0xF0) >> 4;
message[12] = (sum & 0x0F);
}
//Send received data via UART
void sendTC() {
message[6] = 0;
message[7] = (spi_slave_rx_backup_buf[0] & 0xF0) >> 4;
message[8] = (spi_slave_rx_backup_buf[0] & 0x0F);
message[9] = (spi_slave_rx_backup_buf[1] & 0xF0) >> 4;
message[10] = (spi_slave_rx_backup_buf[1] & 0x0F);
checksum();
Serial2.write(message[0]);
for (uint8_t i = 1; i < 13; i++) {
Serial2.print(message[i], HEX);
}
Serial2.write(message[13]);
}
//calculate and transmit pulse duration via UART
void calculatepulse() {
if (printtime == true) {
pulseduration = endtime - starttime;
durationLSB = (pulseduration & 0x00FF);
durationMSB = (pulseduration & 0xFF00) >> 8;
printtime = false;
}
// message[6] = 1;
// message[7] = (durationMSB & 0xF0) >> 4;
// message[8] = (durationMSB & 0x0F);
// message[9] = (durationLSB & 0xF0) >> 4;
// message[10] = (durationLSB & 0x0F);
// checksum();
// //Serial2.write(message, 12);
// Serial2.write(message[0]);
// for (uint8_t i = 1; i < 13; i++) {
// Serial2.print(message[i], HEX);
// }
// Serial2.write("\r");
Serial.println(pulseduration);
}
//send TCexecuted Flag via UART
void sendFlag() {
message[6] = 2;
message[10] = TCexecuted;
checksum();
//Serial2.write(message, 12);
Serial2.write(message[0]);
for (uint8_t i = 1; i < 13; i++) {
Serial2.print(message[i], HEX);
}
Serial2.write("\r");
}
//Send TM Data
void sendTMData() {
for (uint8_t k = 0; k < 36; k = k + 2) {
message[5] = ((3 + j) & 0xF0) >> 4;
message[6] = ((3 + j) & 0x0F);
message[7] = (TMData[k] & 0xF0) >> 4;
message[8] = (TMData[k] & 0x0F);
message[9] = (TMData[k + 1] & 0xF0) >> 4;
message[10] = (TMData[k + 1] & 0x0F);
checksum();
// Serial2.write(message, 12);
Serial2.write(message[0]);
for (uint8_t i = 1; i < 13; i++) {
Serial2.print(message[i], HEX);
}
Serial2.write("\r");
resetMessage();
j++;
}
j = 0;
}
void sendTMDataN(uint8_t caseNumber, uint8_t n) {
message[5] = (caseNumber & 0xF0) >> 4;
message[6] = (caseNumber & 0x0F);
message[7] = (TMData[n] & 0xF0) >> 4;
message[8] = (TMData[n] & 0x0F);
message[9] = (TMData[n + 1] & 0xF0) >> 4;
message[10] = (TMData[n + 1] & 0x0F);
checksum();
//Serial2.write(message, 12);
Serial2.write(message[0]);
for (uint8_t i = 1; i < 13; i++) {
Serial2.print(message[i], HEX);
}
Serial2.write("\r");
resetMessage();
}
void setup() {
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);
delay(2000);
// begin() after setting
// HSPI = CS: 15, CLK: 14, MOSI: 13, MISO: 12
slave.setDataMode(SPI_MODE2); //CPOL = 1, CPHA = 0
slave.setQueueSize(1); // transaction queue size
slave.begin(); // default SPI is HSPI
// clear buffers
memset(spi_slave_tx_buf, 0, BUFFER_SIZE);
memset(spi_slave_rx_buf, 0, BUFFER_SIZE);
memset(spi_slave_rx_backup_buf, 0, BUFFER_SIZE);
//clear and define UART Messages
memset(messageEGSE, 0, 14);
memset(message, 0, 14);
message[0] = 0x24;
message[2] = 0xE;
message[4] = 1;
message[13] = 0x0D;
//Direction signal
pinMode(Direction, INPUT);
pinMode(16, INPUT);
attachInterrupt(16, laduCSISR, CHANGE);
pinMode(5, OUTPUT);
GPIO.out_w1ts = 1 << 5; //CS active LOW, set CS HIGH
// TC Pulse
pinMode(4, INPUT);
attachInterrupt(4, TCPulseISR, CHANGE);
}
void loop() {
//Send every Second: Backupbuf, pulseduration, TMData
// endcycle = millis();
// if (endcycle - startcycle > 2000) { //1s
// sendTC();
// resetMessage();
// calculatepulse();
// resetMessage();
// sendTMData();
// sendTMDataN(16, 26);
// startcycle = millis();
// }
DirectionSignal = (GPIO.in >> 17) & 1; //pin query
while (laduCS == false) { //as long as LaduCS is low
DirectionSignal = (GPIO.in >> 17) & 1; //pin query
//If Direction HIGH, send no Data to Master. Store Recieved Data in spi_slave_rx_backup_buf
if (DirectionSignal == HIGH) {
if (addTR == true) {
TCexecuted = 0;
memcpy(spi_slave_rx_backup_buf, spi_slave_rx_buf, 2);
//Define TC Mirror first(MSB) and second (LSB) Byte with Identifier
TCMirrorMSB1 = 0b11101000 | ((spi_slave_rx_backup_buf[0] & 0b11000000) >> 6);
TCMirrorMSB2 = 0b00000001 | ((spi_slave_rx_backup_buf[0] & 0b00111111) << 2);
TCMirrorLSB1 = 0b11100100 | ((spi_slave_rx_backup_buf[1] & 0b11000000) >> 6);
TCMirrorLSB2 = 0b00000001 | ((spi_slave_rx_backup_buf[1] & 0b00111111) << 2);
//Init Mirror
TMData[28] = TCMirrorMSB1; //15 TCMirror MSB
TMData[29] = TCMirrorMSB2;
TMData[30] = TCMirrorLSB1; //16 TCMirror LSB
TMData[31] = TCMirrorLSB2;
for (uint8_t i = 0; i < 36; i++) {
spi_slave_tx_buf[i] = TMData[i];
}
slave.queue(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE); //Add Transaction to queue
addTR = false;
laduCS = true;
}// End Add Transaction
}// End Direction HIGH
// If Direction LOW, compare Data in spi_slave_rx_backup_buf and send Data to Master
if (DirectionSignal == LOW) {
if (slave.remained() == 0) { //is there no transaction in queue?
slave.queue(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE); //add transaction
} //end if remained
}// end if LOW
// if transaction has completed from master,
// available() returns size of results of transaction,
// and buffer is automatically updated
}//end while LaduCS is low
while (slave.available()) {
slave.queue(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE); //add transaction
slave.pop();
}//end while available
while (Serial2.available()) {
Serial2.readBytes(messageEGSE, 14);
switch (messageEGSE[6]) {
case 0: sendTC();
resetMessage(); break;
case 1: calculatepulse();
resetMessage(); break;
case 2: sendFlag();
resetMessage(); break;
case 3: sendTMDataN(3, 0); break;
case 4: sendTMDataN(4, 2); break;
case 5: sendTMDataN(5, 4); break;
case 6: sendTMDataN(6, 6); break;
case 7: sendTMDataN(7, 8); break;
case 8: sendTMDataN(8, 10); break;
case 9: sendTMDataN(9, 12); break;
case 10: sendTMDataN(10, 14); break;
case 11: sendTMDataN(11, 16); break;
case 12: sendTMDataN(12, 18); break;
case 13: sendTMDataN(13, 20); break;
case 14: sendTMDataN(14, 22); break;
case 15: sendTMDataN(15, 24); break;
case 16: sendTMDataN(16, 26); break;
case 17: sendTMDataN(17, 28); break;
case 18: sendTMDataN(18, 30); break;
case 19: sendTMDataN(19, 32); break;
case 20: sendTMDataN(20, 34); break;
default: Serial.println("Error in cmd");
}
}
} //end loop
And in order to be able to test more easily, I have commented out some parts