diff --git a/pocsag-transmit-test/src/main.cpp b/pocsag-transmit-test/src/main.cpp index f55702c..ad44014 100644 --- a/pocsag-transmit-test/src/main.cpp +++ b/pocsag-transmit-test/src/main.cpp @@ -16,9 +16,10 @@ SX1276 radio = new Module(LORA_SS, LORA_DIO0, LORA_RST, LORA_DIO1); POCSAGTransmitter transmitter; + void setup() { Serial.begin(115200); - int state = radio.beginFSK(434.230,1.2,4.5); + int state = radio.beginFSK(868.23,1.2,4.5); if (state == ERR_NONE) { Serial.println(F("success!")); } else { @@ -26,12 +27,17 @@ void setup() { Serial.println(state); while (true); } - //int state2 = radio.transmit("Hello World!"); Serial.println("initialized modem"); transmitter.begin(&radio); Serial.println("initialized transmitter"); delay(2e2); - transmitter.test(); + transmitter.queuePage(133701, 3, "Testbericht 0"); // should never be sent + transmitter.clearQueue(); + transmitter.queuePage(133701, 3, "Testbericht 1"); + transmitter.queuePage(133703, 3, "Testbericht -2"); + transmitter.queuePage(133706, 3, "Testbericht --3"); + transmitter.queuePage(133707, 3, "Testbericht ---4"); + transmitter.transmitBatch(); } void loop() { diff --git a/pocsag-transmit-test/src/pocsag_transmitter.cpp b/pocsag-transmit-test/src/pocsag_transmitter.cpp index 498cf5c..bea67e0 100644 --- a/pocsag-transmit-test/src/pocsag_transmitter.cpp +++ b/pocsag-transmit-test/src/pocsag_transmitter.cpp @@ -2,149 +2,112 @@ #include "pocsag_encoder.h" -#define POCSAG_MAX_BUFFER_SIZE 2000 // 2000 QBYTEs - - - POCSAGTransmitter::POCSAGTransmitter() { - Serial.println("malloc"); - transmitterData = (uint32_t *)malloc(sizeof(uint32_t) * POCSAG_MAX_BUFFER_SIZE); //TODO: make this static allocated - for (int z=0;zsetFrequencyDeviation(4.5); - /*_radio->_mod->SPIsetRegValue(SX127X_REG_FDEV_MSB, 0x00); - _radio->_mod->SPIsetRegValue(SX127X_REG_FDEV_LSB, 75);*/ - // _radio->setEncoding(RADIOLIB_ENCODING_NRZ); - _radio->_mod->SPIsetRegValue(SX127X_REG_PAYLOAD_LENGTH, 0x00); - _radio->_mod->SPIsetRegValue(SX127X_REG_FIFO_THRESH, SX127X_TX_START_FIFO_NOT_EMPTY | 0x0F); - // _radio->pubmod->SPIsetRegValue(SX127X_REG_FIFO_THRESH, SX127X_TX_START_FIFO_NOT_EMPTY | SX127X_FIFO_THRESH); - //_radio->pubmod->SPIsetRegValue(SX127X_REG_PREAMBLE_LSB, 0x00); - //_radio->setPreambleLength(0); - uint16_t bitRate = 62500; //62500; //(SX127X_CRYSTAL_FREQ * 1000.0) / 0.512; - _radio->_mod->SPIsetRegValue(SX127X_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0); - _radio->_mod->SPIsetRegValue(SX127X_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0); + // 512 baud testing + //uint16_t bitRate = 62500; //62500; //(SX127X_CRYSTAL_FREQ * 1000.0) / 0.512; + //_radio->_mod->SPIsetRegValue(SX127X_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0); + //_radio->_mod->SPIsetRegValue(SX127X_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0); - _radio->_mod->SPIsetRegValue(SX127X_REG_PA_RAMP, SX1278_NO_SHAPING); - _radio->_mod->SPIsetRegValue(SX127X_REG_PACKET_CONFIG_1, SX127X_PACKET_FIXED | SX127X_DC_FREE_NONE | SX127X_CRC_OFF | SX127X_CRC_AUTOCLEAR_ON | SX127X_ADDRESS_FILTERING_OFF, 7, 0); - _radio->_mod->SPIsetRegValue(SX127X_REG_PACKET_CONFIG_2, SX127X_DATA_MODE_PACKET, 6, 6); _radio->setCRC(false); + _radio->setEncoding(RADIOLIB_ENCODING_NRZ); + _radio->setDataShaping(RADIOLIB_SHAPING_NONE); _radio->setPreambleLength(0); + _radio->setBitRate(1.2); + // pinz + pinMode(POCSAG_PIN_DIO1, INPUT); + pinMode(POCSAG_PIN_DIO2, OUTPUT); } -void POCSAGTransmitter::test() { - _radio->standby(); - _radio->_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_PACK_PACKET_SENT); - size_t completeLength = 0; +void test2(); - uint8_t * transmitterByteDataPointer = (uint8_t *)transmitterData; - - Serial.print(F("transmitterData: ")); Serial.println ((unsigned long int)transmitterData, HEX); - Serial.print(F("transmitterByteDataPointer: ")); Serial.println ((unsigned long int)transmitterByteDataPointer, HEX); - /* - for (int y = 0; y < 13; y++) { - size_t beforeLength = completeLength + 0; - size_t messageLength = textMessageLength(y, 133701, 80); - uint32_t *transmission = (uint32_t *)malloc(sizeof(uint32_t) * messageLength); - encodeTransmission(y, 133701 + y, 3, "01234567890123456789012345678901234567890123456789012345678901234567890123456789", transmission); - completeLength += messageLength; - Serial.println(); - Serial.print("messageLength="); Serial.println(messageLength, DEC); - Serial.println("MESSAGE encoded:"); - for (size_t i = 0; i < messageLength; i++) - Serial.print(transmission[i], HEX); - Serial.println(); - - for (size_t i = 0; i < messageLength; i++) { - size_t baseOffset = (beforeLength * sizeof(uint32_t)) + (i * sizeof(uint32_t)); - transmitterByteDataPointer[ baseOffset + 00 ] = ((transmission[ i ] >> 24) & 0xFF); - transmitterByteDataPointer[ baseOffset + 01 ] = ((transmission[ i ] >> 16) & 0xFF); - transmitterByteDataPointer[ baseOffset + 02 ] = ((transmission[ i ] >> 8) & 0xFF); - transmitterByteDataPointer[ baseOffset + 03 ] = (transmission[ i ] & 0xFF); - } - free(transmission); - /*Serial.println("TX encoded after free:"); - for (size_t i = 0; i < messageLength; i++) - Serial.print(transmission[i], HEX);/ - } - */ - uint32_t testTransmission[ 18 + 13 ] = { - // 18 words, 576 bits of preamble - 0xAAAAAAAA, 0xAAAAAAAA, - 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, - 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, - // The real data starts here - 0x7CD215D8, 0x7A89C197, 0x7A89C197, 0x7A89C197, 0x7A89C197, 0x7A89C197, 0x7A89C197, 0x7A89C197, - 0x7A89C197, 0x4F5A0109, 0xC2619CE1, 0x7A89C197, 0x7A89C197, - }; - completeLength = 18+13; - for (size_t i = 0; i < completeLength; i++) { - size_t baseOffset = (0 * sizeof(uint32_t)) + (i * sizeof(uint32_t)); - transmitterByteDataPointer[ baseOffset + 00 ] = ((testTransmission[ i ] >> 24) & 0xFF); - transmitterByteDataPointer[ baseOffset + 01 ] = ((testTransmission[ i ] >> 16) & 0xFF); - transmitterByteDataPointer[ baseOffset + 02 ] = ((testTransmission[ i ] >> 8) & 0xFF); - transmitterByteDataPointer[ baseOffset + 03 ] = (testTransmission[ i ] & 0xFF); +void POCSAGTransmitter::clearQueue() { + queueCount = 0; + transmitterLength = 0; +} +int8_t POCSAGTransmitter::getQueueCount() { + return queueCount; +} +bool POCSAGTransmitter::isActive() { + return transmitterState; +} +void POCSAGTransmitter::queuePage(uint32_t ric, uint8_t functionBit, char *text) { + size_t beforeLength = transmitterLength + 0; + size_t messageLength = textMessageLength(queueCount, ric, strlen(text)); + //uint32_t *transmission = (uint32_t *)malloc(sizeof(uint32_t) * messageLength); + uint32_t *encodingBufferPointer = encodingBuffer; + encodeTransmission(queueCount, ric, functionBit, text, encodingBufferPointer); + transmitterLength += messageLength; + + #ifdef POCSAG_DEBUG + POCSAG_DEBUG_PRINTLN(); + POCSAG_DEBUG_PRINT("RIC: "); POCSAG_DEBUG_PRINT(ric, DEC); + POCSAG_DEBUG_PRINT(" F: "); POCSAG_DEBUG_PRINTLN(functionBit, DEC); + POCSAG_DEBUG_PRINT("TEXT: "); POCSAG_DEBUG_PRINTLN(text); + POCSAG_DEBUG_PRINTLN(); + POCSAG_DEBUG_PRINT("messageLength="); POCSAG_DEBUG_PRINTLN(messageLength, DEC); + POCSAG_DEBUG_PRINTLN("MESSAGE encoded:"); + for (size_t i = 0; i < messageLength; i++) + POCSAG_DEBUG_PRINT(encodingBuffer[i], HEX); + POCSAG_DEBUG_PRINTLN(); + #endif + + // copy it to the correct place lol + for (size_t i = 0; i < messageLength; i++) { + transmitterData[ beforeLength + i ] = encodingBuffer[ i ]; } - Serial.print(F("transmitterData: ")); Serial.println ((unsigned long int)transmitterData, HEX); - Serial.print(F("transmitterByteDataPointer: ")); Serial.println ((unsigned long int)transmitterByteDataPointer, HEX); - - Serial.println(); - Serial.println("TX encoded in big buffer:"); - for (size_t i = 0; i < completeLength*4; i++) - Serial.print(transmitterByteDataPointer[i], HEX); - Serial.println(); - Serial.print("completeLength="); Serial.println(completeLength, DEC); - - Serial.print(F("transmitterData: ")); Serial.println ((unsigned long int)transmitterData, HEX); - Serial.print(F("transmitterByteDataPointer: ")); Serial.println ((unsigned long int)transmitterByteDataPointer, HEX); - - uint8_t * transmissionChunk = (uint8_t *)malloc(16); - for (int i=0;i<16;i++) transmissionChunk[i] = i%2==0?0x55 : 0xAA; // setting it all to 0xFF to see where memcpy works - // do encoding - - byte irq2 = 0x00; - //memcpy(transmissionChunk, transmitterByteDataPointer, 16); - writeFIFOChunk(transmitterByteDataPointer, 16); - transmitterByteDataPointer+=16; - /*for (int i=0;i<16;i++) { - transmissionChunk[ i ] = *transmitterByteDataPointer; - transmitterByteDataPointer++; - }*/ + //free(transmission); + queueCount++; +} +bool POCSAGTransmitter::transmitBatch() { + if (transmitterState > 0) return false; // we already started + if (transmitterLength < 16) return false; // dont start if we have less than 16 bytes - //writeFIFOChunk(transmissionChunk, 16); - Serial.println("starting tx"); - _radio->setMode(SX127X_TX); - /*for (int i=4; i < completeLength; i+=4) { - //memcpy(transmissionChunk, transmitterByteDataPointer, 16); - transmitterByteDataPointer+=16; - writeFIFOChunk(transmissionChunk, 16); - delay(20); - do { - irq2 = _radio->_mod->SPIgetRegValue(SX127X_REG_IRQ_FLAGS_2); - Serial.print(irq2 >> 4 & 1, HEX); - } while ((irq2 >> 4 & 1) > 0); - }*/ - //Serial.println("free'd transmissionChunk, waiting for PacketSent"); - do { - irq2 = _radio->_mod->SPIgetRegValue(SX127X_REG_IRQ_FLAGS_2); - // Serial.print(irq2 >> 3 & 1, HEX); - } while (((irq2 >> 3) & 1) == 0); _radio->standby(); - free(transmissionChunk); - Serial.println("done"); - - Serial.print(F("transmitterData: ")); Serial.println ((unsigned long int)transmitterData, HEX); - Serial.print(F("transmitterByteDataPointer: ")); Serial.println ((unsigned long int)transmitterByteDataPointer, HEX); - + #ifdef POCSAG_DEBUG + POCSAG_DEBUG_PRINT(F("transmitterData: ")); POCSAG_DEBUG_PRINTLN ((unsigned long int)transmitterData, HEX); + + POCSAG_DEBUG_PRINT(F("transmitterData: ")); POCSAG_DEBUG_PRINTLN((unsigned long int)transmitterData, HEX); + POCSAG_DEBUG_PRINTLN(); + POCSAG_DEBUG_PRINTLN("TX encoded in big buffer:"); + for (size_t i = 0; i < transmitterLength; i++) + POCSAG_DEBUG_PRINT(transmitterData[i], HEX); + POCSAG_DEBUG_PRINTLN(); + POCSAG_DEBUG_PRINT("transmitterLength="); POCSAG_DEBUG_PRINTLN(transmitterLength, DEC); + + POCSAG_DEBUG_PRINT(F("transmitterData: ")); POCSAG_DEBUG_PRINTLN((unsigned long int)transmitterData, HEX); + + POCSAG_DEBUG_PRINTLN("starting tx"); + #endif + transmitterState = true; + transmitterBitOffset = 32; + transmitterOffset = 0; + // attach DCLK interrupt + attachInterrupt(digitalPinToInterrupt(POCSAG_PIN_DIO1), onTransmitterClock, RISING); + delay(10); //giving it some time + _currentRadio->transmitDirect(); + return true; } -void POCSAGTransmitter::writeFIFOChunk(uint8_t* data, size_t len) { - for (int z=0;z_mod->SPItransfer(0x80, 0x00, data, NULL, len); +static void IRAM_ATTR onTransmitterClock() { + transmitterBitOffset--; + digitalWrite(POCSAG_PIN_DIO2, ((transmitterData[ transmitterOffset ] >> transmitterBitOffset) & 1) == 0); + if (transmitterBitOffset == 0) { // lets shift to next byte + transmitterBitOffset = 32; + transmitterOffset++; + } + if (transmitterOffset > transmitterLength) { + _currentRadio->standby(); + detachInterrupt(POCSAG_PIN_DIO1); + transmitterState = false; + } } \ No newline at end of file diff --git a/pocsag-transmit-test/src/pocsag_transmitter.h b/pocsag-transmit-test/src/pocsag_transmitter.h index 0bd0a0f..ba6a923 100644 --- a/pocsag-transmit-test/src/pocsag_transmitter.h +++ b/pocsag-transmit-test/src/pocsag_transmitter.h @@ -1,23 +1,50 @@ #if !defined(_POCSAG_TRANSMITTER_H) #define _POCSAG_TRANSMITTER_H #include -// #include + +#define POCSAG_MAX_ENCODING_BUFFER_SIZE 70 // 70 QBYTEs should be enough for max 80char Messages +#define POCSAG_MAX_BUFFER_SIZE 2000 // 2000 QBYTEs +#define POCSAG_PIN_DIO1 33 // DCLK +#define POCSAG_PIN_DIO2 32 // DATA + +// #define POCSAG_DEBUG +#define POCSAG_DEBUG_PORT Serial +#if defined(POCSAG_DEBUG) + #define POCSAG_DEBUG_PRINT(...) { RADIOLIB_DEBUG_PORT.print(__VA_ARGS__); } + #define POCSAG_DEBUG_PRINTLN(...) { RADIOLIB_DEBUG_PORT.println(__VA_ARGS__); } +#else + #define POCSAG_DEBUG_PRINT(...) {} + #define POCSAG_DEBUG_PRINTLN(...) {} +#endif /*! * POCSAG Transmitter -- catSIXe +- catSIXe, encoder is partly transformed from RPITX, with my old contributions(batch-encoding etc.) from the old github */ + +static SX1278* _currentRadio; // we need to put this pointer static for the ISR +static uint32_t transmitterData[ POCSAG_MAX_BUFFER_SIZE ]; // complete transmission +static uint32_t encodingBuffer[ POCSAG_MAX_ENCODING_BUFFER_SIZE ]; // small static allocated memory, for storing a encoded chunk + +static uint16_t transmitterLength; +static uint16_t transmitterOffset; +static uint8_t transmitterBitOffset; +static bool transmitterState; +static void IRAM_ATTR onTransmitterClock(); + class POCSAGTransmitter { public: - uint32_t *transmitterData; - uint32_t *encodingBuffer; + SX1278* _radio; explicit POCSAGTransmitter(); void begin(SX1278 *radio); - void queuePage(uint32_t ric, char* text); - void transmitBatch(); + void clearQueue(); + int8_t getQueueCount(); + bool isActive(); + void queuePage(uint32_t ric, uint8_t functionBit, char* text); + bool transmitBatch(); void test(); - void writeFIFOChunk(uint8_t* data, size_t len); - SX1278* _radio; + private: + int8_t queueCount = 0; }; #endif \ No newline at end of file