OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [spi/] [arm/] [at91/] [current/] [src/] [spi_at91.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      spi_at91.c
4
//
5
//      Atmel AT91 (ARM) SPI driver 
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     Savin Zlobec <savin@elatec.si> 
43
// Date:          2004-08-25
44
//
45
//####DESCRIPTIONEND####
46
//
47
//==========================================================================
48
 
49
#include <pkgconf/hal.h>
50
#include <pkgconf/io_spi.h>
51
#include <pkgconf/devs_spi_arm_at91.h>
52
 
53
#include <cyg/infra/cyg_type.h>
54
#include <cyg/infra/cyg_ass.h>
55
#include <cyg/hal/hal_io.h>
56
#include <cyg/hal/hal_if.h>
57
#include <cyg/hal/hal_intr.h>
58
#include <cyg/hal/drv_api.h>
59
#include <cyg/io/spi.h>
60
#include <cyg/io/spi_at91.h>
61
#include <cyg/error/codes.h>
62
 
63
// -------------------------------------------------------------------------
64
static void spi_at91_init_bus(cyg_spi_at91_bus_t * bus);
65
 
66
static cyg_uint32 spi_at91_ISR(cyg_vector_t vector, cyg_addrword_t data);
67
 
68
static void spi_at91_DSR(cyg_vector_t   vector,
69
                         cyg_ucount32   count,
70
                         cyg_addrword_t data);
71
 
72
static void spi_at91_transaction_begin(cyg_spi_device *dev);
73
 
74
static void spi_at91_transaction_transfer(cyg_spi_device  *dev,
75
                                          cyg_bool         polled,
76
                                          cyg_uint32       count,
77
                                          const cyg_uint8 *tx_data,
78
                                          cyg_uint8       *rx_data,
79
                                          cyg_bool         drop_cs);
80
 
81
static void spi_at91_transaction_tick(cyg_spi_device *dev,
82
                                      cyg_bool        polled,
83
                                      cyg_uint32      count);
84
 
85
static void spi_at91_transaction_end(cyg_spi_device* dev);
86
 
87
static int spi_at91_get_config(cyg_spi_device *dev,
88
                               cyg_uint32      key,
89
                               void           *buf,
90
                               cyg_uint32     *len);
91
 
92
static int spi_at91_set_config(cyg_spi_device *dev,
93
                               cyg_uint32      key,
94
                               const void     *buf,
95
                               cyg_uint32     *len);
96
 
97
// -------------------------------------------------------------------------
98
// AT91 SPI BUS
99
 
100
#ifdef CYGHWR_DEVS_SPI_ARM_AT91_BUS0
101
cyg_spi_at91_bus_t cyg_spi_at91_bus0 = {
102
    .spi_bus.spi_transaction_begin    = spi_at91_transaction_begin,
103
    .spi_bus.spi_transaction_transfer = spi_at91_transaction_transfer,
104
    .spi_bus.spi_transaction_tick     = spi_at91_transaction_tick,
105
    .spi_bus.spi_transaction_end      = spi_at91_transaction_end,
106
    .spi_bus.spi_get_config           = spi_at91_get_config,
107
    .spi_bus.spi_set_config           = spi_at91_set_config,
108
    .interrupt_number                 = CYGNUM_HAL_INTERRUPT_SPI,
109
    .base                             = AT91_SPI,
110
#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS0_NONE
111
    .cs_en[0]                         = true,
112
    .cs_gpio[0]                       = CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS0,
113
#else
114
    .cs_en[0]                         = false,
115
#endif
116
#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS1_NONE
117
    .cs_en[1]                         = true,
118
    .cs_gpio[1]                       = CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS1,
119
#else
120
    .cs_en[1]                         = false,
121
#endif
122
#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS2_NONE
123
    .cs_en[2]                         = true,
124
    .cs_gpio[2]                       = CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS2,
125
#else
126
    .cs_en[2]                         = false,
127
#endif
128
#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS3_NONE
129
    .cs_en[3]                         = true,
130
    .cs_gpio[3]                       = CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS3,
131
#else
132
    .cs_en[3]                         = false,
133
#endif
134
};
135
 
136
CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_at91_device_t, 0);
137
#endif
138
#ifdef CYGHWR_DEVS_SPI_ARM_AT91_BUS1
139
cyg_spi_at91_bus_t cyg_spi_at91_bus1 = {
140
    .spi_bus.spi_transaction_begin    = spi_at91_transaction_begin,
141
    .spi_bus.spi_transaction_transfer = spi_at91_transaction_transfer,
142
    .spi_bus.spi_transaction_tick     = spi_at91_transaction_tick,
143
    .spi_bus.spi_transaction_end      = spi_at91_transaction_end,
144
    .spi_bus.spi_get_config           = spi_at91_get_config,
145
    .spi_bus.spi_set_config           = spi_at91_set_config,
146
    .interrupt_number                 = CYGNUM_HAL_INTERRUPT_SPI1,
147
    .base                             = AT91_SPI1,
148
#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS0_NONE
149
    .cs_en[0]                         = true,
150
    .cs_gpio[0]                       = CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS0,
151
#else
152
    .cs_en[0]                         = false,
153
#endif
154
#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS1_NONE
155
    .cs_en[1]                         = true,
156
    .cs_gpio[1]                       = CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS1,
157
#else
158
    .cs_en[1]                         = false,
159
#endif
160
#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS2_NONE
161
    .cs_en[2]                         = true,
162
    .cs_gpio[2]                       = CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS2,
163
#else
164
    .cs_en[2]                         = false,
165
#endif
166
#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS3_NONE
167
    .cs_en[3]                         = true,
168
    .cs_gpio[3]                       = CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS3,
169
#else
170
    .cs_en[3]                         = false,
171
#endif
172
};
173
 
