📄 mc1319x.c
字号:
DR_13192CTRL |= _BV(DD_RXTXEN);
sei();
return 1;
}
void MC13192_setPower(unsigned char iPower)
{
cli();
SPI_Modify13192Register(MC13192_PA_LVL,cPA_LVL_COARSE|cPA_LVL_FINE, (0x0F&iPower)<<4 );
sei();
}
void MC13192_setChannel(unsigned char iChannel)
{
unsigned char iDiv=0x95;
unsigned short iNum=0x5000;
switch(iChannel)
{
case 1: iDiv=0x95; iNum=0x5000; break;
case 2: iDiv=0x95; iNum=0xA000; break;
case 3: iDiv=0x95; iNum=0xF000; break;
case 4: iDiv=0x96; iNum=0x4000; break;
case 5: iDiv=0x96; iNum=0x9000; break;
case 6: iDiv=0x96; iNum=0xE000; break;
case 7: iDiv=0x97; iNum=0x3000; break;
case 8: iDiv=0x97; iNum=0x8000; break;
case 9: iDiv=0x97; iNum=0xD000; break;
case 10: iDiv=0x98; iNum=0x2000; break;
case 11: iDiv=0x98; iNum=0x7000; break;
case 12: iDiv=0x98; iNum=0xC000; break;
case 13: iDiv=0x99; iNum=0x1000; break;
case 14: iDiv=0x99; iNum=0x6000; break;
case 15: iDiv=0x99; iNum=0xB000; break;
case 16: iDiv=0x9A; iNum=0x0000; break;
}
cli();
SPI_Modify13192Register(MC13192_LO1_INT_DIV,cLO1_IDIV, iDiv );
SPI_Write13192Register(MC13192_LO1_NUM, iNum );
sei();
}
unsigned char MC13192_doCCA(void)
{
cli();
// Check if init ok and no active transfers
if(DSRC_Status!=DSRC_INIT_OK)
{
sei();
return 0;
}
DSRC_Status|=DSRC_CCA;
// Set TX frequency
// Set RXTXEN low
DR_13192CTRL &= ~_BV(DD_RXTXEN);
// Set CCA threshold
// Set RX control bits
SPI_Modify13192Register(MC13192_CONTROL_A,cRX_STRM|cTX_STRM|cTMR_TRIG_EN,0x0000);
SPI_Modify13192Register(MC13192_CONTROL_A,cCCA_MASK,cCCA_MASK);
SPI_Modify13192Register(MC13192_CONTROL_A,cCCA_TYPE,0x0010);
SPI_Modify13192Register(MC13192_CONTROL_A,cXCVR_SEQ,0x0001);
// Set RXTXEN high
DR_13192CTRL |= _BV(DD_RXTXEN);
sei();
return 1;
}
// Int from MC13192
ISR (INT0_vect)
{
//fireLED(LED_GREEN);
//return;
cli();
unsigned short word_tmp,irq_status;
// Check what's up!
SPI_Read13192Register(MC13192_IRQ_STATUS, &irq_status);
if(irq_status==0)
{
SPI_Read13192Register(MC13192_IRQ_STATUS, &word_tmp);
irq_status|=word_tmp;
}
if(irq_status==0)
{
sei();
return;
}
if(cATTN_IRQ&irq_status)
{
// ATTN IRQ
//fireLED(LED_YELLOW);
USART_Transmit( "A",1);
sei();
return;
}
if( (cCCA_IRQ&irq_status) )
{
// CCA done
// Clear CCA-mode
SPI_Modify13192Register(MC13192_CONTROL_A,cCCA_MASK,0);
SPI_Modify13192Register(MC13192_CONTROL_A,cXCVR_SEQ,0x0000);
// Set RXTXEN low
DR_13192CTRL &= ~_BV(DD_RXTXEN);
// Clear CCA mode
DSRC_Status&=~DSRC_CCA;
SPI_Read13192Register(MC13192_RX_STATUS, &word_tmp);
CCAdoneCallback(irq_status&cCCA, (word_tmp&cCCA_FINAL)>>8);
sei();
return;
}
if( (cTMR1_IRQ&irq_status) && (DSRC_Status&DSRC_RCVTMR))
{
// Timeout while listening for packets
// Enable irq when the RX packet has been fully recived
//SPI_Modify13192Register(MC13192_CONTROL_B,cRX_DONE_MASK,cRX_DONE_MASK);
// Disable TC1 and clear IRQ
SPI_Write13192Register(MC13192_TMR_CMP1_A, 0x8000);
//SPI_Write13192Register(MC13192_TMR_CMP1_B, 0x0000);
// Clear rcv mode
DSRC_Status&=~DSRC_RCVTMR;
// Set RXTXEN low
DR_13192CTRL &= ~_BV(DD_RXTXEN);
// Read irq reg again to clear any new irq that has appeared
SPI_Read13192Register(MC13192_IRQ_STATUS, &irq_status);
packetSize=0xFF;
packetReceivedCallback();
packetSize=0x0;
sei();
return;
}
if( (cPLL_LOCK_IRQ&irq_status) )
{
// MC1319x lost LOCK!
// Reenable receive and CCA mode, abort transmit mode
DR_13192CTRL &= ~_BV(DD_RXTXEN);
if( (DSRC_Status|DSRC_RCVTMR) /*|| (DSRC_Status|DSRC_RCV) || (DSRC_Status|DSRC_CCA)*/)
{
// Do nothing, the timeout will restart reception/resend
//fireLED(LED_GREEN);
//DSRC_Status=DSRC_INIT_OK;
//MC13192_receivePacket(MC1319x_RCV_DEFAULT_TIMEOUT);
/*
SPI_Read13192Register(MC13192_CONTROL_A, &word_tmp);
SPI_Write13192Register(MC13192_CONTROL_A, word_tmp&0xFF7F);
// Set RXTXEN high to restart active sequence!
DR_13192CTRL |= _BV(DD_RXTXEN);*/
sei();
return;
}
else if( DSRC_Status|DSRC_SND )
{
// Indicate packet timeout so we can resend
DSRC_Status&=~DSRC_SND;
packetSize=0xff;
packetReceivedCallback();
sei();
return;
}
sei();
return;
}
if(cSTRM_DATA_ERR_IRQ&irq_status)
{
USART_Transmit( "X",1);
}
if(DSRC_Status&DSRC_SND)
{
if(cTX_STRM_IRQ&irq_status)
{
// MC1319x is ready for the next word
MC13192_SendNextPacketWord();
sei();
return;
}
if(cTX_DONE_IRQ&irq_status)
{
// Packet has been sent
// Clear snd mode
DSRC_Status&=~DSRC_SND;
// Set RXTXEN low
DR_13192CTRL &= ~_BV(DD_RXTXEN);
packetSentCallback();
sei();
return;
}
}
else if(DSRC_Status&(DSRC_RCV|DSRC_RCVTMR))
{
if( cRX_STRM_IRQ&irq_status )
{
//if(packetPos<=packetSize)
if(packetSize!=0)
MC13192_ReceiveNextPacketWord();
else
{
// First occurrence of this irq indicates packet length is available
SPI_Read13192Register(MC13192_RX_STATUS, &word_tmp);
packetPos=0;
packetSize=word_tmp&cRX_PKT_LATCH;
/* if(packetSize<3)
{
fireLED(LED_GREEN);
// bad packetsize, reenable receiver
// Set RXTXEN low
DR_13192CTRL &= ~_BV(DD_RXTXEN);
packetSize=0;
SPI_Read13192Register(MC13192_CONTROL_A, &word_tmp);
SPI_Write13192Register(MC13192_CONTROL_A, word_tmp&0xFF7F);
// Set RXTXEN high to restart active sequence!
DR_13192CTRL |= _BV(DD_RXTXEN);
}*/
}
sei();
return;
}
// Weird thing. Sometimes we only get a CRC_VALID and not a RX_DONE IRQ...
if( cRX_DONE_IRQ&irq_status || (cCRC_VALID&irq_status && packetPos+2==packetSize) )
{
//fireLED(LED_GREEN);
// Packet has been received
// Set RXTXEN low
DR_13192CTRL &= ~_BV(DD_RXTXEN);
// Check CRC
if( (cCRC_VALID&irq_status) && packetSize>=3)
{
// Clear snd mode
// Disable TC1 and clear IRQ
SPI_Write13192Register(MC13192_TMR_CMP1_A, 0x8000);
SPI_Write13192Register(MC13192_TMR_CMP1_B, 0x0000);
SPI_Read13192Register(MC13192_IRQ_STATUS, &word_tmp);
DSRC_Status&=~(DSRC_RCV|DSRC_RCVTMR);
packetReceivedCallback();
sei();
return;
}
else
{
// Disable TC1 and clear IRQ
SPI_Write13192Register(MC13192_TMR_CMP1_A, 0x8000);
SPI_Write13192Register(MC13192_TMR_CMP1_B, 0x0000);
SPI_Read13192Register(MC13192_IRQ_STATUS, &irq_status);
DSRC_Status&=~(DSRC_RCV|DSRC_RCVTMR);
packetSize=0;
packetReceivedCallback();
sei();
return;
}
sei();
return;
}
#ifdef USE_USART
char buf[32];
sprintf(buf,"IRQ(r): %x, p%d s%d\r\n", irq_status, packetPos, packetSize);
USART_TransmitStr(buf);
#endif
sei();
return;
}
else if(DSRC_Status&DSRC_ABORTRCV)
{
// Receive aborted 1319x has returned to idle mode
if( cRX_DONE_IRQ&irq_status)
{
DSRC_Status=DSRC_INIT_OK;
rcvAbortedCallback();
sei();
return;
}
}
/*if(cRX_DONE_IRQ&irq_status)
{
// We timed out! Setting RXTXEN low in receive mode generates this irq...
packetSize=0xFF;
packetReceivedCallback();
packetSize=0x0;
return;
}*/
#ifdef USE_USART
char buf[32];
sprintf(buf,"IRQ(g): 0x%x 0x%x\r\n", irq_status, DSRC_Status);
USART_TransmitStr(buf);
#endif
if ((DSRC_Status == DSRC_INIT_OK) || ((cCCA_IRQ&irq_status) != 0) )
{
// If in idle mode or if CCA is done, just return
// Set RXTXEN low
DR_13192CTRL &= ~_BV(DD_RXTXEN);
DSRC_Status=DSRC_INIT_OK;
sei();
return;
}
sei();
}
void MC1319x_MCUenableInterrupts(void)
{
// Generate int on falling edge
//EICRA=2;
// Gen IRQ on low level
EICRA=0;
// Enable INT0, disable INT1
EIMSK=1;
//enable_external_int(_BV(INT0));
// Enable global int
sei();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -