41 #include "ADF7023_Config.h"
42 #include "Communication.h"
59 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
63 #define BIT(n) (1 << (n))
65 #define ADF7023_CS_ASSERT (P2 &= ~BIT(2))
66 #define ADF7023_CS_DEASSERT (P2 |= BIT(2))
67 #define ADF7023_MISO (P0 & BIT(3))
69 #define ADF7023_SPI_BUS (CSI10)
71 #define LOOP_LIMIT 100
73 #ifndef ADF7023_VERBOSE
80 #define ADF7023_VERBOSE 0
83 #if (ADF7023_VERBOSE >= 2)
84 #define break_loop() if(++counter >= LOOP_LIMIT) { printf("Breaking stuck while loop at %s line %u." NEWLINE, __FILE__, __LINE__); break; }
86 #define break_loop() if(++counter >= LOOP_LIMIT) break
89 #define ADF7023_While(condition, body) do { \
91 while(condition) { body; break_loop(); } \
95 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
100 struct ADF7023_BBRAM ADF7023_BBRAMCurrent;
102 #if (ADF7023_VERBOSE >= 7)
103 static unsigned char status_old = 0xff;
104 static unsigned char int0_old = 0xff;
107 const char *ADF7023_state_lookup[] = {
108 "Busy, performing a state transition",
113 "Performing CMD_GET_RSSI",
115 "Performing CMD_IR_CAL",
116 "Performing CMD_AES_DECRYPT_INIT",
117 "Performing CMD_AES_DECRYPT",
118 "Performing CMD_AES_ENCRYPT",
131 const char *ADF7023_cmd_lookup[] = {
132 [CMD_SYNC] =
"CMD_SYNC",
133 [CMD_PHY_OFF] =
"CMD_PHY_OFF",
134 [CMD_PHY_ON] =
"CMD_PHY_ON",
135 [CMD_PHY_RX] =
"CMD_PHY_RX",
136 [CMD_PHY_TX] =
"CMD_PHY_TX",
137 [CMD_PHY_SLEEP] =
"CMD_PHY_SLEEP",
138 [CMD_CONFIG_DEV] =
"CMD_CONFIG_DEV",
139 [CMD_GET_RSSI] =
"CMD_GET_RSSI",
140 [CMD_BB_CAL] =
"CMD_BB_CAL",
141 [CMD_HW_RESET] =
"CMD_HW_RESET",
142 [CMD_RAM_LOAD_INIT] =
"CMD_RAM_LOAD_INIT",
143 [CMD_RAM_LOAD_DONE] =
"CMD_RAM_LOAD_DONE",
144 [CMD_IR_CAL] =
"CMD_IR_CAL",
145 [CMD_AES_ENCRYPT] =
"CMD_AES_ENCRYPT",
146 [CMD_AES_DECRYPT] =
"CMD_AES_DECRYPT",
147 [CMD_AES_DECRYPT_INIT] =
"CMD_AES_DECRYPT_INIT",
148 [CMD_RS_ENCODE_INIT] =
"CMD_RS_ENCODE_INIT",
149 [CMD_RS_ENCODE] =
"CMD_RS_ENCODE",
150 [CMD_RS_DECODE] =
"CMD_RS_DECODE",
153 static int spi_busy = 0;
154 static uint8_t tx_rec[255];
155 static uint8_t rx_rec[255];
156 static uint8_t tx_pos;
157 static uint8_t rx_pos;
159 static void ADF7023_SetCommand_Assume_CMD_READY(
unsigned char command);
162 hexdump(
const void *data,
size_t len)
168 printf(
"%02x", ((
const unsigned char *)data)[0]);
169 for(n = 1; n < len; n++) {
170 printf(
" %02x", ((
const unsigned char *)data)[n]);
174 ADF7023_SPI_Begin(
void)
176 assert(spi_busy == 0);
185 ADF7023_SPI_End(
void)
187 assert(spi_busy > 0);
191 #if (ADF7023_VERBOSE >= 10)
192 printf(
"ADF7023_SPI_End(): wrote \"");
193 hexdump(tx_rec, tx_pos);
194 printf(
"\", read \"");
195 hexdump(rx_rec, rx_pos);
196 printf(
"\"." NEWLINE);
208 ADF7023_WriteReadByte(
unsigned char writeByte,
209 unsigned char *readByte)
211 unsigned char data = 0;
214 SPI_Read(ADF7023_SPI_BUS, 0, &data, 1);
219 assert(tx_pos < ARRAY_SIZE(tx_rec));
220 tx_rec[tx_pos] = writeByte;
223 assert(rx_pos < ARRAY_SIZE(rx_rec));
224 rx_rec[rx_pos] = data;
228 ADF7023_Wait_for_CMD_READY(
void)
230 unsigned char status;
236 ADF7023_GetStatus(&status);
238 if((status & STATUS_SPI_READY) == 0) {
243 if(status & STATUS_CMD_READY) {
248 if((status & STATUS_FW_STATE) == FW_STATE_PHY_OFF) {
251 ADF7023_SetCommand_Assume_CMD_READY(CMD_PHY_ON);
256 ADF7023_Init_Procedure(
void)
259 ADF7023_While(!ADF7023_MISO, (
void)0);
261 ADF7023_Wait_for_CMD_READY();
278 ADF7023_BBRAMCurrent = ADF7023_BBRAMDefault;
279 SPI_Init(ADF7023_SPI_BUS,
285 ADF7023_Init_Procedure();
287 ADF7023_SetCommand(CMD_HW_RESET);
289 ADF7023_Init_Procedure();
291 ADF7023_SetRAM_And_Verify(0x100, 64, (
unsigned char *)&ADF7023_BBRAMCurrent);
292 ADF7023_SetCommand(CMD_CONFIG_DEV);
304 ADF7023_GetStatus(
unsigned char *status)
307 ADF7023_WriteReadByte(SPI_NOP, 0);
308 ADF7023_WriteReadByte(SPI_NOP, status);
311 #if (ADF7023_VERBOSE >= 7)
312 if(*status != status_old) {
313 printf(
"ADF7023_GetStatus: SPI_READY=%u, IRQ_STATUS=%u, CMD_READY=%u, FW_STATE=0x%02x",
317 *status & STATUS_FW_STATE
319 if((*status & STATUS_FW_STATE) < ARRAY_SIZE(ADF7023_state_lookup)) {
320 printf(
"=\"%s\"", ADF7023_state_lookup[*status & STATUS_FW_STATE]);
323 status_old = *status;
328 ADF7023_SetCommand_Assume_CMD_READY(
unsigned char command)
330 #if (ADF7023_VERBOSE >= 7)
331 assert(ADF7023_cmd_lookup[command] !=
NULL);
332 printf(
"Sending command 0x%02x = \"%s\"." NEWLINE, command, ADF7023_cmd_lookup[command]);
335 ADF7023_WriteReadByte(command, 0);
346 ADF7023_SetCommand(
unsigned char command)
348 ADF7023_Wait_for_CMD_READY();
349 ADF7023_SetCommand_Assume_CMD_READY(command);
352 ADF7023_SetFwState_NoWait(
unsigned char fwState)
355 case FW_STATE_PHY_OFF:
356 ADF7023_SetCommand(CMD_PHY_OFF);
358 case FW_STATE_PHY_ON:
359 ADF7023_SetCommand(CMD_PHY_ON);
361 case FW_STATE_PHY_RX:
362 ADF7023_SetCommand(CMD_PHY_RX);
364 case FW_STATE_PHY_TX:
365 ADF7023_SetCommand(CMD_PHY_TX);
368 ADF7023_SetCommand(CMD_PHY_SLEEP);
379 ADF7023_SetFwState(
unsigned char fwState)
381 unsigned char status = 0;
382 ADF7023_SetFwState_NoWait(fwState);
383 ADF7023_While((status & STATUS_FW_STATE) != fwState, ADF7023_GetStatus(&status));
395 ADF7023_GetRAM(
unsigned long address,
396 unsigned long length,
400 ADF7023_WriteReadByte(SPI_MEM_RD | ((address & 0x700) >> 8), 0);
401 ADF7023_WriteReadByte(address & 0xFF, 0);
402 ADF7023_WriteReadByte(SPI_NOP, 0);
404 ADF7023_WriteReadByte(SPI_NOP, data++);
418 ADF7023_SetRAM(
unsigned long address,
419 unsigned long length,
422 ADF7023_Wait_for_CMD_READY();
425 ADF7023_WriteReadByte(SPI_MEM_WR | ((address & 0x700) >> 8), 0);
426 ADF7023_WriteReadByte(address & 0xFF, 0);
428 ADF7023_WriteReadByte(*(data++), 0);
433 ADF7023_SetRAM_And_Verify(
unsigned long address,
unsigned long length,
unsigned char *data)
435 unsigned char readback[256];
437 ADF7023_SetRAM(address, length, data);
439 assert(length <=
sizeof(readback));
440 if(length >
sizeof(readback)) {
443 ADF7023_GetRAM(address, length, readback);
445 if(memcmp(data, readback, length)) {
446 printf(
"ADF7023_SetRAM_And_Verify failed. Wrote:" NEWLINE);
447 hexdump(data, length);
448 printf(NEWLINE
"Read:" NEWLINE);
449 hexdump(readback, length);
454 ADF7023_Wait_for_SPI_READY(
void)
456 unsigned char status = 0;
457 ADF7023_While((status & STATUS_SPI_READY) == 0, ADF7023_GetStatus(&status));
463 unsigned char status;
464 unsigned int counter = 0;
467 status = ADF7023_Wait_for_SPI_READY();
469 switch(status & STATUS_FW_STATE) {
471 ADF7023_SetCommand(CMD_PHY_ON);
478 case FW_STATE_PHY_ON:
489 unsigned char status;
490 unsigned int counter = 0;
493 status = ADF7023_Wait_for_SPI_READY();
495 switch(status & STATUS_FW_STATE) {
505 case FW_STATE_PHY_ON:
506 case FW_STATE_PHY_TX:
507 ADF7023_While((status & STATUS_CMD_READY) == 0, ADF7023_GetStatus(&status));
508 ADF7023_SetCommand(CMD_PHY_RX);
511 case FW_STATE_PHY_RX:
522 unsigned char status;
523 unsigned int counter = 0;
526 status = ADF7023_Wait_for_SPI_READY();
528 switch(status & STATUS_FW_STATE) {
538 case FW_STATE_PHY_ON:
539 case FW_STATE_PHY_RX:
540 ADF7023_While((status & STATUS_CMD_READY) == 0, ADF7023_GetStatus(&status));
541 ADF7023_SetCommand(CMD_PHY_TX);
549 ADF7023_ReadInterruptSource(
void)
551 unsigned char interruptReg;
553 ADF7023_GetRAM(MCR_REG_INTERRUPT_SOURCE_0, 0x1, &interruptReg);
555 #if (ADF7023_VERBOSE >= 7)
556 if(interruptReg != int0_old) {
557 printf(
"ADF7023_ReadInterruptSource: %u%u%u%u%u%u%u%u." NEWLINE,
558 (interruptReg >> 7) & 1,
559 (interruptReg >> 6) & 1,
560 (interruptReg >> 5) & 1,
561 (interruptReg >> 4) & 1,
562 (interruptReg >> 3) & 1,
563 (interruptReg >> 2) & 1,
564 (interruptReg >> 1) & 1,
565 (interruptReg >> 0) & 1
567 int0_old = interruptReg;
573 ADF7023_ReceivePacketAvailable(
void)
575 unsigned char status;
577 ADF7023_GetStatus(&status);
578 if((status & STATUS_SPI_READY) == 0) {
582 if((status & STATUS_FW_STATE) != FW_STATE_PHY_RX) {
587 if((status & STATUS_IRQ_STATUS) == 0) {
591 return ADF7023_ReadInterruptSource() & BBRAM_INTERRUPT_MASK_0_INTERRUPT_CRC_CORRECT;
602 ADF7023_ReceivePacket(
unsigned char *packet,
unsigned char *payload_length)
604 unsigned char length;
605 unsigned char interruptReg = 0;
607 ADF7023_While(!(interruptReg & BBRAM_INTERRUPT_MASK_0_INTERRUPT_CRC_CORRECT),
608 interruptReg = ADF7023_ReadInterruptSource());
610 interruptReg = BBRAM_INTERRUPT_MASK_0_INTERRUPT_CRC_CORRECT;
612 ADF7023_SetRAM(MCR_REG_INTERRUPT_SOURCE_0,
616 ADF7023_GetRAM(ADF7023_RX_BASE_ADR, 1, &length);
618 *payload_length = length - 1 + LENGTH_OFFSET - 4;
620 ADF7023_GetRAM(ADF7023_RX_BASE_ADR + 1, *payload_length, packet);
622 #if (ADF7023_VERBOSE >= 5)
625 printf(
"ADF7023_ReceivePacket, length=%u: ", *payload_length);
626 hexdump(packet, *payload_length);
640 ADF7023_TransmitPacket(
unsigned char *packet,
unsigned char length)
642 unsigned char interruptReg = 0;
643 unsigned char status;
644 unsigned char length_plus_one;
647 ADF7023_GetStatus(&status);
648 if((status & STATUS_SPI_READY) == 0) {
651 if((status & STATUS_CMD_READY) == 0) {
657 length_plus_one = length + 1;
658 ADF7023_SetRAM_And_Verify(ADF7023_TX_BASE_ADR, 1, &length_plus_one);
659 ADF7023_SetRAM_And_Verify(ADF7023_TX_BASE_ADR + 1, length, packet);
661 #if (ADF7023_VERBOSE >= 5)
664 printf(
"ADF7023_TransmitPacket, length=%u: ", length);
665 hexdump(packet, length);
672 ADF7023_While(!(interruptReg & BBRAM_INTERRUPT_MASK_0_INTERRUPT_TX_EOF),
673 ADF7023_GetRAM(MCR_REG_INTERRUPT_SOURCE_0, 0x1, &interruptReg));
685 ADF7023_SetChannelFrequency(
unsigned long chFreq)
687 chFreq = (
unsigned long)(((
float)chFreq / 26000000) * 65535);
688 ADF7023_BBRAMCurrent.channelFreq0 = (chFreq & 0x0000FF) >> 0;
689 ADF7023_BBRAMCurrent.channelFreq1 = (chFreq & 0x00FF00) >> 8;
690 ADF7023_BBRAMCurrent.channelFreq2 = (chFreq & 0xFF0000) >> 16;
691 ADF7023_SetRAM_And_Verify(0x100, 64, (
unsigned char *)&ADF7023_BBRAMCurrent);
701 ADF7023_SetDataRate(
unsigned long dataRate)
703 dataRate = (
unsigned long)(dataRate / 100);
704 ADF7023_BBRAMCurrent.radioCfg0 =
705 BBRAM_RADIO_CFG_0_DATA_RATE_7_0((dataRate & 0x00FF) >> 0);
706 ADF7023_BBRAMCurrent.radioCfg1 &= ~BBRAM_RADIO_CFG_1_DATA_RATE_11_8(0xF);
707 ADF7023_BBRAMCurrent.radioCfg1 |=
708 BBRAM_RADIO_CFG_1_DATA_RATE_11_8((dataRate & 0x0F00) >> 8);
709 ADF7023_SetRAM_And_Verify(0x100, 64, (
unsigned char *)&ADF7023_BBRAMCurrent);
710 ADF7023_SetFwState(FW_STATE_PHY_OFF);
711 ADF7023_SetCommand(CMD_CONFIG_DEV);
721 ADF7023_SetFrequencyDeviation(
unsigned long freqDev)
723 freqDev = (
unsigned long)(freqDev / 100);
724 ADF7023_BBRAMCurrent.radioCfg1 &=
725 ~BBRAM_RADIO_CFG_1_FREQ_DEVIATION_11_8(0xF);
726 ADF7023_BBRAMCurrent.radioCfg1 |=
727 BBRAM_RADIO_CFG_1_FREQ_DEVIATION_11_8((freqDev & 0x0F00) >> 8);
728 ADF7023_BBRAMCurrent.radioCfg2 =
729 BBRAM_RADIO_CFG_2_FREQ_DEVIATION_7_0((freqDev & 0x00FF) >> 0);
730 ADF7023_SetRAM_And_Verify(0x100, 64, (
unsigned char *)&ADF7023_BBRAMCurrent);
731 ADF7023_SetFwState(FW_STATE_PHY_OFF);
732 ADF7023_SetCommand(CMD_CONFIG_DEV);
#define NULL
The null pointer.
#define BIT(x)
Useful to reference a single bit of a byte.
void clock_wait(clock_time_t t)
Wait for a given number of ticks.
#define CLOCK_SECOND
A second, measured in system clock time.