123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- #include "stm32l0xx_hal.h"
- #include "lt8920.h"
- #include "lt8920_trs.h"
- #include <stdio.h>
- #undef DBG
- #define DBG if(0)
- void LT8920::dump_register(uint8_t reg)
- {
- uint16_t r = readRegister(reg);
- printf("reg: %u, value: %X\r\n", reg, r);
- }
- LT8920::LT8920(void)
- {
- _channel = DEFAULT_CHANNEL;
-
- LT8920_CS_HIGH;
- }
- void LT8920::begin()
- {
- LT8920_RESET_LOW;
- HAL_Delay(200);
- LT8920_RESET_HIGH;
- HAL_Delay(200);
-
- //setup
- writeRegister(0, 0x6fe0);
- writeRegister(1, 0x5681);
- writeRegister(2, 0x6617);
- writeRegister(4, 0x9cc9); //why does this differ from powerup (5447)
- writeRegister(5, 0x6637); //why does this differ from powerup (f000)
- writeRegister(8, 0x6c90); //power (default 71af) UNDOCUMENTED
-
- setCurrentControl(4, 0); // power & gain.
-
- writeRegister(10, 0x7ffd); //bit 0: XTAL OSC enable
- writeRegister(11, 0x0000); //bit 8: Power down RSSI (0= RSSI operates normal)
- writeRegister(12, 0x0000);
- writeRegister(13, 0x48bd); //(default 4855)
-
- writeRegister(22, 0x00ff);
- writeRegister(23, 0x8005); //bit 2: Calibrate VCO before each Rx/Tx enable
- writeRegister(24, 0x0067);
- writeRegister(25, 0x1659);
- writeRegister(26, 0x19e0);
- writeRegister(27, 0x1300); //bits 5:0, Crystal Frequency adjust
- writeRegister(28, 0x1800);
-
- //fedcba9876543210
- writeRegister(32, 0x5000); //AAABBCCCDDEEFFFG A preamble length, B, syncword length, c trailer length, d packet type
- // E FEC_type, F BRCLK_SEL, G reserved
- //0x5000 = 0101 0000 0000 0000 = preamble 010 (3 bytes), B 10 (48 bits)
- writeRegister(33, 0x3fc7);
- writeRegister(34, 0x2000); //
- writeRegister(35, 0x0300); //POWER mode, bit 8/9 on = retransmit = 3x (default)
- setSyncWord(0x03805a5a03800380);
-
- writeRegister(40, 0x4401); //max allowed error bits = 0 (01 = 0 error bits)
- writeRegister(R_PACKETCONFIG, PACKETCONFIG_CRC_ON |
- PACKETCONFIG_PACK_LEN_ENABLE | PACKETCONFIG_FW_TERM_TX);
-
- writeRegister(42, 0xfdb0);
- writeRegister(43, 0x000f);
-
- //setDataRate(LT8920_1MBPS);
-
- writeRegister(R_FIFO, 0x0000); //TXRX_FIFO_REG (FIFO queue)
-
- writeRegister(R_FIFO_CONTROL, 0x8080); //Fifo Rx/Tx queue reset
-
- HAL_Delay(200);
- writeRegister(R_CHANNEL, _BV(CHANNEL_TX_BIT)); //set TX mode. (TX = bit 8, RX = bit 7, so RX would be 0x0080)
- HAL_Delay(2);
- writeRegister(R_CHANNEL, _channel); // Frequency = 2402 + channel
- }
- void LT8920::setChannel(uint8_t channel)
- {
- _channel = channel;
- writeRegister(R_CHANNEL, (_channel & CHANNEL_MASK));
- }
- uint8_t LT8920::getChannel()
- {
- return _channel;
- }
- void LT8920::setCurrentControl(uint8_t power, uint8_t gain)
- {
- writeRegister(R_CURRENT,
- ((power << CURRENT_POWER_SHIFT) & CURRENT_POWER_MASK) |
- ((gain << CURRENT_GAIN_SHIFT) & CURRENT_GAIN_MASK));
- }
- bool LT8920::setDataRate(DataRate rate)
- {
- uint16_t newValue;
- switch (rate)
- {
- case LT8920_1MBPS:
- newValue = DATARATE_1MBPS;
- break;
- case LT8920_250KBPS:
- newValue = DATARATE_250KBPS;
- break;
- case LT8920_125KBPS:
- newValue = DATARATE_125KBPS;
- break;
- case LT8920_62KBPS:
- newValue = DATARATE_62KBPS;
- break;
- default:
- return false;
- }
-
- writeRegister(R_DATARATE, newValue);
-
- return ( (readRegister(R_DATARATE) & DATARATE_MASK) == (newValue & DATARATE_MASK));
- }
- LT8920::DataRate LT8920::getDataRate()
- {
- uint16_t value = readRegister(R_DATARATE) & DATARATE_MASK;
-
- switch (value)
- {
- case DATARATE_1MBPS:
- return LT8920_1MBPS;
- case DATARATE_250KBPS:
- return LT8920_250KBPS;
- case DATARATE_125KBPS:
- return LT8920_125KBPS;
- case DATARATE_62KBPS:
- return LT8920_62KBPS;
- default :
- return LT8920_ERROR;
- }
- }
- uint16_t LT8920::readRegister(uint8_t reg)
- {
- LT8920_CS_LOW;
-
- lt_spi_transfer_byte(REGISTER_READ | (REGISTER_MASK & reg));
- uint8_t high = lt_spi_transfer_byte(0x00);
- uint8_t low = lt_spi_transfer_byte(0x00);
- LT8920_CS_HIGH;
-
- DBG printf("reg: %X = %X\r\n", reg, (high << 8 | low));
- return (high << 8 | low);
- }
- uint8_t LT8920::writeRegister(uint8_t reg, uint16_t data)
- {
- uint8_t high = data >> 8;
- uint8_t low = data & 0xFF;
- return writeRegister2(reg, high, low);
- }
- uint8_t LT8920::writeRegister2(uint8_t reg, uint8_t high, uint8_t low)
- {
- // char sbuf[32];
- // sprintf_P(sbuf, PSTR("%d => %02x%02x"), reg, high, low);
- // Serial.println(sbuf);
- LT8920_CS_LOW;
- uint8_t result = lt_spi_transfer_byte(REGISTER_WRITE | (REGISTER_MASK & reg));
- lt_spi_transfer_byte(high);
- lt_spi_transfer_byte(low);
-
- LT8920_CS_HIGH;
- return result;
- }
- void LT8920::sleep()
- {
- //set bit 14 on register 35.
- writeRegister(35, readRegister(35) | _BV(14));
- }
- void LT8920::whatsUp(void)
- {
- uint16_t mode = readRegister(R_CHANNEL);
-
- DBG printf("Tx_EN = %u, Rx_EN = %u\r\n", (mode & _BV(CHANNEL_TX_BIT)), (mode & _BV(CHANNEL_RX_BIT)));
- DBG printf("Channel = %u\r\n", (mode & CHANNEL_MASK));
-
- //read the status register.
- uint16_t state = readRegister(R_STATUS);
- bool crc_error = state & _BV(15);
- bool fec23_error = state & _BV(14);
- uint8_t framer_st = (state & 0b0011111100000000) >> 8;
- bool pkt_flag = state & _BV(6);
- bool fifo_flag = state & _BV(5);
- DBG printf("CRC = %u, FEC = %u, FRAMER_ST = %u, PKT = %u, FIFO = %u\r\n",
- crc_error, fec23_error, framer_st, pkt_flag, fifo_flag);
- uint16_t fifo = readRegister(R_FIFO_CONTROL);
-
- DBG printf("FIFO_WR_PTR = %X, FIFO_RD_PTR = %X\r\n",
- ((fifo >> 8) & 0b111111), (fifo & 0b111111));
- }
- bool LT8920::available()
- {
- //read the PKT_FLAG state; this can also be done with a hard wire.
- if (LT8920_GET_PKT != 0) {
- return true;
- }
- return false;
- }
- int LT8920::read(uint8_t *buffer, size_t maxBuffer)
- {
- uint16_t value = readRegister(R_STATUS);
- uint8_t pos = 0;
-
- if (bitRead(value, STATUS_CRC_BIT) == 0)
- {
- //CRC ok
- uint16_t data = readRegister(R_FIFO);
- uint8_t packetSize = data >> 8;
-
- if (maxBuffer < packetSize + 1) {
- //BUFFER TOO SMALL
- return -2;
- }
-
- buffer[pos++] = (data & 0xFF);
-
- while (pos < packetSize)
- {
- data = readRegister(R_FIFO);
- buffer[pos++] = data >> 8;
- buffer[pos++] = data & 0xFF;
- }
- return packetSize;
- }
- else {
- //CRC error
- return -1;
- }
- }
- void LT8920::startListening()
- {
- writeRegister(R_CHANNEL, _channel & CHANNEL_MASK); // turn off rx/tx
- HAL_Delay(3);
- writeRegister(R_FIFO_CONTROL, 0x0080); //flush rx
- writeRegister(R_CHANNEL, (_channel & CHANNEL_MASK) | _BV(CHANNEL_RX_BIT)); //enable RX
- HAL_Delay(5);
- }
- /* set the BRCLK_SEL value */
- void LT8920::setClock(uint8_t clock)
- {
- //register 32, bits 3:1.
- uint16_t val = readRegister(35);
- val &= 0b1111111111110001;
- val |= ((clock & 0x07) << 1);;
- writeRegister(35, val);
- }
- bool LT8920::sendPacket(uint8_t *data, size_t packetSize)
- {
- if (packetSize < 1 || packetSize > 255)
- {
- return false;
- }
- writeRegister(R_CHANNEL, 0x0000);
- writeRegister(R_FIFO_CONTROL, 0x8000); //flush tx
- // packets are sent in 16bit words, and the first word will be the packet size.
- // start spitting out words until we are done.
- uint8_t pos = 0;
- writeRegister2(R_FIFO, packetSize, data[pos++]);
-
- while (pos < packetSize)
- {
- uint8_t msb = data[pos++];
- uint8_t lsb = data[pos++];
- writeRegister2(R_FIFO, msb, lsb);
- }
- writeRegister(R_CHANNEL, (_channel & CHANNEL_MASK) | _BV(CHANNEL_TX_BIT)); //enable TX
- // Wait until the packet is sent.
- while (LT8920_GET_PKT == 0)
- {
- //do nothing.
- }
- return true;
- }
- void LT8920::setSyncWord(uint64_t syncWord)
- {
- writeRegister(R_SYNCWORD1, syncWord);
- writeRegister(R_SYNCWORD2, syncWord >> 16);
- writeRegister(R_SYNCWORD3, syncWord >> 32);
- writeRegister(R_SYNCWORD4, syncWord >> 48);
- }
- void LT8920::setSyncWordLength(uint8_t option)
- {
- option &= 0x03;
- option <<= 11;
- writeRegister(32, (readRegister(32) & 0b0001100000000000) | option);
- }
- uint8_t LT8920::getRSSI()
- {
- // RSSI: 15:10
- uint16_t value = readRegister(6);
- return (value >> 10);
- }
- void LT8920::scanRSSI(uint16_t *buffer, uint8_t start_channel, uint8_t num_channels)
- {
- uint8_t pos = 0;
-
- // writeRegister(R_CHANNEL, _BV(CHANNEL_RX_BIT));
- //
- // //add read mode.
- writeRegister(R_FIFO_CONTROL, 0x8080); //flush rx
- // writeRegister(R_CHANNEL, 0x0000);
- //set number of channels to scan.
- writeRegister(42, (readRegister(42) & 0b0000001111111111) | ((num_channels-1 & 0b111111) << 10));
- //set channel scan offset.
- writeRegister(43, (readRegister(43) & 0b0000000011111111) | ((start_channel & 0b1111111) << 8));
- writeRegister(43, (readRegister(43) & 0b0111111111111111) | _BV(15));
- while (LT8920_GET_PKT == 0) {}
- //read the results.
- while (pos < num_channels)
- {
- uint16_t data = readRegister(R_FIFO);
- buffer[pos++] = data >> 8;
- }
- }
|