Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: alarm_slave iq_sx126x sx126x_simple_TX_shield_2020a sx126x_simple_RX_shield_2020a ... more
Revision 2:e6e159c8ab4d, committed 2018-06-11
- Comitter:
- Wayne Roberts
- Date:
- Mon Jun 11 11:15:18 2018 -0700
- Parent:
- 1:497af0bd9e53
- Child:
- 3:f6f2f8adcd22
- Commit message:
- send 0 value for NOP to radio chip
Changed in this revision
| sx126x.cpp | Show annotated file Show diff for this revision Revisions of this file |
| sx12xx.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/sx126x.cpp Tue May 22 14:26:32 2018 -0700
+++ b/sx126x.cpp Mon Jun 11 11:15:18 2018 -0700
@@ -32,7 +32,7 @@
buf[5] = 0; // dio2
buf[6] = 0; // dio3
buf[7] = 0; // dio3
- xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, buf);
+ xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
}
@@ -61,17 +61,18 @@
printf("\r\n");
}
+extern RawSerial pc;
void SX126x::service()
{
- //unsigned n = 0;
IrqFlags_t irqFlags, clearIrqFlags;
uint8_t buf[4];
- if (busy)
+ if (busy) {
return;
+ }
while (dio1) {
- xfer(OPCODE_GET_IRQ_STATUS, 3, buf);
+ xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf);
irqFlags.word = buf[1] << 8;
irqFlags.word |= buf[2];
clearIrqFlags.word = 0;
@@ -86,10 +87,10 @@
uint8_t len;
float snr, rssi;
int8_t s;
- xfer(OPCODE_GET_RX_BUFFER_STATUS, 3, buf);
+ xfer(OPCODE_GET_RX_BUFFER_STATUS, 0, 3, buf);
len = buf[1];
- ReadBuffer(len);
- xfer(OPCODE_GET_PACKET_STATUS, 4, buf);
+ ReadBuffer(len, buf[2]);
+ xfer(OPCODE_GET_PACKET_STATUS, 0, 4, buf);
rssi = -buf[1] / 2.0; // TODO FSK
s = buf[2];
snr = s / 4.0;
@@ -109,36 +110,47 @@
if (clearIrqFlags.word != 0) {
buf[0] = clearIrqFlags.word >> 8;
buf[1] = (uint8_t)clearIrqFlags.word;
- xfer(OPCODE_CLEAR_IRQ_STATUS, 2, buf);
+ xfer(OPCODE_CLEAR_IRQ_STATUS, 2, 0, buf);
}
} // ...while (dio1)
} // ..service()
-void SX126x::xfer(uint8_t opcode, uint8_t len, uint8_t* ptr)
+void SX126x::xfer(uint8_t opcode, uint8_t wlen, uint8_t rlen, uint8_t* ptr)
{
+ const uint8_t* stopPtr;
+ const uint8_t* wstop;
+ const uint8_t* rstop;
+ uint8_t nop = 0;
+
if (sleeping) {
nss = 0;
while (busy)
;
sleeping = false;
} else {
- //unsigned n = 0;
- while (busy) {
- /*wait_us(0.002);
- if (++n > 200) {
- return -1;
- }*/
- }
+ while (busy)
+ ;
nss = 0;
}
spi.write(opcode);
- while (len > 0) {
- *ptr = spi.write(*ptr);
- len--;
- ptr++;
+
+ wstop = ptr + wlen;
+ rstop = ptr + rlen;
+ if (rlen > wlen)
+ stopPtr = rstop;
+ else
+ stopPtr = wstop;
+
+ for (; ptr < stopPtr; ptr++) {
+ if (ptr < wstop && ptr < rstop)
+ *ptr = spi.write(*ptr);
+ else if (ptr < wstop)
+ spi.write(*ptr);
+ else
+ *ptr = spi.write(nop); // n >= write length: send NOP
}
nss = 1;
@@ -170,7 +182,7 @@
buf[0] = 0x40;
buf[1] = 0x00;
buf[2] = 0x00;
- xfer(OPCODE_SET_TX, 3, buf);
+ xfer(OPCODE_SET_TX, 3, 0, buf);
chipMode = CHIPMODE_TX;
}
@@ -182,12 +194,11 @@
buf[0] = timeout >> 16;
buf[1] = timeout >> 8;
buf[2] = timeout;
- xfer(OPCODE_SET_RX, 3, buf);
+ xfer(OPCODE_SET_RX, 3, 0, buf);
chipMode = CHIPMODE_RX;
}
-#define MHZ_TO_FRF 1048576 // = (1<<25) / Fxtal_MHz
uint8_t SX126x::setMHz(float MHz)
{
unsigned frf = MHz * MHZ_TO_FRF;
@@ -197,21 +208,27 @@
buf[1] = frf >> 16;
buf[2] = frf >> 8;
buf[3] = frf;
- xfer(OPCODE_SET_RF_FREQUENCY, 4, buf);
+ xfer(OPCODE_SET_RF_FREQUENCY, 4, 0, buf);
return buf[3];
}
+float SX126x::getMHz()
+{
+ uint32_t frf = readReg(REG_ADDR_RFFREQ, 4);
+ return frf / (float)MHZ_TO_FRF;
+}
+
void SX126x::setPacketType(uint8_t type)
{
- xfer(OPCODE_SET_PACKET_TYPE, 1, &type);
+ xfer(OPCODE_SET_PACKET_TYPE, 1, 0, &type);
}
void SX126x::SetDIO2AsRfSwitchCtrl(uint8_t en)
{
- xfer(OPCODE_SET_DIO2_AS_RFSWITCH, 1, &en);
+ xfer(OPCODE_SET_DIO2_AS_RFSWITCH, 1, 0, &en);
}
-void SX126x::ReadBuffer(uint8_t size)
+void SX126x::ReadBuffer(uint8_t size, uint8_t offset)
{
unsigned i;
while (busy)
@@ -220,7 +237,7 @@
nss = 0;
spi.write(OPCODE_READ_BUFFER);
- spi.write(0); // offset
+ spi.write(offset);
spi.write(0); // NOP
i = 0;
for (i = 0; i < size; i++) {
@@ -258,7 +275,7 @@
else if (dbm < -3)
dbm = -3;
}
- xfer(OPCODE_SET_PA_CONFIG, 4, buf);
+ xfer(OPCODE_SET_PA_CONFIG, 4, 0, buf);
if (is1262 && dbm > 18) {
/* OCP is set by chip whenever SetPaConfig() is called */
@@ -269,7 +286,7 @@
buf[0] = dbm;
//if (opt == 0) txco
buf[1] = SET_RAMP_200U;
- xfer(OPCODE_SET_TX_PARAMS, 2, buf);
+ xfer(OPCODE_SET_TX_PARAMS, 2, 0, buf);
}
void SX126x::writeReg(uint16_t addr, uint32_t data, uint8_t len)
@@ -282,13 +299,13 @@
buf[n+1] = (uint8_t)data;
data >>= 8;
}
- xfer(OPCODE_WRITE_REGISTER, 2+len, buf);
+ xfer(OPCODE_WRITE_REGISTER, 2+len, 2+len, buf);
}
void SX126x::setStandby(stby_t stby)
{
uint8_t octet = stby;
- xfer(OPCODE_SET_STANDBY, 1, &octet);
+ xfer(OPCODE_SET_STANDBY, 1, 0, &octet);
chipMode = CHIPMODE_NONE;
}
@@ -300,7 +317,7 @@
sc.octet = 0;
sc.bits.rtcWakeup = rtcWakeup;
sc.bits.warmStart = warmStart;
- xfer(OPCODE_SET_SLEEP, 1, &sc.octet);
+ xfer(OPCODE_SET_SLEEP, 1, 0, &sc.octet);
chipMode = CHIPMODE_NONE;
}
@@ -327,7 +344,7 @@
uint8_t buf[7];
buf[0] = addr >> 8;
buf[1] = (uint8_t)addr;
- xfer(OPCODE_READ_REGISTER, 3+len, buf);
+ xfer(OPCODE_READ_REGISTER, 2, 3+len, buf);
for (i = 0; i < len; i++) {
ret <<= 8;
ret |= buf[i+3];
--- a/sx12xx.h Tue May 22 14:26:32 2018 -0700
+++ b/sx12xx.h Mon Jun 11 11:15:18 2018 -0700
@@ -5,9 +5,11 @@
#define RC_TICKS_PER_MS 0.015625 /* 64KHz */
#define RC_TICKS_PER_US 15.625 /* 64KHz */
-#define XTAL_FREQ 32000000
+#define XTAL_FREQ_HZ 32000000
#define FREQ_DIV 33554432
#define FREQ_STEP 0.95367431640625 // ( ( double )( XTAL_FREQ / ( double )FREQ_DIV ) )
+#define MHZ_TO_FRF 1048576 // = (1<<25) / Fxtal_MHz
+#define KHZ_TO_FRF 1048.576
/***************************************************************/
#define OPCODE_CLEAR_IRQ_STATUS 0x02
@@ -55,12 +57,42 @@
#define INVERTED_IQ 1
/* direct register access */
-#define REG_ADDR_LORA_CONFIG0 0x0703 // 8bit bw/sf
-#define REG_ADDR_LORA_IRQ_MASK 0x070a // 24bit
-#define REG_ADDR_LORA_SYNC 0x0740 // config22, config23: frame sync peak position
-#define REG_ADDR_RANDOM 0x0819
-#define REG_ADDR_OCP 0x08e7
-#define REG_ADDR_
+#define REG_ADDR_IRQ_STATUS 0x58a // 16bit
+#define REG_ADDR_IRQ_MASK 0x58c // 16bit
+#define REG_ADDR_MODCFG 0x680 // 8bit
+#define REG_ADDR_BITRATE 0x6a1 // 24bit fsk
+#define REG_ADDR_FREQDEV 0x6a4 // 18bit fsk
+#define REG_ADDR_SHAPECFG 0x6a7 // 5bit
+#define REG_ADDR_FSK_PKTCTRL0 0x6b3 // 8bit
+#define REG_ADDR_FSK_PKTCTRL1 0x6b4 // 3bit
+#define REG_ADDR_FSK_PREAMBLE_TXLEN 0x6b5 // 16bit
+#define REG_ADDR_FSK_SYNC_LEN 0x6b7 // 7bit
+#define REG_ADDR_FSK_PKTCTRL2 0x6ba // 8bit
+#define REG_ADDR_FSK_PAYLOAD_LEN 0x6bb // 8bit
+#define REG_ADDR_SYNCADDR 0x6c0 // 64bit fsk
+#define REG_ADDR_NODEADDR 0x6cd // 8bit fsk
+#define REG_ADDR_NODEADDRCOMP 0x6cf // 2bit fsk
+
+#define REG_ADDR_LORA_TXPKTLEN 0x702 // 8bit
+#define REG_ADDR_LORA_CONFIG0 0x703 // 8bit bw/sf
+#define REG_ADDR_LORA_CONFIG1 0x704 // 8bit ppm_offset, fixlen, invertiq, cr
+#define REG_ADDR_LORA_CONFIG2 0x705 // 8bit crcType
+#define REG_ADDR_LORA_IRQ_MASK 0x70a // 24bit
+#define REG_ADDR_LORA_PREAMBLE_SYMBNB 0x73a // 16bit
+#define REG_ADDR_LORA_SYNC 0x740 // config22, config23: frame sync peak position
+
+#define REG_ADDR_DIGFECTL 0x804 // 6bits
+#define REG_ADDR_BWSEL 0x807 // 5bits
+#define REG_ADDR_RANDOM 0x819 // ro
+#define REG_ADDR_RFFREQ 0x88b // 31bits
+#define REG_ADDR_FREQ_OFFSET 0x88f // 19bits
+#define REG_ADDR_ANACTRL6 0x8d7 // 6bits
+#define REG_ADDR_ANACTRL7 0x8d8 // 6bits
+#define REG_ADDR_ANACTRL15 0x8e1 // 7bits
+#define REG_ADDR_OCP 0x8e7
+#define REG_ADDR_ 0x
+
+/**********************************************/
#define SET_RAMP_10U 0x00
#define SET_RAMP_20U 0x01
@@ -101,6 +133,7 @@
uint8_t PacketType; // param6
uint8_t PayloadLength; // param7
uint8_t CRCType; // param8
+ uint8_t Whitening; // param9
} gfsk;
uint8_t buf[8];
} PacketParams_t;
@@ -128,6 +161,9 @@
#define GFSK_PREAMBLE_DETECTOR_LENGTH_24BITS 0x06
#define GFSK_PREAMBLE_DETECTOR_LENGTH_32BITS 0x07
+#define GFSK_WHITENING_OFF 0
+#define GFSK_WHITENING_ON 1
+
#define GFSK_CRC_OFF 0x01
#define GFSK_CRC_1_BYTE 0x00
#define GFSK_CRC_2_BYTE 0x02
@@ -167,6 +203,152 @@
STBY_XOSC
} stby_t;
+#define MOD_TYPE_IQ 0
+#define MOD_TYPE_FSK 1
+#define MOD_TYPE_MSK 2
+#define MOD_TYPE_LORA 3
+typedef union {
+ struct {
+ uint8_t mod_order : 2; // 0,1 modulation size 2points to 16points
+ uint8_t mod_type : 2; // 2,3 IQ, FSK, MSK, LoRa
+ uint8_t data_src : 1; // 4
+ uint8_t clk_src : 2; // 5,6
+ uint8_t mod_en : 1; // 7
+ } bits;
+ uint8_t octet;
+} modCfg_t; // at 0x680 fsk
+
+typedef union {
+ struct {
+ uint8_t bt : 2; // 0,1 0=BT1.0 1=BT0.5 2=BT0.3
+ uint8_t double_rate : 1; // 2 double oversampling rate
+ uint8_t pulse_shape : 2; // 3,4 0=noFilter 1=gaussian 2=RRC
+ uint8_t res : 3; // 5,6,7
+ } bits;
+ uint8_t octet;
+} shapeCfg_t; // at 0x6a7 fsk
+
+typedef union {
+ struct {
+ uint8_t pkt_start_p : 1; // 0 ros1
+ uint8_t pkt_abort_p : 1; // 1 ros1
+ uint8_t pkt_sw_clr_p : 1; // 2 ros1
+ uint8_t crl_status_p : 1; // 3 ros1
+ uint8_t clk_en : 1; // 4 ro
+ uint8_t pkt_rx_ntx : 1; // 5
+ uint8_t pkt_len_format : 1; // 6
+ uint8_t cont_rx : 1; // 7
+ } bits;
+ uint8_t octet;
+} pktCtrl0_t; // at 0x6b3 fsk
+
+typedef union {
+ struct {
+ uint8_t preamble_len_rx : 2; // 0,1 number of preamble bits detected
+ uint8_t preamble_det_on : 1; // 2 enable rx-sde preamble detector
+ uint8_t res : 1; // 7
+ } bits;
+ uint8_t octet;
+} pktCtrl1_t; // at 0x6b4 fsk
+
+typedef union {
+ struct {
+ uint8_t crc_disable : 1; // 0
+ uint8_t crc_len : 1; // 1 0=1byte 1=2byte
+ uint8_t crc_inv : 1; // 2
+ uint8_t crc_in_fifo : 1; // 3
+ uint8_t whit_enable : 1; // 4
+ uint8_t manchester_en : 1; // 5
+ uint8_t rssi_mode : 2; // 6,7
+ } bits;
+ uint8_t octet;
+} pktCtrl2_t; // at 0x6ba fsk
+
+
+typedef union {
+ struct {
+ uint8_t modem_sf: 4; // 0,1,2,3
+ uint8_t modem_bw: 4; // 4,5,6,7
+ } bits;
+ uint8_t octet;
+} loraConfig0_t; // at 0x703
+
+typedef union {
+ struct {
+ uint8_t tx_coding_rate : 3; // 0,1,2
+ uint8_t ppm_offset : 2; // 3,4 aka long range mode
+ uint8_t tx_mode : 1; // 5
+ uint8_t rx_invert_iq : 1; // 6
+ uint8_t implicit_header : 1; // 7 0=variable length packet
+ } bits;
+ uint8_t octet;
+} loraConfig1_t; // at 0x704
+
+typedef union {
+ struct {
+ uint8_t cad_rxtx : 2; // 0,1
+ uint8_t tx_payload_crc16_en : 1; // 2
+ uint8_t cont_rx : 1; // 3
+ uint8_t freeze_dagc_upon_synch : 2; // 4,5
+ uint8_t fine_sync_en : 1; // 6
+ uint8_t res : 1; // 7
+ } bits;
+ uint8_t octet;
+} loraConfig2_t; // at 0x705
+
+typedef union {
+ struct {
+ uint8_t inv_edge : 1; // 0
+ uint8_t swap_iq : 1; // 1
+ uint8_t dig_fe_clear : 1; // 2
+ uint8_t lora_ngfsk : 1; // 3 data buffer selection lora/gfsk
+ uint8_t adc_from_dio : 1; // 4
+ uint8_t lora_pre_cf_en : 1; // 5
+ uint8_t res : 2; // 6,7
+ } bits;
+ uint8_t octet;
+} digFeCtrl_t; // at 0x804
+
+typedef union {
+ struct {
+ uint8_t exp : 3; // 0,1,2
+ uint8_t mant : 2; // 3,4
+ uint8_t res : 3; // 5,6,7
+ } bits;
+ uint8_t octet;
+} bwSel_t; // at 0x807 rx_bw
+
+typedef union {
+ struct {
+ uint8_t pa_hp_ena_ana : 1; // 0
+ uint8_t tx_ena_bat : 1; // 1
+ uint8_t pa_dctrim_select_ana : 4; // 2,3,4,5
+ uint8_t res : 2; // 6,7
+ } bits;
+ uint8_t octet;
+} AnaCtrl6_t; // at 0x8d7
+
+typedef union {
+ struct {
+ uint8_t pa_lp_ena_ana : 1; // 0
+ uint8_t pa_clamp_code_bat : 3; // 1,2,3
+ uint8_t pa_clamp_override_bat : 1; // 4
+ uint8_t pa_hp_sel_ana : 1; // 5,6,7
+ } bits;
+ uint8_t octet;
+} AnaCtrl7_t; // at 0x8d8
+
+typedef union {
+ struct {
+ uint8_t reg_pa_comp_poarity_ana : 1; // 0
+ uint8_t reg_pa_comp_en_ana : 1; // 1
+ uint8_t fir_dac_sign_ana : 2; // 2,3
+ uint8_t fir_dac_pole_ana : 3; // 4,5,6
+ uint8_t res : 1; // 7
+ } bits;
+ uint8_t octet;
+} AnaCtrl15_t; // at 0x8e1
+
typedef union {
struct {
uint8_t spreadingFactor; // param1
@@ -179,10 +361,10 @@
uint8_t bitrateMid; // param2
uint8_t bitrateLo; // param3
uint8_t PulseShape; // param4
- uint8_t bandwith; // param5
- uint8_t fdevHi; // param6
+ uint8_t bandwidth; // param5
+ uint8_t fdevHi; // param6
uint8_t fdevMid; // param7
- uint8_t fdevLo; // param8
+ uint8_t fdevLo; // param8
} gfsk;
uint8_t buf[8];
} ModulationParams_t;
@@ -225,9 +407,10 @@
void hw_reset(PinName nrst);
- void xfer(uint8_t opcode, uint8_t len, uint8_t* buf);
+ void xfer(uint8_t opcode, uint8_t writeLen, uint8_t readLen, uint8_t* buf);
void setPacketType(uint8_t);
uint8_t setMHz(float);
+ float getMHz(void);
/* start_tx and start_rx assumes DIO1 is connected, and only pin used to generate radio interrupt */
void start_tx(uint8_t pktLen); // tx_buf must be filled prior to calling
@@ -236,7 +419,7 @@
#define RX_TIMEOUT_CONTINUOUS 0xffffff /* keep RXing */
void start_rx(unsigned);
- void ReadBuffer(uint8_t size);
+ void ReadBuffer(uint8_t size, uint8_t offset);
void SetDIO2AsRfSwitchCtrl(uint8_t);
void set_tx_dbm(bool is1262, int8_t dbm);
uint32_t readReg(uint16_t addr, uint8_t len);
@@ -260,7 +443,6 @@
*/
inline bool getDIO1(void) { return dio1.read(); }
void PrintChipStatus(status_t);
- //bool txing;
chipMote_e chipMode;
private: