SPI coding in C8051F340

Status
Not open for further replies.

freemanantony

Member level 4
Joined
May 19, 2010
Messages
70
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Chennai, India
Visit site
Activity points
2,005
hi everybody,
i am trying to interface C8051F340 with AD7795 using SPI interface ,but when i am writing to SPI0DAT it is not getting written can anybody help me on this i am adding my code with this


Code C - [expand]
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
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
#include <C8051F340.h>                 // SFR declarations
 
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
 
#define SYSCLK             12000000    // Internal oscillator frequency in Hz
 
#define SPI_CLOCK          250000      // Maximum SPI clock
                                       // The SPI clock is a maximum of 250 kHz
                                       // when this example is used with
                                       // the SPI0_Slave code example.
 
#define MAX_BUFFER_SIZE    8           // Maximum buffer Master will send
 
// Instruction Set
#define  SLAVE_LED_ON      0x80       // Turn the Slave LED on
#define  SLAVE_LED_OFF     0x02        // Turn the Slave LED off
#define  SPI_WRITE         0x60        // Send a byte from the Master to the
                                       // Slave
#define  SPI_READ          0x40        // Send a byte from the Slave to the
                                       // Master
#define  SPI_WRITE_BUFFER  0x10        // Send a series of bytes from the
                                       // Master to the Slave
#define  SPI_READ_BUFFER   0x20        // Send a series of bytes from the Slave
                                       // to the Master
#define  ERROR_OCCURRED    0x40        // Indicator for the Slave to tell the
                                       // Master an error occurred
 
sbit LED = P2^2;                       // LED='1' means ON
 
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
 
unsigned char SPI_Data = 0xA5;
 
unsigned char SPI_Data_Array[MAX_BUFFER_SIZE] = {0};
 
bit Error_Flag = 0;
 
unsigned char Command = 0x00;
unsigned char tst_rcv = 0x03;
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
 
void PCA0_Init (void);
void Oscillator_Init (void);
void Port_Init (void);
void SPI0_Init (void);
void Init_Device (void);
 
//void SPI_LED_On (void);
//void SPI_LED_Off (void);
void SPI_Byte_Write (void);
void SPI_Byte_Read (void);
//void SPI_Array_Write (void);
//void SPI_Array_Read (void);
 
void Delay(void);
 
//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------
void main (void)
{
   unsigned char test_value = 0x55;
   unsigned char test_array[MAX_BUFFER_SIZE] = {1,2,3,4,5,6,7,8};
  // unsigned char i;
 
   Init_Device ();                     // Initializes hardware peripherals
 
   EA = 1;                             // Enable global interrupts
 
   LED = 0;
 
   // TEST BEGIN --------------------------------------------------------------
 
   //SPI_Data = test_value;
 
   // Write a value
  SPI_Byte_Write ();
 
/*   while (!NSSMD0);                    // Wait until the Write transfer has
                                       // finished
 
   // Read the same value back
   SPI_Data = 0x00;
   SPI_Byte_Read ();
 
   while (!NSSMD0);                    // Wait until the Read transfer has
                                       // finished
 
   // Check if the sent value and returned value match
   if (SPI_Data != test_value)
   {
      Error_Flag = 1;
   }
 
   // Copy test_array into SPI_Data_Array
   for (i = 0; i < MAX_BUFFER_SIZE; i++)
   {
      SPI_Data_Array[i] = test_array[i];
   }
 
   // Send the array to the slave
   SPI_Array_Write ();
 
   while (!NSSMD0);                    // Wait until the Write transfer has
                                       // finished
 
   // Clear SPI_Data_Array for the SPI_Buffer_Read function
   for (i = 0; i < MAX_BUFFER_SIZE; i++)
   {
      SPI_Data_Array[i] = 0;
   }
 
   // Read the array back from the slave
   SPI_Array_Read ();
 
   while (!NSSMD0);                    // Wait until the Read transfer has
                                       // finished
 
   // Check if the received array matches the sent array
   for (i = 0; i < MAX_BUFFER_SIZE; i++)
   {
      if (SPI_Data_Array[i] != test_array[i])
      {
         Error_Flag = 1;
      }
   }*/
 
   // END OF TEST -------------------------------------------------------------
 
   while (1)
   {
      // If no error has occurred, blink the LEDs on the Master and Slave
      // boards
      if (Error_Flag == 0)
      {
        // LED = 1;
 
        SPI_Byte_Read ();
 
         //while (!NSSMD0);
 
         Delay ();
 
         SPI_Byte_Read ();
 
         //LED = 0;
 
         //while (!NSSMD0);
 
         Delay ();
      }
   };
}
 
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
 
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function disables the watchdog timer.
//
//-----------------------------------------------------------------------------
void PCA0_Init (void)
{
   PCA0MD &= ~0x40;                    // Disable the Watchdog Timer
   PCA0MD = 0x00;
}
 
