/* * CC2500 helper routines */ #ifdef DEBUG //#define DEBUG_STATUS #endif #include #include "spi.h" #include "cc2500.h" #include "main.h" #ifdef DEBUG_STATUS static void cc2500PrintStatusByte(uint8_t status) { static int16_t lastStatusByte = -1; //if ((status & ~CC2500_STATUS_FIFO_BYTES_AVAILABLE_BM) != (lastStatusByte & ~CC2500_STATUS_FIFO_BYTES_AVAILABLE_BM)) { if (status != lastStatusByte) { lastStatusByte = status; debugWrite("\nStatus change: 0x"); debugHex(status); debugWrite("\n"); if (status & CC2500_STATUS_CHIP_RDYn_BM) { debugWrite(" Power/Crystal NOT ready!\n"); } debugWrite(" State: "); switch (status & CC2500_STATUS_STATE_BM) { case CC2500_STATE_IDLE: debugWrite("IDLE"); break; case CC2500_STATE_RX: debugWrite("RX"); break; case CC2500_STATE_TX: debugWrite("TX"); break; case CC2500_STATE_FSTXON: debugWrite("Freq Synth TX on"); break; case CC2500_STATE_CALIBRATE: debugWrite("Freq Synth Calibration"); break; case CC2500_STATE_SETTLING: debugWrite("PLL settling"); break; case CC2500_STATE_RX_OVERFLOW: debugWrite("RX FIFO Overflow"); break; case CC2500_STATE_TX_UNDERFLOW: debugWrite("TX FIFO Underflow"); break; default: debugWrite("UNKNOWN"); break; } debugWrite("\n"); debugWrite(" FIFO Bytes available: 0x"); debugHex(status & CC2500_STATUS_FIFO_BYTES_AVAILABLE_BM); debugWrite("\n\n"); } } #endif void cc2500ReadRegisterMulti(uint8_t address, uint8_t data[], uint8_t length) { CS_off; #ifdef DEBUG_STATUS uint8_t status = spiWrite(address); #else spiWrite(address); #endif for (uint8_t i = 0; i < length; i++) { data[i] = spiRead(); } CS_on; #ifdef DEBUG_STATUS cc2500PrintStatusByte(status); #endif } void cc2500WriteRegisterMulti(uint8_t address, const uint8_t data[], uint8_t length) { CS_off; #ifdef DEBUG_STATUS uint8_t status = spiWrite(CC2500_WRITE_BURST | address); #else spiWrite(CC2500_WRITE_BURST | address); #endif for (uint8_t i = 0; i < length; i++) { spiWrite(data[i]); } CS_on; #ifdef DEBUG_STATUS cc2500PrintStatusByte(status); #endif } void cc2500WriteReg(uint8_t address, uint8_t data) { CS_off; #ifdef DEBUG_STATUS uint8_t status = spiWrite(address); #else spiWrite(address); #endif NOP(); spiWrite(data); CS_on; #ifdef DEBUG_STATUS cc2500PrintStatusByte(status); #endif } uint8_t cc2500ReadReg(uint8_t address) { CS_off; if ((address >= 0x30) && (address <= 0x3D)) { // Status Registers need a burst read address |= CC2500_READ_BURST; } else { address |= CC2500_READ_SINGLE; } #ifdef DEBUG_STATUS uint8_t status = spiWrite(address); #else spiWrite(address); #endif uint8_t result = spiRead(); CS_on; #ifdef DEBUG_STATUS cc2500PrintStatusByte(status); #endif return result; } void cc2500Strobe(uint8_t address) { CS_off; #ifdef DEBUG_STATUS uint8_t status = spiWrite(address); #else spiWrite(address); #endif CS_on; #ifdef DEBUG_STATUS cc2500PrintStatusByte(status); #endif } void cc2500ResetChip(void) { // Toggle chip select signal CS_on; _delay_us(30); CS_off; _delay_us(30); CS_on; _delay_us(45); cc2500Strobe(CC2500_SRES); _delay_ms(100); }