sx1261/2 driver
Dependents: alarm_slave iq_sx126x sx126x_simple_TX_shield_2020a sx126x_simple_RX_shield_2020a ... more
Driver for SX1261 or SX1262
Diff: sx126x.cpp
- Revision:
- 2:e6e159c8ab4d
- Parent:
- 1:497af0bd9e53
- Child:
- 3:f6f2f8adcd22
--- 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];