-
Notifications
You must be signed in to change notification settings - Fork 0
/
COMM.c
411 lines (347 loc) · 16.5 KB
/
COMM.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
#include <msp430.h>
#include <ctl_api.h>
#include <stdio.h>
#include <ARCbus.h>
#include <string.h>
#include <SDlib.h>
#include "COMM.h"
#include "AX25_EncodeDecode.h"
#include "Radio_functions.h"
#include "COMM_Events.h"
#include "SD-dat.h"
COMM_STAT status;
short beacon_on=0, beacon_flag=0;
CTL_EVENT_SET_t COMM_evt;
unsigned char Tx1Buffer[600];
unsigned char RxBuffer[600], RxTemp[30];
unsigned int Tx1Buffer_Len, TxBufferPos=0, TxBytesRemaining;
unsigned int RxBuffer_Len=0, RxBufferPos=0, RxBytesRemaining;
unsigned char IMG_Blk;
unsigned int state;
void sub_events(void *p) __toplevel{
unsigned int e;
int i, j, resp;
unsigned char buf[BUS_I2C_HDR_LEN+sizeof(COMM_STAT)+BUS_I2C_CRC_LEN],*ptr;
//source and type for SPI data
char src,type;
for(;;){
e=ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,&SUB_events,SUB_EV_ALL,CTL_TIMEOUT_NONE,0);
//******************* COMMAND TO POWER OFF??? NOTHING HAPPENING HERE **************
if(e&SUB_EV_PWR_OFF){
puts("System Powering Down\r\n"); //print message
beacon_on = 0;
}
//******************* COMMAND TO POWER ON??? NOTHING HAPPENING HERE **************
if(e&SUB_EV_PWR_ON){
puts("System Powering Up\r\n"); //print message
beacon_on = 1;
}
//******************* SEND COMM STATUS TO CDH ***************************
if(e&SUB_EV_SEND_STAT){
puts("Sending status\r\n"); //send status
ptr=BUS_cmd_init(buf,CMD_COMM_STAT); //setup packet
for(i=0;i<sizeof(COMM_STAT);i++){ //fill in telemetry data
ptr[i]=((unsigned char*)(&status))[i];
}
resp=BUS_cmd_tx(BUS_ADDR_CDH,buf,sizeof(COMM_STAT),0,BUS_I2C_SEND_FOREGROUND); //send command
ctl_events_set_clear(&COMM_evt,COMM_EVT_STATUS_REQ,0); //call status update
if(resp!=RET_SUCCESS){
printf("Failed to send status %s\r\n",BUS_error_str(resp));
}
}
// ******************* RECEIVING DATA OVER SPI *************************
if(e&SUB_EV_SPI_DAT){
puts("SPI data recived:\r");
status.CC1101 = Radio_Read_Status(TI_CCxxx0_MARCSTATE, CC1101);
printf("status.CC1101 = 0X%02X \r\n",status.CC1101);
//First byte contains data type
//Second byte contains sender address
//Both bytes are removed before the data is passed on to COMM
type=arcBus_stat.spi_stat.rx[0];
src=arcBus_stat.spi_stat.rx[1];
printf("SPI: type = 0x%02x, src = 0x%02x\r\n",type, src);
printf("Trying to send beacon ON = %d FLAG = %d\r\n",beacon_on, beacon_flag);
//PrintBuffer(arcBus_stat.spi_stat.rx, arcBus_stat.spi_stat.len); //TEST
switch(type){
case SPI_BEACON_DAT:
if(!beacon_on){
BUS_free_buffer_from_event();
break;
}
for(i=0;i<COMM_TXHEADER_LEN;i++){ //LOAD UP HEADER
Tx1Buffer[i]=__bit_reverse_char(Tx1_Header[i]); //AX.25 octets are sent LSB first
}
if(!beacon_flag){ //SEND HELLO MESSAGE
Tx1Buffer_Len=COMM_TXHEADER_LEN+sizeof(Hello)+1; //Set length of message
for(i=0;i<sizeof(Hello);i++){
Tx1Buffer[i+COMM_TXHEADER_LEN]=__bit_reverse_char(Hello[i]); //load message after header
}
} else { //SEND STATUS MESSAGE
Tx1Buffer_Len=COMM_TXHEADER_LEN+(arcBus_stat.spi_stat.len)+1; //Set length of message: HeaderLen+(arcbusLen)+1 for carriage return
for(i=0;i<arcBus_stat.spi_stat.len;i++) { //load message after header
Tx1Buffer[i+COMM_TXHEADER_LEN]=__bit_reverse_char(arcBus_stat.spi_stat.rx[i]);
}
}
Tx1Buffer[Tx1Buffer_Len-1]=__bit_reverse_char(COMM_CR); //Add carriage return
BUS_free_buffer_from_event(); //Free Buffer before call to Stuff_Transition_Scramble()
//**** Create AX.25 packet (needs to include FCS, bit stuffed, flags) ***
printf("Tx1Buffer_Len=%d COMM_TXHEADER_LEN=%d\r\n", Tx1Buffer_Len,COMM_TXHEADER_LEN);
// PrintBufferBitInv(Tx1Buffer, Tx1Buffer_Len); //THIS IS FOR TESTING ONLY
CRC_CCITT_Generator(Tx1Buffer, &Tx1Buffer_Len); //Generate FCS
Stuff_Transition_Scramble(Tx1Buffer, &Tx1Buffer_Len); //Bit stuff - Encode for transitions - Scramble data
ctl_events_set_clear(&COMM_evt,CC1101_EV_TX_START,0); //Send to Radio to transmit
break;
//other data, write to SD card
default:
//write data to SD card
writeSD_Data(src,type,arcBus_stat.spi_stat.rx+2);
if(src==BUS_ADDR_IMG && *(unsigned short*)(arcBus_stat.spi_stat.rx+2) == 0x990F){
IMG_Blk = arcBus_stat.spi_stat.rx[5];
}
ctl_events_set_clear(&ev_SPI_data,SPI_EV_DATA_REC,0);
//free buffer
BUS_free_buffer_from_event();
break;
}
}
if(e&SUB_EV_SPI_ERR_CRC){
puts("SPI bad CRC\r");
type=arcBus_stat.spi_stat.rx[0];
src=arcBus_stat.spi_stat.rx[1];
printf("SPI: type = 0x%02x, src = 0x%02x\r\n",type, src);
printf("Trying to send beacon ON = %d FLAG = %d\r\n",beacon_on, beacon_flag);
}
}
}
//handle COMM specific commands don't wait here.
int SUB_parseCmd(unsigned char src, unsigned char cmd, unsigned char *dat, unsigned short len){
int i;
switch(cmd){
case CMD_BEACON_ON:
beacon_flag = 1;
return RET_SUCCESS;
}
return ERR_UNKNOWN_CMD;
}
void COMM_events(void *p) __toplevel{
unsigned int e, count;
int i, resp;
//initialize status
Reset_Radio(CC1101); // Reset Radios
__delay_cycles(800); //Wait for radio to be ready before writing registers
// after reset need to wait until radio is ready.....
// cc1101.pdf Table 13 indicates a power-on start-up time of 150 us for the crystal to be stable
// After reset chip is in IDLE state
Write_RF_Settings(CC1101); // Write radios Settings
// Radio_Write_Burst_Registers(TI_CCxxx0_PATABLE, paTable_CC1101, paTableLen, CC1101);
Radio_Interrupt_Setup();
Radio_Strobe(TI_CCxxx0_SRX, CC1101); //Initialize CC1101 in Rx mode
// Need to wait first for RF on command from CDH. Nothing happens until we get that command!
// After RF on command we can send Beacon data.
// Would like to create some test here where we read radio status and make sure it is in the correct state.
//read SD card and determine the number of bytes stored
data_setup();
ctl_events_init(&COMM_evt,0); //Initialize Event
//endless loop
for(;;){
//wait for events
e=ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,&COMM_evt,COMM_EVT_ALL,CTL_TIMEOUT_NONE,0);
//update status
if(e&COMM_EVT_STATUS_REQ){
status.CC1101 = Radio_Read_Status(TI_CCxxx0_MARCSTATE,CC1101);
status.ACDS_data=sd_data_table.next_ACDS; //#ACDS packets in COMM SD card
status.LEDL_data=sd_data_table.next_LEDL; //#LEDL packets in COMM SD card
status.IMG_data=sd_data_table.next_IMG;
}
if(e & CC1101_EV_RX_READ){ //READ RX FIFO
// Triggered by GDO0 interrupt
// Entering here indicates that the RX FIFO is more than half filed.
// Need to read RXThrBytes into RXBuffer then move RxBufferPos by RxThrBytes
// Then wait until interrupt received again.
Radio_Read_Burst_Registers(TI_CCxxx0_RXFIFO, RxTemp, RxThrBytes, CC1101);
Reverse_Scramble_Transition_Stuff(RxTemp, RxThrBytes);
status.CC1101 = Radio_Read_Status(TI_CCxxx0_MARCSTATE,CC1101);
//printf("Radio State: 0x%02x \n\r", status.CC1101);
}
if(e&CC1101_EV_TX_START){ //INITIALIZE TX START
//puts("TX Start\r\n");
state = TX_START;
TxBufferPos = 0;
P2IFG &= ~CC1101_GDO2;
P2IE |= CC1101_GDO2; // Enable Port 2 GDO2
P6OUT |= RF_SW1; //Set T/R switch to transmit
// Switch on the length of the initial packet.
// If packet is > 256 then radio set up as INFINITE.
// If packet is > 64 and < 256 then radio is set up as Fixed Mode
// If packet is < 64 then radio is set up as Fixed Mode
if (Radio_Read_Status(TI_CCxxx0_MARCSTATE,CC1101) == 0x16) // Check for TX FIFO underflow, if yes then flush dat buffer
{
Radio_Strobe(TI_CCxxx0_SFTX,CC1101);
Radio_Strobe(TI_CCxxx0_SRX,CC1101); // do I need this?
__delay_cycles(16000); //what is the delay for?
printf("Underflow Error, TX FIFO flushed, radio state now: ");
printf("%x \r\n",Radio_Read_Status(TI_CCxxx0_MARCSTATE,CC1101));
}
TxBytesRemaining = Tx1Buffer_Len;
if(TxBytesRemaining > 64)
{
if(TxBytesRemaining > 256)
{
Radio_Write_Registers(TI_CCxxx0_PKTLEN, (Tx1Buffer_Len % 256), CC1101); // Pre-program the packet length
Radio_Write_Registers(TI_CCxxx0_PKTCTRL0, 0x02, CC1101); // Infinite byte mode
}
else
{
Radio_Write_Registers(TI_CCxxx0_PKTLEN, Tx1Buffer_Len, CC1101); // Pre-program packet length
Radio_Write_Registers(TI_CCxxx0_PKTCTRL0, 0x00, CC1101); // Fixed byte mode
}
Radio_Write_Burst_Registers(TI_CCxxx0_TXFIFO, Tx1Buffer+TxBufferPos, 64, CC1101); // Write first 64 TX data bytes to TX FIFO
TxBytesRemaining = TxBytesRemaining - 64;
TxBufferPos = TxBufferPos + 64;
state = TX_RUNNING;
}
else
{
Radio_Write_Registers(TI_CCxxx0_PKTLEN, Tx1Buffer_Len, CC1101); // Pre-program packet length
Radio_Write_Registers(TI_CCxxx0_PKTCTRL0, 0x00, CC1101); // Fixed byte mode
Radio_Write_Burst_Registers(TI_CCxxx0_TXFIFO, Tx1Buffer+TxBufferPos, Tx1Buffer_Len, CC1101); // Write TX data
TxBytesRemaining = 0;
TxBufferPos = TxBufferPos+Tx1Buffer_Len;
state = TX_END;
}
Radio_Strobe(TI_CCxxx0_STX, CC1101); // Set radio state to Tx
}
if(e & CC1101_EV_TX_THR)
{
//printf("TX THR TxBytesRemaining = %d\r\n", TxBytesRemaining);
// Entering here indicates that the TX FIFO has emptied to below TX threshold.
// Need to write TXThrBytes (30 bytes) from TXBuffer then move TxBufferPos by TxThrBytes
// Then wait until interrupt received again or go to TX_END.
if(TxBytesRemaining > TxThrBytes)
{
Radio_Write_Burst_Registers(TI_CCxxx0_TXFIFO, Tx1Buffer+TxBufferPos, TxThrBytes, CC1101);
TxBufferPos += TxThrBytes;
TxBytesRemaining = TxBytesRemaining - TxThrBytes;
state = TX_RUNNING;
}
else
{
Radio_Write_Registers(TI_CCxxx0_PKTCTRL0, 0x00, CC1101); // Enter fixed length mode to transmit the last of the bytes
Radio_Write_Burst_Registers(TI_CCxxx0_TXFIFO, Tx1Buffer+TxBufferPos, TxBytesRemaining, CC1101);
TxBufferPos += TxBytesRemaining;
TxBytesRemaining = 0;
state = TX_END;
}
//printf("TX THR TxBytesRemaining = %d\r\n", TxBytesRemaining);
}
if(e & CC1101_EV_TX_END)
{
// Entering here indicates that the TX FIFO has emptied to the last byte sent
// No more bytes to send.
// Need to change interrupts.
ctl_timeout_wait(ctl_get_current_time()+26); //25 ms delay to flush 30 possible remaining bytes. Before we turn off power amplifier
P6OUT &= ~RF_SW1; //Set T/R switches to receive
P2IE &= ~CC1101_GDO2; // Disable Port 2 GDO2 interrupt
P2IFG &= ~CC1101_GDO2; // Clear flag
while (Radio_Read_Status(TI_CCxxx0_MARCSTATE,CC1101) == 0x13){
__delay_cycles(500);
}
Radio_Write_Registers(TI_CCxxx0_PKTLEN,0xFF,CC1101); //Reset PKTLEN
Radio_Write_Registers(TI_CCxxx0_PKTCTRL0, 0x02, CC1101); //Reset infinite packet length mode set
printf("TX End\r\n");
printf("TxBufferPos = %d\r\n", TxBufferPos);
// Check for TX FIFO underflow, if yes then flush dat buffer
if (Radio_Read_Status(TI_CCxxx0_MARCSTATE,CC1101) == 0x16)
{
Radio_Strobe(TI_CCxxx0_SFTX,CC1101);
Radio_Strobe(TI_CCxxx0_SRX,CC1101);
__delay_cycles(16000); //what is the delay for?
printf("Underflow Error, TX FIFO flushed, radio state now: ");
printf("%x \r\n",Radio_Read_Status(TI_CCxxx0_MARCSTATE,CC1101));
}
// Toggle LED to indicate packet sent
ctl_events_set_clear(&ev_SPI_data,SPI_EV_DATA_TX,0);
P7OUT ^= BIT7;
}
if(e&COMM_EVT_IMG_DAT)
{
puts("Received IMG Data");
//Need to store IMG data in SD Card so it is ready for transmission.
//Question as to whether or not to store data as already processed AX.25
//or raw data ready to be processed.
//Data will transmit on Radio 2 on command.
}
if(e&COMM_EVT_LEDL_DAT)
{
puts("Received LEDL Data");
//Need to store LEDL data in SD Card so it is ready for transmission.
//Question as to whether or not to store data as already processed AX.25
//or raw data ready to be processed.
//Data will transmit on Radio 2 on command.
}
} //end for loop
}
void COMM_Setup(void){
//Set up peripherals for COMM MSP
//Radio SPI on P5: P5.1=UCB1SIMO, P5.2=USB1SOMI, P5.3=UCB1CLK
UCB1CTL1 = UCSWRST; // Put UCB1 into reset
UCB1CTL0 = UCCKPH|UCMSB|UCMST|UCMODE_0|UCSYNC; // Data Read/Write on Rising Edge
// MSB first, Master mode, 3-pin SPI
// Synchronous mode
UCB1CTL1 |= UCSSEL_2; // SMCLK
UCB1BR0 = 16; // Set frequency divider so SPI runs at 16/16 = 1 MHz
UCB1BR1 = 0;
//Radio CS P5.4=CC250_CS, P5.5=CC1101_CS, P5.6=Temp_Sensor1_CS, P5.7=TEMP_Sensor2_CS (outputs)
//Initial state for CS is High, CS pulled low to initiate SPI
P5OUT |= CS_1101; // Ensure CS for CC1101 is disabled
P5OUT |= CS_2500; // Ensure CS for CC2500 is disabled
P5OUT |= CS_TEMP1; // Ensure CS for temperature sensor 1 is disabled
P5OUT |= CS_TEMP2; // Ensure CS for temperature sensor 2 is disabled
P5DIR |= CS_1101; //Set output for CC1101 CS
P5DIR |= CS_2500; //Set output for CC2500 CS
P5DIR |= CS_TEMP1;
P5DIR |= CS_TEMP2;
P5DIR |= RADIO_PIN_SIMO|RADIO_PIN_SCK;
//Set pins for SPI usage
P5SEL |= RADIO_PINS_SPI;
//Bring UCB1 out of reset state
UCB1CTL1 &= ~UCSWRST;
//UC1IE = UCB1TXIE|UCB1RXIE; //Enable transmit and receive interrupt
//Radio SW P6.0, P6.1 (outputs)
P6OUT = 0x00;
P6DIR |= RF_SW1|RF_SW2;
P6SEL = 0;
//SD Card SPI on P3/P5: P3.6=UCA1SIMO, P3.7=UCA2SOMI, P5.0=UCA1CLK
//THIS IS HANDELED IN JESSE'S LIBRARY
//Tx-Rx LED's P7.0-3 (inputs) CURRENTLY USED IN MAIN TO SHOW ADDR ON DEV BOARD.
}
void Radio_Interrupt_Setup(void){ // Enable RX interrupts only! TX interrupt enabled in TX Start
// Use GDO0 and GDO2 as interrupts to control TX/RX of radio
P2DIR = 0; // Port 2 configured as inputs (i.e. GDO0 and GDO2 are inputs)
P2IES = 0;
P2IES |= CC1101_GDO2; // GDO0 interrupts on rising edge = 0, GDO2 interrupts on falling edge = 1
P2IFG = 0; // Clear all flags
P2IE |= CC1101_GDO0; // Enable GDO0 interrupt only (RX interrupt)
}
void PrintBuffer(char *dat, unsigned int len){
int i;
for(i=0;i<len;i++){
printf("0X%02X ",dat[i]); //print LSB first
if((i)%16==15){
printf("\r\n");
}
}
printf("\r\n");
printf("\r\n");
}
void PrintBufferBitInv(char *dat, unsigned int len){
int i;
for(i=0;i<len;i++){
printf("0X%02X ",__bit_reverse_char(dat[i])); //print MSB first so it is understandable
if((i)%16==15){
printf("\r\n");
}
}
printf("\r\n");
printf("\r\n");
}