📄 main.c
字号:
/******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + Audio Link main control code *
* *** + + *** *
* *** +++ *** *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* Main control loops for master and slave *
*******************************************************************************************************
* Compiler: Keil C51 *
* Target platform: 8051F005 *
*******************************************************************************************************
* Revision history: *
* Initial release, HKI, 01.08.2004 *
******************************************************************************************************/
#pragma REGISTERBANK(0)
#pragma OPTIMIZE(4, SPEED)
#pragma REGPARMS
#include <Cinclude.h>
/******************************************************************************************************
* State definitions *
******************************************************************************************************/
BYTE data state _at_ statePtr;
#define IDLE 0x00
#define TX_RUN 0x10
#define FIFO_LOW 0x11
#define TX_END 0x12
#define WAIT_ACK 0x13
#define RX_RUN 0x20
#define FIFO_HIGH 0x21
#define SEND_ACK 0x22
#define FH 0x40
/******************************************************************************************************
* Control flags *
******************************************************************************************************/
BYTE data systemFlags _at_ systemFlagsPtr;
// TX flags
#define RESEND_PREVIOUS (systemFlags & 0x02)
// RX flags
#define INVALID_SEQNO (systemFlags & 0x01)
// Common flags
#define INVALID_SYSID (systemFlags & 0x04)
/******************************************************************************************************
* Buffer locks *
******************************************************************************************************/
#define AUDIO_IN_LOCK ((audioInWritePage & 0x07) != audioInReadPage)
#define AUDIO_OUT_LOCK (audioOutWritePage != (audioOutReadPage & 0x07))
#define TX_BUFFER_LOCK (txBufferWritePage != txBufferReadPage)
#define PACKETIZE_WINDOW (AUDIO_IN_LOCK && (TX_BUFFER_LOCK || (txBufferReadLowB == 0x01)))
#define RX_BUFFER_LOCK (rxBufferWritePage != rxBufferReadPage)
#define DEPACKETIZE_WINDOW (AUDIO_OUT_LOCK && RX_BUFFER_LOCK)
/******************************************************************************************************
* Global/register pointers *
******************************************************************************************************/
BYTE data txBufferReadPage _at_ 0x13; // R3, Bank 2
BYTE data txBufferReadLowB _at_ 0x11; // R1, Bank 2
BYTE data txBufferWritePage _at_ 0x0A; // R2, Bank 1
BYTE data audioInReadPage _at_ 0x0B; // R3, Bank 1
#define audioInWritePage DPH
BYTE data rxBufferWritePage _at_ 0x13; // R3, Bank 2
BYTE data rxBufferWriteLowB _at_ 0x11; // R1, Bank 2
BYTE data rxBufferReadPage _at_ 0x0A; // R2, Bank 1
BYTE data audioOutWritePage _at_ 0x0B; // R3, Bank 1
#define audioOutReadPage DPH
// Make sure the compiler stays away from register bank 1,2 and 3,
// as these are in use by the assembly code
BYTE data reserveREGS[24] _at_ 0x08;
/******************************************************************************************************
* Macros *
******************************************************************************************************/
#define REVERSE_TX_BUFFER_READ_PAGE_POINTER() \
do { \
txBufferReadPage++; \
txBufferReadPage &= 0x03; \
} while(FALSE)
#define REVERSE_RX_BUFFER_WRITE_PAGE_POINTER() \
do { \
rxBufferWritePage++; \
rxBufferWritePage &= 0x03; \
} while(FALSE)
#define CLEAR_INVALID_SEQNO_FLAG() \
do { \
systemFlags &= 0xFE; \
} while(FALSE)
#define CLEAR_INVALID_SYSID_FLAG() \
do { \
systemFlags &= 0xFB; \
} while(FALSE)
#define SET_RESEND_PREVIOUS_FLAG() \
do { \
systemFlags |= 0x02; \
} while(FALSE)
#define CLEAR_RESEND_PREVIOUS_FLAG() \
do { \
systemFlags &= 0xFD; \
} while(FALSE)
/*******************************************************************************************************
* Main *
*******************************************************************************************************/
void main(void) {
static BYTE data n; // Counter/loop variable
static BYTE data ack = OK_ACK; // Ack byte, default ACK_OK
static BYTE data sysID = SYS_ID; // System ID
static BYTE data byteCount16 = 0; // RX/TX byte count (mod 16 -> FIFO threshold)
fN_1 = SEED; // Previous FH frequency f(N-1)/LCG seed
fhiLevel = FHI_NORMAL;
state = IDLE;
systemFlags = 0x00;
mcuConfig();
sysConfig();
NEXT_FREQ(); // Pre-calculate first channel
if (!M_MASTER) {
/*********************** Radio master - main control loop ***********************/
// Make first initial packet before TX is started
while(audioInWritePage != 0x04);
while(audioInWritePage == 0x04);
while (txBufferWritePage != 0x02) {
packetize();
}
while (TRUE) {
switch(state) {
case IDLE:
while(TRUE) { // To speed up packetize()
if (TX_BUFFER_LOCK){ // Packet ready?
R_RX = 0; // Start TX
writeFIFO(); // Fill the FIFO (writeFIFO() is fixed at 16 bytes)
writeFIFO();
byteCount16 += 2;
state = TX_RUN;
break;
}
if (PACKETIZE_WINDOW) {
packetize();
}
}
break;
case TX_RUN: // Sending data, FIFO > 16
while (FIFO) {
if (PACKETIZE_WINDOW) {
packetize();
}
}
state = FIFO_LOW;
break;
case FIFO_LOW: // FIFO < 16
writeFIFO();
byteCount16++;
if (byteCount16 == 16) { // End of packet in FIFO?
byteCount16 = 0;
state = TX_END;
break;
} else {
state = TX_RUN;
}
break;
case TX_END: // End of packet written to FIFO
while (PKT_ACTIVE) { // Packet transmission complete?
if (PACKETIZE_WINDOW) {
packetize();
}
}
R_RX = 1; // Stop TX, start RX
R_TX = 0;
ENABLE_ACK_TIMER();
state = WAIT_ACK;
break;
case WAIT_ACK: // Wait for ACK, reset pointers if not received, stop RF before FH
SPI_SETREG(CC2400_INT, ACK_FIFO_TH);
while(TRUE) {
if (ACK_TIMEOUT) {
if (RESEND_PREVIOUS) {
REVERSE_TX_BUFFER_READ_PAGE_POINTER();
CLEAR_RESEND_PREVIOUS_FLAG();
}
SPI_SETREG(CC2400_INT, AUDIO_FIFO_TH);
RESET_ACK_TIMER();
R_RX = 0; // Stop RF
M_GLED = ~M_GLED;
state = FH;
break;
}
if (!FIFO) { // ACK in FIFO
SPI_READ_FIFO(&sysID, 1, n);
SPI_READ_FIFO(&ack, 1, n);
if ((sysID == SYS_ID) && (ack == OK_ACK)) {
SET_RESEND_PREVIOUS_FLAG(); // Resend at next ACK timeout
RESET_ACK_TIMER();
R_RX = 0; // Stop RF
state = FH;
}
SPI_SETREG(CC2400_INT, AUDIO_FIFO_TH);
break;
}
if (PACKETIZE_WINDOW) {
packetize();
}
}
break;
case FH: // Next frequency
SPI_SETREG(CC2400_FSDIV, f);
NEXT_FREQ(); // Calculate next frequency
R_TX = 1; // Goto FS calibrate and packetize while not in lock
R_RX = 1;
do {
SPI_UPD_STATUS();
if (PACKETIZE_WINDOW) {
packetize();
}
} while (!(CC2400status & FS_LOCK));
state = IDLE;
break;
default:
M_BLED = 0; // Error state
M_BLED = 0;
while(TRUE) {
wait(1000);
M_GLED = ~M_GLED;
M_BLED = ~M_BLED;
}
} // switch
} // while
/*******************************************************************************/
} else {
/*********************** Radio slave - main control loop ***********************/
while(!(!PKT && PKT_ACTIVE)); // Wait for first packet
while (TRUE) {
switch(state) {
case IDLE:
while (TRUE) { // To speed up dePacketize()
if (!PKT && PKT_ACTIVE) { // Sync. w. found
// Start outCodecISR() when rxBuffer is 3/4 full
// This implies that audioOut is full as the ISR is not started yet
if (!EA && (rxBufferWritePage == 0x01)) {
syncRLInt();
}
state = RX_RUN;
RESET_CLEAR_AHEAD_TIMER();
fhiLevel = FHI_NORMAL;
resetFHtimer(FHI_NORMAL);
break;
} else {
ENABLE_CLEAR_AHEAD_TIMER();
}
if (FH_TIMEOUT && (fhiLevel <= FHI_MAX)) {
R_TX = 0;
R_RX = 0;
M_BLED = ~M_BLED;
fhiLevel++;
resetFHtimer(fhiLevel);
state = FH;
break;
}
if (DEPACKETIZE_WINDOW) {
dePacketize();
} else if (CLEAR_AHEAD_TIMEOUT) {
// Too much time has elapsed since the last packet was received,
// must start to clear memory (go silent)
audioOutClearAhead();
RESET_CLEAR_AHEAD_TIMER();
}
}
break;
case RX_RUN: // Receiving audio packet
while(FIFO) {
if (DEPACKETIZE_WINDOW) {
dePacketize();
}
}
state = FIFO_HIGH;
break;
case FIFO_HIGH: // FIFO > 16
readFIFO();
byteCount16++;
if (byteCount16 == 16) {
byteCount16 = 0;
state = SEND_ACK;
break;
} else {
state = RX_RUN;
}
break;
case SEND_ACK: // End of packet, send ACK if CRC and seqNo is OK
R_TX = 1; // Stop RX, goto FSON
if (CRC_OK && !INVALID_SEQNO && !INVALID_SYSID) {
R_RX = 0; // Start TX and send ACK
sysID = SYS_ID;
ack = OK_ACK;
SPI_WRITE_FIFO(&sysID, 1, n);
SPI_WRITE_FIFO(&ack, 1, n);
while(!PKT_ACTIVE);
while (PKT_ACTIVE) {
if (DEPACKETIZE_WINDOW) {
dePacketize();
}
}
R_RX = 1; // Stop TX
} else { // Packet is OK
REVERSE_RX_BUFFER_WRITE_PAGE_POINTER();
CLEAR_INVALID_SEQNO_FLAG();
CLEAR_INVALID_SYSID_FLAG();
M_GLED = ~M_GLED;
}
while(!PKT); // Sending ACK
R_TX = 0; // Stop RF
R_RX = 0;
state = FH;
break;
case FH: // Next frequency
SPI_SETREG(CC2400_FSDIV, f);
NEXT_FREQ(); // Calculate next frequency
R_TX = 1; // Goto FS calibrate and de-packetize while not in lock
R_RX = 1;
do {
SPI_UPD_STATUS();
if (DEPACKETIZE_WINDOW) {
dePacketize();
}
} while (!(CC2400status & FS_LOCK));
R_TX = 0; // Restart RX
ENABLE_FH_TIMER();
state = IDLE;
break;
default:
M_GLED = 0; // Error state
M_BLED = 0;
while(TRUE) {
wait(1000);
M_GLED = ~M_GLED;
M_BLED = ~M_BLED;
}
} // switch
} // while
/*******************************************************************************/
}// if
} // main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -