Skip to content

Commit

Permalink
[driver] Adding SX128x driver
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmuskleist committed Jul 14, 2023
1 parent 027811f commit 000868a
Show file tree
Hide file tree
Showing 6 changed files with 1,943 additions and 0 deletions.
219 changes: 219 additions & 0 deletions src/modm/driver/radio/sx128x.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*
* Copyright (c) 2023, Lasse Alexander Jensen
* Copyright (c) 2023, Rasmus Kleist Hørlyck Sørensen
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#ifndef MODM_SX128X_HPP
#define MODM_SX128X_HPP

#include <modm/architecture/interface/spi_device.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing/resumable.hpp>

#include "sx128x_definitions.hpp"
#include "sx128x_hal.hpp"

namespace modm
{

/**
* @tparam Hal Hardware Abstraction Layer for SX128x
*
* @ingroup modm_driver_sx128x
* @author Lasse Alexander Jensen
* @author Rasmus Kleist Hørlyck Sørensen
*/
template< class Hal >
class Sx128x : public sx128x, public Hal
{
public:
Sx128x();

/// Get the transciever status directly.
/// @attention this command can be issued at any time as long as it is not the very first command send over the interface
modm::ResumableResult<bool>
getStatus(Status &status);

/// Writes a block of bytes in a data memory space starting at a specific address
modm::ResumableResult<bool>
writeRegister(Register reg, uint8_t data);

/// Writes a block of bytes in a data memory space starting at a specific address
modm::ResumableResult<bool>
writeRegister(Register reg, uint8_t *data, size_t length);

/// Read a block of data starting at a given address
modm::ResumableResult<bool>
readRegister(Register reg, uint8_t &data);

/// Read a block of data starting at a given address
modm::ResumableResult<bool>
readRegister(Register reg, uint8_t *data, size_t length);

/// This function is used to write the data payload to be transmitted
/// @attention When the address exceeds 255 it wraps back to 0 due to the circular nature of data buffer
modm::ResumableResult<bool>
writeBuffer(uint8_t offset, uint8_t *data, size_t length);

/// This function allows reading (n-3) bytes of payload received starting at offset
modm::ResumableResult<bool>
readBuffer(uint8_t offset, uint8_t *data, size_t length);

/// Set the transceiver to Sleep mode with the lowest current consumption possible
/// @warning Depending on the specified level of memory retention not all instruction will be retained
modm::ResumableResult<bool>
setSleep(SleepConfig_t sleepConfig);

/// Set the device in either STDBY_RC or STDBY_XOSC mode which are intermediate levels of power consumption
/// By default in this state, the system is clocked by the 13 MHz RC oscillator to reduce power consumption.
/// However if the application is time critical, the XOSC block can be turned or left ON.
/// @attention In this Standby mode, the transceiver may be configured for future F operations
modm::ResumableResult<bool>
setStandby(Oscillator oscillatorMode = Oscillator::Rc);

/// Set the device in Frequency Synthesizer mode where the PLL is locked to the carrier frequency
/// @attention In normal operation of the transceiver, the user does not normally need to use FS mode
modm::ResumableResult<bool>
setFs();

/// Set the device in Transmit mode
/// @warning The IRQ status must be cleared before using this command
modm::ResumableResult<bool>
setTx(PeriodBase periodBase, uint16_t periodBaseCount);

/// Set the device in Reciever mode
/// @warning The IRQ status must be cleared before using this command
/// @attention Setting periodBaseCount = 0 puts the transciever in RX Single Mode
/// @attention Setting periodBaseCount = 0xFFFF puts the transciever in Rx Continuous mode
modm::ResumableResult<bool>
setRx(PeriodBase periodBase, uint16_t periodBaseCount);

/// Set the transceiver in sniff mode, so that it regularly looks for new packets
/// @warning RxDone interrupt must be configured prior to enter Duty cycled operations
/// @warning SetLongPreamble must be issued prior to setRxDutyCycle
modm::ResumableResult<bool>
setRxDutyCycle(PeriodBase periodBase, uint16_t rxPeriodBaseCount, uint16_t sleepPeriodBaseCount);

/// Set the transceiver to use CAD (Channel Activity Detection) mode
/// @warning The Channel Activity Detection is a LoRa specific mode of operation
modm::ResumableResult<bool>
setCad();

/// Set the transciever to generate a Continuous Wave (RF tone) at a selected frequency and output power
/// @attention The device remains in Tx Continuous Wave until the host sends a mode confiquration command.
modm::ResumableResult<bool>
setTxContinuousWave();

/// Set the transciever to generate an infinite sequence of alternating 'O's and '1's in GFSK modulation and symbol 0 in LoRa
/// @attention The device remains in transmit until the host sends a mode confiquration command
modm::ResumableResult<bool>
setTxContinuousPreamble();

/// Set the transceiver radio frame out of a choice of 5 different packet types
/// @attention the packet type must be set first in the radio configuration sequence
modm::ResumableResult<bool>
setPacketType(PacketType packetType);

/// Get the current operating packet type of the radio
modm::ResumableResult<bool>
getPacketType(PacketType &packetType);

/// Set the frequency of the RF frequency mode.
modm::ResumableResult<bool>
setRfFrequency(uint32_t rfFrequency);

/// Set the Tx output power and the Tx ramp time
/// @attention the physical output power is in the range [-18..13]dBm
modm::ResumableResult<bool>
setTxParams(uint8_t power, RampTime rampTime);

/// Set the number of symbols on which which Channel Activity Detected (CAD) operates
modm::ResumableResult<bool>
setCadParams(CadSymbolNumber cadSymbolNumber);

/// Set the base address for the packet handling operation in Tx and Rx mode for all packet types
modm::ResumableResult<bool>
setBufferBaseAddress(uint8_t txBaseAddress, uint8_t rxBaseAddress);

/// Set the modulation parameters of the radio
/// @attention The modulation parameters will be interpreted depending on the frame type
modm::ResumableResult<bool>
setModulationParams(ModulationParams modulationParams);

/// Set the parameters of the packet handling block
/// @warning Interpretation by the transceiver of the packet parameters depends upon the chosen packet type
modm::ResumableResult<bool>
setPacketParams(PacketParams packetParams);

/// Get length of the last received packet and the address of the first byte received
modm::ResumableResult<bool>
getRxBufferStatus(RxBufferStatus &rxBufferStatus);

/// Retrieve information about the last received packet
/// @attention The returned parameters are frame-dependent
modm::ResumableResult<bool>
getPacketStatus(PacketStatus &packetStatus);

/// Get the instantaneous RSSI value during reception of the packet
modm::ResumableResult<bool>
getRssiInst(uint8_t &rssiInst);

/// Enable IRQs and to route IRQs to DIO pins.
modm::ResumableResult<bool>
setDioIrqParams(Irq_t irqMask, Irq_t dio1Mask = Irq_t(), Irq_t dio2Mask = Irq_t(), Irq_t dio3Mask = Irq_t());

/// Get the value of the IRQ register
modm::ResumableResult<bool>
getIrqStatus(Irq_t &irqStatus);

/// Clear IRQ flags in the IRQ register
modm::ResumableResult<bool>
clearIrqStatus(Irq_t irqMask);

/// Specify if DC-DC or LDO is used for power regulation
modm::ResumableResult<bool>
setRegulatorMode(RegulatorMode regModeParam);

/// Save the present context of the radio register values to the Data RAM
modm::ResumableResult<bool>
setSaveContext();

/// Set the chip so that the state following a Rx or Tx operation is FS and not STDBY
/// This feature is to be used to reduce the switching time between consecutive Rx and/or Tx operations
modm::ResumableResult<bool>
setAutoFs(bool enable = true);

/// Set the device to be able to send back a response 150 us after a packet reception
modm::ResumableResult<bool>
setAutoTx(uint16_t time);

/// Set the transceiver into Long Preamble mode
/// @warning Long Preamble mode can only be used with either LoRa mode and GFSK mode
modm::ResumableResult<bool>
setLongPreamble(bool enable = true);

/// Set the role of the transciever in ranging operation
modm::ResumableResult<bool>
setRangingRole(RangingRole rangingRole);

/// Enable advanced ranging
modm::ResumableResult<bool>
setAdvancedRanging(bool enable = true);

private:
uint8_t buffer[8];

};

}

#include "sx128x_impl.hpp"

#endif
37 changes: 37 additions & 0 deletions src/modm/driver/radio/sx128x.lb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023, Rasmus Kleist Hørlyck Sørensen
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------


def init(module):
module.name = ":driver:sx128x"
module.description = """\
Semtech SX1280/SX1281 Driver
Long Range, Low Power, 2.4 GHz Transceiver with Ranging Capability
"""

def prepare(module, options):
module.depends(
":architecture:gpio",
":architecture:spi.device",
":math:utils",
":processing:resumable",
":processing:timer")
return True

def build(env):
env.outbasepath = "modm/src/modm/driver/radio"
env.copy("sx128x.hpp")
env.copy("sx128x_impl.hpp")
env.copy("sx128x_definitions.hpp")
env.copy("sx128x_hal.hpp")
env.copy("sx128x_hal_impl.hpp")
Loading

0 comments on commit 000868a

Please sign in to comment.