/* rf.c Copyright (C) 2009 Telekatz <telekatz@gmx.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <P89LPC932.h> #include "cc1100.h" #include "cmd.h" #include "rf.h" #include "serial.h" bit WORsend; unsigned char cc1100Addr; extern volatile bit terminal; extern volatile bit redirector; void RF_init (void) { cc1100_init(); WORsend=0; cc1100Addr = conf[0x09]; } void RF_startIRQ (void) { KBPATN = 0x40; KBMASK = 0x40; KBCON = 0x02; EKBI = 1; } void RF_isr (void) __interrupt (7) { struct cc1100frameheader_ RXframe; unsigned char i; if(KBPATN & 0x40) { KBPATN = 0x00; //IRQ on low level KBCON = 0x02; return; } RXframe.len = cc1100_read1(RXBYTES); if (RXframe.len) { bit startTX = 0; if(RXframe.len > 3) cc1100_read(RX_fifo, &RXframe.len,4); else cc1100_read(RX_fifo, &RXframe.len,RXframe.len); if (RXframe.len > 3) { if(terminal || redirector) { bit ACK = 0; switch ( RXframe.packetType) { case packet_ping: if (cc1100_read1(RX_fifo) == 0x01) { RXframe.len = 0x04; RXframe.destAddr = RXframe.srcAddr; RXframe.srcAddr = cc1100Addr; RXframe.packetType = packet_ping; cc1100_write(TX_fifo,(unsigned char*)RXframe,4); cc1100_write1(TX_fifo,0x02); startTX = 1; } break; case packet_redirDAT: cc1100_single(RX_fifo | BURST | READ,0); for(i=3;i<RXframe.len;i++) { send_byte(cc1100_single(0,0)); } CS = 1; break; case packet_redirCMD: switch (cc1100_read1(RX_fifo)) { case redir_ACK: break; case redir_SET: if (RXframe.len > 4) { unsigned char x; x = cc1100_read1(RX_fifo); if(x <= baud_115200) { redir_baud = x; } ACK = 1; } break; case redir_START: redir_dest = RXframe.srcAddr; setbaud(redir_baud); redirector = 1; ACK = 1; break; case redir_STOP: redirector = 0; setbaud(baud_default); ACK = 1; break; case redir_PING: ACK = 1; break; } if(ACK) { RXframe.len = 0x04; RXframe.destAddr = RXframe.srcAddr; RXframe.srcAddr = cc1100Addr; RXframe.packetType = packet_redirCMD; cc1100_write(TX_fifo,(unsigned char*)RXframe,4); cc1100_write1(TX_fifo,redir_ACK); startTX = 1; } break; default: if ((RXframe.len > 3) && terminal) { send_string(crlf); send_string("RX: "); cc1100_single(RX_fifo | BURST | READ,0); for(i=3;i<RXframe.len;i++) { send_byte(cc1100_single(0,0)); } CS = 1; send_string(crlf); } } } else { send_byte(0x02); send_bytes(&RXframe.len, 4); cc1100_single(RX_fifo | BURST | READ,0); for(i=3;i<RXframe.len;i++) { send_byte(cc1100_single(0,0)); } CS = 1; } } cc1100_strobe(SIDLE); while (cc1100_read1(MARCSTATE) != MARCSTATE_IDLE); cc1100_strobe(SFRX); if(startTX) cc1100_strobe(STX); else cc1100_strobe(SRX); } else { if(cc1100_read1(MARCSTATE) != MARCSTATE_RX) { cc1100_strobe(SIDLE); while (cc1100_read1(MARCSTATE) != MARCSTATE_IDLE); cc1100_strobe(SFRX); cc1100_strobe(SFTX); cc1100_strobe(SRX); } } KBPATN = 0x40; //IRQ on high level KBCON = 0x02; } void waitTX(void) { unsigned char status; unsigned char x; x=1; while (x) { status = cc1100_strobe(SNOP); switch ( 0xf0 & status) { case 0x70: cc1100_strobe(SFTX); break; case 0x10: if (WORsend) cc1100_strobe(SIDLE); x=0; break; case 0x00: if (!(WORsend)) cc1100_strobe(SRX); x=0; break; } } } void sendWOR(unsigned char addr) { unsigned char b[2]; unsigned int i; b[0]=0x01; b[1]=addr; EKBI = 0; WORsend=1; cc1100_write1(0x18,conf[0x18] & 0xCF); cc1100_strobe(SIDLE); cc1100_strobe(SCAL); waitTX(); i=0; while (i++ < 250) { cc1100_write(TX_fifo | BURST,b,2); cc1100_strobe(STX); waitTX(); } cc1100_write1(0x18,conf[0x18]); WORsend=0; waitTX(); KBCON = 0x02; EKBI = 1; }