]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/spi/arm/at91/v2_0/src/spi_at91.c
Initial revision
[karo-tx-redboot.git] / packages / devs / spi / arm / at91 / v2_0 / src / spi_at91.c
1 //==========================================================================
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 Red Hat, 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 version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):     Savin Zlobec <savin@elatec.si> 
44 // Date:          2004-08-25
45 //
46 //####DESCRIPTIONEND####
47 //
48 //==========================================================================
49
50 #include <pkgconf/hal.h>
51 #include <pkgconf/io_spi.h>
52 #include <pkgconf/devs_spi_arm_at91.h>
53
54 #include <cyg/infra/cyg_type.h>
55 #include <cyg/infra/cyg_ass.h>
56 #include <cyg/hal/hal_io.h>
57 #include <cyg/hal/hal_if.h>
58 #include <cyg/hal/hal_intr.h>
59 #include <cyg/hal/drv_api.h>
60 #include <cyg/io/spi.h>
61 #include <cyg/io/spi_at91.h>
62 #include <cyg/error/codes.h>
63
64 // -------------------------------------------------------------------------
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 cyg_spi_at91_bus_t cyg_spi_at91_bus = {
101     .spi_bus.spi_transaction_begin    = spi_at91_transaction_begin,
102     .spi_bus.spi_transaction_transfer = spi_at91_transaction_transfer,
103     .spi_bus.spi_transaction_tick     = spi_at91_transaction_tick,
104     .spi_bus.spi_transaction_end      = spi_at91_transaction_end,
105     .spi_bus.spi_get_config           = spi_at91_get_config,
106     .spi_bus.spi_set_config           = spi_at91_set_config
107 };
108
109 CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_at91_device_t, 0);
110
111 // -------------------------------------------------------------------------
112
113 void
114 cyg_spi_at91_bus_init(void)
115 {
116     // Create and attach SPI interrupt object
117     cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_SPI,
118                              4,                   
119                              (cyg_addrword_t)&cyg_spi_at91_bus,   
120                              spi_at91_ISR,
121                              spi_at91_DSR,
122                              &cyg_spi_at91_bus.spi_interrupt_handle,
123                              &cyg_spi_at91_bus.spi_interrupt);
124
125     cyg_drv_interrupt_attach(cyg_spi_at91_bus.spi_interrupt_handle);
126
127     // Init transfer mutex and condition
128     cyg_drv_mutex_init(&cyg_spi_at91_bus.transfer_mx);
129     cyg_drv_cond_init(&cyg_spi_at91_bus.transfer_cond, 
130                       &cyg_spi_at91_bus.transfer_mx);
131    
132     // Init flags
133     cyg_spi_at91_bus.transfer_end = true;
134     cyg_spi_at91_bus.cs_up        = false;
135     
136     // Soft reset the SPI controller
137     HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_CR, AT91_SPI_CR_SWRST);
138
139     // Configure SPI pins
140       
141     // NOTE: here we let the SPI controller control 
142     //       the data in, out and clock signals, but 
143     //       we need to handle the chip selects manually 
144     //       in order to achieve better chip select control 
145     //       inbetween transactions.
146     
147     // Put SPI MISO, MOIS and SPCK pins into peripheral mode
148     HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_PDR, AT91_PIO_PSR_SPCK |
149                                                 AT91_PIO_PSR_MISO |
150                                                 AT91_PIO_PSR_MOIS); 
151  
152     // Put SPI chip select pins in IO output mode
153     HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_SODR, AT91_SPI_PIO_NPCS(0x0F));
154     HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_PER,  AT91_SPI_PIO_NPCS(0x0F));
155     HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_OER,  AT91_SPI_PIO_NPCS(0x0F));
156
157     // Call upper layer bus init
158     CYG_SPI_BUS_COMMON_INIT(&cyg_spi_at91_bus.spi_bus);
159 }
160
161 // -------------------------------------------------------------------------
162
163 static cyg_uint32 
164 spi_at91_ISR(cyg_vector_t vector, cyg_addrword_t data)
165 {
166     cyg_uint32 stat;
167
168     // Read the status register and disable
169     // the SPI int events that have occoured
170     
171     HAL_READ_UINT32(AT91_SPI+AT91_SPI_SR,   stat);
172     HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_IDR, stat);
173     
174     cyg_drv_interrupt_mask(vector);
175     cyg_drv_interrupt_acknowledge(vector);
176
177     return CYG_ISR_CALL_DSR;
178 }
179
180 static void 
181 spi_at91_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
182 {
183     cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *) data;
184     cyg_uint32 stat;
185     
186     // Read the status register and 
187     // check for transfer completition
188     
189     HAL_READ_UINT32(AT91_SPI+AT91_SPI_SR, stat);
190
191     if((stat & AT91_SPI_SR_ENDRX) && (stat & AT91_SPI_SR_ENDTX))
192     {
193         // Transfer ended  
194         spi_bus->transfer_end = true;
195         cyg_drv_cond_signal(&spi_bus->transfer_cond);
196     }
197     else
198     {
199         // Transfer still in progress - unmask the SPI 
200         // int so we can get more SPI int events
201         cyg_drv_interrupt_unmask(vector);
202     }
203 }
204
205 static cyg_bool 
206 spi_at91_calc_scbr(cyg_spi_at91_device_t *dev)
207 {
208     cyg_uint32 scbr;
209     cyg_bool   res = true;
210     
211     // Calculate SCBR from baud rate
212     
213     scbr = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / (2*dev->cl_brate);
214
215     if (scbr < 2)
216     {
217         dev->cl_scbr  = 2;
218         dev->cl_div32 = 0;
219         res = false;
220     }
221     else if (scbr > 255)
222     {
223         dev->cl_div32 = 1;
224         
225         scbr = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / (64*dev->cl_brate);
226
227         if (scbr < 2) 
228         {
229             dev->cl_scbr = 2;
230             res = false;
231         }
232         else if (scbr > 255) 
233         {
234             dev->cl_scbr = 255;
235             res = false;
236         }
237         else
238             dev->cl_scbr = (cyg_uint8)scbr;
239     }
240     else
241     {
242         dev->cl_scbr  = (cyg_uint8)scbr;
243         dev->cl_div32 = 0;
244     }
245     
246     return res;
247 }
248
249 static void
250 spi_at91_start_transfer(cyg_spi_at91_device_t *dev)
251 {
252     cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
253   
254     if (spi_bus->cs_up)
255         return;
256  
257     // Force minimal delay between two transfers - in case two transfers
258     // follow each other w/o delay, then we have to wait here in order for
259     // the peripheral device to detect cs transition from inactive to active. 
260     CYGACC_CALL_IF_DELAY_US(dev->tr_bt_udly);
261     
262     // Raise CS
263
264 #ifdef CYGHWR_DEVS_SPI_ARM_AT91_PCSDEC
265     HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_CODR, 
266                      AT91_SPI_PIO_NPCS(~dev->dev_num));
267 #else
268     HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_CODR,
269                       AT91_SPI_PIO_NPCS(1<<dev->dev_num));
270 #endif
271     CYGACC_CALL_IF_DELAY_US(dev->cs_up_udly);
272    
273     spi_bus->cs_up = true;
274 }
275
276 static void
277 spi_at91_drop_cs(cyg_spi_at91_device_t *dev)
278 {
279     cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
280     
281     if (!spi_bus->cs_up)
282        return;
283            
284     // Drop CS
285
286     CYGACC_CALL_IF_DELAY_US(dev->cs_dw_udly);
287     HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_SODR, AT91_SPI_PIO_NPCS(0x0F)); 
288     spi_bus->cs_up = false;
289 }
290
291 static void
292 spi_at91_transfer(cyg_spi_at91_device_t *dev,
293                   cyg_uint32             count, 
294                   const cyg_uint8       *tx_data,
295                   cyg_uint8             *rx_data)
296 {
297     cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
298
299     // Since PDC transfer buffer counters are 16 bit long, 
300     // we have to split longer transfers into chunks. 
301     while (count > 0)
302     {
303         cyg_uint16 tr_count = count > 0xFFFF ? 0xFFFF : count;
304
305         // Set rx buf pointer and counter 
306         if (NULL != rx_data)
307         {
308             HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_RPR, (cyg_uint32)rx_data);
309             HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_RCR, (cyg_uint32)tr_count);
310         }
311
312         // Set tx buf pointer and counter  
313         HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_TPR, (cyg_uint32)tx_data);
314         HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_TCR, (cyg_uint32)tr_count);
315    
316         // Enable the SPI int events we are interested in
317         HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_IER, AT91_SPI_SR_ENDRX | 
318                                                 AT91_SPI_SR_ENDTX);
319
320         cyg_drv_mutex_lock(&spi_bus->transfer_mx);
321         {
322             spi_bus->transfer_end = false;
323     
324             // Unmask the SPI int
325             cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_SPI);
326         
327             // Wait for its completition
328             cyg_drv_dsr_lock();
329             {
330                 while (!spi_bus->transfer_end)
331                     cyg_drv_cond_wait(&spi_bus->transfer_cond);
332             }
333             cyg_drv_dsr_unlock();
334         }    
335         cyg_drv_mutex_unlock(&spi_bus->transfer_mx);
336
337         if (NULL == rx_data)
338         {
339             cyg_uint32 val;
340         
341             // If rx buffer was NULL, then the PDC receiver data transfer
342             // was not started and we didn't wait for ENDRX, but only for 
343             // ENDTX. Meaning that right now the last byte is being serialized 
344             // over the line and when finished input data will appear in 
345             // rx data reg. We have to wait for this to happen here, if we
346             // don't we'll get the last received byte as the first one in the
347             // next transfer!
348         
349             // FIXME: is there any better way to do this? 
350             // If not, then precalculate this value.
351             val = 8000000/dev->cl_brate;
352             CYGACC_CALL_IF_DELAY_US(val > 1 ? val : 1);
353
354             // Clear the rx data reg
355             HAL_READ_UINT32(AT91_SPI+AT91_SPI_RDR, val);
356         }
357
358         // Adjust running variables
359         
360         if (NULL != rx_data)
361             rx_data += tr_count;
362         tx_data += tr_count;
363         count   -= tr_count;
364     }
365 }
366
367 static void
368 spi_at91_transfer_polled(cyg_spi_at91_device_t *dev, 
369                          cyg_uint32             count,
370                          const cyg_uint8       *tx_data,
371                          cyg_uint8             *rx_data)
372 {
373     cyg_uint32 val;
374
375     // Transmit and receive byte by byte
376     while (count-- > 0)
377     {
378         // Wait for transmit data register empty
379         do
380         {
381             HAL_READ_UINT32(AT91_SPI+AT91_SPI_SR, val);
382         } while ( !(val & AT91_SPI_SR_TDRE) );
383        
384         // Send next byte over the wire 
385         val = *tx_data++;
386         HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_TDR, val);
387         
388         // Wait for reveive data register full 
389         do
390         {
391             HAL_READ_UINT32(AT91_SPI+AT91_SPI_SR, val);
392         } while ( !(val & AT91_SPI_SR_RDRF) );
393         
394         // Store received byte 
395         HAL_READ_UINT32(AT91_SPI+AT91_SPI_RDR, val);
396         if (NULL != rx_data)
397             *rx_data++ = val; 
398     }
399 }
400
401 // -------------------------------------------------------------------------
402
403 static void 
404 spi_at91_transaction_begin(cyg_spi_device *dev)
405 {
406     cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;    
407     cyg_uint32 val;
408     
409     if (!at91_spi_dev->init)
410     {
411         at91_spi_dev->init = true;
412         spi_at91_calc_scbr(at91_spi_dev);
413     }
414     
415     // Configure SPI channel 0 - this is the only channel we 
416     // use for all devices since we drive chip selects manually
417     
418     val = AT91_SPI_CSR_BITS8;
419
420     if (1 == at91_spi_dev->cl_pol)
421         val |= AT91_SPI_CSR_CPOL;
422
423     if (1 == at91_spi_dev->cl_pha)
424         val |= AT91_SPI_CSR_NCPHA;
425
426     val |= AT91_SPI_CSR_SCBR(at91_spi_dev->cl_scbr);
427
428     HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_CSR0, val); 
429
430     // Enable SPI clock
431     HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, AT91_PMC_PCER_SPI);
432     
433     // Enable the SPI controller
434     HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_CR, AT91_SPI_CR_SPIEN);
435     
436     // Put SPI bus into master mode
437     if (1 == at91_spi_dev->cl_div32)
438         HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_MR, AT91_SPI_MR_MSTR | 
439                                                AT91_SPI_MR_DIV32);
440     else
441         HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_MR, AT91_SPI_MR_MSTR);
442 }
443
444 static void 
445 spi_at91_transaction_transfer(cyg_spi_device  *dev, 
446                               cyg_bool         polled,  
447                               cyg_uint32       count, 
448                               const cyg_uint8 *tx_data, 
449                               cyg_uint8       *rx_data, 
450                               cyg_bool         drop_cs) 
451 {
452     cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
453
454     // Select the device if not already selected
455     spi_at91_start_transfer(at91_spi_dev);
456  
457     // Perform the transfer
458     if (polled)
459         spi_at91_transfer_polled(at91_spi_dev, count, tx_data, rx_data);
460     else
461         spi_at91_transfer(at91_spi_dev, count, tx_data, rx_data);
462
463     // Deselect the device if requested
464     if (drop_cs)
465         spi_at91_drop_cs(at91_spi_dev);
466 }
467
468 static void 
469 spi_at91_transaction_tick(cyg_spi_device *dev, 
470                           cyg_bool        polled,  
471                           cyg_uint32      count)
472 {
473     const cyg_uint32 zeros[10] = { 0,0,0,0,0,0,0,0,0,0 };
474
475     cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
476     
477     // Transfer count zeros to the device - we don't touch the
478     // chip select, the device could be selected or deselected.
479     // It is up to the device driver to decide in wich state the
480     // device will be ticked.
481     
482     while (count > 0)
483     {
484         int tcnt = count > 40 ? 40 : count;
485         
486         if (polled)
487             spi_at91_transfer_polled(at91_spi_dev, tcnt, 
488                                      (const cyg_uint8 *) zeros, NULL);
489         else
490             spi_at91_transfer(at91_spi_dev, tcnt, 
491                               (const cyg_uint8 *) zeros, NULL);
492
493         count -= tcnt;
494     }
495 }
496
497 static void                    
498 spi_at91_transaction_end(cyg_spi_device* dev)
499 {
500     // Disable the SPI controller
501     HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_CR, AT91_SPI_CR_SPIDIS);
502
503     // Disable SPI clock
504     HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCDR, AT91_PMC_PCER_SPI);
505
506     spi_at91_drop_cs((cyg_spi_at91_device_t *) dev);
507 }
508
509 static int                     
510 spi_at91_get_config(cyg_spi_device *dev, 
511                     cyg_uint32      key, 
512                     void           *buf,
513                     cyg_uint32     *len)
514 {
515     cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
516     
517     switch (key) 
518     {
519         case CYG_IO_GET_CONFIG_SPI_CLOCKRATE:
520         {
521             if (*len != sizeof(cyg_uint32))
522                 return -EINVAL;
523             else
524             {
525                 cyg_uint32 *cl_brate = (cyg_uint32 *)buf;
526                 *cl_brate = at91_spi_dev->cl_brate; 
527             }
528         }
529         break;
530         default:
531             return -EINVAL;
532     }
533     return ENOERR;
534 }
535
536 static int                     
537 spi_at91_set_config(cyg_spi_device *dev, 
538                     cyg_uint32      key, 
539                     const void     *buf, 
540                     cyg_uint32     *len)
541 {
542     cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
543    
544     switch (key) 
545     {
546         case CYG_IO_SET_CONFIG_SPI_CLOCKRATE:
547         {
548             if (*len != sizeof(cyg_uint32))
549                 return -EINVAL;
550             else
551             {
552                 cyg_uint32 cl_brate     = *((cyg_uint32 *)buf);
553                 cyg_uint32 old_cl_brate = at91_spi_dev->cl_brate;
554            
555                 at91_spi_dev->cl_brate = cl_brate;
556             
557                 if (!spi_at91_calc_scbr(at91_spi_dev))
558                 {
559                     at91_spi_dev->cl_brate = old_cl_brate;
560                     spi_at91_calc_scbr(at91_spi_dev);
561                     return -EINVAL;
562                 }
563             }
564         }
565         break;
566         default:
567             return -EINVAL;
568     }
569     return ENOERR;
570 }
571
572 // -------------------------------------------------------------------------
573 // EOF spi_at91.c