diff --git a/.vscode/arduino.json b/.vscode/arduino.json index e0b924b..488acc1 100644 --- a/.vscode/arduino.json +++ b/.vscode/arduino.json @@ -1,6 +1,6 @@ { "board": "bsfrance:avr:lora32u4", "sketch": "crossbow.ino", - "port": "COM17", + "port": "COM4", "output": "./build" } \ No newline at end of file diff --git a/crossbow.ino b/crossbow.ino index 39fc969..da81631 100644 --- a/crossbow.ino +++ b/crossbow.ino @@ -1,10 +1,10 @@ #define DEVICE_MODE_TX // #define DEVICE_MODE_RX -#define FEATURE_TX_OLED -// #define FORCE_TX_WITHOUT_INPUT +// #define FEATURE_TX_OLED +#define FORCE_TX_WITHOUT_INPUT -// #define DEBUG_SERIAL +#define DEBUG_SERIAL // #define DEBUG_PING_PONG // #define DEBUG_LED @@ -60,6 +60,8 @@ RxDeviceState_t rxDeviceState = {}; TxDeviceState_t txDeviceState = {}; volatile RadioState_t radioState; +uint8_t tmpBuffer[MAX_PACKET_SIZE]; + uint8_t getRadioRssi(void) { return 164 - constrain(LoRa.packetRssi() * -1, 0, 164); @@ -263,10 +265,12 @@ void loop(void) { if (radioState.bytesToRead != NO_DATA_TO_READ) { + LoRa.read(tmpBuffer, radioState.bytesToRead); for (int i = 0; i < radioState.bytesToRead; i++) { - qspDecodeIncomingFrame(&qsp, LoRa.fastRead(), &rxDeviceState, &txDeviceState, &radioState); + qspDecodeIncomingFrame(&qsp, tmpBuffer[i], &rxDeviceState, &txDeviceState, &radioState); } + radioState.rssi = getRadioRssi(); radioState.snr = getRadioSnr(); @@ -391,8 +395,12 @@ void loop(void) if (qsp.canTransmit && transmitPayload) { + uint8_t size; LoRa.beginPacket(); - qspEncodeFrame(&qsp); + //Prepare packet + qspEncodeFrame(&qsp, tmpBuffer, &size); + //Sent it to radio in one SPI transaction + LoRa.write(tmpBuffer, size); LoRa.endPacket(); //After ending packet, put device into receive mode again LoRa.receive(); diff --git a/lora.cpp b/lora.cpp index 9ccb8d6..80b867e 100644 --- a/lora.cpp +++ b/lora.cpp @@ -208,12 +208,17 @@ float LoRaClass::packetSnr() return ((int8_t)readRegister(REG_PKT_SNR_VALUE)) * 0.25; } -size_t LoRaClass::write(uint8_t byte) +void LoRaClass::write(uint8_t data) { - return write(&byte, sizeof(byte)); + int currentLength = readRegister(REG_PAYLOAD_LENGTH); + + writeRegister(REG_FIFO, data); + + // update length + writeRegister(REG_PAYLOAD_LENGTH, currentLength + 1); } -size_t LoRaClass::write(const uint8_t *buffer, size_t size) +void LoRaClass::write(uint8_t buffer[], size_t size) { int currentLength = readRegister(REG_PAYLOAD_LENGTH); @@ -222,15 +227,10 @@ size_t LoRaClass::write(const uint8_t *buffer, size_t size) size = MAX_PKT_LENGTH - currentLength; } - // write data - for (size_t i = 0; i < size; i++) { - writeRegister(REG_FIFO, buffer[i]); - } + writeRegister(REG_FIFO, buffer, size); // update length writeRegister(REG_PAYLOAD_LENGTH, currentLength + size); - - return size; } int LoRaClass::available() @@ -244,6 +244,11 @@ int LoRaClass::fastRead() { return readRegister(REG_FIFO); } +void LoRaClass::read(uint8_t buffer[], uint8_t size) { + _packetIndex += size; + return readRegister(REG_FIFO, buffer, size); +} + int LoRaClass::read() { if (!available()) { @@ -498,6 +503,29 @@ uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value) return response; } +void LoRaClass::writeRegister(uint8_t address, uint8_t buffer[], size_t size) +{ + bufferTransfer(address | 0x80, buffer, size); +} + +void LoRaClass::readRegister(uint8_t address, uint8_t buffer[], size_t size) +{ + bufferTransfer(address & 0x7f, buffer, size); +} + +void LoRaClass::bufferTransfer(uint8_t address, uint8_t buffer[], uint8_t size) { + uint8_t response; + + digitalWrite(_ss, LOW); + + SPI.beginTransaction(_spiSettings); + SPI.transfer(address); + SPI.transfer(buffer, size); + SPI.endTransaction(); + + digitalWrite(_ss, HIGH); +} + void LoRaClass::onDio0Rise() { LoRa.handleDio0Rise(); diff --git a/lora.h b/lora.h index 2c237dd..17ca80d 100644 --- a/lora.h +++ b/lora.h @@ -30,11 +30,12 @@ public: int packetRssi(); float packetSnr(); - size_t write(uint8_t byte); - size_t write(const uint8_t *buffer, size_t size); + void write(uint8_t byte); + void write(uint8_t buffer[], size_t size); int available(); int read(); int fastRead(); + void read(uint8_t buffer[], uint8_t size); void onReceive(void(*callback)(int)); @@ -69,6 +70,10 @@ private: void writeRegister(uint8_t address, uint8_t value); uint8_t singleTransfer(uint8_t address, uint8_t value); + void readRegister(uint8_t address, uint8_t buffer[], size_t size); + void writeRegister(uint8_t address, uint8_t buffer[], size_t size); + void bufferTransfer(uint8_t address, uint8_t buffer[], uint8_t size); + static void onDio0Rise(); private: diff --git a/qsp.cpp b/qsp.cpp index 3315d12..84b8c3d 100644 --- a/qsp.cpp +++ b/qsp.cpp @@ -230,26 +230,27 @@ void qspDecodeIncomingFrame( /** * Encode frame is corrent format and write to hardware */ -void qspEncodeFrame(QspConfiguration_t *qsp) { +void qspEncodeFrame(QspConfiguration_t *qsp, uint8_t buffer[], uint8_t *size) { //Zero CRC qsp->crc = 0; - //Write CHANNEL_ID - qsp->hardwareWriteFunction(CHANNEL_ID, qsp); + qspComputeCrc(qsp, CHANNEL_ID); + buffer[0] = CHANNEL_ID; //Write frame type and length uint8_t data = qsp->payloadLength & 0x0f; data |= (qsp->frameToSend << 4) & 0xf0; - qsp->hardwareWriteFunction(data, qsp); + qspComputeCrc(qsp, data); + buffer[1] = data; - //Write payload for (uint8_t i = 0; i < qsp->payloadLength; i++) { - qsp->hardwareWriteFunction(qsp->payload[i], qsp); + qspComputeCrc(qsp, qsp->payload[i]); + buffer[i + 2] = qsp->payload[i]; } - //Finally write CRC - qsp->hardwareWriteFunction(qsp->crc, qsp); + buffer[qsp->payloadLength + 2] = qsp->crc; + *size = qsp->payloadLength + 3; //Total length of QSP frame } void encodePingPayload(QspConfiguration_t *qsp, uint32_t currentMicros) { diff --git a/qsp.h b/qsp.h index e80f72f..84728b1 100644 --- a/qsp.h +++ b/qsp.h @@ -17,6 +17,6 @@ void qspDecodeIncomingFrame( RadioState_t *radioState ); void qspClearPayload(QspConfiguration_t *qsp); -void qspEncodeFrame(QspConfiguration_t *qsp); +void qspEncodeFrame(QspConfiguration_t *qsp, uint8_t buffer[], uint8_t *size); void encodePingPayload(QspConfiguration_t *qsp, uint32_t currentMicros); \ No newline at end of file