소스 검색

first commit

Pierre Bourdin 2 달 전
커밋
c39c79807b
9개의 변경된 파일1046개의 추가작업 그리고 0개의 파일을 삭제
  1. 39 0
      include/README
  2. 46 0
      lib/README
  3. 36 0
      platformio.ini
  4. 39 0
      src/board.h
  5. 131 0
      src/main.cpp
  6. 393 0
      src/sx1262.cpp
  7. 123 0
      src/sx1262.h
  8. 228 0
      src/sx1262regs.h
  9. 11 0
      test/README

+ 39 - 0
include/README

@@ -0,0 +1,39 @@
+
+This directory is intended for project header files.
+
+A header file is a file containing C declarations and macro definitions
+to be shared between several project source files. You request the use of a
+header file in your project source file (C, C++, etc) located in `src` folder
+by including it, with the C preprocessing directive `#include'.
+
+```src/main.c
+
+#include "header.h"
+
+int main (void)
+{
+ ...
+}
+```
+
+Including a header file produces the same results as copying the header file
+into each source file that needs it. Such copying would be time-consuming
+and error-prone. With a header file, the related declarations appear
+in only one place. If they need to be changed, they can be changed in one
+place, and programs that include the header file will automatically use the
+new version when next recompiled. The header file eliminates the labor of
+finding and changing all the copies as well as the risk that a failure to
+find one copy will result in inconsistencies within a program.
+
+In C, the usual convention is to give header files names that end with `.h'.
+It is most portable to use only letters, digits, dashes, and underscores in
+header file names, and at most one dot.
+
+Read more about using header files in official GCC documentation:
+
+* Include Syntax
+* Include Operation
+* Once-Only Headers
+* Computed Includes
+
+https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

+ 46 - 0
lib/README

@@ -0,0 +1,46 @@
+
+This directory is intended for project specific (private) libraries.
+PlatformIO will compile them to static libraries and link into executable file.
+
+The source code of each library should be placed in a an own separate directory
+("lib/your_library_name/[here are source files]").
+
+For example, see a structure of the following two libraries `Foo` and `Bar`:
+
+|--lib
+|  |
+|  |--Bar
+|  |  |--docs
+|  |  |--examples
+|  |  |--src
+|  |     |- Bar.c
+|  |     |- Bar.h
+|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
+|  |
+|  |--Foo
+|  |  |- Foo.c
+|  |  |- Foo.h
+|  |
+|  |- README --> THIS FILE
+|
+|- platformio.ini
+|--src
+   |- main.c
+
+and a contents of `src/main.c`:
+```
+#include <Foo.h>
+#include <Bar.h>
+
+int main (void)
+{
+  ...
+}
+
+```
+
+PlatformIO Library Dependency Finder will find automatically dependent
+libraries scanning project source files.
+
+More information about PlatformIO Library Dependency Finder
+- https://docs.platformio.org/page/librarymanager/ldf.html

+ 36 - 0
platformio.ini

@@ -0,0 +1,36 @@
+; PlatformIO Project Configuration File
+;
+;   Build options: build flags, source filter
+;   Upload options: custom upload port, speed and extra flags
+;   Library options: dependencies, extra library storages
+;   Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+
+
+
+[env]
+platform = espressif32
+framework = arduino
+monitor_speed = 115200
+monitor_filters = esp32_exception_decoder, default, log2file, colorize
+
+lib_ldf_mode = deep+
+lib_deps = 
+	peterus/esp-logger @ 1.0.0
+	adafruit/Adafruit ST7735 and ST7789 Library@^1.10.3
+	mikalhart/TinyGPSPlus @ ^1.0.3
+
+
+[env:heltec_wifi_lora_32_V3]
+platform = espressif32
+board = heltec_wifi_lora_32_V3
+
+#[env:esp32-s3-devkitc-1]
+#platform = espressif32
+#board = esp32-s3-devkitc-1
+#chip = esp32s3
+
+#board_build.f_cpu = 240000000L

+ 39 - 0
src/board.h

@@ -0,0 +1,39 @@
+#ifdef LED_BUILTIN
+#undef LED_BUILTIN
+#endif
+#define LED_BUILTIN 18
+
+/*
+ * Définition des pins pour l'alimentation des périphériques
+ * Type : å chercher
+ */
+#define VEXT_CTL 3
+
+/*
+ * Définition des pins pour le GPS
+ * Type : GNSS UC6580
+ */
+#define GPS_RX 33
+#define GPS_TX 34
+
+/*
+ * Définition des pins pour l'écran TFT
+ */
+#define TFT_LED  21
+#define TFT_CS   38
+#define TFT_RST  39
+#define TFT_DC   40
+#define TFT_SCLK 41
+#define TFT_MOSI 42
+
+/*
+ * Définition des pins pour le module radio
+ * Type : LoRa SX1276
+ */
+#define SX1262_DIO1 14
+#define SX1262_BUSY 13
+#define SX1262_RST 12
+#define SX1262_MISO 11
+#define SX1262_MOSI 10
+#define SX1262_SCK 9
+#define SX1262_NSS 8