//-----------------------------------------------------------------------------
// Oscillator_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function initializes the system clock to use the internal oscillator
// at 12 MHz.
//
//-----------------------------------------------------------------------------
void Oscillator_Init (void)
{
   OSCICN = 0x83;                      // Set the internal oscillator to
                                       // 12 MHz
}
 
//-----------------------------------------------------------------------------
// Port_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function configures the crossbar and GPIO ports.
//
// P0.0  -  SCK  (SPI0), Push-Pull,  Digital
// P0.1  -  MISO (SPI0), Open-Drain, Digital
// P0.2  -  MOSI (SPI0), Push-Pull,  Digital
// P0.3  -  NSS  (SPI0), Push-Pull,  Digital
//
// P2.2  -  Skipped,     Push-Pull,  Digital (LED D4 on Target Board)
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
   P0MDOUT = 0x0D;                     // Make SCK, MOSI, and NSS push-pull
   P2MDOUT = 0x04;                     // Make the LED push-pull
 
   P2SKIP = 0x04;                      // Skip the LED (P2.2)
 
   XBR0 = 0x02;                        // Enable the SPI on the XBAR
   XBR1 = 0x40;                        // Enable the XBAR and weak pull-ups
}
 
//-----------------------------------------------------------------------------
// SPI0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configures SPI0 to use 4-wire Single Master mode. The SPI timing is
// configured for Mode 0,0 (data centered on first edge of clock phase and
// SCK line low in idle state).
//
//-----------------------------------------------------------------------------
void SPI0_Init()
{
   SPI0CFG   = 0x40;                   // Enable the SPI as a Master
                                       // CKPHA = '0', CKPOL = '0'
   SPI0CN    = 0x0D;                   // 4-wire Single Master, SPI enabled
 
   // SPI clock frequency equation from the datasheet
   SPI0CKR   = (SYSCLK/(2*SPI_CLOCK))-1;
 
   ESPI0 = 1;                          // Enable SPI interrupts
}
 
//-----------------------------------------------------------------------------
// Init_Device
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Calls all device initialization functions.
//
//-----------------------------------------------------------------------------
void Init_Device (void)
{
   PCA0_Init ();                       // Disable the Watchdog Timer first
   Oscillator_Init ();
   Port_Init ();
   SPI0_Init ();
}
 
//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------
 
