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
| /*
________ _______
VDD | \/ | VSS
RA5 | PIC16F1459 | RA0
RA4 | | RA1
RA3 | | Vusb3v3
LED Red RC5 | | RC0
LED Gr RC4 | | RC1
SDI CSN RC3 | | RC2
SDI CE RC6 | | RB4 SPI Serial Data in
SPI SDO RC7 | | RB5
SDI IRQ RB7 |_________________| RB6 SPI SCL (white)
*/
#include <xc.h>
#include <stdbool.h>
#define _XTAL_FREQ 16000000
#define byte unsigned char
#define laag 0
#define hoog 1
#define CE RC6 // Chip Enable output
#define IRQ RB7 // Interrupt input
#define CSN RC3 // Chip Select Not output
#define SDO RC7 // Serial Data Out output
#define SDI RB4 // Serial Data In input
#define CLK RB6 // Clock output
// Config Register: CONFIG1
// Oscillator Selection: FOSC_ECH,FOSC_ECH,FOSC_ECL,FOSC_INTOSC,FOSC_EXTRC,FOSC_HS,FOSC_XT,FOSC_LP
// Watchdog Timer Enable: WDTE_ON,WDTE_NSLEEP,WDTE_SWDTEN,WDTE_OFF
// WDT enabled
// Power-up Timer PWRTE_OFF,PWRTE_ON
// MCLR Pin Function Select MCLRE_ON,MCLRE_OFF
// Flash Program Memory Code Protection CP_OFF,CP_ON
// Brown-out Reset Enable BOREN_ON,BOREN_NSLEEP,BOREN_SBODEN,BOREN_OFF
// Clock Out Enable CLKOUTEN_OFF,CLKOUTEN_ON
//
// Internal/External Switchover IESO_ON,IESO_OFF
// Fail-Safe Clock Monitor Enable FCMEN_ON,FCMEN_OFF
// Config Register:CONFIG2
// Flash Memory Self-Write Protection WRT_OFF,WRT_BOOT,WRT_HALF,WRT_ALL
// PLL PLLEN_ENABLE,PLLEN_DISABLE
// Stack Overflow/Underflow Reset Enable STVREN_ON,STVREN_OFF
// Brown-out Reset Voltage Selection BORV_LO,BORV_HI
// Low-Voltage Programming Enable LVP_ON,LVP_OFF
#pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=OFF, MCLRE=ON, CP=OFF, BOREN=OFF, CLKOUTEN=OFF, IESO=OFF, FCMEN=OFF, WRT=OFF, PLLEN=DISABLED, STVREN=OFF, BORV=HI, LVP=OFF,
int knop1, knop2, j;
bool ack;
unsigned char dataR;
unsigned char dummydata;
unsigned char data1, data2, data3, data4;
unsigned char spi_send(unsigned char dataS)
{
SSP1IF = 0; // clear interrupt flag
SSP1BUF = dataS; // send dataS(end)
while (!SSP1IF); // wait till SSP interrupt flag is set
dataR = SSP1BUF; // read SSPBUF to dataR(ead)
return dataR;
}
void nrf_config() // NRF initialisation code RX mode
{
CE = laag; // chip standby, does not monitor the airdata
__delay_ms(10); // delay
CSN = hoog; // must be high when idle
__delay_ms(100); // delay
CSN = laag; // indicate data transmitting to NRF
spi_send(0x20); // write register(=001) 0 0000
spi_send(0x09); // (0000 1010) CRC enabled, interrupts on IRQ enabled, PRX (=transceiver), power up
CSN = hoog; // end data transmitting
__delay_us(1); // delay
CSN = laag;
spi_send(0x21); // write register(=001) 0 0001
spi_send(0x00); // turn off auto ACK
CSN = hoog;
__delay_us(1);
/* // register 0x22 is used only in RX mode
CSN = laag;
spi_send(0x22); // write register(=001) 0 0010
spi_send(0x03); // receive trough data pipe 0 & 1
CSN = hoog;
__delay_us(1); */
CSN = laag;
spi_send(0x23); // write register(=001) 0 0003
spi_send(0x01); // address width 3 bytes
CSN = hoog;
__delay_us(1);
/* CSN = laag; // enable in TX mode
spi_send(0x24); // write register(=001) 0 0004
spi_send(0x03); // retry transmitting when failed after 250 uS, try 3 times
CSN = hoog;
__delay_us(1); */
CSN = laag;
spi_send(0x25); // write register(=001) 0 0005
spi_send(0x05); // operating frequency set to 0000 0101
CSN = hoog;
__delay_us(1);
CSN = laag;
spi_send(0x26); // write register(=001) 0 0006
spi_send(0x04); // 1MB/s data rate, -6 dBm output power
CSN = hoog;
__delay_us(1);
// register 0x27 is status register
// register 0x28 is transmitter observer
// register 0x29 is received power detector
// triggered by power levels above -64dBm in slected channel
// register 0x2A - 2F = data pipe addresses
// register 0x30 is transmit address
int i;
CSN = laag;
spi_send(0x2A); // write register (=001) 1 0000 = transmit address
for (i=0; i<5; i++) // write addressbyte E7 3x for complete TX_ADDR (= E7E7E7)
{
spi_send(0xE7);
}
CSN = hoog;
__delay_us(1);
CSN = laag;
spi_send(0x31); // write register (=001) 1 0001
spi_send(0x04); // 4 byte payload in data pipe 0
CSN = hoog;
__delay_us(1);
CSN = laag; // indicate data transmitting to NRF
spi_send(0x20); // write register(=001) 0 0000
spi_send(0x0B); // (0000 1010) CRC enabled, interrupts on IRQ enabled, PRX (=transceiver), power up
CSN = hoog; // end data transmitting
__delay_us(1); // delay
CE = hoog; // CE high means receiver is listening to the air data
}
// send to NRF unit, 4 byte payload
// after sending data to NRF, empty FIFO by transmitting this data
unsigned char nrf_send(unsigned char data1, unsigned char data2, unsigned char data3, unsigned char data4)
{
CSN = laag;
spi_send(0xA0); // command to write TX FIFO
spi_send(data1); // send data1 to TX FIFO
spi_send(data2); // send data2 to TX FIFO
spi_send(data3); // send data3 to TX FIFO
spi_send(data4); // send data4 to TX FIFO
CSN = hoog;
__delay_us(1);
CE = hoog; // make CE high to initiate data transmitting
__delay_us(100); // keep CE high for at least 10 uS to transmit data
CE = laag; // make CE low again to stop transmitting
__delay_us(1);
return 0;
}
// read from NRF unit, 4 byte payload
// empty RX FIFO after transmission
void nrf_read()
{
CSN = laag;
spi_send(0x61); // command to read RX FIFO
spi_send(0x01); // read data, send 0x01
data1 = dataR; // read SSP1BUF to data1
spi_send(0x01); // read data, send 0x01
data2 = dataR; // read SSP1BUF to data2
spi_send(0x01); // read data, send 0x01
data3 = dataR; // read SSP1BUF to data3
spi_send(0x01); // read data, send 0x01
data4 = dataR; // read SSP1BUF to data4
CSN = hoog;
__delay_us(1);
CSN = laag;
spi_send(0xE2); // flush RX FIFO data, data not needed anymore
CSN = hoog;
__delay_us(1);
CSN = laag;
spi_send(0x27); // call status register
spi_send(0x4E); // clear interrupt, RX FIFO empty
CSN = hoog;
__delay_us(1);
}
void main(void) // main program
{
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00;
TRISA = 0x00;
TRISB = 0b10010000;
TRISB7 = 1;
TRISB4 = 1;
TRISC = 0b00000000;
OSCCON = 0b00111100; //internal clock 16 MHz no PLL
PORTB = 0x00;
PORTC = 0x00;
// [SPI mastermode]
INTCON = 0xD1;
PIE1 = 0b00001000;
PIE2 = 0x00;
PIR1 = 0b00;
PIR2 = 0x00;
SSP1ADD = 0x27; // 100 kHz, SSPAD 39. instellen Fosc zo langzaam mogelijk !!!
SSP1STAT = 0b11000000; // input sampled at end of output time, sending at clock from active to idle
SSP1CON1 = 0b00111010; // SSP high clock, baudrate calculated with SSPADD
SSP1CON3 = 0b00010000; // SSP overwrite data when buffer is not read in slave mode, no use in mastermode
// [/SPI mastermode]
nrf_config();
//mastercode start
while (1)
{
if (IRQ == 0)
{
LATC4 = 1;
}
else if (IRQ == 1)
{
LATC5 = 1;
}
__delay_ms(300);
LATC4 = LATC5 = 0;
__delay_ms(300);
/* LATC5 = 1;
__delay_ms(500);
nrf_read();
if (data1 == 0x12)
{
LATC4 = 1;
}
else
{
LATC5 = 0;
__delay_ms(100);
LATC5 = 1;
}
__delay_ms(500);
LATC5 = LATC4 = 0;
__delay_ms(500); */
}
}
//master stop |