+ 131 - 0
src/main.cpp

@@ -0,0 +1,131 @@
+#include <Arduino.h>
+#include <Adafruit_ST7735.h>
+#include <TinyGPSPlus.h>
+#include <logger.h>
+#include "board.h"
+#include "sx1262.h"
+
+TinyGPSPlus gps;
+Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
+logging::Logger logger;
+Sx1262 radio = Sx1262(SX1262_RST, SX1262_SCK, SX1262_MOSI, SX1262_MISO, SX1262_NSS ,SX1262_DIO1);
+
+void setup_radio()
+{
+    radio.beginSPI();
+    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
+    tft.setCursor(0, 12);
+    tft.print("[Sx1262] ");
+    tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
+    delay(3000);
+    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "[SX1262]", "Setup done");
+   
+}
+
+void setup_gps()
+{    
+    Serial1.begin(115200, SERIAL_8N1, GPS_RX, GPS_TX);
+    tft.setCursor(0, 0);
+    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
+    tft.print("[GPS] ");
+    tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
+    tft.print("Setup done.");
+    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "GPS", "Setup done");
+}
+
+void setup_tft()
+{
+    pinMode(TFT_CS, OUTPUT);
+    pinMode(TFT_RST, OUTPUT);
+    pinMode(TFT_CS, OUTPUT);
+
+    tft.initR(INITR_MINI160x80_PLUGIN);
+    tft.setRotation(1); // Landscape
+    tft.fillScreen(ST77XX_BLACK);
+    tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
+    tft.setTextSize(1.5);
+
+    delay(50); // Wait for screen to clear
+
+    // Enable backlight
+    pinMode(TFT_LED, OUTPUT);
+    digitalWrite(TFT_LED, HIGH);
+}
+
+
+void setup() 
+{
+    pinMode(LED_BUILTIN, OUTPUT);
+    digitalWrite(LED_BUILTIN, HIGH);
+
+    USBSerial.begin(115200);
+    logger.setSerial(&USBSerial);
+
+    // Enable power to peripherals
+    pinMode(VEXT_CTL, OUTPUT);
+    digitalWrite(VEXT_CTL, HIGH);
+    
+    setup_tft();
+    setup_gps();
+    setup_radio();
+    
+    digitalWrite(LED_BUILTIN, LOW);
+    delay(3000);
+    tft.fillScreen(ST77XX_BLACK);
+    delay(1000);
+    tft.fillCircle(150, 10, 2, ST77XX_WHITE);
+    
+
+
+}
+
+void read_nmea(uint32_t ms)
+{
+    unsigned long start = millis();
+    char c;
+    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "GPS", "Reading NMEA data :");
+    do
+    {
+
+        while (Serial1.available()) {
+            c = Serial1.read();
+            gps.encode(c);
+            USBSerial.write(c);
+        }
+    } while (millis() - start < ms);
+}
+
+void loop() 
+{
+    tft.setTextColor(ST7735_GREEN, ST77XX_BLACK);
+    tft.setCursor(0, 0);
+    tft.print("[GPS NMEA] ");
+    tft.setTextColor(ST7735_WHITE, ST77XX_BLACK);
+
+        
+    if (gps.time.isUpdated())
+    {
+        tft.setCursor(0, 9);
+        tft.printf("%04u-%02u-%02u %02u:%02u:%02u",
+                   gps.date.year(), gps.date.month(), gps.date.day(),
+                   gps.time.hour(), gps.time.minute(), gps.time.second());
+    }
+
+    if (gps.location.isUpdated())
+    {
+        tft.setCursor(0, 24);
+        tft.printf("Lat: % 3.6f\nLon: % 3.6f\n", gps.location.lat(), gps.location.lng());
+        logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "GPS", "Lat: % 3.6f, Lon: % 3.6f", gps.location.lat(), gps.location.lng());
+    }
+
+    if (gps.altitude.isUpdated())
+    {
+        tft.setCursor(0, 28);
+        tft.printf("Alt: %3.0fft ", gps.altitude.feet());
+        logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "GPS", "Alt: %3.0fft", gps.altitude.feet());
+    }
+    tft.fillCircle(150, 10, 2, ST77XX_GREEN);
+    read_nmea(1000);
+    tft.fillCircle(150, 10, 2, ST77XX_WHITE);
+
+}

+ 393 - 0
src/sx1262.cpp