174
CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_at91_device_t, 1);
175
#endif
176
// -------------------------------------------------------------------------
177
 
178
// If C constructor with init priority functionality is not in compiler,
179
// rely on spi_at91_init.cxx to init us.
180
#ifndef CYGBLD_ATTRIB_C_INIT_PRI
181
# define CYGBLD_ATTRIB_C_INIT_PRI(x)
182
#endif
183
 
184
void CYGBLD_ATTRIB_C_INIT_PRI(CYG_INIT_BUS_SPI)
185
cyg_spi_at91_bus_init(void)
186
{
187
 
188
#ifdef CYGHWR_DEVS_SPI_ARM_AT91_BUS0
189
   // NOTE: here we let the SPI controller control 
190
   //       the data in, out and clock signals, but 
191
   //       we need to handle the chip selects manually 
192
   //       in order to achieve better chip select control 
193
   //       in between transactions.
194
 
195
   // Put SPI MISO, MOSI and SPCK pins into peripheral mode
196
   HAL_ARM_AT91_PIO_CFG(AT91_SPI_SPCK);
197
   HAL_ARM_AT91_PIO_CFG(AT91_SPI_MISO);
198
   HAL_ARM_AT91_PIO_CFG(AT91_SPI_MOSI);
199
   spi_at91_init_bus(&cyg_spi_at91_bus0);
200
#endif
201
#ifdef CYGHWR_DEVS_SPI_ARM_AT91_BUS1
202
   // NOTE: here we let the SPI controller control 
203
   //       the data in, out and clock signals, but 
204
   //       we need to handle the chip selects manually 
205
   //       in order to achieve better chip select control 
206
   //       in between transactions.
207
 
208
   // Put SPI MISO, MOSI and SPCK pins into peripheral mode
209
   HAL_ARM_AT91_PIO_CFG(AT91_SPI1_SPCK);
210
   HAL_ARM_AT91_PIO_CFG(AT91_SPI1_MISO);
211
   HAL_ARM_AT91_PIO_CFG(AT91_SPI1_MOSI);
212
   spi_at91_init_bus(&cyg_spi_at91_bus1);
213
#endif
214
}
215
 
216
// -------------------------------------------------------------------------
217
 
