41 #include "ADF7023_Config.h"
42 #include "Communication.h"
60 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
64 #define BIT(n) (1 << (n))
66 #define ADF7023_CS_ASSERT (P2 &= ~BIT(2))
67 #define ADF7023_CS_DEASSERT (P2 |= BIT(2))
68 #define ADF7023_MISO (P0 & BIT(3))
70 #define ADF7023_SPI_BUS (CSI10)
72 #define LOOP_LIMIT 100
74 #ifndef ADF7023_VERBOSE
81 #define ADF7023_VERBOSE 0
84 #if (ADF7023_VERBOSE >= 2)
85 #define break_loop() if(++counter >= LOOP_LIMIT) { printf("Breaking stuck while loop at %s line %u." NEWLINE, __FILE__, __LINE__); break; }
87 #define break_loop() if(++counter >= LOOP_LIMIT) break
90 #define ADF7023_While(condition, body) do { \
92 while(condition) { body; break_loop(); } \
98 struct ADF7023_BBRAM ADF7023_BBRAMCurrent;
100 #if (ADF7023_VERBOSE >= 7)
101 static unsigned char status_old = 0xff;
102 static unsigned char int0_old = 0xff;
105 const char *ADF7023_state_lookup[] = {
106 "Busy, performing a state transition",
111 "Performing CMD_GET_RSSI",
113 "Performing CMD_IR_CAL",
114 "Performing CMD_AES_DECRYPT_INIT",
115 "Performing CMD_AES_DECRYPT",
116 "Performing CMD_AES_ENCRYPT",
129 const char *ADF7023_cmd_lookup[] = {
130 [CMD_SYNC] =
"CMD_SYNC",
131 [CMD_PHY_OFF] =
"CMD_PHY_OFF",
132 [CMD_PHY_ON] =
"CMD_PHY_ON",
133 [CMD_PHY_RX] =
"CMD_PHY_RX",
134 [CMD_PHY_TX] =
"CMD_PHY_TX",
135 [CMD_PHY_SLEEP] =
"CMD_PHY_SLEEP",
136 [CMD_CONFIG_DEV] =
"CMD_CONFIG_DEV",
137 [CMD_GET_RSSI] =
"CMD_GET_RSSI",
138 [CMD_BB_CAL] =
"CMD_BB_CAL",
139 [CMD_HW_RESET] =
"CMD_HW_RESET",
140 [CMD_RAM_LOAD_INIT] =
"CMD_RAM_LOAD_INIT",
141 [CMD_RAM_LOAD_DONE] =
"CMD_RAM_LOAD_DONE",
142 [CMD_IR_CAL] =
"CMD_IR_CAL",
143 [CMD_AES_ENCRYPT] =
"CMD_AES_ENCRYPT",
144 [CMD_AES_DECRYPT] =
"CMD_AES_DECRYPT",
145 [CMD_AES_DECRYPT_INIT] =
"CMD_AES_DECRYPT_INIT",
146 [CMD_RS_ENCODE_INIT] =
"CMD_RS_ENCODE_INIT",
147 [CMD_RS_ENCODE] =
"CMD_RS_ENCODE",
148 [CMD_RS_DECODE] =
"CMD_RS_DECODE",
151 static int spi_busy = 0;
152 static uint8_t tx_rec[255];
153 static uint8_t rx_rec[255];
154 static uint8_t tx_pos;
155 static uint8_t rx_pos;
157 static void ADF7023_SetCommand_Assume_CMD_READY(
unsigned char command);
160 hexdump(
const void *data,
size_t len)
166 printf(
"%02x", ((
const unsigned char *)data)[0]);
167 for(n = 1; n < len; n++) {
168 printf(
" %02x", ((
const unsigned char *)data)[n]);
172 ADF7023_SPI_Begin(
void)
174 assert(spi_busy == 0);
183 ADF7023_SPI_End(
void)
185 assert(spi_busy > 0);
189 #if (ADF7023_VERBOSE >= 10)
190 printf(
"ADF7023_SPI_End(): wrote \"");
191 hexdump(tx_rec, tx_pos);
192 printf(
"\", read \"");
193 hexdump(rx_rec, rx_pos);
194 printf(
"\"." NEWLINE);
206 ADF7023_WriteReadByte(
unsigned char writeByte,
207 unsigned char *readByte)
209 unsigned char data = 0;
212 SPI_Read(ADF7023_SPI_BUS, 0, &data, 1);
217 assert(tx_pos < ARRAY_SIZE(tx_rec));
218 tx_rec[tx_pos] = writeByte;
221 assert(rx_pos < ARRAY_SIZE(rx_rec));
222 rx_rec[rx_pos] = data;
226 ADF7023_Wait_for_CMD_READY(
void)
228 unsigned char status;
234 ADF7023_GetStatus(&status);
236 if((status & STATUS_SPI_READY) == 0) {
241 if(status & STATUS_CMD_READY) {
246 if((status & STATUS_FW_STATE) == FW_STATE_PHY_OFF) {
249 ADF7023_SetCommand_Assume_CMD_READY(CMD_PHY_ON);
254 ADF7023_Init_Procedure(
void)
257 ADF7023_While(!ADF7023_MISO, (
void)0);
259 ADF7023_Wait_for_CMD_READY();
276 ADF7023_BBRAMCurrent = ADF7023_BBRAMDefault;
277 SPI_Init(ADF7023_SPI_BUS,
283 ADF7023_Init_Procedure();
285 ADF7023_SetCommand(CMD_HW_RESET);
287 ADF7023_Init_Procedure();
289 ADF7023_SetRAM_And_Verify(0x100, 64, (
unsigned char *)&ADF7023_BBRAMCurrent);
290 ADF7023_SetCommand(CMD_CONFIG_DEV);
302 ADF7023_GetStatus(
unsigned char *status)
305 ADF7023_WriteReadByte(SPI_NOP, 0);
306 ADF7023_WriteReadByte(SPI_NOP, status);
309 #if (ADF7023_VERBOSE >= 7)
310 if(*status != status_old) {
311 printf(
"ADF7023_GetStatus: SPI_READY=%u, IRQ_STATUS=%u, CMD_READY=%u, FW_STATE=0x%02x",
315 *status & STATUS_FW_STATE
317 if((*status & STATUS_FW_STATE) < ARRAY_SIZE(ADF7023_state_lookup)) {
318 printf(
"=\"%s\"", ADF7023_state_lookup[*status & STATUS_FW_STATE]);
321 status_old = *status;
326 ADF7023_SetCommand_Assume_CMD_READY(
unsigned char command)
328 #if (ADF7023_VERBOSE >= 7)
329 assert(ADF7023_cmd_lookup[command] !=
NULL);
330 printf(
"Sending command 0x%02x = \"%s\"." NEWLINE, command, ADF7023_cmd_lookup[command]);
333 ADF7023_WriteReadByte(command, 0);
344 ADF7023_SetCommand(
unsigned char command)
346 ADF7023_Wait_for_CMD_READY();
347 ADF7023_SetCommand_Assume_CMD_READY(command);
350 ADF7023_SetFwState_NoWait(
unsigned char fwState)
353 case FW_STATE_PHY_OFF:
354 ADF7023_SetCommand(CMD_PHY_OFF);
356 case FW_STATE_PHY_ON:
357 ADF7023_SetCommand(CMD_PHY_ON);
359 case FW_STATE_PHY_RX:
360 ADF7023_SetCommand(CMD_PHY_RX);
362 case FW_STATE_PHY_TX:
363 ADF7023_SetCommand(CMD_PHY_TX);
366 ADF7023_SetCommand(CMD_PHY_SLEEP);
377 ADF7023_SetFwState(
unsigned char fwState)
379 unsigned char status = 0;
380 ADF7023_SetFwState_NoWait(fwState);
381 ADF7023_While((status & STATUS_FW_STATE) != fwState, ADF7023_GetStatus(&status));
393 ADF7023_GetRAM(
unsigned long address,
394 unsigned long length,
398 ADF7023_WriteReadByte(SPI_MEM_RD | ((address & 0x700) >> 8), 0);
399 ADF7023_WriteReadByte(address & 0xFF, 0);
400 ADF7023_WriteReadByte(SPI_NOP, 0);
402 ADF7023_WriteReadByte(SPI_NOP, data++);
416 ADF7023_SetRAM(
unsigned long address,
417 unsigned long length,
420 ADF7023_Wait_for_CMD_READY();
423 ADF7023_WriteReadByte(SPI_MEM_WR | ((address & 0x700) >> 8), 0);
424 ADF7023_WriteReadByte(address & 0xFF, 0);
426 ADF7023_WriteReadByte(*(data++), 0);
431 ADF7023_SetRAM_And_Verify(
unsigned long address,
unsigned long length,
unsigned char *data)
433 unsigned char readback[256];
435 ADF7023_SetRAM(address, length, data);
437 assert(length <=
sizeof(readback));
438 if(length >
sizeof(readback)) {
441 ADF7023_GetRAM(address, length, readback);
443 if(memcmp(data, readback, length)) {
444 printf(
"ADF7023_SetRAM_And_Verify failed. Wrote:" NEWLINE);
445 hexdump(data, length);
446 printf(NEWLINE
"Read:" NEWLINE);
447 hexdump(readback, length);
452 ADF7023_Wait_for_SPI_READY(
void)
454 unsigned char status = 0;
455 ADF7023_While((status & STATUS_SPI_READY) == 0, ADF7023_GetStatus(&status));
461 unsigned char status;
462 unsigned int counter = 0;
465 status = ADF7023_Wait_for_SPI_READY();
467 switch(status & STATUS_FW_STATE) {
469 ADF7023_SetCommand(CMD_PHY_ON);
476 case FW_STATE_PHY_ON:
487 unsigned char status;
488 unsigned int counter = 0;
491 status = ADF7023_Wait_for_SPI_READY();
493 switch(status & STATUS_FW_STATE) {
503 case FW_STATE_PHY_ON:
504 case FW_STATE_PHY_TX:
505 ADF7023_While((status & STATUS_CMD_READY) == 0, ADF7023_GetStatus(&status));
506 ADF7023_SetCommand(CMD_PHY_RX);
509 case FW_STATE_PHY_RX:
520 unsigned char status;
521 unsigned int counter = 0;
524 status = ADF7023_Wait_for_SPI_READY();
526 switch(status & STATUS_FW_STATE) {
536 case FW_STATE_PHY_ON:
537 case FW_STATE_PHY_RX:
538 ADF7023_While((status & STATUS_CMD_READY) == 0, ADF7023_GetStatus(&status));
539 ADF7023_SetCommand(CMD_PHY_TX);
547 ADF7023_ReadInterruptSource(
void)
549 unsigned char interruptReg;
551 ADF7023_GetRAM(MCR_REG_INTERRUPT_SOURCE_0, 0x1, &interruptReg);
553 #if (ADF7023_VERBOSE >= 7)
554 if(interruptReg != int0_old) {
555 printf(
"ADF7023_ReadInterruptSource: %u%u%u%u%u%u%u%u." NEWLINE,
556 (interruptReg >> 7) & 1,
557 (interruptReg >> 6) & 1,
558 (interruptReg >> 5) & 1,
559 (interruptReg >> 4) & 1,
560 (interruptReg >> 3) & 1,
561 (interruptReg >> 2) & 1,
562 (interruptReg >> 1) & 1,
563 (interruptReg >> 0) & 1
565 int0_old = interruptReg;
571 ADF7023_ReceivePacketAvailable(
void)
573 unsigned char status;
575 ADF7023_GetStatus(&status);
576 if((status & STATUS_SPI_READY) == 0) {
580 if((status & STATUS_FW_STATE) != FW_STATE_PHY_RX) {
585 if((status & STATUS_IRQ_STATUS) == 0) {
589 return ADF7023_ReadInterruptSource() & BBRAM_INTERRUPT_MASK_0_INTERRUPT_CRC_CORRECT;
600 ADF7023_ReceivePacket(
unsigned char *packet,
unsigned char *payload_length)
602 unsigned char length;
603 unsigned char interruptReg = 0;
605 ADF7023_While(!(interruptReg & BBRAM_INTERRUPT_MASK_0_INTERRUPT_CRC_CORRECT),
606 interruptReg = ADF7023_ReadInterruptSource());
608 interruptReg = BBRAM_INTERRUPT_MASK_0_INTERRUPT_CRC_CORRECT;
610 ADF7023_SetRAM(MCR_REG_INTERRUPT_SOURCE_0,
614 ADF7023_GetRAM(ADF7023_RX_BASE_ADR, 1, &length);
616 *payload_length = length - 1 + LENGTH_OFFSET - 4;
618 ADF7023_GetRAM(ADF7023_RX_BASE_ADR + 1, *payload_length, packet);
620 #if (ADF7023_VERBOSE >= 5)
623 printf(
"ADF7023_ReceivePacket, length=%u: ", *payload_length);
624 hexdump(packet, *payload_length);
638 ADF7023_TransmitPacket(
unsigned char *packet,
unsigned char length)
640 unsigned char interruptReg = 0;
641 unsigned char status;
642 unsigned char length_plus_one;
645 ADF7023_GetStatus(&status);
646 if((status & STATUS_SPI_READY) == 0) {
649 if((status & STATUS_CMD_READY) == 0) {
655 length_plus_one = length + 1;
656 ADF7023_SetRAM_And_Verify(ADF7023_TX_BASE_ADR, 1, &length_plus_one);
657 ADF7023_SetRAM_And_Verify(ADF7023_TX_BASE_ADR + 1, length, packet);
659 #if (ADF7023_VERBOSE >= 5)
662 printf(
"ADF7023_TransmitPacket, length=%u: ", length);
663 hexdump(packet, length);
670 ADF7023_While(!(interruptReg & BBRAM_INTERRUPT_MASK_0_INTERRUPT_TX_EOF),
671 ADF7023_GetRAM(MCR_REG_INTERRUPT_SOURCE_0, 0x1, &interruptReg));
683 ADF7023_SetChannelFrequency(
unsigned long chFreq)
685 chFreq = (
unsigned long)(((
float)chFreq / 26000000) * 65535);
686 ADF7023_BBRAMCurrent.channelFreq0 = (chFreq & 0x0000FF) >> 0;
687 ADF7023_BBRAMCurrent.channelFreq1 = (chFreq & 0x00FF00) >> 8;
688 ADF7023_BBRAMCurrent.channelFreq2 = (chFreq & 0xFF0000) >> 16;
689 ADF7023_SetRAM_And_Verify(0x100, 64, (
unsigned char *)&ADF7023_BBRAMCurrent);
699 ADF7023_SetDataRate(
unsigned long dataRate)
701 dataRate = (
unsigned long)(dataRate / 100);
702 ADF7023_BBRAMCurrent.radioCfg0 =
703 BBRAM_RADIO_CFG_0_DATA_RATE_7_0((dataRate & 0x00FF) >> 0);
704 ADF7023_BBRAMCurrent.radioCfg1 &= ~BBRAM_RADIO_CFG_1_DATA_RATE_11_8(0xF);
705 ADF7023_BBRAMCurrent.radioCfg1 |=
706 BBRAM_RADIO_CFG_1_DATA_RATE_11_8((dataRate & 0x0F00) >> 8);
707 ADF7023_SetRAM_And_Verify(0x100, 64, (
unsigned char *)&ADF7023_BBRAMCurrent);
708 ADF7023_SetFwState(FW_STATE_PHY_OFF);
709 ADF7023_SetCommand(CMD_CONFIG_DEV);
719 ADF7023_SetFrequencyDeviation(
unsigned long freqDev)
721 freqDev = (
unsigned long)(freqDev / 100);
722 ADF7023_BBRAMCurrent.radioCfg1 &=
723 ~BBRAM_RADIO_CFG_1_FREQ_DEVIATION_11_8(0xF);
724 ADF7023_BBRAMCurrent.radioCfg1 |=
725 BBRAM_RADIO_CFG_1_FREQ_DEVIATION_11_8((freqDev & 0x0F00) >> 8);
726 ADF7023_BBRAMCurrent.radioCfg2 =
727 BBRAM_RADIO_CFG_2_FREQ_DEVIATION_7_0((freqDev & 0x00FF) >> 0);
728 ADF7023_SetRAM_And_Verify(0x100, 64, (
unsigned char *)&ADF7023_BBRAMCurrent);
729 ADF7023_SetFwState(FW_STATE_PHY_OFF);
730 ADF7023_SetCommand(CMD_CONFIG_DEV);
#define BIT(x)
Useful to reference a single bit of a byte.
Default definitions of C compiler quirk work-arounds.
#define NULL
The null pointer.
#define CLOCK_SECOND
A second, measured in system clock time.
void clock_wait(clock_time_t t)
Wait for a given number of ticks.