@@ -0,0 +1,393 @@
+/**
+ * @file sx1262.cpp
+ * @brief implementation file for the SX1262 transceiver class.
+ *
+ * @author Julia CABARBAYE (Student, ENSIL-ENSCI [ELT], France)
+ * @author Adrien CHEVRIER (Student, ENSIL-ENSCI [ELT], France)
+ *
+ * @date Created on: 2024-11-25
+ * @date Last updated: 2025-01-05
+ *
+ * @see sx1262.h
+ * @see { @link https://www.semtech.fr/products/wireless-rf/lora-connect/sx1262 }
+ * for detailed information about the SX1262.  
+ */
+
+/// Include class header
+#include "sx1262.h"
+#include "logger.h"
+#include "board.h"
+
+extern logging::Logger logger;
+
+/**
+ * @brief Begin the SPI commmunication with the SX1262 transceiver.
+ */
+void Sx1262::beginSPI() const
+{
+  SPI.begin(Sx1262::getSclk(), Sx1262::getMiso(), Sx1262::getMosi(), Sx1262::getCs());
+  pinMode(Sx1262::getCs(), OUTPUT);
+  digitalWrite(Sx1262::getCs(), HIGH);
+};
+
+/**
+ * @brief Get the reset pin.
+ * @return The reset pin number.
+ */
+uint8_t Sx1262::getRst() const
+{
+  return _rst;
+};
+
+/**
+ * @brief Get the specified DIO pin.
+ * @param n The DIO pin index (1-3). Default is 1.
+ * @return The DIO pin number.
+ */
+uint8_t Sx1262::getDio(uint8_t n) const
+{ 
+  uint8_t dioPin;
+  switch(n)
+  {
+    case 1: dioPin = _dio1; break;
+    case 2: dioPin = _dio2; break;
+    case 3: dioPin = _dio3; break;
+    default: dioPin = _dio1; break;
+  }
+  return dioPin;
+};
+
+/**
+ * @brief Get the SPI clock pin.
+ * @return The SPI clock pin number.
+ */
+uint8_t Sx1262::getSclk() const
+{
+  return _sclk;
+};
+
+/**
+ * @brief Get the SPI MOSI pin.
+ * @return The SPI MOSI pin number.
+ */
+uint8_t Sx1262::getMosi() const
+{
+  return _mosi;
+};
+
+/**
+ * @brief Get the SPI MISO pin.
+ * @return The SPI MISO pin number.
+ */
+uint8_t Sx1262::getMiso() const
+{
+  return _miso;
+};
+
+/**
+ * @brief Get the chip select pin.
+ * @return The chip select pin number.
+ */
+uint8_t Sx1262::getCs() const
+{
+  return _cs;
+};
+
+/**
+ * @brief Reset the Sx1262 device.
+ */
+void Sx1262::reset() const
+{
+  for (uint32_t delay = 0; delay < 0xFFF; delay++)
+  {
+    /// The reset pin operates with inverted logic
+    digitalWrite(_rst, LOW);
+  }
+  for (uint32_t delay = 0; delay < 0xFFFFF; delay++)
+  {
+    digitalWrite(_rst, HIGH);
+  }
+};
+
+/**
+ * @brief Introduce an uninterruptible delay.
+ *
+ * @details This member calls `digitalRead()` to read the SX1276 RST pin value.
+ * `digitalRead()` utilizes interrupts to work. When calling `wait()`,
+ * this ensures that other interrupt events are temporarily blocked,
+ * allowing the SX1276 registers to be configured without interference.
+ *
+ * @warning This member should only be used within other members of the
+ * Sx1276 class, as blocking interrupts may cause issues with FreeRTOS.
+ * Make sure that the delay remains short if you plan to use them in
+ * members that would be executed in a FreeRTOS task.
+ *
+ * @param delay The delay duration in loop rounds.
+ */
+void Sx1262::wait(uint32_t delay) const
+{
+  for (uint32_t i = 0; i < delay; i++)
+  {
+    digitalRead(_rst);
+  }
+};
+
+/**
+ * @brief Read a register value.
+ * @param reg The register address.
+ */
+uint8_t Sx1262::regRead(uint16_t reg) const
+{
+  /**
+   * Standard method to read data from a device at a specified address via SPI.
+   * pareil, on a un adressage en 16 bits donc on split en 2 adresses sur 8 bits
+   */
+  uint8_t ret;
+  digitalWrite(_cs, LOW);             ///< Lower Chip Select pin
+  SPI.transfer(SX126X_READ_REGISTER); ///< Write the register address with a read-enabled flag
+  SPI.transfer((reg >> 8) & 0xFF);    ///< Write the register address bit [15:8]
+  SPI.transfer(reg & 0xFF);           ///< Write the register address bit [7:0]
+  // read SPI.transfert until it equals 0x00
+  if (SPI.transfer(0x00) == 0xAA) {
+    ret = SPI.transfer(0x00); ///< Read the value at the register address
+  }
+  else {
+    ret = 0x00;
+  }
+  digitalWrite(_cs, HIGH);            ///< Raise Chip Select pin
+  return ret;
+};
+
+/**
+ * @brief Write a value to a register.
+ * @param reg The register address.
+ * @param val The value to write.
+ */ 
+void Sx1262::regWrite(uint16_t reg, uint8_t val) const
+{
+  /**
+   * Standard method to write data to a device at a specified address via SPI.
+   * on a une adresse sur 16 bits, on va donc split en 2 adresses sur 8 bits
+   */
+  digitalWrite(_cs, LOW);   ///< Lower Chip Select pin
+  SPI.transfer(SX126X_WRITE_REGISTER);
+  SPI.transfer((reg >> 8) & 0xFF);  ///< Write the register address bit [15:8]
+  SPI.transfer(reg & 0xFF);         ///< Write the register address bit [7:0]
+  SPI.transfer(val);        ///< Write the value at the register address
+  digitalWrite(_cs, HIGH);  ///< Raise Chip Select pin
+};
+
+/*
+ * @brief Method to read the Status Command Communication
+ * 11.5 Status Commands in datasheet SX1261-2
+ * @param opcode The opcode of the status command
+ * @return The status
+ * 
+ * on aura le Status byte en position 1 tout le temps pour chaque opcode
+ * les autres bytes sont les réponses fonction de l'opcode
+ * on va donc aprser le StatusByte pour vérifier que tout s'est bien passé
+ * puis on va lire le reste de la réponse
+ * 
+ */
+uint8_t Sx1262::readStatusCommand(uint8_t opcode) const
+{
+  digitalWrite(_cs, LOW);
+  SPI.transfer(opcode);
+  uint8_t statusByte = SPI.transfer(0x00);
+
+  // Le 1er byte de réponse c'est le statusCode
+  // on va parser tout ça
+  uint8_t cmdStatus = (statusByte & 0x0E) >> 1;
+  uint8_t cmdChipMode = (statusByte & 0x70) >> 4;
+  logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "SX1262", "cmdStatus : 0x%02X", cmdStatus);
+  logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "SX1262", "cmdChipMode : 0x%02X", cmdChipMode);
+
+  //on parse le status byte pour vérifier que tout s'est bien passé
+  if (cmdStatus == 0x02) logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "[SX1262]", "cmdStatus : Data is available to host");
+  else if (cmdStatus == 0x03) logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "[SX1262]", "cmdStatus : Command timeout");
+  else if (cmdStatus == 0x04) logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "[SX1262]", "cmdStatus : Command processing error");
+  else if (cmdStatus == 0x05) logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "[SX1262]", "cmdStatus : Failure to execute command");
+  else if (cmdStatus == 0x06) logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "[SX1262]", "cmdStatus : Command TX done");
+  else return -1; 
+  
+  // on parse le mode du chip pour vérifier que tout s'est bien passé
+  if (cmdChipMode == 0x02) logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "[SX1262]", "cmdChipMode : STBY_RC ");
+  else if (cmdChipMode == 0x03) logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "[SX1262]", "cmdChipMode : STBY_XOSC ");
+  else if (cmdChipMode == 0x04) logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "[SX1262]", "cmdChipMode : FS");
+  else if (cmdChipMode == 0x05) logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "[SX1262]", "cmdChipMode : RX");
+  else if (cmdChipMode == 0x06) logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "[SX1262]", "cmdChipMode : TX");
+  else return -1;
+
+  switch (opcode) {
+    case (SX126X_GET_RX_BUFFER_STATUS): {
+      uint8_t rxBufferStatus = SPI.transfer(0x00);
+      uint8_t rxBufferPayloadLenghtRx = SPI.transfer(0x00);
+      uint8_t rxBufferRxStartBufferPointer = SPI.transfer(0x00);
+      // todo print the log
+      break;
+    }
+
+    case (SX126X_GET_PKT_STATUS): {
+      uint8_t rxStatus = SPI.transfer(0x00);
+      uint8_t rssiSync = SPI.transfer(0x00);
+      uint8_t rssiAvg = SPI.transfer(0x00);
+      // todo print the log
+      break;
+    }
+
+    case (SX126X_GET_RSSI_INST): {
+      uint8_t rssiValue = SPI.transfer(0x00);
+      // todo print the log 
+      break;
+    }
+
+    case (SX126X_GET_STATS): {
+      uint8_t statsPktReceived2 = SPI.transfer(0x00);
+      uint8_t statsPktReceived1 = SPI.transfer(0x00);
+      uint8_t statsPktError2 = SPI.transfer(0x00);
+      uint8_t statsPktError1 = SPI.transfer(0x00);
+      uint8_t NbPktLengthError2 = SPI.transfer(0x00);
+      uint8_t NbPktLengthError1 = SPI.transfer(0x00);
+      // todo print the log
+      break;
+    }
+
+    default:
+      return -1;
+    
+  }
+  // hé oui, on lache le trig ;)
+  digitalWrite(_cs, HIGH);
+  return 0;
+};
+
+/**
+ * @brief Set the transceiver carrier frequency to work on.
+ * @param freq The carrier frequency in Hz.
+ * @return `0` if successful, `-1` otherwise.
+ */
+int8_t Sx1262::setFreq(uint32_t freq) const
+{
+  int8_t exitCode = 0;
+  /**
+   * @details Carrier frequency conversion for the SX1262 registers
+   * as specified into the datasheet. The covertyed frequency
+   * must stands on 24 bits.
+   */
+  /*
+  uint32_t tmpFreq = static_cast<uint32_t>(
+    round(freq * sx1262::radio_div / sx1262::radio_clk)
+  );
+  if (tmpFreq > 0x00FFFFFF)
+  {
+    /// Handeling too high converted carrier frequency
+    tmpFreq = 0x00FFFFFF;
+    exitCode = -1;
+  }
+  */
+  /**
+   * @details Extract the frequency bytes (MSB, MID, LSB) using bitwise masks.
+   * 
+   * @example With the carrier frequency MSB
+   *
+   * tempFreq: 0x0012AC7E
+   *       &   0x00FF0000 (bitwise AND to take the MSB)
+   *       --------------
+   *           0x00120000
+   *       >> 16          (right shifting on 16 bits)
+   *       --------------
+   *           0x00000012 => REG_FRFMSB
+   */
+  /*
+  uint8_t msb = (tmpFreq & 0x00FF0000) >> 16;
+  regWrite(REG_FRFMSB, msb);
+  uint8_t mid = (tmpFreq & 0x0000FF00) >> 8;
+  regWrite(REG_FRFMID, mid);
+  uint8_t lsb = tmpFreq & 0x000000FF;
+  regWrite(REG_FRFLSB, lsb);
+  */
+  return exitCode;
+};
+
+
+/**
+ * @brief Get the FIFO buffer size.
+ * @return The FIFO size in bytes.
+ */
+uint8_t Sx1262::getFifoSize() const
+{
+  return 0; //regRead(SX126X_REG_RXTX_PAYLOAD_LEN);
+};
+
+
+/**
+ * @brief Perform a FIFO read/write operation.
+ *
+ * @param mode The operation mode (0x00 to read, 0xFF to write).
+ * @param buff The buffer to read/write (as a span of bytes).
+ *
+ * @return `0` if successful.
+ * @return `-1` if the buffer is too short.
+ * @return `-2` if the operation mode is wrong.
+ *
+ * @note A writting should be performed only if the SX1276 is in idle mode.
+ * @see At namespace sx1276: fifo_read and fifo_write
+ * @see rxToStdby() 
+ */
+int8_t Sx1262::fifo(uint8_t mode, uint8_t *buff) const
+{
+  int8_t exitCode = 0;
+  /*
+  uint8_t sz = getFifoSize();
+  if (mode == sx1262::fifo_read)
+  {
+    if (sz + 1 <= sizeof(buff))
+    {
+      /// Reading by using special internal FIFO buffer SPI burst method
+      digitalWrite(_cs, LOW);
+      SPI.transfer(REG_FIFO);
+      for (uint8_t i = 0; i < sz; i++)
+      {
+        /// Byte-per-byte reading without the need to reselect the address
+        buff[i] = SPI.transfer(0x00);
+      }
+      digitalWrite(_cs, HIGH);
+    }
+    else
+      /// Handeling too short buffer
+      exitCode = -1;
+  }
+  else if (mode == sx1262::fifo_write)
+  {
+    /// Writting by using special internal FIFO buffer SPI burst method
+    regWrite(REG_OPMODE, 0x01);
+    wait(0xFFFF);
+    digitalWrite(_cs, LOW);
+    SPI.transfer(REG_FIFO | 0x80);
+    for (uint8_t i = 0; i < sz; i++)
+    {
+      /// Byte-per-byte writting without the need to reselect the address
+      SPI.transfer(buff[i]);
+    }
+    digitalWrite(_cs, HIGH);
+  }
+  else
+    /// Handeling wrong modes
+    exitCode = -2;
+
+  */
+  return exitCode;
+};
+
+
+
+int8_t Sx1262::setTxConfig(uint32_t freq, uint8_t debug) const
+{
+  int8_t exitCode = 0;
+  regWrite(0x01, 0x01);
+  wait(0xFFFF);
+
+
+  return exitCode;
+};
+