218
static void spi_at91_init_bus(cyg_spi_at91_bus_t * spi_bus)
219
{
220
    cyg_uint32 ctr;
221
    // Create and attach SPI interrupt object
222
    cyg_drv_interrupt_create(spi_bus->interrupt_number,
223
                             4,
224
                             (cyg_addrword_t)spi_bus,
225
                             spi_at91_ISR,
226
                             spi_at91_DSR,
227
                             &spi_bus->spi_interrupt_handle,
228
                             &spi_bus->spi_interrupt);
229
 
230
    cyg_drv_interrupt_attach(spi_bus->spi_interrupt_handle);
231
 
232
    // Init transfer mutex and condition
233
    cyg_drv_mutex_init(&spi_bus->transfer_mx);
234
    cyg_drv_cond_init(&spi_bus->transfer_cond,
235
                      &spi_bus->transfer_mx);
236
 
237
    // Init flags
238
    spi_bus->transfer_end = true;
239
    spi_bus->cs_up        = false;
240
 
241
    // Soft reset the SPI controller
242
    HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CR, AT91_SPI_CR_SWRST);
243
 
244
    // Configure SPI pins
245
 
246
 
247
    // Put SPI chip select pins in IO output mode
248
    for(ctr = 0;ctr<4;ctr++)
249
    {
250
       if(spi_bus->cs_en[ctr])
251
       {
252
          HAL_ARM_AT91_GPIO_CFG_DIRECTION(spi_bus->cs_gpio[ctr],AT91_PIN_OUT);
253
          HAL_ARM_AT91_GPIO_SET(spi_bus->cs_gpio[ctr]);
254
       }
255
    }
256
    // Call upper layer bus init
257
    CYG_SPI_BUS_COMMON_INIT(&spi_bus->spi_bus);
258
}
259
 
260
static cyg_uint32
261
spi_at91_ISR(cyg_vector_t vector, cyg_addrword_t data)
262
{
263
    cyg_uint32 stat;
264
    cyg_spi_at91_bus_t * spi_bus = (cyg_spi_at91_bus_t *)data;
265
    // Read the status register and disable
266
    // the SPI int events that have occurred
267
 
268
    HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR,   stat);
269
    HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_IDR, stat);
270
 
271
    cyg_drv_interrupt_mask(vector);
272
    cyg_drv_interrupt_acknowledge(vector);
273
 
274
    return CYG_ISR_CALL_DSR;
275
}
276
 
277
static void
278
spi_at91_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
279
{
280
    cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *) data;
281
    cyg_uint32 stat;
282
 
283
    // Read the status register and 
284
    // check for transfer completion
285
 
286
    HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR, stat);
287
 
288
    if((stat & AT91_SPI_SR_ENDRX) && (stat & AT91_SPI_SR_ENDTX))
289
    {
290
        // Transfer ended  
291
        spi_bus->transfer_end = true;
292
        cyg_drv_cond_signal(&spi_bus->transfer_cond);
293
    }
294
    else
295
    {
296
        // Transfer still in progress - unmask the SPI 
297
        // int so we can get more SPI int events
298
        cyg_drv_interrupt_unmask(vector);
299
    }
300
}
301
 
302
static cyg_bool
303
spi_at91_calc_scbr(cyg_spi_at91_device_t *dev)
304
{
305
    cyg_uint32 scbr;
306
    cyg_bool   res = true;
307
 
308
    // Calculate SCBR from baud rate
309
 
310
    scbr = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / dev->cl_brate;
311
    if ((2*(CYGNUM_HAL_ARM_AT91_CLOCK_SPEED % dev->cl_brate)) >= dev->cl_brate)
312
        scbr++;
313
 
314
    if (scbr < 2)
315
    {
316
        dev->cl_scbr  = 2;
317
        dev->cl_div32 = 0;
318
        res = false;
319
    }
320
    else if (scbr > 255)
321
    {
322
        dev->cl_div32 = 1;
323
 
324
        scbr = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / (32*dev->cl_brate);
325
 
326
        if (scbr < 2)
327
        {
328
            dev->cl_scbr = 2;
329
            res = false;
330
        }
331
        else if (scbr > 255)
332
        {
333
            dev->cl_scbr = 255;
334
            res = false;
335
        }
336
        else
337
            dev->cl_scbr = (cyg_uint8)scbr;
338
    }
339
    else
340
    {
341
        dev->cl_scbr  = (cyg_uint8)scbr;
342
        dev->cl_div32 = 0;
343
    }
344
 
345
    return res;
346
}
347
 
