Skip to content

Instantly share code, notes, and snippets.

@Pascal66
Created June 12, 2023 10:37

Revisions

  1. Pascal66 created this gist Jun 12, 2023.
    262 changes: 262 additions & 0 deletions Heletc iwo version
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,262 @@
    #include <utils.h>
    #include <RadioLib.h>

    // Heltec WiFi LoRa has the following connections:
    #define I2C_SDA 21
    #define I2C_SCL 22
    // #define OLED_RST UNUSE_PIN

    #define RADIO_SCLK_PIN 5 // OK Heltec
    #define RADIO_MISO_PIN 19 // OK Heltec
    #define RADIO_MOSI_PIN 27 // OK Heltec
    #define RADIO_CS_PIN 18 // OK Heltec
    #define RADIO_DIO0_PIN 26 // OK Heltec
    #define RADIO_RST_PIN 14 // LilyGO 23
    #define RADIO_DIO1_PIN 35 // LilyGO 33
    #define RADIO_DIO2_PIN 34
    #define RADIO_BUSY_PIN 32

    #define SDCARD_MOSI 15
    #define SDCARD_MISO 2
    #define SDCARD_SCLK 14
    #define SDCARD_CS 13

    #define BOARD_LED 25
    #define LED_ON HIGH

    #define ADC_PIN 35
    SX1276 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO1_PIN);

    // DIO2 pin: 34
    // const int pin = RADIO_DIO2_PIN;
    // uint8_t message[48]; // Déclaration du tableau

    #define RADIOLIB_DEBUG
    void setup()
    {
    Serial.begin(921600);

    // initialize SX1278 with FSK modem at 921600 bps
    Serial.print(F("[SX1276] Initializing ... "));

    int state = radio.beginFSK();

    if (state == RADIOLIB_ERR_NONE)
    {
    Serial.println(F("success!"));
    // Serial.println(radio.getChipVersion());
    // Serial.println(radio.getModemStatus());
    // Serial.println(radio.getTempRaw());
    // Serial.println(radio.randomByte());
    }
    else
    {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true)
    ;
    }
    state = radio.setFrequency(868.95);
    if (state != RADIOLIB_ERR_NONE)
    {
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true)
    ;
    }
    state = radio.setPreambleLength(64);
    if (state != RADIOLIB_ERR_NONE)
    {
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    state = radio.setOutputPower(17);
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    state = radio.setCurrentLimit(200);
    // Needed to transmit in packet mode
    u_int8_t transmitSyncWord[] = {0x7f, 0xd9}; //{0x57, 0xfd, 0x99}; // 57fd99
    state = radio.setSyncWord(transmitSyncWord, 2); //sizeof(syncSendWord));
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }

    state = radio.setBitRate(38.4); // 153.6); //
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    state = radio.setFrequencyDeviation(19.2); // 10.0);
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    state = radio.setDataShaping(RADIOLIB_SHAPING_NONE);
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    state = radio.setEncoding(RADIOLIB_ENCODING_NRZ);
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    state = radio.setRxBandwidth(250.0);
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }

    state = radio.setCRC(false); // true);
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    state = radio.setCrcFiltering(false);
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    state = radio.disableAddressFiltering();
    if (state != RADIOLIB_ERR_NONE){
    Serial.print(F("Unable to set configuration, code "));
    Serial.println(state);
    while (true);
    }
    // radio.enableBitSync();
    pinMode(RADIO_DIO2_PIN, INPUT);
    // set function that will be called each time a bit is received
    radio.setDirectAction(readBit);
    // Needed to receive in direct mode
    int32_t directSyncWord = 0x7fd9; //0x557FD9; //
    state = radio.setDirectSyncWord(directSyncWord, 16); //24); // 0x01, 8); //24); //
    // start direct mode reception
    radio.receiveDirect();
    }

    // this function is called when a new bit is received
    #if defined(ESP8266) || defined(ESP32)
    ICACHE_RAM_ATTR
    #endif
    void readBit(void) {
    // read the data bit
    radio.readBit(RADIO_DIO2_PIN);
    }

    u_int8_t to[] = {0x8c, 0xcb, 0x30}; //{0xb4, 0x9b, 0x05}; // //{0x00, 0x00, 0x3f}; //
    u_int8_t from[] = {0xb4, 0x9b, 0x05}; //{0xba, 0x11, 0xad}; //
    u_int8_t cmd[] = {0x3c}; //{0x38}; //
    u_int8_t data[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //{0x0c, 0x61, 0x01, 0x10, 0x01}; //{0xad, 0xd1, 0xee, 0xe2, 0xbd, 0x16};
    //u_int8_t crc[] = {0x20, 0xe5};
    //uint8_t forgedFrame[] = {0xff, 0x33, 0xe, 0x0, 0x8c, 0xcb, 0x30, 0xb4, 0x9b, 0x5, 0x3c, 0xad, 0xd1, 0xee, 0xe2, 0xbd, 0x16, 0x20, 0xe5};
    uint8_t forgedFrame[] = {0xff, 0x33, 0xe, 0x0, 0x8c, 0xcb, 0x30, 0xb4, 0x9b, 0x5, 0x38, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x00, 0x00}; //, 0x00};
    //uint8_t forgedFrame[] = {0xff, 0x33, 0x8, 0x0, 0x8c, 0xcb, 0x30, 0xb4, 0x9b, 0x5, 0x28, 0x20, 0xe5};
    void loop() {
    bool start = false;
    if (radio.available() >= 32) {
    uint8_t message[radio.available()] = {0x7f, 0xd9}; // Déclaration du tableau
    // Serial.print(radio.available());
    // Serial.println("\t [SX1276] Received in direct mode!");
    int16_t countByte = 2;

    while (radio.available()) {
    // read all bytes
    byte b = radio.read();
    //if (b != 0x95 & !start) continue;
    //start = true;
    message[countByte++] = b;
    }
    u_int8_t dst[countByte] ;
    unsigned num_byte_extracted = extract_bytes_uart (message, 480, dst);
    if (num_byte_extracted < 11) {start = false; return;}
    start = true;

    //TODO decodeMessage return structure
    if(!decodeMessage(dst, num_byte_extracted)) {start = false; return;}
    Serial.print("(");Serial.print(dst[2] & 0x1f, HEX); Serial.print(") "); // The coded len [2]
    //TODO Create a new frame : forgedFrame[2] = dst[2] & 0x1f; // MSGLEN tODO need to be adatped
    for (unsigned i = 0; i < num_byte_extracted; i++) {
    char buffer[4];
    sprintf(buffer, "%02X ", dst[i]); //message[i]);
    Serial.print(buffer);
    //Serial.print(" ");
    }
    Serial.println();
    //if(dst[10] == 0x3D) cmd[0] = {0x21};
    //if(dst[10] != 0x3D) cmd[0] = {0x3C};

    // Only 2W need an answer with from/to reversed (We can also send the same or modified 1W frame with start = true;)
    if((dst[2] & 0x20) >> 5 == 0) {
    memcpy(from, dst + 4, 3);
    memcpy(to, dst + 7, 3);}
    } else start = false;

    if (!start) return;

    // delay(100);
    radio.packetMode();
    // forgedFrame[2] = 0x0e; // Frame Len
    // forgedFrame[2] |= (1 << 6); // Start Frame // If 3C if not a start frame
    memcpy(forgedFrame + 4, to, 3);
    memcpy(forgedFrame + 7, from, 3);
    memcpy(forgedFrame + 10, cmd, 1);
    memcpy(forgedFrame + 11, data, 6);
    unsigned int num_values = sizeof(forgedFrame);
    uint8_t crc_bytes[2];
    compute_crc_8408(forgedFrame+2, num_values-4, crc_bytes);
    // printf("CRC-16-LSB/KERMIT 2: 0x%02X%02X\n",crc_bytes[0], crc_bytes[1]);
    // memcpy(forgedFrame + 11, crc_bytes, 2); // 11 without data
    memcpy(forgedFrame + 17, crc_bytes, 2); // 17 with 6 bytes data
    // for (unsigned i = 0; i < num_values; i++) {
    // char buffer[4];
    // sprintf(buffer, "%02X", forgedFrame[i]);
    // Serial.print(buffer);
    // Serial.print(" ");
    // }
    // Serial.println();

    unsigned int length;
    //u_int8_t* binary_array = convertHexToBinary(forgedFrame, num_values, &length);
    //int transmissionState = radio.fixedPacketLengthMode(length);

    for (int i =0; i < 0x01; i++) {
    // u_int8_t cmd[] = {i}; //0x28};
    // memcpy(forgedFrame + 10, cmd, 1);
    // compute_crc_8408(forgedFrame+2, num_values-4, crc_bytes);
    // memcpy(forgedFrame + 17, crc_bytes, 2);
    // delay(1000);
    u_int8_t* binary_array = convertHexToBinary(forgedFrame, num_values, &length);
    int transmissionState = radio.fixedPacketLengthMode(length);

    transmissionState = radio.transmit(binary_array + 2, length);

    if (transmissionState == RADIOLIB_ERR_NONE) {
    Serial.println(F("[SX1276] Packet transmitted successfully!"));
    }
    else if (transmissionState == RADIOLIB_ERR_PACKET_TOO_LONG) {
    Serial.println(F("[SX1276] Packet too long!"));
    }
    else if (transmissionState == RADIOLIB_ERR_TX_TIMEOUT) {
    Serial.println(F("[SX1276] Timed out while transmitting!"));
    }
    else {
    Serial.println(F("[SX1276] Failed to transmit packet, code "));
    Serial.println(transmissionState);
    }
    }
    radio.receiveDirect();
    //delay(1000 * 60);
    }