+ 123 - 0
src/sx1262.h

@@ -0,0 +1,123 @@
+/**
+ * @file sx1262.h
+ * @brief Header file for the SX1276 transceiver class.
+ *
+ * This file provides the `Sx1262` class implementation, to control the SX126
+ * transceiver. It includes methods for configuring the device, reading/writing
+ * registers, and managing the FIFO buffer.
+ *
+ * @details The class is currently designed to use the SX126x in BFSK
+ * configuration, but it supports many others digital modulations.
+ * The SX1262 is commonly used in LoRa communication systems.
+ * This class tries to abstract the hardware-level details and offers an API 
+ * to work with the SX1276 on ESP32 platforms.
+ *
+ * @author Julia CABARBAYE (Student, ENSIL-ENSCI [ELT], France)
+ * @author Adrien CHEVRIER (Student, ENSIL-ENSCI [ELT], France)
+ *
+ * @date Created on: 2024-11-25
+ * @date Last updated: 2025-01-05
+ *
+ * @see { @link https://www.semtech.fr/products/wireless-rf/lora-connect/sx1276 }
+ * for detailed information about the SX1276.  
+ */
+
+#ifndef SX1262_H
+#define SX1262_H
+
+#include <stdint.h>
+#include <Arduino.h>
+#include <SPI.h>
+#include <Adafruit_ST7735.h>
+
+#include "sx1262regs.h"
+
+/**
+ * @namespace sx1262
+ * @brief Contains constants related to the SX1276 transceiver.
+ *
+ * This namespace holds static constants such as clock frequency, FIFO size,
+ * and default read/write commands.
+ */
+namespace sx1262
+{
+  constexpr double radio_clk = 32E6;     ///< SX1276 clock frequency in Hz.
+  constexpr double radio_div = 524288.0; ///< Divider for frequency calculations (2^19).
+  constexpr uint8_t fifo_len = 64;       ///< FIFO size in bytes
+  constexpr uint8_t fifo_read = 0x00;    ///< Command to read from FIFO.
+  constexpr uint8_t fifo_write = 0xFF;   ///< Command to write to FIFO.
+}
+
+/**
+ * @class Sx1262
+ * @brief A class to manage the Sx1262 transceiver.
+ *
+ * This class provides an interface to interact with the Sx1262 transceiver,
+ * including methods for frequency configuration, reading/writing registers, 
+ * handling FIFO operations, and managing pin states.
+ */
+class Sx1262
+{
+  public:
+    /**
+     * @brief Constructor for the Sx1262 class.
+     *
+     * @param rst Reset pin.
+     * @param sclk SPI clock pin.
+     * @param mosi SPI MOSI pin.
+     * @param miso SPI MISO pin.
+     * @param cs Chip select pin.
+     * @param dio1 Digital Input/Output pin DIO1.
+     * 
+     */
+    Sx1262(
+      uint8_t rst,
+      uint8_t sclk,
+      uint8_t mosi,
+      uint8_t miso,
+      uint8_t cs,
+      uint8_t dio1
+    ) : 
+      _rst(rst),
+      _sclk(sclk),
+      _mosi(mosi),
+      _miso(miso),
+      _cs(cs),
+      _dio1(dio1)
+    { }
+
+
+    void beginSPI() const;
+    uint8_t getRst() const;
+    uint8_t getDio(uint8_t n = 0) const;
+    uint8_t getSclk() const;
+    uint8_t getMosi() const;
+    uint8_t getMiso() const;
+    uint8_t getCs() const;
+    void reset() const;
+    void wait(uint32_t delay) const;
+    uint8_t regRead(uint16_t reg) const;
+    void regWrite(uint16_t reg, uint8_t val) const;
+    uint8_t readStatusCommand(uint8_t opcode) const;
+    int8_t setFreq(uint32_t freq) const;
+    uint32_t getFreq() const;
+    uint8_t getFifoSize() const;
+    int8_t getRssi() const;
+    int8_t fifo(uint8_t mode, uint8_t *buff) const;
+    int8_t setTxConfig(uint32_t freq, uint8_t debug) const;
+    int8_t txToStdby(uint8_t debug) const;
+    int8_t stdbyToTx(uint8_t debug) const;
+    void freqUpdate(uint32_t freq,uint8_t debug) const;
+
+  private:
+    uint8_t _rst;  ///< Reset pin.
+    uint8_t _sclk; ///< SPI clock pin.
+    uint8_t _mosi; ///< SPI MOSI pin.
+    uint8_t _miso; ///< SPI MISO pin.
+    uint8_t _cs;   ///< Chip select pin.
+    uint8_t _dio1; ///< DIO1 pin.
+    uint8_t _dio2; ///< DIO2 pin.
+    uint8_t _dio3; ///< DIO3 pin.
+};
+
+#endif //SX1262_H