348
static void
349
spi_at91_set_npcs(cyg_spi_at91_bus_t *spi_bus,int val)
350
{
351
   cyg_uint32 ctr;
352
   for(ctr=0;ctr<4;ctr++)
353
   {
354
      if(spi_bus->cs_en[ctr])
355
      {
356
        HAL_ARM_AT91_GPIO_PUT(spi_bus->cs_gpio[ctr], (val & (1<<ctr)));
357
      }
358
   }
359
}
360
 
361
static void
362
spi_at91_start_transfer(cyg_spi_at91_device_t *dev)
363
{
364
    cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
365
 
366
    if (spi_bus->cs_up)
367
        return;
368
 
369
    // Force minimal delay between two transfers - in case two transfers
370
    // follow each other w/o delay, then we have to wait here in order for
371
    // the peripheral device to detect cs transition from inactive to active. 
372
    CYGACC_CALL_IF_DELAY_US(dev->tr_bt_udly);
373
 
374
    // Raise CS
375
 
376
#ifdef CYGHWR_DEVS_SPI_ARM_AT91_PCSDEC
377
    spi_at91_set_npcs(spi_bus,~dev->dev_num);
378
#else
379
    spi_at91_set_npcs(spi_bus,~(1<<dev->dev_num));
380
#endif
381
    CYGACC_CALL_IF_DELAY_US(dev->cs_up_udly);
382
 
383
    spi_bus->cs_up = true;
384
}
385
 
386
static void
387
spi_at91_drop_cs(cyg_spi_at91_device_t *dev)
388
{
389
    cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
390
 
391
    if (!spi_bus->cs_up)
392
       return;
393
 
394
    // Drop CS
395
 
396
    CYGACC_CALL_IF_DELAY_US(dev->cs_dw_udly);
397
    spi_at91_set_npcs(spi_bus,0x0F);
398
    spi_bus->cs_up = false;
399
}
400
 
401
static void
402
spi_at91_transfer(cyg_spi_at91_device_t *dev,
403
                  cyg_uint32             count,
404
                  const cyg_uint8       *tx_data,
405
                  cyg_uint8             *rx_data)
406
{
407
    cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
408
 
409
    // Since PDC transfer buffer counters are 16 bit long, 
410
    // we have to split longer transfers into chunks. 
411
    while (count > 0)
412
    {
413
        cyg_uint16 tr_count = count > 0xFFFF ? 0xFFFF : count;
414
 
415
        // Set rx buf pointer and counter 
416
        if (NULL != rx_data)
417
        {
418
            HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_RPR, (cyg_uint32)rx_data);
419
            HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_RCR, (cyg_uint32)tr_count);
420
        }
421
 
422
        // Set tx buf pointer and counter  
423
        HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_TPR, (cyg_uint32)tx_data);
424
        HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_TCR, (cyg_uint32)tr_count);
425
 
426
#ifdef AT91_SPI_PTCR
427
        HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_PTCR,
428
                         AT91_SPI_PTCR_RXTEN | AT91_SPI_PTCR_TXTEN);
429
#endif
430
        // Enable the SPI int events we are interested in
431
        HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_IER,
432
                         AT91_SPI_SR_ENDRX | AT91_SPI_SR_ENDTX);
433
 
434
        cyg_drv_mutex_lock(&spi_bus->transfer_mx);
435
        {
436
            spi_bus->transfer_end = false;
437
 
438
            // Unmask the SPI int
439
            cyg_drv_interrupt_unmask(spi_bus->interrupt_number);
440
 
441
            // Wait for its completion
442
            cyg_drv_dsr_lock();
443
            {
444
                while (!spi_bus->transfer_end)
445
                    cyg_drv_cond_wait(&spi_bus->transfer_cond);
446
            }
447
            cyg_drv_dsr_unlock();
448
        }
449
        cyg_drv_mutex_unlock(&spi_bus->transfer_mx);
450
 
451
        if (NULL == rx_data)
452
        {
453
            cyg_uint32 val;
454
 
455
            // If rx buffer was NULL, then the PDC receiver data transfer
456
            // was not started and we didn't wait for ENDRX, but only for 
457
            // ENDTX. Meaning that right now the last byte is being serialized 
458
            // over the line and when finished input data will appear in 
459
            // rx data reg. We have to wait for this to happen here, if we
460
            // don't we'll get the last received byte as the first one in the
461
            // next transfer!
462
 
463
            // FIXME: is there any better way to do this? 
464
            // If not, then precalculate this value.
465
            val = 8000000/dev->cl_brate;
466
            CYGACC_CALL_IF_DELAY_US(val > 1 ? val : 1);
467
 
468
            // Clear the rx data reg
469
            HAL_READ_UINT32(spi_bus->base+AT91_SPI_RDR, val);
470
        }
