Semtech SX1278 модуль DRF1278F - FSK модуляция
- Войдите на сайт для отправки комментариев
Сб, 04/02/2017 - 02:23
Всем привет.
Я начал работать с модулем DRF1278F созданном на чипе SX1278. Я испытал радиосвязь в режиме LoRa с применением например библиотеки RadioHead и все произошло в порядке. Но для меня является угодным режим FSK. Я хочу сделать свой код простым прежде всего на исходных значениях чипа с минимальной корректировкой. Я написал основной код для Rx и Тx, но код неработает правильно и я не знаю вот кде ошибка. Кроме того мне этот режим нужен для работы от батарейного питания с применением режима Idle(sleep + RC). Я буду рад если кто работающий с этой штукой помог бы мне исправить или добавить код. Спасибо.
Код для Rx:
#include <SPI.h>
uint8_t RADIO_SS = 10;
uint8_t RADIO_RST = 9;
/* ===================================================================
* SX1276-8 Internal registers Address
* ===================================================================
*/
#define REG_FIFO 0x00
// Common settings
#define REG_OPMODE 0x01
#define RF_OPMODE_MASK 0xF8
#define RF_OPMODE_SLEEP 0x00
#define RF_OPMODE_STANDBY 0x01 // Default
#define RF_OPMODE_SYNTHESIZER_TX 0x02
#define RF_OPMODE_TRANSMITTER 0x03
#define RF_OPMODE_SYNTHESIZER_RX 0x04
#define RF_OPMODE_RECEIVER 0x05
// Tx settings
#define REG_PACONFIG 0x09
#define RF_PACONFIG_PASELECT_MASK 0x7F
#define RF_PACONFIG_PASELECT_PABOOST 0x80
#define RF_PACONFIG_PASELECT_RFO 0x00 // Default
#define RF_PACONFIG_MAX_POWER_MASK 0x8F
#define RF_PACONFIG_OUTPUTPOWER_MASK 0xF0
// Rx settings
#define REG_LNA 0x0C
#define REG_RXCONFIG 0x0D
#define RF_RXCONFIG_RESTARTRXONCOLLISION_MASK 0x7F
#define RF_RXCONFIG_RESTARTRXONCOLLISION_ON 0x80
#define RF_RXCONFIG_RESTARTRXONCOLLISION_OFF 0x00 // Default
#define RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK 0x40 // Write only
#define RF_RXCONFIG_RESTARTRXWITHPLLLOCK 0x20 // Write only
#define RF_RXCONFIG_AFCAUTO_MASK 0xEF
#define RF_RXCONFIG_AFCAUTO_ON 0x10
#define RF_RXCONFIG_AFCAUTO_OFF 0x00 // Default
#define RF_RXCONFIG_AGCAUTO_MASK 0xF7
#define RF_RXCONFIG_AGCAUTO_ON 0x08 // Default
#define RF_RXCONFIG_AGCAUTO_OFF 0x00
#define RF_RXCONFIG_RXTRIGER_MASK 0xF8
#define RF_RXCONFIG_RXTRIGER_OFF 0x00
#define RF_RXCONFIG_RXTRIGER_RSSI 0x01
#define RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT 0x06 // Default
#define RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT 0x07
// Packet handler settings
#define REG_PREAMBLEMSB 0x25
#define REG_PREAMBLELSB 0x26
#define REG_SYNCCONFIG 0x27
#define REG_SYNCVALUE1 0x28
#define REG_SYNCVALUE2 0x29
#define REG_SYNCVALUE3 0x2A
#define REG_SYNCVALUE4 0x2B
#define REG_PAYLOADLENGTH 0x32
#define REG_FIFOTHRESH 0x35
// Status
#define REG_IRQFLAGS1 0x3E
#define RF_IRQFLAGS1_MODEREADY 0x80
#define RF_IRQFLAGS1_RXREADY 0x40
#define RF_IRQFLAGS1_TXREADY 0x20
#define RF_IRQFLAGS1_PLLLOCK 0x10
#define RF_IRQFLAGS1_RSSI 0x08
#define RF_IRQFLAGS1_TIMEOUT 0x04
#define RF_IRQFLAGS1_PREAMBLEDETECT 0x02
#define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01
#define REG_IRQFLAGS2 0x3F
#define RF_IRQFLAGS2_FIFOFULL 0x80
#define RF_IRQFLAGS2_FIFOEMPTY 0x40
#define RF_IRQFLAGS2_FIFOLEVEL 0x20
#define RF_IRQFLAGS2_FIFOOVERRUN 0x10
#define RF_IRQFLAGS2_PACKETSENT 0x08
#define RF_IRQFLAGS2_PAYLOADREADY 0x04
#define RF_IRQFLAGS2_CRCOK 0x02
#define RF_IRQFLAGS2_LOWBAT 0x01
namespace Radio {
void init();
void configTx();
void configRx();
void sendMsg(unsigned char *buffer, uint8_t size);
void receiveMsg();
void readFifo(unsigned char *buffer, uint8_t size);
void writeFifo(unsigned char *buffer, uint8_t size);
void reset();
void sleep();
void standby();
}
namespace Spi {
void init();
uint8_t readRegister(uint8_t reg);
uint8_t writeRegister(uint8_t reg, uint8_t val);
void readBurst(uint8_t reg, uint8_t *buffer, uint8_t len);
void writeBurst(uint8_t reg, uint8_t *buffer, uint8_t len);
}
unsigned char msg[] = "This is message!";
const uint8_t RX_BUFFER_SIZE = 0xFF;
unsigned char rxBuffer[RX_BUFFER_SIZE];
void setup()
{
Serial.begin(9600);
Radio::init();
Radio::configTx();
for (uint8_t i = 0; i <= 0x70; i++) {
Serial.print("Register ");
Serial.print(i, HEX);
Serial.print(" : ");
Serial.println(Spi::readRegister(i), HEX);
}
Serial.println("End of initialization!");
Serial.println("RX ready...");
Radio::receiveMsg();
}
void loop()
{
if (Spi::readRegister(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY)
{
Radio::readFifo( rxBuffer, 0x2F);
// clear the flags
Spi::writeRegister( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
Serial.println("data!");
// restart th receiver
Spi::writeRegister( REG_RXCONFIG, Spi::readRegister( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
for(int i = 0; i < 0x2F; i++)
{
Serial.println(rxBuffer[i], HEX);
}
}
}
namespace Radio {
void init()
{
// Initialise the interrupt pin - monitor the PacketDone pin.
//pinMode(sx1276_di0_, INPUT_PULLUP);
// Initialise the slave select pin.
// Set the RADIO_SS as disabled and then as output (to avoid a glitch during init)
digitalWrite(RADIO_SS, HIGH);
pinMode(RADIO_SS, OUTPUT);
// Initialise the slave select pin.
digitalWrite(RADIO_RST, HIGH);
pinMode(RADIO_RST, OUTPUT);
// Reset radio
reset();
// initialise SPI:
Spi::init();
}
void configTx()
{
sleep();
Spi::writeRegister(REG_PACONFIG, Spi::readRegister(REG_PACONFIG) | RF_PACONFIG_PASELECT_PABOOST);
Spi::writeRegister(REG_SYNCVALUE1, 0xD3);
Spi::writeRegister(REG_SYNCVALUE2, 0x91);
Spi::writeRegister(REG_SYNCVALUE3, 0xDA);
Spi::writeRegister(REG_SYNCVALUE4, 0x26);
Spi::writeRegister(REG_FIFOTHRESH, 0x0A);
}
void configRx()
{
sleep();
//Spi::writeRegister(REG_PACONFIG, Spi::readRegister(REG_PACONFIG) | RF_PACONFIG_PASELECT_PABOOST);
Spi::writeRegister(REG_SYNCVALUE1, 0xD3);
Spi::writeRegister(REG_SYNCVALUE2, 0x91);
Spi::writeRegister(REG_SYNCVALUE3, 0xDA);
Spi::writeRegister(REG_SYNCVALUE4, 0x26);
Spi::writeRegister( REG_PAYLOADLENGTH, 0xFF );
}
void sendMsg(unsigned char *buffer, uint8_t size)
{
// write the buffer to the FIFO: FIFO size is only 64 bytes so the chunk must fit!
writeFifo( buffer, size );
// turn the transmitter ON
Spi::writeRegister(REG_OPMODE, Spi::readRegister(REG_OPMODE) | RF_OPMODE_SYNTHESIZER_TX);
Spi::writeRegister(REG_OPMODE, Spi::readRegister(REG_OPMODE) | RF_OPMODE_TRANSMITTER);
}
void receiveMsg()
{
// turn the receiver ON
Spi::writeRegister(REG_OPMODE, Spi::readRegister(REG_OPMODE) | RF_OPMODE_SYNTHESIZER_RX);
Spi::writeRegister(REG_OPMODE, Spi::readRegister(REG_OPMODE) | RF_OPMODE_RECEIVER);
}
void readFifo(unsigned char *buffer, uint8_t size)
{
Spi::readBurst( REG_FIFO, buffer, size );
}
void writeFifo(unsigned char *buffer, uint8_t size)
{
Spi::writeBurst( REG_FIFO, buffer, size );
}
void reset()
{
digitalWrite(RADIO_RST, LOW);
delay(10);
digitalWrite(RADIO_RST, HIGH);
delay(20);
}
void sleep()
{
Spi::writeRegister(REG_OPMODE, Spi::readRegister(REG_OPMODE) | RF_OPMODE_SLEEP);
}
void standby()
{
Spi::writeRegister(REG_OPMODE, Spi::readRegister(REG_OPMODE) | RF_OPMODE_STANDBY);
}
}
namespace Spi {
// This is the bit in the SPI address that marks it as a write
static const uint8_t SPI_WRITE_MASK = 0x80;
void init()
{
// Start the SPI library with the default values
SPI.begin();
// Set Most significant bit first
SPI.setBitOrder(MSBFIRST);
// Divide the clock frequency
SPI.setClockDivider(SPI_CLOCK_DIV2);
// Set data mode
SPI.setDataMode(SPI_MODE0);
delay(100);
}
uint8_t readRegister(uint8_t reg)
{
uint8_t value = 0x00;
digitalWrite(RADIO_SS, LOW); // take slave select pin low to select the chip
SPI.transfer(reg & ~SPI_WRITE_MASK); // send the address with the write mask off
value = SPI.transfer(0x00); // the written value is ignored, reg value is read
digitalWrite(RADIO_SS, HIGH); // take slave select pin high to deselect the chip
return value;
}
uint8_t writeRegister(uint8_t reg, uint8_t val)
{
uint8_t status = 0x00;
digitalWrite(RADIO_SS, LOW); // take slave select pin low to select the chip
status = SPI.transfer(reg | SPI_WRITE_MASK); // send the address with the write mask on
SPI.transfer(val); // write new value
digitalWrite(RADIO_SS, HIGH);
return status;
}
void readBurst(uint8_t reg, uint8_t *buffer, uint8_t len)
{
digitalWrite(RADIO_SS, LOW); // take slave select pin low to select the chip
SPI.transfer(reg & ~SPI_WRITE_MASK); // send the address with the write mask off
// read the value
for (uint8_t i = 0; i < len; i++)
{
buffer[i] = SPI.transfer(0);
}
digitalWrite(RADIO_SS, HIGH); // take slave select pin high to deselect the chip
}
void writeBurst(uint8_t reg, uint8_t *buffer, uint8_t len)
{
digitalWrite(RADIO_SS, LOW); // take slave select pin low to select the chip
SPI.transfer(reg | SPI_WRITE_MASK); // send the address with the write mask on
// write new value
for (unsigned char i = 0; i < len; i++)
{
SPI.transfer(buffer[i]);
}
digitalWrite(RADIO_SS, HIGH); // take slave select pin high to deselect the chip
}
}
Код для Tx:
unsigned char msg[] = "This is message!";
void setup()
{
Serial.begin(9600);
Radio::init();
Radio::configTx();
for (uint8_t i = 0; i <= 0x70; i++) {
Serial.print("Register ");
Serial.print(i, HEX);
Serial.print(" : ");
Serial.println(Spi::readRegister(i), HEX);
}
Serial.println("End of initialization!");
}
void loop()
{
Radio::sendMsg(msg, sizeof(msg)/sizeof(msg[0]));
Serial.println( "Message sent !" );
//Radio::sleep();
delay(5000);
}
Остальное ка в Rx.