Jonathan Jones
/
Radios
Radio Structures in OOP
Diff: drivers/CC1101/CC1101.cpp
- Revision:
- 5:146523a0d1f4
- Parent:
- 3:dc7e9c6bc26c
- Child:
- 6:4a3dbfbc30f1
--- a/drivers/CC1101/CC1101.cpp Sat Jan 03 11:04:31 2015 +0000 +++ b/drivers/CC1101/CC1101.cpp Wed Jan 14 17:46:44 2015 +0000 @@ -41,6 +41,7 @@ assign_channel_spacing(200000); // 200kHz datarate(250000); // 250 kBaud set_rf_settings(); + init(); // [] - 2 - Test the interrupt pin for proper operation // ================= @@ -115,11 +116,11 @@ return 0; // success } + void CC1101::set_init_vars(void) { - // define an initial state of an unselected chip + // define the initial state of an unselected chip *_cs = 1; - _channel = 1; _address = 0x00; @@ -175,6 +176,169 @@ } +void CC1101::put_rf_settings() +{ + write_reg(CCXXX1_IOCFG2, rfSettings.IOCFG2); + write_reg(CCXXX1_IOCFG1, rfSettings.IOCFG1); + write_reg(CCXXX1_IOCFG0, rfSettings.IOCFG0); + write_reg(CCXXX1_FIFOTHR, rfSettings.FIFOTHR); + // SYNC1 + // SYNC0 + write_reg(CCXXX1_PCKLEN, rfSettings.PCKLEN); + write_reg(CCXXX1_PCKCTRL1, rfSettings.PCKCTRL1); + write_reg(CCXXX1_PCKCTRL0, rfSettings.PCKCTRL0); + write_reg(CCXXX1_ADDR, rfSettings.ADDR); + + write_reg(CCXXX1_CHANNR, rfSettings.CHANNR); + write_reg(CCXXX1_FSCTRL1, rfSettings.FSCTRL1); + write_reg(CCXXX1_FSCTRL0, rfSettings.FSCTRL0); + write_reg(CCXXX1_FREQ2, rfSettings.FREQ2); + + write_reg(CCXXX1_FREQ1, rfSettings.FREQ1); + write_reg(CCXXX1_FREQ0, rfSettings.FREQ0); + write_reg(CCXXX1_MDMCFG4, rfSettings.MDMCFG4); + write_reg(CCXXX1_MDMCFG3, rfSettings.MDMCFG3); + + write_reg(CCXXX1_MDMCFG2, rfSettings.MDMCFG2); + write_reg(CCXXX1_MDMCFG1, rfSettings.MDMCFG1); + write_reg(CCXXX1_MDMCFG0, rfSettings.MDMCFG0); + write_reg(CCXXX1_DEVIATN, rfSettings.DEVIATN); + write_reg(CCXXX1_MCSM2 , rfSettings.MCSM2); + write_reg(CCXXX1_MCSM1 , rfSettings.MCSM1); + write_reg(CCXXX1_MCSM0 , rfSettings.MCSM0 ); + write_reg(CCXXX1_FOCCFG, rfSettings.FOCCFG); + write_reg(CCXXX1_BSCFG, rfSettings.BSCFG); + write_reg(CCXXX1_AGCCTRL2, rfSettings.AGCCTRL2); + write_reg(CCXXX1_AGCCTRL1, rfSettings.AGCCTRL1); + write_reg(CCXXX1_AGCCTRL0, rfSettings.AGCCTRL0); + // WOREVT1 + // WOREVT0 + // WORCTRL + write_reg(CCXXX1_FREND1, rfSettings.FREND1); + write_reg(CCXXX1_FREND0, rfSettings.FREND0); + //write_reg(CCXXX1_FSCAL3, rfSettings.FSCAL3); + //write_reg(CCXXX1_FSCAL2, rfSettings.FSCAL2); + //write_reg(CCXXX1_FSCAL1, rfSettings.FSCAL1); + //write_reg(CCXXX1_FSCAL0, rfSettings.FSCAL0); + // PCCTRL1 + // PCCTRL0 + // FSTEST + // PTEST + // AGCTEST + //write_reg(CCXXX1_TEST2, rfSettings.TEST2); + //write_reg(CCXXX1_TEST1, rfSettings.TEST1); + //write_reg(CCXXX1_TEST0, rfSettings.TEST0); +} // put_rf_settings + + + +void CC1101::power_on_reset(void) +{ +#if DEBUG_MODE > 0 + std::printf(" Starting Power-on-Reset procedure..."); +#endif + delete _spi; + + // make sure chip is not selected + toggle_cs(); + + DigitalOut *SI = new DigitalOut(_mosi_pin); + DigitalOut *SCK = new DigitalOut(_sck_pin); + DigitalIn *SO = new DigitalIn(_miso_pin); + + // bring SPI lines to a defined state. Reasons are outlined in CC1101 datasheet - section 11.3 + *SI = 0; + *SCK = 1; + + // toggle chip select and remain in high state afterwards + toggle_cs(); + toggle_cs(); + + // wait at least 40us + wait_us(45); + + // pull CSn low & wait for the serial out line to go low + *_cs = 0; + + while(*SO); + + // cleanup everything before the mbed's SPI library calls take back over + delete SI; + delete SO; + delete SCK; + + // reestablish the SPI bus and call the reset strobe + setup_spi(); + reset(); + + delete _spi; + // wait for the SO line to go low again. Once low, reset is complete and CC1101 is in IDLE state + DigitalIn *SO2 = new DigitalIn(_miso_pin); + while(*SO2); + + // make sure chip is deselected before returning + *_cs = 1; + + // reestablish the SPI bus for the final time after removing the DigitalIn object + delete SO2; + setup_spi(); + +#if DEBUG_MODE > 0 + std::printf("==============done\r\n"); +#endif +} + +// 2nd ighest level of initilization routines behind CC1101::setup(); +void CC1101::init(void) +{ + + power_on_reset(); + + // send all configuration values to the CC1101 registers +#if DEBUG_MODE > 0 + std::printf(" Writing configuration registers..."); +#endif + + put_rf_settings(); + +#if DEBUG_MODE > 0 + std::printf("done\r\n"); +#endif + uint8_t paTable[] = {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 10dB + write_reg(CCXXX1_PATABLE, paTable[0]); + + // flush TX and RX buffers before beginning +#if DEBUG_MODE > 0 + std::printf(" Clearing TX and RX buffers..."); +#endif + + flush_rx(); + flush_tx(); + +#if DEBUG_MODE > 0 + std::printf("done\r\n"); +#endif + +#if DEBUG_MODE > 0 + std::printf(" Configuring frequency offset estimate..."); +#endif + + //write_reg(CCXXX1_FSCTRL0, status(CCXXX1_FREQEST)); + +#if DEBUG_MODE > 0 + std::printf("done\r\n"); +#endif + + // Enter RX mode +#if DEBUG_MODE > 0 + std::printf(" Entering RX mode..."); +#endif + rx_mode(); +#if DEBUG_MODE > 0 + std::printf("done\r\n"); +#endif +} + // returns the current mode that the CC1101 is operating in uint8_t CC1101::mode(void) { @@ -183,7 +347,7 @@ int32_t CC1101::sendData(uint8_t *buf, uint8_t size) -{ +{ // [X] - 1 - Move all values down by 1 to make room for the packet's size value. // ================= for (uint8_t i = size; i > 0; i--) @@ -303,8 +467,10 @@ // Read Register uint8_t CC1101::read_reg(uint8_t addr) { + _spi->frequency(8000000); toggle_cs(); _spi->write(addr | CCXXX1_READ_SINGLE); + //tiny_delay(); uint8_t x = _spi->write(0); toggle_cs(); @@ -315,12 +481,13 @@ } // read_reg void CC1101::read_reg(uint8_t addr, uint8_t *buffer, uint8_t count) { + _spi->frequency(4500000); toggle_cs(); _spi->write(addr | CCXXX1_READ_BURST); - tiny_delay(); + //tiny_delay(); for (uint8_t i = 0; i < count; i++) { buffer[i] = _spi->write(0); - tiny_delay(); + //tiny_delay(); } toggle_cs(); @@ -334,8 +501,10 @@ // Write Register void CC1101::write_reg(uint8_t addr, uint8_t value) { + _spi->frequency(8000000); toggle_cs(); _spi->write(addr); + //tiny_delay(); _spi->write(value); toggle_cs(); @@ -345,12 +514,11 @@ } // write_reg void CC1101::write_reg(uint8_t addr, uint8_t *buffer, uint8_t count) { + _spi->frequency(4500000); toggle_cs(); _spi->write(addr | CCXXX1_WRITE_BURST); - tiny_delay(); for (uint8_t i = 0; i < count; i++) { _spi->write(buffer[i]); - tiny_delay(); } toggle_cs(); @@ -363,6 +531,7 @@ // Strobe uint8_t CC1101::strobe(uint8_t addr) { + _spi->frequency(4500000); toggle_cs(); uint8_t x = _spi->write(addr); toggle_cs(); @@ -377,20 +546,20 @@ strobe(CCXXX1_SCAL); // Wait for the radio to leave the calibration step - while( (mode() == 0x04) | (mode() == 0x05) ); +// while( (mode() == 0x04) | (mode() == 0x05) ); // The radio is now is IDLE mode, so go to RX mode rx_mode(); // Wait for the radio to enter back into RX mode - while( mode() != 0x0D ); + //while( mode() != 0x0D ); } void CC1101::tiny_delay(void) { int i = 0; - while(i < 5) { + while(i < 4) { i++; } } @@ -488,8 +657,7 @@ // Send the IDLE strobe strobe(CCXXX1_SIDLE); // Wait before returning - // === THIS LIKELY ISN'T NEEDED === - while( mode() != 0x01); + //while( mode() != 0x01); } @@ -501,6 +669,7 @@ uint8_t CC1101::status(uint8_t addr) { + _spi->frequency(800000); toggle_cs(); _spi->write(addr | CCXXX1_READ_BURST); tiny_delay();