471
 
472
        // Adjust running variables
473
 
474
        if (NULL != rx_data)
475
            rx_data += tr_count;
476
        tx_data += tr_count;
477
        count   -= tr_count;
478
    }
479
}
480
 
481
static void
482
spi_at91_transfer_polled(cyg_spi_at91_device_t *dev,
483
                         cyg_uint32             count,
484
                         const cyg_uint8       *tx_data,
485
                         cyg_uint8             *rx_data)
486
{
487
    cyg_uint32 val;
488
    cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
489
 
490
    // Transmit and receive byte by byte
491
    while (count-- > 0)
492
    {
493
        // Wait for transmit data register empty
494
        do
495
        {
496
            HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR, val);
497
        } while ( !(val & AT91_SPI_SR_TDRE) );
498
 
499
        // Send next byte over the wire 
500
        val = *tx_data++;
501
        HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_TDR, val);
502
 
503
        // Wait for reveive data register full 
504
        do
505
        {
506
            HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR, val);
507
        } while ( !(val & AT91_SPI_SR_RDRF) );
508
 
509
        // Store received byte 
510
        HAL_READ_UINT32(spi_bus->base+AT91_SPI_RDR, val);
511
        if (NULL != rx_data)
512
            *rx_data++ = val;
513
    }
514
}
515
 
516
// -------------------------------------------------------------------------
517
 
518
static void
519
spi_at91_transaction_begin(cyg_spi_device *dev)
520
{
521
    cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
522
    cyg_spi_at91_bus_t *spi_bus =
523
      (cyg_spi_at91_bus_t *)at91_spi_dev->spi_device.spi_bus;
524
    cyg_uint32 val;
525
 
526
    if (!at91_spi_dev->init)
527
    {
528
        at91_spi_dev->init = true;
529
        spi_at91_calc_scbr(at91_spi_dev);
530
    }
531
 
532
    // Configure SPI channel 0 - this is the only channel we 
533
    // use for all devices since we drive chip selects manually
534
 
535
    val = AT91_SPI_CSR_BITS8;
536
 
537
    if (1 == at91_spi_dev->cl_pol)
538
        val |= AT91_SPI_CSR_CPOL;
539
 
540
    if (1 == at91_spi_dev->cl_pha)
541
        val |= AT91_SPI_CSR_NCPHA;
542
 
543
    val |= AT91_SPI_CSR_SCBR(at91_spi_dev->cl_scbr);
544
 
545
    HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CSR0, val);
546
 
547
    // Enable SPI clock
548
    HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 1<<spi_bus->interrupt_number);
549
 
550
    // Enable the SPI controller
551
    HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CR, AT91_SPI_CR_SPIEN);
552
 
553
    /* As we are using this driver only in master mode with NPCS0
554
       configured as GPIO instead of a peripheral pin, it is necessary
555
       for the Mode Failure detection to be switched off as this will
556
       cause havoc with the driver */
557
 
558
    // Put SPI bus into master mode
559
    if (1 == at91_spi_dev->cl_div32) {
560
      val = AT91_SPI_MR_MSTR | AT91_SPI_MR_DIV32;
561
#ifdef AT91_SPI_MR_MODFDIS
562
      val |= AT91_SPI_MR_MODFDIS;
563
#endif
564
      HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_MR, val);
565
    } else {
566
      val = AT91_SPI_MR_MSTR;
567
#ifdef AT91_SPI_MR_MODFDIS
568
      val |= AT91_SPI_MR_MODFDIS;
569
#endif
570
      HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_MR, val);
571
    }
572
}
573
 
574
static void
575
spi_at91_transaction_transfer(cyg_spi_device  *dev,
576
                              cyg_bool         polled,
577
                              cyg_uint32       count,
578
                              const cyg_uint8 *tx_data,
579
                              cyg_uint8       *rx_data,
580
                              cyg_bool         drop_cs)
