changing circuitry to disable RTC, update initialization to match
[fw/openalt] / fatfs / spi.c
1 #include <stdio.h> // ###
2 #include "lpc210x.h"
3 #include "mmc.h"
4 #include "spi.h"
5
6 /*************************************************************************
7  *
8  *    Used with ICCARM and AARM.
9  *
10  *    (c) Copyright IAR Systems 2003
11  *
12  *    File name   : mmc_ll.h
13  *    Description : define MMC module
14  *
15  *    History :
16  *    1. Data        : July 1, 2005
17  *       Author      : Stanimir Bonev
18  *       Description : Create
19  *    2. Data        : July 1, 2005
20  *       Author      : Stanimir Bonev
21  *       Description : Modify
22  *        Fix a lock problem in spiReceiveBlock
23  *
24  *    $Revision: 1.4 $
25  * (C) Joel Winarske, 2006,2007                                        
26 **************************************************************************/
27
28 /*************************************************************************
29  * Function Name: spiChipSelect
30  * Parameters: Boolean Select
31  * Return: none
32  *
33  * Description: MMC Chip select control
34  * Select = true  - Chip is enabled
35  * Select = false - Chip is disabled
36  *
37  *************************************************************************/
38 void spiChipSelect (BOOL select)
39 {
40   if (select)
41     GPIO0_IOCLR = GPIO_IO_P20;
42   else
43   {
44     GPIO0_IOSET = GPIO_IO_P20;
45     
46     while (!(SSP_SR & SSP_SR_TNF))
47       ;
48
49     SSP_DR = 0xff;
50
51     //
52     // Wait until TX fifo and TX shift buffer are empty
53     //
54     while (SSP_SR & SSP_SR_BSY)
55       ;
56     while (!(SSP_SR & SSP_SR_RNE))
57       ;
58
59     do
60     {
61       select = SSP_DR;
62     }
63     while (SSP_SR & SSP_SR_RNE);
64   }
65 }
66
67 /*************************************************************************
68  * Function Name: spiPresent
69  * Parameters: none
70  * Return: Boolean - true card present
71  *                 - false card not present
72  *
73  * Description: MMC present check
74  *
75  *************************************************************************/
76 inline BOOL spiPresent (void)
77 {
78   return TRUE;
79 }
80
81 /*************************************************************************
82  * Function Name: spiWriteProtect
83  * Parameters: none
84  * Return: Boolean - true card is protected
85  *                 - false card not protected
86  *
87  * Description: MMC Write protect check
88  *
89  *************************************************************************/
90 inline BOOL spiWriteProtect (void)
91 {
92   return FALSE;
93 }
94
95 /*************************************************************************
96  * Function Name: spiSetClockFreq
97  * Parameters: Int32U Frequency
98  * Return: Int32U
99  *
100  * Description: Set SPI ckl frequency
101  *
102  *************************************************************************/
103 U32 spiSetClockFreq (U32 frequency)
104 {
105   U32 Div = SystemPeripherialClock / frequency;
106
107   if (Div < 2)
108     Div = 2;
109   else if (Div > 254)
110     Div = 254;
111
112   ++Div; 
113   Div &= ~1;
114   SSP_CPSR = Div;
115
116   return (SystemPeripherialClock / Div);
117 }
118
119 /*************************************************************************
120  * Function Name: spiInit
121  * Parameters: none
122  * Return: int
123  * 0 - no error
124  * 1 - speed is to high
125  *
126  * Description: Init SPI, Cart Present, Write Protect and Chip select pins
127  *
128  *************************************************************************/
129 void spiInit (void)
130 {
131   U32 i;
132   volatile U32 dummy;
133
134   //
135   //  Chip select
136   //
137   GPIO0_IOSET = GPIO_IO_P20;
138   GPIO0_IODIR |= GPIO_IO_P20;
139
140   //
141   //  SPI init
142   //
143   SCB_PCONP |= SCB_PCONP_PCSPI1;
144
145   SSP_CR0  = SSP_CR0_DSS_8 | SSP_CR0_FRF_SPI;
146   SSP_CR1  = 0x00;
147   SSP_IMSC = 0x00;
148
149   //
150   //  Clock Freq. Identification Mode < 400kHz
151   //
152   spiSetClockFreq (400000);
153
154   PCB_PINSEL1 |=  PCB_PINSEL1_P017_SCK1;
155   PCB_PINSEL1 |=  PCB_PINSEL1_P018_MISO1;
156   PCB_PINSEL1 |=  PCB_PINSEL1_P019_MOSI1;
157   PCB_PINSEL1 &= ~PCB_PINSEL1_P020_MASK;
158
159   //
160   //  Enable SPI
161   //
162   SSP_CR1 |= SSP_CR1_SSE;
163
164   for (i = 0; i < 8; i++)
165     dummy = SSP_DR;
166 }
167
168 /*************************************************************************
169  * Function Name: spiTransferByte
170  * Parameters: U8 ch
171  * Return: U8
172  *
173  * Description: Read byte from SPI
174  *
175  *************************************************************************/
176 U8 spiTransferByte (U8 c)
177 {
178   while (!(SSP_SR & SSP_SR_TNF))
179     ;
180
181   SSP_DR = c;
182
183   while (!(SSP_SR & SSP_SR_RNE))
184     ;
185
186   return SSP_DR;
187 }
188
189 /*-----------------------------------------------------------------------*/
190 /* Wait for card ready                                                   */
191 /*-----------------------------------------------------------------------*/
192 U8 spiWaitReady (void)
193 {
194   U8 res;
195
196   do                        /* TODO: add in 500ms timeout */
197   {      
198     SSP_DR = 0xff;
199
200     while (!(SSP_SR & SSP_SR_RNE))
201       ;
202
203     res = SSP_DR;
204   }
205   while (res != 0xff);
206
207   return res;
208 }
209
210 /*************************************************************************
211  * Function Name: spiSendBlock
212  * Parameters: pInt8U pData, Int32U Size
213  *
214  * Return: void
215  *
216  * Description: Read byte from SPI
217  *
218  *************************************************************************/
219 void spiSendBlock (U8 *pData, U32 size)
220 {
221   U32 outCount = size;
222   volatile U32 dummy;
223
224   while (outCount)
225   {
226     while ((SSP_SR & SSP_SR_TNF) && outCount)
227     {
228       SSP_DR = *pData++;
229       --outCount;
230     }
231   }
232
233   while ((SSP_SR & SSP_SR_RNE) || !(SSP_SR & SSP_SR_TFE))
234     dummy = SSP_DR;
235 }
236
237 /*************************************************************************
238  * Function Name: spiReceiveBlock
239  * Parameters: pInt8U pData, Int32U Size
240  *
241  * Return: void
242  *
243  * Description: Read byte from SPI
244  *
245  *************************************************************************/
246 void spiReceiveBlock (U8 *pData, U32 size)
247 {
248   U32 delta = 0;
249
250   while (size || delta)
251   {
252     while ((SSP_SR & SSP_SR_TNF) && (delta < SSP_FIFO_DEPTH) && size)
253     {
254       SSP_DR = 0xff;
255       --size; 
256       ++delta;
257     }
258
259     while (SSP_SR & SSP_SR_RNE)
260     {
261       *pData++ = SSP_DR;
262       --delta;
263     }
264   }
265 }
266
267 /*************************************************************************
268  * Function Name: spiDly_1ms
269  * Parameters: Int32U Delay
270  * Return: none
271  *
272  * Description: Delay [msec]
273  *
274  *************************************************************************/
275 void spiDelay1ms (U32 delay)
276 {
277   volatile U32 i;
278
279   for (;delay; --delay)
280   {
281     for (i = MMC_DLY_1MSEC; i; --i)
282       ;
283   }
284 }