smartPOC-tx/src/pocsag_transmitter.cpp
2025-03-30 15:15:54 +02:00

151 lines
No EOL
4.5 KiB
C++

#include "pocsag_transmitter.h"
#include "pocsag_encoder.h"
POCSAGTransmitter::POCSAGTransmitter()
{
POCSAG_DEBUG_PRINTLN("malloc'ating and prefilling encodingBuffer");
for (int i = 0; i < POCSAG_MAX_BUFFER_SIZE; i++)
transmitterData[i] = 0xFFFFFFFF;
for (int i = 0; i < POCSAG_MAX_ENCODING_BUFFER_SIZE; i++)
encodingBuffer[i] = 0xFFFFFFFF;
}
void POCSAGTransmitter::begin(SX1278 *radio)
{
_radio = radio;
_currentRadio = _radio;
//_radio->setFrequencyDeviation(4.5);
// 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->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 test2();
void POCSAGTransmitter::clearQueue()
{
queueCount = 0;
transmitterLength = 0;
}
int8_t POCSAGTransmitter::getQueueCount()
{
return queueCount;
}
bool POCSAGTransmitter::isActive()
{
return transmitterState;
}
uint16_t POCSAGTransmitter::getTransmitLength()
{
return transmitterLength;
}
uint16_t POCSAGTransmitter::getTransmitPos()
{
return transmitterOffset;
}
uint8_t POCSAGTransmitter::getBitOffset()
{
return transmitterBitOffset;
}
uint32_t POCSAGTransmitter::getTransmitWord()
{
return transmitterData[ transmitterOffset ];
}
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];
}
// 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
_radio->standby();
#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;
}
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;
}
}