Contiki 2.5
efs-sdcard-arch.c
1 #include <AT91SAM7S64.h>
2 #include <interfaces/sd.h>
3 #include <efs-sdcard.h>
4 #include <sys/etimer.h>
5 #include <stdio.h>
6 
7 #define SPI_SPEED 10000000 /* 10MHz clock*/
8 
9 #define SPI_TRANSFER (AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK)
10 
11 #define SPI_CS (AT91C_PA11_NPCS0)
12 
13 static struct process *event_process = NULL;
14 
15 static void
16 init_spi()
17 {
18  *AT91C_SPI_CR = AT91C_SPI_SPIDIS | AT91C_SPI_SWRST;
19  *AT91C_PMC_PCER = (1 << AT91C_ID_SPI);
20  *AT91C_PIOA_ASR = SPI_TRANSFER | SPI_CS;
21  *AT91C_PIOA_PDR = SPI_TRANSFER | SPI_CS;
22  *AT91C_PIOA_PPUER = AT91C_PA12_MISO | SPI_CS;
23  *AT91C_SPI_MR = (AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED
24  | AT91C_SPI_MODFDIS);
25 
26  /* It seems necessary to set the clock speed for chip select 0
27  even if it's not used. */
28 
29  AT91C_SPI_CSR[0] =
30  ((((MCK+SPI_SPEED/2)/SPI_SPEED)<<8) | AT91C_SPI_CPOL
31  | AT91C_SPI_BITS_8 | AT91C_SPI_CSAAT);
32  *AT91C_SPI_CR = AT91C_SPI_SPIEN;
33 
34 }
35 
36 void
37 if_spiInit(hwInterface *iface)
38 {
39  unsigned int i;
40  *AT91C_PIOA_SODR = AT91C_PA11_NPCS0;
41  *AT91C_PIOA_PER = AT91C_PA11_NPCS0;
42  for(i=0;i<20;i++) {
43  if_spiSend(iface, 0xff);
44  }
45  *AT91C_PIOA_PDR = AT91C_PA11_NPCS0;
46 }
47 
48 /* Borrowed from at91_spi.c (c)2006 Martin Thomas */
49 
50 esint8
51 if_initInterface(hwInterface* file, eint8* opts)
52 {
53  euint32 sc;
54 
55  if_spiInit(file);
56  if(sd_Init(file)<0) {
57  DBG((TXT("Card failed to init, breaking up...\n")));
58  return(-1);
59  }
60 
61  if(sd_State(file)<0){
62  DBG((TXT("Card didn't return the ready state, breaking up...\n")
63  ));
64  return(-2);
65  }
66 
67 
68 
69  sd_getDriveSize(file, &sc);
70  file->sectorCount = sc/512;
71  if( (sc%512) != 0) {
72  file->sectorCount--;
73  }
74  DBG((TXT("Card Capacity is %lu Bytes (%lu Sectors)\n"), sc, file->sectorCount));
75 
76 
77  return(0);
78 }
79 
80 /* Borrowed from lpc2000_spi.c (c)2005 Martin Thomas */
81 
82 esint8
83 if_readBuf(hwInterface* file,euint32 address,euint8* buf)
84 {
85  return(sd_readSector(file,address,buf,512));
86 }
87 
88 esint8
89 if_writeBuf(hwInterface* file,euint32 address,euint8* buf)
90 {
91  return(sd_writeSector(file,address, buf));
92 }
93 
94 esint8
95 if_setPos(hwInterface* file,euint32 address)
96 {
97  return(0);
98 }
99 
100 
101 euint8
102 if_spiSend(hwInterface *iface, euint8 outgoing)
103 {
104  euint8 ingoing;
105  *AT91C_SPI_TDR = outgoing;
106  while(!(*AT91C_SPI_SR & AT91C_SPI_RDRF));
107  ingoing = *AT91C_SPI_RDR;
108  /* printf(">%02x <%02x\n", outgoing, ingoing); */
109  return ingoing;
110 }
111 
112 static EmbeddedFileSystem sdcard_efs;
113 
114 PROCESS(sdcard_process, "SD card process");
115 
116 PROCESS_THREAD(sdcard_process, ev , data)
117 {
118  static struct etimer timer;
119  PROCESS_BEGIN();
120  *AT91C_PIOA_PER = AT91C_PIO_PA20 | AT91C_PIO_PA1;
121  *AT91C_PIOA_ODR = AT91C_PIO_PA20 | AT91C_PIO_PA1;
122 
123 
124  /* Card not inserted */
125  sdcard_efs.myCard.sectorCount = 0;
126  init_spi();
127 
128  while(1) {
129  if (!(*AT91C_PIOA_PDSR & AT91C_PA20_IRQ0)) {
130  if (sdcard_efs.myCard.sectorCount == 0) {
131  if (efs_init(&sdcard_efs,0) == 0) {
132  if (event_process) {
133  process_post(event_process, sdcard_inserted_event, NULL);
134  }
135  printf("SD card inserted\n");
136  } else {
137  printf("SD card insertion failed\n");
138  }
139  }
140  } else {
141  if (sdcard_efs.myCard.sectorCount != 0) {
142  /* Card removed */
143  fs_umount(&sdcard_efs.myFs);
144  sdcard_efs.myCard.sectorCount = 0;
145  if (event_process) {
146  process_post(event_process, sdcard_removed_event, NULL);
147  }
148  printf("SD card removed\n");
149  }
150  }
151 
153  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT ||
154  ev == PROCESS_EVENT_TIMER);
155  if (ev == PROCESS_EVENT_EXIT) break;
156  if (!(*AT91C_PIOA_PDSR & AT91C_PA20_IRQ0)) {
157  /* Wait for card to be preperly inserted */
159  PROCESS_WAIT_EVENT_UNTIL(ev== PROCESS_EVENT_TIMER);
160  }
161 
162  }
163  PROCESS_END();
164 }
165 
166 FileSystem *
167 efs_sdcard_get_fs()
168 {
169  efs_sdcard_init();
170  return &sdcard_efs.myFs;
171 }
172 
173 void
174 efs_sdcard_init()
175 {
176  static int initialized = 0;
177  if (!initialized) {
178  sdcard_inserted_event = process_alloc_event();
179  sdcard_removed_event = process_alloc_event();
180  process_start(&sdcard_process, NULL);
181  initialized = 1;
182  }
183 }
184 
185 int
186 sdcard_ready()
187 {
188  return sdcard_efs.myCard.sectorCount > 0;
189 }
190 
191 void
192 sdcard_event_process(struct process *p)
193 {
194  event_process = p;
195 }