1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-27 01:56:14 +01:00

Make own interrupt routine selection array as RMT api only can have one interrupt routine with one argument

This commit is contained in:
Harald Barth 2022-08-02 01:22:36 +02:00
parent e5ce76e703
commit 33c9155f6e
2 changed files with 18 additions and 9 deletions

View File

@ -57,9 +57,15 @@ void setEOT(rmt_item32_t* item) {
item->val = 0;
}
// This is an array that contains the this pointers
// to all uses channel objects. This is used to determine
// which of the channels was triggering the ISR as there
// is only ONE common ISR routine for all channels.
RMTChannel *channelHandle[8] = { 0 };
void IRAM_ATTR interrupt(rmt_channel_t channel, void *t) {
RMTChannel *tt = (RMTChannel *)t;
tt->RMTinterrupt();
RMTChannel *tt = channelHandle[channel];
if (tt) tt->RMTinterrupt();
}
RMTChannel::RMTChannel(byte pin, bool isMain) {
@ -133,18 +139,17 @@ RMTChannel::RMTChannel(byte pin, bool isMain) {
DIAG(F("Register interrupt on core %d"), xPortGetCoreID());
ESP_ERROR_CHECK(rmt_set_tx_loop_mode(channel, true));
rmt_register_tx_end_callback(interrupt, this);
channelHandle[channel] = this; // used by interrupt
rmt_register_tx_end_callback(interrupt, 0);
rmt_set_tx_intr_en(channel, true);
DIAG(F("Starting channel %d signal generator"), config.channel);
DIAG(F("Starting channel %d signal generator for %s"), config.channel, isMainTrack ? "MAIN" : "PROG");
// send one bit to kickstart the signal, remaining data will come from the
// packet queue. We intentionally do not wait for the RMT TX complete here.
//rmt_write_items(channel, preamble, preambleLen, false);
RMTprefill();
preambleNext = true;
dataReady = false;
RMTinterrupt();
}
void RMTChannel::RMTprefill() {
@ -161,10 +166,10 @@ int RMTChannel::RMTfillData(const byte buffer[], byte byteCount, byte repeatCoun
// to the HW. dataRepeat on the other hand signals back to
// the caller of this function if the data has been sent enough
// times (0 to 3 means 1 to 4 times in total).
if (dataReady == true)
return 1000;
if (dataRepeat > 0) // we have still old work to do
return dataRepeat;
if (dataReady == true) // the packet is not copied out yet
return 1000;
if (DATA_LEN(byteCount) > maxDataLen) { // this would overun our allocated memory for data
DIAG(F("Can not convert DCC bytes # %d to DCC bits %d, buffer too small"), byteCount, maxDataLen);
return -1; // something very broken, can not convert packet

View File

@ -36,6 +36,11 @@ class RMTChannel {
void RMTprefill();
//int RMTfillData(dccPacket packet);
int RMTfillData(const byte buffer[], byte byteCount, byte repeatCount);
inline bool busy() {
if (dataRepeat > 0) // we have still old work to do
return true;
return dataReady;
};
private:
@ -50,7 +55,6 @@ class RMTChannel {
byte dataLen;
byte maxDataLen;
// flags
volatile bool preambleNext = true; // alternate between preamble and content
volatile bool dataReady = false; // do we have real data available or send idle
volatile byte dataRepeat = 0;
};