//-----------------------------------------------------------------------------
// SPI_ISR
//-----------------------------------------------------------------------------
//
// Handles all error checks and single-byte writes.
//
// Note: SPI_WRITE_ARRAY is not handled by this ISR in order to take
// advantage of double-buffering (checking the TXBMT flag) using polling.
//
//
// Typical Write:
//
//              | 1st sent | 2nd sent | 3rd sent |   ...    | last sent |
//              ---------------------------------------------------------
//  Master NSSv | Command  |   Data1  |   Data2  |   ...    |   DataN   |  NSS^
//  Slave       |   N/A    |    N/A   |    N/A   |   ...    |    N/A    |
//
// Typical Read:
//
//              | 1st sent | 2nd sent | 3rd sent |   ...    | last sent |
//              ---------------------------------------------------------
//  Master NSSv | Command  |   dummy  |   dummy  |   ...    |   dummy   |  NSS^
//  Slave       |   N/A    |   Data1  |   Data2  |   ...    |   DataN   |
//-----------------------------------------------------------------------------
void SPI_ISR (void) interrupt 6
{
   static unsigned char array_index = 0;
   static char state = 0;
 
   if (WCOL == 1)
   {
      // Write collision occurred
      WCOL = 0;                        // Clear the write collision flag
 
      Error_Flag = 1;
   }
   else
   {
      if (SPI0DAT == ERROR_OCCURRED)
      {
         // This example recognizes when an error occurs, but does not include
         // any error handling.  The transfer can be aborted or rescheduled,
         // if desired.
         Error_Flag = 1;
      }
 
      // When the Master enters the ISR, the SPIF flag should be set from
      // sending the Command byte.  This ISR handles the remaining steps of the
      // SPI transfer process.
      // <state> == 0: writing or reading 1 byte of data
      // <state> == 1: for READ commands (first time, only a dummy byte is
      //               sent but the second time, the data must be read from
      //               SPI0DAT)
      // <state> == 2: NSS = 1 to end the transfer, final byte read
      //
      // Note: SPI_WRITE_BUFFER is not handled here because it's done in
      // polled mode
      if (state == 0)
      {
         switch (Command)
         {
            case SLAVE_LED_ON:
            case SLAVE_LED_OFF:
               NSSMD0 = 1;             // Release the slave (not expecting
                                       // data back)
 
               break;
 
            case SPI_WRITE:
               SPI0DAT = SPI_Data;
 
               state = 2;              // Advance to the final state (only
                                       // writing one byte)
 
               break;
 
            case SPI_READ:
               SPI_Data = SPI0DAT;        // Send a dummy byte so the Slave can
                                       // send the data
 
               state = 2;              // Advance to the final state (only
                                       // reading one byte)
 
               break;
 
            case SPI_READ_BUFFER:
               array_index = 0;        // Clear the data counter
 
               SPI0DAT = 0xFF;         // Send a dummy byte so the Slave can
                                       // start sending the data
 
               state = 1;              // Advance to the next state where the
                                       // data can be received
                                       // The data from the slave is not
                                       // available until after the second
                                       // transfer is completed.
                                       // The dummy byte allows the slave to
                                       // send data, since the Master controls
                                       // SCK.
 
               break;
 
            default:
               state = 2;              // Any errors in the Command parsing
                                       // should go to state 2 where NSSMD0
                                       // is de-asserted
         }
      }
      else if (state == 1)             // This state is for READ_ARRAY
      {                                // commands where the data must be read
                                       // after the first dummy byte is sent
         switch (Command)
         {
            case SPI_READ_BUFFER:
               SPI_Data_Array[array_index] = SPI0DAT;
               SPI0DAT = 0xFF;
 
               array_index++;
 
               if (array_index == (MAX_BUFFER_SIZE-1))
               {
                  state = 2;
               }
 
               break;
            default:
               state = 2;              // Any errors in the Command parsing
                                       // should go to state 2 where NSSMD0
                                       // is de-asserted
         }
      }
      else if (state == 2)
      {
         switch (Command)
         {
            case SPI_READ:
               SPI_Data = SPI0DAT;     // Read the data from the slave
 
               break;
 
            case SPI_READ_BUFFER:
               SPI_Data_Array[array_index] = SPI0DAT; // Read the last data
                                                      // without sending a
                                                      // dummy byte
 
               break;
         }
 
         NSSMD0 = 1;                   // De-select the Slave
 
         state = 0;                    // Reset the state
      }
 
      SPIF = 0;                        // Clear the SPIF flag
   }
}
 
//-----------------------------------------------------------------------------
// Support Routines
//-----------------------------------------------------------------------------
 
//-----------------------------------------------------------------------------
// SPI_LED_On
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Turns the LED on the SPI Slave on.  The slave does not respond to this
// command, so the command consists of:
//
// Command = SLAVE_LED_ON
// Length = 1 byte (the command itself)
//
//-----------------------------------------------------------------------------
/*void SPI_LED_On (void)
{
   while (!NSSMD0);                    // Wait until the SPI is free, in case
                                       // it's already busy
 
   NSSMD0 = 0;
 
   Command = SLAVE_LED_ON;
 
   SPI0DAT = Command;
 
   // The rest of this command will be handled by the SPI ISR, which will
   // trigger when SPIF is set from sending the Command
}*/
 
//-----------------------------------------------------------------------------
// SPI_LED_Off
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Turns the LED on the SPI Slave off.  The slave does not respond to this
// command, so the command consists of:
//
// Command = SLAVE_LED_OFF
// Length = 1 byte (the command itself)
//
//-----------------------------------------------------------------------------
/*void SPI_LED_Off (void)
{
   while (!NSSMD0);                    // Wait until the SPI is free, in case
                                       // it's already busy
 
   NSSMD0 = 0;
 
   Command = SLAVE_LED_OFF;
 
   SPI0DAT = Command;
 
   // The rest of this command will be handled by the SPI ISR, which will
   // trigger when SPIF is set from sending the Command
}*/
 
