You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.2 KiB
100 lines
2.2 KiB
/* |
|
low level driver for the TI CC2500 radio on SPI |
|
|
|
With thanks to betaflight |
|
*/ |
|
|
|
#include "driver_cc2500.h" |
|
#include <utility> |
|
|
|
// #pragma GCC optimize("O0") |
|
|
|
extern const AP_HAL::HAL& hal; |
|
|
|
// constructor |
|
Radio_CC2500::Radio_CC2500(AP_HAL::OwnPtr<AP_HAL::SPIDevice> _dev) : |
|
dev(std::move(_dev)) |
|
{} |
|
|
|
void Radio_CC2500::ReadFifo(uint8_t *dpbuffer, uint8_t len) |
|
{ |
|
(void)dev->read_registers(CC2500_3F_RXFIFO | CC2500_READ_BURST, dpbuffer, len); |
|
} |
|
|
|
void Radio_CC2500::WriteFifo(const uint8_t *dpbuffer, uint8_t len) |
|
{ |
|
WriteRegisterMulti(CC2500_3F_TXFIFO | CC2500_WRITE_BURST, dpbuffer, len); |
|
} |
|
|
|
void Radio_CC2500::ReadRegisterMulti(uint8_t address, uint8_t *data, uint8_t length) |
|
{ |
|
(void)dev->read_registers(address, data, length); |
|
} |
|
|
|
void Radio_CC2500::WriteRegisterMulti(uint8_t address, const uint8_t *data, uint8_t length) |
|
{ |
|
uint8_t buf[length+1]; |
|
buf[0] = address; |
|
memcpy(&buf[1], data, length); |
|
dev->transfer(buf, length+1, nullptr, 0); |
|
} |
|
|
|
uint8_t Radio_CC2500::ReadReg(uint8_t reg) |
|
{ |
|
uint8_t ret = 0; |
|
(void)dev->read_registers(reg | CC2500_READ_SINGLE, &ret, 1); |
|
return ret; |
|
} |
|
|
|
uint8_t Radio_CC2500::Strobe(uint8_t address) |
|
{ |
|
uint8_t status=0; |
|
(void)dev->transfer(&address, 1, &status, 1); |
|
return status; |
|
} |
|
|
|
void Radio_CC2500::WriteReg(uint8_t address, uint8_t data) |
|
{ |
|
(void)dev->write_register(address, data); |
|
} |
|
|
|
void Radio_CC2500::SetPower(uint8_t power) |
|
{ |
|
const uint8_t patable[8] = { |
|
0xC5, // -12dbm |
|
0x97, // -10dbm |
|
0x6E, // -8dbm |
|
0x7F, // -6dbm |
|
0xA9, // -4dbm |
|
0xBB, // -2dbm |
|
0xFE, // 0dbm |
|
0xFF // 1.5dbm |
|
}; |
|
if (power > 7) { |
|
power = 7; |
|
} |
|
WriteReg(CC2500_3E_PATABLE, patable[power]); |
|
} |
|
|
|
bool Radio_CC2500::Reset(void) |
|
{ |
|
Strobe(CC2500_SRES); |
|
hal.scheduler->delay_microseconds(1000); |
|
// CC2500_SetTxRxMode(TXRX_OFF); |
|
// RX_EN_off;//off tx |
|
// TX_EN_off;//off rx |
|
return ReadReg(CC2500_0E_FREQ1) == 0xC4; // check if reset |
|
} |
|
|
|
/* |
|
write register with up to 5 retries |
|
*/ |
|
void Radio_CC2500::WriteRegCheck(uint8_t address, uint8_t data) |
|
{ |
|
uint8_t tries=5; |
|
while (--tries) { |
|
dev->write_register(address, data); |
|
uint8_t v = ReadReg(address); |
|
if (v == data) break; |
|
} |
|
}
|
|
|