+ 228 - 0
src/sx1262regs.h

@@ -0,0 +1,228 @@
+#ifndef SX126X_REGS_H
+#define SX126X_REGS_H
+
+// Operational Modes Functions
+#define SX126X_SET_SLEEP                    0x84
+#define SX126X_SET_STANDBY                  0x80
+#define SX126X_SET_FS                       0xC1
+#define SX126X_SET_TX                       0x83
+#define SX126X_SET_RX                       0x82
+#define SX126X_SET_STOP_TIMER_ON_PREAMBLE   0x9F
+#define SX126X_SET_RX_DUTY_CYCLE            0x94
+#define SX126X_SET_CAD                      0xC5
+#define SX126X_SET_TX_CONTINUOUS_WAVE       0xD1
+#define SX126X_SET_TX_INFINITE_PREAMBLE     0xD2
+#define SX126X_SET_REGULATOR_MODE           0x96
+#define SX126X_CALIBRATE                    0x89
+#define SX126X_CALIBRATE_IMAGE              0x98
+#define SX126X_SET_PA_CFG                   0x95
+#define SX126X_SET_RX_TX_FALLBACK_MODE      0x93
+
+// Registers and buffer Access
+#define SX126X_WRITE_REGISTER               0x0D
+#define SX126X_READ_REGISTER                0x1D
+#define SX126X_WRITE_BUFFER                 0x0E
+#define SX126X_READ_BUFFER                  0x1E
+
+// DIO and IRQ Control Functions
+#define SX126X_SET_DIO_IRQ_PARAMS           0x08
+#define SX126X_GET_IRQ_STATUS               0x12
+#define SX126X_CLR_IRQ_STATUS               0x02
+#define SX126X_SET_DIO2_AS_RF_SWITCH_CTRL   0x9D
+#define SX126X_SET_DIO3_AS_TCXO_CTRL        0x97
+
+// RF Modulation and Packet-Related Functions
+#define SX126X_SET_RF_FREQUENCY             0x86
+#define SX126X_SET_PKT_TYPE                 0x8A
+#define SX126X_GET_PKT_TYPE                 0x11
+#define SX126X_SET_TX_PARAMS                0x8E
+#define SX126X_SET_MODULATION_PARAMS        0x8B
+#define SX126X_SET_PKT_PARAMS               0x8C
+#define SX126X_SET_CAD_PARAMS               0x88
+#define SX126X_SET_BUFFER_BASE_ADDRESS      0x8F
+#define SX126X_SET_LORA_SYMB_NUM_TIMEOUT    0xA0
+
+// Communication Status Information
+#define SX126X_GET_STATUS                   0xC0
+#define SX126X_GET_RX_BUFFER_STATUS         0x13
+#define SX126X_GET_PKT_STATUS               0x14
+#define SX126X_GET_RSSI_INST                0x15
+#define SX126X_GET_STATS                    0x10
+#define SX126X_RESET_STATS                  0x00
+
+// Miscellaneous
+
+#define SX126X_GET_DEVICE_ERRORS            0x17
+#define SX126X_CLR_DEVICE_ERRORS            0x07
+
+
+/* et la suite des registres ici */
+/**
+ * @brief The address of the register holding the first byte defining the CRC seed
+ */
+#define SX126X_REG_CRCSEEDBASEADDRESS 0x06BC
+
+/**
+ * @brief The address of the register holding the first byte defining the CRC polynomial
+ */
+#define SX126X_REG_CRCPOLYBASEADDRESS 0x06BE
+
+/**
+ * @brief The address of the register holding the first byte defining the whitening seed
+ */
+#define SX126X_REG_WHITSEEDBASEADDRESS 0x06B8
+
+/**
+ * @brief The addresses of the registers holding SyncWords values
+ */
+#define SX126X_REG_SYNCWORDBASEADDRESS 0x06C0
+
+/**
+ * @brief The addresses of the register holding LoRa Modem SyncWord value
+ *        0x1424: LoRaWAN private network,
+ *        0x3444: LoRaWAN public network
+ */
+#define SX126X_REG_LR_SYNCWORD 0x0740
+
+/**
+ * @brief The address of the register holding the coding rate configuration extracted from a received LoRa header
+ */
+#define SX126X_REG_LR_HEADER_CR 0x0749
+#define SX126X_REG_LR_HEADER_CR_POS ( 4U )
+#define SX126X_REG_LR_HEADER_CR_MASK ( 0x07UL << SX126X_REG_LR_HEADER_CR_POS )
+
+/**
+ * @brief The address of the register holding the CRC configuration extracted from a received LoRa header
+ */
+#define SX126X_REG_LR_HEADER_CRC 0x076B
+#define SX126X_REG_LR_HEADER_CRC_POS ( 4U )
+#define SX126X_REG_LR_HEADER_CRC_MASK ( 0x01UL << SX126X_REG_LR_HEADER_CRC_POS )
+
+/*!
+ * The address of the register giving a 32-bit random number
+ */
+#define SX126X_REG_RNGBASEADDRESS 0x0819
+
+/*!
+ * The address of the register used to disable the LNA
+ */
+#define SX126X_REG_ANA_LNA 0x08E2
+
+/*!
+ * The address of the register used to disable the mixer
+ */
+#define SX126X_REG_ANA_MIXER 0x08E5
+
+/*!
+ * The address of the register holding RX Gain value
+ *     0x94: power saving,
+ *     0x96: rx boosted
+ */
+#define SX126X_REG_RXGAIN 0x08AC
+
+/**
+ * @brief Change the value on the device internal trimming capacitor
+ */
+#define SX126X_REG_XTATRIM 0x0911
+
+/**
+ * @brief Set the current max value in the over current protection
+ */
+#define SX126X_REG_OCP 0x08E7
+
+/**
+ * @brief WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4
+ */
+#define SX126X_REG_IQ_POLARITY 0x0736
+
+/**
+ * @brief WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 15.1
+ */
+#define SX126X_REG_TX_MODULATION 0x0889
+
+/**
+ * @brief WORKAROUND - Better resistance to antenna mismatch, see DS_SX1261-2_V1.2 datasheet chapter 15.2
+ */
+#define SX126X_REG_TX_CLAMP_CFG 0x08D8
+#define SX126X_REG_TX_CLAMP_CFG_POS ( 1U )
+#define SX126X_REG_TX_CLAMP_CFG_MASK ( 0x0FUL << SX126X_REG_TX_CLAMP_CFG_POS )
+
+/**
+ * @brief RTC control
+ */
+#define SX126X_REG_RTC_CTRL 0x0902
+
+/**
+ * @brief Event clear
+ */
+#define SX126X_REG_EVT_CLR 0x0944
+#define SX126X_REG_EVT_CLR_TIMEOUT_POS ( 1U )
+#define SX126X_REG_EVT_CLR_TIMEOUT_MASK ( 0x01UL << SX126X_REG_EVT_CLR_TIMEOUT_POS )
+
+/**
+ * @brief RX address pointer
+ */
+#define SX126X_REG_RX_ADDRESS_POINTER 0x0803
+
+/**
+ * @brief RX/TX payload length
+ */
+#define SX126X_REG_RXTX_PAYLOAD_LEN 0x06BB
+
+/**
+ * @brief Output disable
+ */
+#define SX126X_REG_OUT_DIS_REG 0x0580
+#define SX126X_REG_OUT_DIS_REG_DIO3_POS ( 3U )
+#define SX126X_REG_OUT_DIS_REG_DIO3_MASK ( 0x01UL << SX126X_REG_OUT_DIS_REG_DIO3_POS )
+
+/**
+ * @brief Input enable
+ */
+#define SX126X_REG_IN_EN_REG 0x0583
+#define SX126X_REG_IN_EN_REG_DIO3_POS ( 3U )
+#define SX126X_REG_IN_EN_REG_DIO3_MASK ( 0x01UL << SX126X_REG_IN_EN_REG_DIO3_POS )
+
+/**
+ * @brief TX bitbang A
+ */
+#define SX126X_REG_BITBANG_A_REG 0x0680
+#define SX126X_REG_BITBANG_A_REG_ENABLE_POS ( 4U )
+#define SX126X_REG_BITBANG_A_REG_ENABLE_MASK ( 0x07UL << SX126X_REG_BITBANG_A_REG_ENABLE_POS )
+#define SX126X_REG_BITBANG_A_REG_ENABLE_VAL ( 0x01UL << SX126X_REG_BITBANG_A_REG_ENABLE_POS )
+
+/**
+ * @brief TX bitbang B
+ */
+#define SX126X_REG_BITBANG_B_REG 0x0587
+#define SX126X_REG_BITBANG_B_REG_ENABLE_POS ( 0U )
+#define SX126X_REG_BITBANG_B_REG_ENABLE_MASK ( 0x0FUL << SX126X_REG_BITBANG_B_REG_ENABLE_POS )
+#define SX126X_REG_BITBANG_B_REG_ENABLE_VAL ( 0x0CUL << SX126X_REG_BITBANG_B_REG_ENABLE_POS )
+
+/**
+ * @brief Number of symbols given as SX126X_REG_LR_SYNCH_TIMEOUT[7:3] * 2 ^ (2*SX126X_REG_LR_SYNCH_TIMEOUT[2:0] + 1)
+ */
+#define SX126X_REG_LR_SYNCH_TIMEOUT 0x0706
+
+/**
+ * @brief Base address of the register retention list
+ */
+#define SX126X_REG_RETENTION_LIST_BASE_ADDRESS 0x029F
+
+/**
+ * @brief GFSK node address
+ *
+ * @remark Reset value is 0x00
+ */
+#define SX126X_REG_GFSK_NODE_ADDRESS 0x06CD
+
+/**
+ * @brief GFSK broadcast address
+ *
+ * @remark Reset value is 0x00
+ */
+#define SX126X_REG_GFSK_BROADCAST_ADDRESS 0x06CE
+
+
+
+#endif // SX126XREGS_H

+ 11 - 0
test/README

@@ -0,0 +1,11 @@
+
+This directory is intended for PlatformIO Test Runner and project tests.
+
+Unit Testing is a software testing method by which individual units of
+source code, sets of one or more MCU program modules together with associated
+control data, usage procedures, and operating procedures, are tested to
+determine whether they are fit for use. Unit testing finds problems early
+in the development cycle.
+
+More information about PlatformIO Unit Testing:
+- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html