1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-25 05:31:24 +01:00

transmit preamble and idle

This commit is contained in:
Harald Barth 2021-11-14 14:48:32 +01:00
parent 4668e116f4
commit 97065e892d
3 changed files with 28 additions and 43 deletions

View File

@ -41,34 +41,37 @@ void setDCCBit0(rmt_item32_t* item) {
item->duration1 = DCC_0_HALFPERIOD; item->duration1 = DCC_0_HALFPERIOD;
} }
void setEOT(rmt_item32_t* item) {
item->val = 0;
}
void IRAM_ATTR interrupt(rmt_channel_t channel, void *t) { void IRAM_ATTR interrupt(rmt_channel_t channel, void *t) {
BaseType_t wtf = pdFALSE;
RMTPin *tt = (RMTPin *)t; RMTPin *tt = (RMTPin *)t;
//DIAG(F("interrupt %d"), tt->idleLen); tt->RMTinterrupt(channel);
tt->RMTinterrupt(channel,t);
rmt_tx_start(channel,true);
portYIELD_FROM_ISR(wtf);
} }
RMTPin::RMTPin(byte pin, byte ch, byte plen) { RMTPin::RMTPin(byte pin, byte ch, byte plen) {
// preamble // preamble
preambleLen = plen+1; preambleLen = plen+2; // plen 1 bits, one 0 bit and one EOF marker
preamble = (rmt_item32_t*)malloc(preambleLen*sizeof(rmt_item32_t)); preamble = (rmt_item32_t*)malloc(preambleLen*sizeof(rmt_item32_t));
for (byte n=0; n<plen; n++) for (byte n=0; n<plen; n++)
setDCCBit1(preamble + n); setDCCBit1(preamble + n); // preamble bits
setDCCBit0(preamble + plen); setDCCBit0(preamble + plen); // start of packet 0 bit
setEOT(preamble + plen + 1); // EOT marker
// idle // idle
idleLen = 28; idleLen = 29;
idle = (rmt_item32_t*)malloc(idleLen*sizeof(rmt_item32_t)); idle = (rmt_item32_t*)malloc(idleLen*sizeof(rmt_item32_t));
for (byte n=0; n<8; n++) // 0 to 7 for (byte n=0; n<8; n++) // 0 to 7
setDCCBit1(idle + n); setDCCBit1(idle + n);
for (byte n=8; n<18; n++) // 8, 9 to 16, 17 for (byte n=8; n<18; n++) // 8, 9 to 16, 17
setDCCBit0(idle + n); for (byte n=18; n<26; n++) // 18 to 25 setDCCBit0(idle + n);
for (byte n=18; n<26; n++) // 18 to 25
setDCCBit1(idle + n); setDCCBit1(idle + n);
setDCCBit1(idle + 26); // end bit setDCCBit1(idle + 26); // end bit
setDCCBit0(idle + 27); // finish always with 0 setDCCBit0(idle + 27); // finish always with 0
setEOT(idle + 28); // EOT marker
rmt_config_t config; rmt_config_t config;
// Configure the RMT channel for TX // Configure the RMT channel for TX
@ -101,38 +104,23 @@ RMTPin::RMTPin(byte pin, byte ch, byte plen) {
// send one bit to kickstart the signal, remaining data will come from the // 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. // packet queue. We intentionally do not wait for the RMT TX complete here.
rmt_write_items(channel, preamble, preambleLen, false); rmt_write_items(channel, preamble, preambleLen, false);
//RMTinterrupt(channel, this); preambleNext = false;
dataNext = false;
} }
void IRAM_ATTR RMTPin::RMTinterrupt(rmt_channel_t channel, void* t) { void IRAM_ATTR RMTPin::RMTinterrupt(rmt_channel_t channel) {
//DIAG(F("QP"));
/* if (preambleNext) {
//RMT.int_clr.ch0_tx_end = 1; rmt_fill_tx_items(channel, preamble, preambleLen, 0);
for(uint32_t i = 0; i < preambleLen; i++) preambleNext = false;
RMTMEM.chan[channel].data32[i].val = preamble[i].val;
RMT.conf_ch[channel].conf1.mem_rd_rst = 1;
RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX;
RMT.conf_ch[channel].conf1.tx_start = 1;
*/
rmt_fill_tx_items(channel, preamble, preambleLen, 0);
//rmt_tx_start(channel,true);
return;
/*
RMTPin *obj = (RMTPin *)t;
if (obj->preambleNext) {
rmt_fill_tx_items(channel, obj->preamble, obj->preambleLen, 0);
//obj->preambleNext = false;
} else { } else {
if (obj->dataNext) { if (dataNext) {
rmt_fill_tx_items(channel, obj->packetBits, obj->packetLen, 0); rmt_fill_tx_items(channel, packetBits, packetLen, 0);
} else { } else {
// here we should not get as now we need to send idle packet // here we should not get as now we need to send idle packet
rmt_fill_tx_items(channel, obj->idle, obj->idleLen, 0); rmt_fill_tx_items(channel, idle, idleLen, 0);
} }
obj->preambleNext = true; preambleNext = true;
} }
rmt_tx_start(channel,true); rmt_tx_start(channel,true);
DIAG(F("START"));
*/
} }

View File

@ -29,12 +29,12 @@
class RMTPin { class RMTPin {
public: public:
RMTPin(byte pin, byte ch, byte plen); RMTPin(byte pin, byte ch, byte plen);
void IRAM_ATTR RMTinterrupt(rmt_channel_t, void *t); void IRAM_ATTR RMTinterrupt(rmt_channel_t);
static RMTPin mainRMTPin; static RMTPin mainRMTPin;
static RMTPin progRMTPin; static RMTPin progRMTPin;
// private: private:
rmt_channel_t channel; rmt_channel_t channel;
// 3 types of data to send, preamble and then idle or data // 3 types of data to send, preamble and then idle or data

View File

@ -51,14 +51,11 @@ void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
&& (mainDriver->getFaultPin() != UNUSED_PIN)); && (mainDriver->getFaultPin() != UNUSED_PIN));
// Only use PWM if both pins are PWM capable. Otherwise JOIN does not work // Only use PWM if both pins are PWM capable. Otherwise JOIN does not work
MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable(); MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable();
/*
if (MotorDriver::usePWM) if (MotorDriver::usePWM)
DIAG(F("Signal pin config: high accuracy waveform")); DIAG(F("Signal pin config: high accuracy waveform"));
else else
DIAG(F("Signal pin config: normal accuracy waveform")); DIAG(F("Signal pin config: normal accuracy waveform"));
DCCTimer::begin(DCCWaveform::interruptHandler); DCCTimer::begin(DCCWaveform::interruptHandler);
*/
DIAG(F("No waveform"));
} }
#ifdef SLOW_ANALOG_READ #ifdef SLOW_ANALOG_READ