boop/betty_scart/trunk/rf.c
2017-07-01 21:56:25 +02:00

223 lines
4.7 KiB
C

/*
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;
}