source: rtems/c/src/lib/libbsp/arm/nds/libnds/source/common/card.c @ ef4c461

4.115
Last change on this file since ef4c461 was ef4c461, checked in by Joel Sherrill <joel.sherrill@…>, on 10/09/14 at 20:35:10

arm/nds: Warning clean up

This patch eliminates most of the warnings in this BSP but attempts
very little clean up. This BSP includes copies of a lot of code
from free NDS libraries and modifications should be kept to a minimum.

  • Property mode set to 100644
File size: 12.4 KB
Line 
1/*---------------------------------------------------------------------------------
2        Copyright (C) 2005
3                Michael Noland (joat)
4                Jason Rogers (dovoto)
5                Dave Murphy (WinterMute)
6
7        This software is provided 'as-is', without any express or implied
8        warranty.  In no event will the authors be held liable for any
9        damages arising from the use of this software.
10
11        Permission is granted to anyone to use this software for any
12        purpose, including commercial applications, and to alter it and
13        redistribute it freely, subject to the following restrictions:
14
15        1.      The origin of this software must not be misrepresented; you
16                must not claim that you wrote the original software. If you use
17                this software in a product, an acknowledgment in the product
18                documentation would be appreciated but is not required.
19        2.      Altered source versions must be plainly marked as such, and
20                must not be misrepresented as being the original software.
21        3.      This notice may not be removed or altered from any source
22                distribution.
23
24
25---------------------------------------------------------------------------------*/
26#include "nds/card.h"
27#include "nds/dma.h"
28#include "nds/memory.h"
29
30
31//---------------------------------------------------------------------------------
32void cardWriteCommand(const uint8 * command) {
33//---------------------------------------------------------------------------------
34        int index;
35
36        CARD_CR1H = CARD_CR1_ENABLE | CARD_CR1_IRQ;
37
38        for (index = 0; index < 8; index++) {
39                CARD_COMMAND[7-index] = command[index];
40        }
41}
42
43
44//---------------------------------------------------------------------------------
45void cardPolledTransfer(uint32 flags, uint32 * destination, uint32 length, const uint8 * command) {
46//---------------------------------------------------------------------------------
47        u32 data;
48        cardWriteCommand(command);
49        CARD_CR2 = flags;
50        uint32 * target = destination + length;
51        do {
52                // Read data if available
53                if (CARD_CR2 & CARD_DATA_READY) {
54                        data=CARD_DATA_RD;
55                        if (destination < target)
56                                *destination = data;
57                        destination++;
58                }
59        } while (CARD_CR2 & CARD_BUSY);
60}
61
62
63//---------------------------------------------------------------------------------
64void cardStartTransfer(const uint8 * command, uint32 * destination, int channel, uint32 flags) {
65//---------------------------------------------------------------------------------
66        cardWriteCommand(command);
67
68        // Set up a DMA channel to transfer a word every time the card makes one
69        DMA_SRC(channel) = (uint32)&CARD_DATA_RD;
70        DMA_DEST(channel) = (uint32)destination;
71        DMA_CR(channel) = DMA_ENABLE | DMA_START_CARD | DMA_32_BIT | DMA_REPEAT | DMA_SRC_FIX | 0x0001;
72
73        CARD_CR2 = flags;
74}
75
76
77//---------------------------------------------------------------------------------
78uint32 cardWriteAndRead(const uint8 * command, uint32 flags) {
79//---------------------------------------------------------------------------------
80        cardWriteCommand(command);
81        CARD_CR2 = flags | CARD_ACTIVATE | CARD_nRESET | 0x07000000;
82        while (!(CARD_CR2 & CARD_DATA_READY)) ;
83        return CARD_DATA_RD;
84}
85
86
87//---------------------------------------------------------------------------------
88void cardRead00(uint32 address, uint32 * destination, uint32 length, uint32 flags) {
89//---------------------------------------------------------------------------------f
90        uint8 command[8];
91        command[7] = 0;
92        command[6] = (address >> 24) & 0xff;
93        command[5] = (address >> 16) & 0xff;
94        command[4] = (address >> 8) & 0xff;
95        command[3] = address & 0xff;
96        command[2] = 0;
97        command[1] = 0;
98        command[0] = 0;
99        cardPolledTransfer(flags, destination, length, command);
100}
101
102
103//---------------------------------------------------------------------------------
104void cardReadHeader(uint8 * header) {
105//---------------------------------------------------------------------------------
106        cardRead00(0, (uint32 *)header, 512, 0xA93F1FFF);
107}
108
109
110//---------------------------------------------------------------------------------
111int cardReadID(uint32 flags) {
112//---------------------------------------------------------------------------------
113        uint8 command[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90};
114        return cardWriteAndRead(command, flags);
115}
116
117
118//---------------------------------------------------------------------------------
119static inline void EepromWaitBusy(void) {
120//---------------------------------------------------------------------------------
121        while (CARD_CR1 & /*BUSY*/0x80);
122}
123
124//---------------------------------------------------------------------------------
125uint8 cardEepromReadID(uint8 i) {
126//---------------------------------------------------------------------------------
127    return cardEepromCommand(/*READID*/0xAB, i&1);
128}
129
130//---------------------------------------------------------------------------------
131uint8 cardEepromCommand(uint8 command, uint32 address) {
132//---------------------------------------------------------------------------------
133    uint8 retval;
134    int k;
135    CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
136
137    CARD_CR1 = 0xFFFF;
138    CARD_EEPDATA = command;
139
140    EepromWaitBusy();
141
142    CARD_EEPDATA = (address >> 16) & 0xFF;
143    EepromWaitBusy();
144
145    CARD_EEPDATA = (address >> 8) & 0xFF;
146    EepromWaitBusy();
147
148    CARD_EEPDATA = (address) & 0xFF;
149    EepromWaitBusy();
150
151    for(k=0;k<256;k++)
152    {
153        retval = CARD_EEPDATA;
154        if(retval!=0xFF)
155            break;
156        EepromWaitBusy();
157    }
158
159    CARD_CR1 = /*MODE*/0x40;
160    return retval;
161}
162
163//---------------------------------------------------------------------------------
164int cardEepromGetType(void)
165//---------------------------------------------------------------------------------
166{
167        uint8 c00;
168        uint8 c05;
169        uint8 c9f;
170        uint8 c03;
171
172#ifdef ARM9
173        sysSetBusOwners(BUS_OWNER_ARM9, BUS_OWNER_ARM9);
174#endif
175
176        (void) c03; /* avoid set but not used warning */
177        c03=cardEepromCommand(0x03,0);
178        c05=cardEepromCommand(0x05,0);
179        c9f=cardEepromCommand(0x9f,0);
180        c00=cardEepromCommand(0x00,0);
181
182        if((c00==0x00) && (c9f==0x00)) return 0; // PassMe?
183        if((c00==0xff) && (c05==0xff) && (c9f==0xff))return -1;
184
185        if((c00==0xff) &&  (c05 & 0xFD) == 0xF0 && (c9f==0xff))return 1;
186        if((c00==0xff) &&  (c05 & 0xFD) == 0x00 && (c9f==0xff))return 2;
187        if((c00==0xff) &&  (c05 & 0xFD) == 0x00 && (c9f==0x00))return 3;
188        if((c00==0xff) &&  (c05 & 0xFD) == 0x00 && (c9f==0x12))return 3;        //      NEW TYPE 3
189        if((c00==0xff) &&  (c05 & 0xFD) == 0x00 && (c9f==0x13))return 3;        //      NEW TYPE 3+  4Mbit
190        if((c00==0xff) &&  (c05 & 0xFD) == 0x00 && (c9f==0x14))return 3;        //      NEW TYPE 3++ 8Mbit MK4-FLASH Memory
191
192        return 0;
193}
194
195//---------------------------------------------------------------------------------
196uint32 cardEepromGetSize() {
197//---------------------------------------------------------------------------------
198
199    int type = cardEepromGetType();
200
201    if(type == -1)
202        return 0;
203    if(type == 0)
204        return 8192;
205    if(type == 1)
206        return 512;
207    if(type == 2) {
208        static const uint32 offset0 = (8*1024-1);        //      8KB
209        static const uint32 offset1 = (2*8*1024-1);      //      16KB
210        u8 buf1;     //      +0k data        read -> write
211        u8 buf2;     //      +8k data        read -> read
212        u8 buf3;     //      +0k ~data          write
213        u8 buf4;     //      +8k data new    comp buf2
214        cardReadEeprom(offset0,&buf1,1,type);
215        cardReadEeprom(offset1,&buf2,1,type);
216        buf3=~buf1;
217        cardWriteEeprom(offset0,&buf3,1,type);
218        cardReadEeprom (offset1,&buf4,1,type);
219        cardWriteEeprom(offset0,&buf1,1,type);
220        if(buf4!=buf2)      //      +8k
221            return 8*1024;  //       8KB(64kbit)
222        else
223            return 64*1024; //      64KB(512kbit)
224    }
225    if(type == 3) {
226        uint8 c9f;
227        c9f=cardEepromCommand(0x9f,0);
228
229        if(c9f==0x14)
230            return 1024*1024; //   NEW TYPE 3++ 8Mbit(1024KByte)
231
232        if(c9f==0x13)
233            return 512*1024;  //   NEW TYPE 3+ 4Mbit(512KByte)
234
235        return 256*1024;      //   TYPE 3  2Mbit(256KByte)
236    }
237
238    return 0;
239}
240
241
242//---------------------------------------------------------------------------------
243void cardReadEeprom(uint32 address, uint8 *data, uint32 length, uint32 addrtype) {
244//---------------------------------------------------------------------------------
245
246    CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
247    CARD_EEPDATA = 0x03 | ((addrtype == 1) ? address>>8<<3 : 0);
248    EepromWaitBusy();
249
250    if (addrtype == 3) {
251        CARD_EEPDATA = (address >> 16) & 0xFF;
252            EepromWaitBusy();
253    }
254
255    if (addrtype >= 2) {
256        CARD_EEPDATA = (address >> 8) & 0xFF;
257            EepromWaitBusy();
258    }
259
260
261        CARD_EEPDATA = (address) & 0xFF;
262    EepromWaitBusy();
263
264    while (length > 0) {
265        CARD_EEPDATA = 0;
266        EepromWaitBusy();
267        *data++ = CARD_EEPDATA;
268        length--;
269    }
270
271    EepromWaitBusy();
272    CARD_CR1 = /*MODE*/0x40;
273}
274
275
276//---------------------------------------------------------------------------------
277void cardWriteEeprom(uint32 address, uint8 *data, uint32 length, uint32 addrtype) {
278//---------------------------------------------------------------------------------
279
280        uint32 address_end = address + length;
281        int i;
282    int maxblocks = 32;
283    if(addrtype == 1) maxblocks = 16;
284    if(addrtype == 2) maxblocks = 32;
285    if(addrtype == 3) maxblocks = 256;
286
287        while (address < address_end) {
288                // set WEL (Write Enable Latch)
289                CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
290                CARD_EEPDATA = 0x06; EepromWaitBusy();
291                CARD_CR1 = /*MODE*/0x40;
292
293                // program maximum of 32 bytes
294                CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
295
296        if(addrtype == 1) {
297        //  WRITE COMMAND 0x02 + A8 << 3
298            CARD_EEPDATA = 0x02 | (address & BIT(8)) >> (8-3) ;
299            EepromWaitBusy();
300            CARD_EEPDATA = address & 0xFF;
301            EepromWaitBusy();
302        }
303        else if(addrtype == 2) {
304            CARD_EEPDATA = 0x02;
305            EepromWaitBusy();
306            CARD_EEPDATA = address >> 8;
307            EepromWaitBusy();
308            CARD_EEPDATA = address & 0xFF;
309            EepromWaitBusy();
310        }
311        else if(addrtype == 3) {
312            CARD_EEPDATA = 0x02;
313            EepromWaitBusy();
314            CARD_EEPDATA = (address >> 16) & 0xFF;
315            EepromWaitBusy();
316            CARD_EEPDATA = (address >> 8) & 0xFF;
317            EepromWaitBusy();
318            CARD_EEPDATA = address & 0xFF;
319            EepromWaitBusy();
320        }
321
322                for (i=0; address<address_end && i<maxblocks; i++, address++) {
323            CARD_EEPDATA = *data++;
324            EepromWaitBusy();
325        }
326                CARD_CR1 = /*MODE*/0x40;
327
328                // wait programming to finish
329                CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
330                CARD_EEPDATA = 0x05; EepromWaitBusy();
331                do { CARD_EEPDATA = 0; EepromWaitBusy(); } while (CARD_EEPDATA & 0x01); // WIP (Write In Progress) ?
332        EepromWaitBusy();
333        CARD_CR1 = /*MODE*/0x40;
334        }
335}
336
337
338//  Chip Erase : clear FLASH MEMORY (TYPE 3 ONLY)
339//---------------------------------------------------------------------------------
340void cardEepromChipErase(void) {
341//---------------------------------------------------------------------------------
342    int sz;
343    sz=cardEepromGetSize();
344    cardEepromSectorErase(0x00000);
345    cardEepromSectorErase(0x10000);
346    cardEepromSectorErase(0x20000);
347    cardEepromSectorErase(0x30000);
348    if(sz==512*1024)
349    {
350        cardEepromSectorErase(0x40000);
351        cardEepromSectorErase(0x50000);
352        cardEepromSectorErase(0x60000);
353        cardEepromSectorErase(0x70000);
354    }
355}
356
357//  COMMAND Sec.erase 0xD8
358void cardEepromSectorErase(uint32 address)
359{
360        // set WEL (Write Enable Latch)
361        CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
362        CARD_EEPDATA = 0x06;
363        EepromWaitBusy();
364
365        CARD_CR1 = /*MODE*/0x40;
366
367        // SectorErase 0xD8
368        CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
369        CARD_EEPDATA = 0xD8;
370        EepromWaitBusy();
371        CARD_EEPDATA = (address >> 16) & 0xFF;
372        EepromWaitBusy();
373        CARD_EEPDATA = (address >> 8) & 0xFF;
374        EepromWaitBusy();
375        CARD_EEPDATA = address & 0xFF;
376        EepromWaitBusy();
377
378        CARD_CR1 = /*MODE*/0x40;
379
380        // wait erase to finish
381        CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
382        CARD_EEPDATA = 0x05;
383        EepromWaitBusy();
384
385        do
386        {
387            CARD_EEPDATA = 0;
388            EepromWaitBusy();
389        } while (CARD_EEPDATA & 0x01);  // WIP (Write In Progress) ?
390        CARD_CR1 = /*MODE*/0x40;
391}
392
393
Note: See TracBrowser for help on using the repository browser.