-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspi.c
525 lines (453 loc) · 11.7 KB
/
spi.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
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
/****************************************************************
* FILENAME: spi.c
*
* BRIEF: Contains functions to initialize SPI interface using
* USCI_B0 and communicate with the TRF796x via this interface.
*
* Copyright (C) 2010 Texas Instruments, Inc.
*
* AUTHOR(S): Reiser Peter DATE: 02 DEC 2010
*
* CHANGES:
* REV. DATE WHO DETAIL
* 00 02Dec2010 RP Orginal Version
* 01 07Dec2010 RP Changed SPI clock frequency from 6.78 MHz
* to 1.70 MHz in SpiUsciExtClkSet() and
* also reduced frequency in SpiUsciSet()
* 01 07Dec2010 RP integrated wait while busy loops in
* spi-communication
*
****************************************************************/
#include "spi.h"
#include "trf796x.h"
//===============================================================
u08_t temp = 0;
extern u08_t direct_mode;
//===============================================================
void SpiStartCondition(void);
void SpiUsciSet(void);
//===============================================================
// NAME: void SpiDirectCommand (u08_t *pbuf)
//
// BRIEF: Is used in SPI mode to transmit a Direct Command to
// reader chip.
//
// INPUTS:
// Parameters:
// u08_t *pbuf Direct Command
//
// OUTPUTS:
//
// PROCESS: [1] transmit Direct Command
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP integrated wait while busy loops
//===============================================================
void
SpiDirectCommand(u08_t *pbuf)
{
SLAVE_SELECT_LOW; // Start SPI Mode
// set Address/Command Word Bit Distribution to command
*pbuf = (0x80 | *pbuf); // command
*pbuf = (0x9f &*pbuf); // command code
while (!(IFG2 & UCB0TXIFG)) // USCI_B0 TX buffer ready?
{
}
UCB0TXBUF = *pbuf; // Previous data to TX, RX
while(UCB0STAT & UCBUSY)
{
}
temp = UCB0RXBUF;
SpiStartCondition(); //SCLK High
while(UCB0STAT & UCBUSY)
{
}
SLAVE_SELECT_HIGH; //Stop SPI Mode
P3SEL |= BIT3; //Revert Back
}
//===============================================================
// NAME: void SpiDirectMode (void)
//
// BRIEF: Is used in SPI mode to start Direct Mode.
//
// INPUTS:
//
// OUTPUTS:
//
// PROCESS: [1] start Direct Mode
//
// NOTE: No stop condition
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP integrated wait while busy loops
//===============================================================
void
SpiDirectMode(void)
{
u08_t command [2];
command[0] = CHIP_STATE_CONTROL;
command[1] = CHIP_STATE_CONTROL;
SpiReadSingle(&command[1],1);
command[1] |= 0x60; // RF on and BIT 6 in Chip Status Control Register set
SpiWriteSingle(command, 2);
}
//===============================================================
// NAME: void SpiRawWrite (u08_t *pbuf, u08_t length)
//
// BRIEF: Is used in SPI mode to write direct to the reader chip.
//
// INPUTS:
// Parameters:
// u08_t *pbuf raw data
// u08_t length number of data bytes
//
// OUTPUTS:
//
// PROCESS: [1] send raw data to reader chip
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP integrated wait while busy loops
//===============================================================
void
SpiRawWrite(u08_t *pbuf, u08_t length)
{
SLAVE_SELECT_LOW; //Start SPI Mode
while(length > 0)
{ while (!(IFG2 & UCB0TXIFG)); // USCI_B0 TX buffer ready?
{
}
UCB0TXBUF = *pbuf; // Previous data to TX, RX
while(UCB0STAT & UCBUSY)
{
}
temp=UCB0RXBUF;
pbuf++;
length--;
}
while(UCB0STAT & UCBUSY)
{
}
SLAVE_SELECT_HIGH; // Stop SPI Mode
}
//===============================================================
// NAME: void SpiReadCont (u08_t *pbuf, u08_t length)
//
// BRIEF: Is used in SPI mode to read a specified number of
// reader chip registers from a specified address upwards.
//
// INPUTS:
// Parameters:
// u08_t *pbuf address of first register
// u08_t length number of registers
//
// OUTPUTS:
//
// PROCESS: [1] read registers
// [2] write contents to *pbuf
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP integrated wait while busy loops
//===============================================================
void
SpiReadCont(u08_t *pbuf, u08_t length)
{
u08_t j = 0;
SLAVE_SELECT_LOW; //Start SPI Mode
// Address/Command Word Bit Distribution
*pbuf = (0x60 | *pbuf); // address, read, continuous
*pbuf = (0x7f &*pbuf); // register address
while (!(IFG2 & UCB0TXIFG)) // USCI_B0 TX buffer ready?
{
}
UCB0TXBUF = *pbuf; // Previous data to TX, RX
while(UCB0STAT & UCBUSY)
{
}
temp = UCB0RXBUF;
UCB0CTL0 &= ~UCCKPH;
if(*pbuf != 0x6C) // execute only when IRQRead is not called
{
if (length != 0x1F)
{
for (j=0;j<2;j++)
{
while (!(IFG2 & UCB0TXIFG)) // USCI_B0 TX buffer ready?
{
}
UCB0TXBUF = 0x00; // Receive initiated by a dummy TX write
while(UCB0STAT & UCBUSY)
{
}
_NOP();
_NOP();
temp = UCB0RXBUF;
}
}
}
while(length > 0)
{
while (!(IFG2 & UCB0TXIFG))
{
}
UCB0TXBUF = 0x00; // Receive initiated by a dummy TX write
while(UCB0STAT & UCBUSY)
{
}
_NOP();
_NOP();
*pbuf = UCB0RXBUF;
pbuf++;
length--;
}
UCB0CTL0 |= UCCKPH;
while(UCB0STAT & UCBUSY)
{
}
SLAVE_SELECT_HIGH; // Stop SPI Mode
}
//===============================================================
// NAME: void SpiReadSingle (u08_t *pbuf, u08_t number)
//
// BRIEF: Is used in SPI mode to read specified reader chip
// registers.
//
// INPUTS:
// Parameters:
// u08_t *pbuf addresses of the registers
// u08_t number number of the registers
//
// OUTPUTS:
//
// PROCESS: [1] read registers
// [2] write contents to *pbuf
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP integrated wait while busy loops
//===============================================================
void
SpiReadSingle(u08_t *pbuf, u08_t number)
{
SLAVE_SELECT_LOW; // Start SPI Mode
while(number > 0)
{
// Address/Command Word Bit Distribution
*pbuf = (0x40 | *pbuf); // address, read, single
*pbuf = (0x5f & *pbuf); // register address
while (!(IFG2 & UCB0TXIFG)) // USCI_B0 TX buffer ready?
{
}
UCB0TXBUF = *pbuf; // Previous data to TX, RX
while(UCB0STAT & UCBUSY)
{
}
temp=UCB0RXBUF;
UCB0CTL0 &= ~UCCKPH;
while (!(IFG2 & UCB0TXIFG)) // USCI_B0 TX buffer ready?
{
}
UCB0TXBUF = 0x00; // Receive initiated by a dummy TX write???
while (!(IFG2 & UCB0RXIFG)) // USCI_B0 RX buffer ready?
{
}
_NOP();
_NOP();
*pbuf = UCB0RXBUF;
pbuf++;
number--;
UCB0CTL0 |= UCCKPH;
}
while(UCB0STAT & UCBUSY)
{
}
SLAVE_SELECT_HIGH; // Stop SPI Mode
}
//===============================================================
// Settings for SPI Mode ;
// 02DEC2010 RP Original Code
//===============================================================
void
SpiSetup(void)
{
ENABLE_SET;
IRQ_PIN_SET;
IRQ_EDGE_SET; // rising edge interrupt
SpiUsciSet(); // Set the USART
LED_ALL_OFF;
LED_PORT_SET;
}
//===============================================================
// 02DEC2010 RP Original Code
//===============================================================
void
SpiStartCondition(void) //Make the SCLK High
{
P3SEL &= ~ BIT3;
P3DIR |= BIT3;
P3OUT |= BIT3; //Make SCLK High
}
//===============================================================
// NAME: void SpiUsciExtClkSet (void)
//
// BRIEF: Is used to switch SPI data clock from DCO to more
// stabile extern clock
//
// INPUTS:
//
// OUTPUTS:
//
// PROCESS: [1] switch SPI data clock
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP changed SPI clock from 6.78MHz to 1.70MHz
//===============================================================
void
SpiUsciExtClkSet(void) //Uses USCI_B0
{
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master
UCB0CTL1 |= UCSSEL_2; // SMCLK
UCB0BR0 |= 4; // SPI clock frequency = SMCLK / 4 (1.70 MHz)
UCB0BR1 = 0;
P3SEL |= BIT1 + BIT2 + BIT3; // P3.1, 3.2, 3.3 UCB0SIMO,UCB0SOMI,UCBOCLK option select
SLAVE_SELECT_PORT_SET; // P3.0 - Slave Select
SLAVE_SELECT_HIGH; // Slave Select - inactive ( high)
UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
}
//===============================================================
// NAME: void SpiUsciSet (void)
//
// BRIEF: Is used to set USCI B0 for SPI communication
//
// INPUTS:
//
// OUTPUTS:
//
// PROCESS: [1] make settings
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP reduced SPI clock frequency
//===============================================================
void
SpiUsciSet(void) //Uses USCI_B0
{
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master
UCB0CTL1 |= UCSSEL_2; // SMCLK
UCB0BR0 |= 4; // SPI clock frequency = SMCLK / 4
UCB0BR1 = 0;
P3SEL |= BIT1 + BIT2 + BIT3; // P3.1,3.2,3.3 UCB0SIMO,UCB0SOMI,UCBOCLK option select
SLAVE_SELECT_PORT_SET; // P3.0 - Slave Select
SLAVE_SELECT_HIGH; // Slave Select - inactive ( high)
UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
}
//===============================================================
// NAME: void SpiWriteCont (u08_t *pbuf, u08_t length)
//
// BRIEF: Is used in SPI mode to write to a specific number of
// reader chip registers from a specific address upwards.
//
// INPUTS:
// u08_t *pbuf address of first register followed by the
// contents to write
// u08_t length number of registers + 1
//
// OUTPUTS:
//
// PROCESS: [1] write to the registers
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP integrated wait while busy loops
//===============================================================
void
SpiWriteCont(u08_t *pbuf, u08_t length)
{
SLAVE_SELECT_LOW; // Start SPI Mode
// Address/Command Wort Bit Distribution
*pbuf = (0x20 | *pbuf); // address, write, continuous
*pbuf = (0x3f &*pbuf); // register address
while(length > 0)
{
while (!(IFG2 & UCB0TXIFG)) // USCI_B0 TX buffer ready?
{
}
UCB0TXBUF = *pbuf; // Previous data to TX, RX
while(UCB0STAT & UCBUSY)
{
}
temp = UCB0RXBUF;
pbuf++;
length--;
}
while(UCB0STAT & UCBUSY)
{
}
SLAVE_SELECT_HIGH; // Stop SPI Mode
}
//===============================================================
// NAME: void SpiWriteSingle (u08_t *pbuf, u08_t length)
//
// BRIEF: Is used in SPI mode to write to a specified reader chip
// registers.
//
// INPUTS:
// u08_t *pbuf addresses of the registers followed by the
// contends to write
// u08_t length number of registers * 2
//
// OUTPUTS:
//
// PROCESS: [1] write to the registers
//
// CHANGE:
// DATE WHO DETAIL
// 24Nov2010 RP Original Code
// 07Dec2010 RP integrated wait while busy loops
//===============================================================
void
SpiWriteSingle(u08_t *pbuf, u08_t length)
{
u08_t i = 0;
SLAVE_SELECT_LOW; // Start SPI Mode
while(length > 0)
{
// Address/Command Word Bit Distribution
// address, write, single (fist 3 bits = 0)
*pbuf = (0x1f &*pbuf); // register address
for(i = 0; i < 2; i++)
{
while (!(IFG2 & UCB0TXIFG)) // USCI_B0 TX buffer ready?
{
}
UCB0TXBUF = *pbuf; // Previous data to TX, RX
while(UCB0STAT & UCBUSY)
{
}
temp = UCB0RXBUF;
pbuf++;
length--;
}
}
while(UCB0STAT & UCBUSY)
{
}
if(direct_mode == 0x00)
{
SLAVE_SELECT_HIGH; // Stop SPI Mode
}
}