581
{
582
    cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
583
 
584
    // Select the device if not already selected
585
    spi_at91_start_transfer(at91_spi_dev);
586
 
587
    // Perform the transfer
588
    if (polled)
589
        spi_at91_transfer_polled(at91_spi_dev, count, tx_data, rx_data);
590
    else
591
        spi_at91_transfer(at91_spi_dev, count, tx_data, rx_data);
592
 
593
    // Deselect the device if requested
594
    if (drop_cs)
595
        spi_at91_drop_cs(at91_spi_dev);
596
}
597
 
598
static void
599
spi_at91_transaction_tick(cyg_spi_device *dev,
600
                          cyg_bool        polled,
601
                          cyg_uint32      count)
602
{
603
    const cyg_uint32 zeros[10] = { 0,0,0,0,0,0,0,0,0,0 };
604
 
605
    cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
606
 
607
    // Transfer count zeros to the device - we don't touch the
608
    // chip select, the device could be selected or deselected.
609
    // It is up to the device driver to decide in wich state the
610
    // device will be ticked.
611
 
612
    while (count > 0)
613
    {
614
        int tcnt = count > 40 ? 40 : count;
615
 
616
        if (polled)
617
            spi_at91_transfer_polled(at91_spi_dev, tcnt,
618
                                     (const cyg_uint8 *) zeros, NULL);
619
        else
620
            spi_at91_transfer(at91_spi_dev, tcnt,
621
                              (const cyg_uint8 *) zeros, NULL);
622
 
623
        count -= tcnt;
624
    }
625
}
626
 
627
static void
628
spi_at91_transaction_end(cyg_spi_device* dev)
629
{
630
    cyg_spi_at91_device_t * at91_spi_dev = (cyg_spi_at91_device_t *)dev;
631
    cyg_spi_at91_bus_t *spi_bus =
632
      (cyg_spi_at91_bus_t *)at91_spi_dev->spi_device.spi_bus;
633
 
634
    // Disable the SPI controller
635
    HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CR, AT91_SPI_CR_SPIDIS);
636
 
637
    // Disable SPI clock
638
    HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCDR,1<<spi_bus->interrupt_number);
639
 
640
    spi_at91_drop_cs((cyg_spi_at91_device_t *) dev);
641
}
642
 
643
static int
644
spi_at91_get_config(cyg_spi_device *dev,
645
                    cyg_uint32      key,
646
                    void           *buf,
647
                    cyg_uint32     *len)
648
{
649
    cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
650
 
651
    switch (key)
652
    {
653
        case CYG_IO_GET_CONFIG_SPI_CLOCKRATE:
654
        {
655
            if (*len != sizeof(cyg_uint32))
656
                return -EINVAL;
657
            else
658
            {
659
                cyg_uint32 *cl_brate = (cyg_uint32 *)buf;
660
                *cl_brate = at91_spi_dev->cl_brate;
661
            }
662
        }
663
        break;
664
        default:
665
            return -EINVAL;
666
    }
667
    return ENOERR;
668
}
669
 
670
static int
671
spi_at91_set_config(cyg_spi_device *dev,
672
                    cyg_uint32      key,
673
                    const void     *buf,
674
                    cyg_uint32     *len)
675
{
676
    cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
677
 
678
    switch (key)
679
    {
680
        case CYG_IO_SET_CONFIG_SPI_CLOCKRATE:
681
        {
682
            if (*len != sizeof(cyg_uint32))
683
                return -EINVAL;
684
            else
685
            {
686
                cyg_uint32 cl_brate     = *((cyg_uint32 *)buf);
687
                cyg_uint32 old_cl_brate = at91_spi_dev->cl_brate;
688
 
689
                at91_spi_dev->cl_brate = cl_brate;
690
 
691
                if (!spi_at91_calc_scbr(at91_spi_dev))
692
                {
693
                    at91_spi_dev->cl_brate = old_cl_brate;
694
                    spi_at91_calc_scbr(at91_spi_dev);
695
                    return -EINVAL;
696
                }
697
            }
698
        }
699
        break;
700
        default:
701
            return -EINVAL;
702
    }
703
    return ENOERR;
704
}
705
 
706
// -------------------------------------------------------------------------
707
// EOF spi_at91.c

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.