//-----------------------------------------------------------------------------
// SPI_Byte_Write
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Note: SPI_Data must contain the data to be sent before calling this
// function.
//
// Writes a single byte to the SPI Slave.  The slave does not respond to this
// command, so the command consists of:
//
// Command = SPI_WRITE
// Length = 1 byte of command, 1 byte of data
//
//-----------------------------------------------------------------------------
void SPI_Byte_Write (void)
{
   while (!NSSMD0);                    // Wait until the SPI is free, in case
                                       // it's already busy
 
   NSSMD0 = 0;
   tst_rcv = SPI0DAT;
 
   Command = SPI_WRITE;
   SPI0DAT = Command;
   while(!TXBMT);
 
   // The rest of this command will be handled by the SPI ISR, which will
   // trigger when SPIF is set from sending the Command
}
 
//-----------------------------------------------------------------------------
// SPI_Byte_Read
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Note: SPI_Data will contain the data received after calling this function.
//
// Reads a single byte from the SPI Slave.  The command consists of:
//
// Command = SPI_READ
// Length = 1 byte of command, 1 byte of data
//
//-----------------------------------------------------------------------------
void SPI_Byte_Read (void)
{
   while (!NSSMD0);                    // Wait until the SPI is free, in case
                                       // it's already busy
 
   NSSMD0 = 0;
 
   Command = SPI_READ;
 
   SPI0DAT = Command;
   while(!TXBMT);
 
   // The rest of this command will be handled by the SPI ISR, which will
   // trigger when SPIF is set from sending the Command
}
 
//-----------------------------------------------------------------------------
// SPI_Array_Write
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Note: SPI_Data_Array must contain the data to be sent before calling this
// function.
//
// Writes an array of values of size MAX_BUFFER_SIZE to the SPI Slave.  The
// command consists of:
//
// Command = SPI_WRITE_BUFFER
// Length = 1 byte of command, MAX_BUFFER_SIZE bytes of data
//
// Note: Polled mode is used for this function in order to buffer the data
// being sent using the TXBMT flag.
//
//-----------------------------------------------------------------------------
/*void SPI_Array_Write (void)
{
   unsigned char array_index;
 
   while (!NSSMD0);                    // Wait until the SPI is free, in case
                                       // it's already busy
 
   ESPI0 = 0;                          // Disable SPI interrupts
 
   NSSMD0 = 0;
 
   SPI0DAT = SPI_WRITE_BUFFER;         // Load the XMIT register
   while (TXBMT != 1)                  // Wait until the command is moved into
   {                                   // the XMIT buffer
   }
 
   for (array_index = 0; array_index < MAX_BUFFER_SIZE; array_index++)
   {
      SPI0DAT = SPI_Data_Array[array_index]; // Load the data into the buffer
      while (TXBMT != 1)               // Wait until the data is moved into
      {                                // the XMIT buffer
      }
   }
   SPIF = 0;
   while (SPIF != 1)                   // Wait until the last byte of the
   {                                   // data reaches the Slave
   }
   SPIF = 0;
 
   NSSMD0 = 1;                         // Diable the Slave
 
   ESPI0 = 1;                          // Re-enable SPI interrupts
}*/
 
//-----------------------------------------------------------------------------
// SPI_Array_Read
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Note: SPI_Data_Array will contain the data received after calling this
// function.
//
// Reads a single byte from the SPI Slave.  The command consists of:
//
// Command = SPI_READ_BUFFER
// Length = 1 byte of command, MAX_BUFFER_SIZE bytes of data
//
//-----------------------------------------------------------------------------
/*void SPI_Array_Read (void)
{
   while (!NSSMD0);                    // Wait until the SPI is free, in case
                                       // it's already busy
 
   NSSMD0 = 0;
 
   Command = SPI_READ_BUFFER;
 
   SPI0DAT = Command;
 
   // The rest of this command will be handled by the SPI ISR, which will
   // trigger when SPIF is set from sending the Command
}*/
 
//-----------------------------------------------------------------------------
// Delay
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Delay for little while (used for blinking the LEDs)
//
//-----------------------------------------------------------------------------
void Delay (void)
{
   unsigned long count;
 
   for (count = 100000; count > 0; count--);
}
 
//-----------------------------------------------------------------------------

 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…