Forum: Mikrocontroller und Digitale Elektronik elm-chan SDHC Anbindungsmöglichkeiten HW SW


von .. (Gast)


Lesenswert?

Hi
neben eigenen Ansätze versuche ich z.Zt. auch verschiedene andere zur SD 
Card Anbindung. Bei elm-chan werde ich auf die schnelle nicht fündig, ob 
es sich als reines SPI Software Model oder reines Hardware Model oder 
auch für beides nutzen lässt.
Bin mir sicher, dass es sich in einem CFG File einstellen lässt.
Weiss jemand wo?

http://elm-chan.org/docs/mmc/mmc_e.html

von Falk B. (falk)


Lesenswert?

@ .. (Gast)

>Card Anbindung. Bei elm-chan werde ich auf die schnelle nicht fündig, ob
>es sich als reines SPI Software Model oder reines Hardware Model oder
>auch für beides nutzen lässt.

Beides

>Bin mir sicher, dass es sich in einem CFG File einstellen lässt.
>Weiss jemand wo?

>http://elm-chan.org/docs/mmc/mmc_e.html

Hier gar nicht. Lad dir die Beispiele runter, dort ist eine 
narrensichere Version mit Soft-SPI dabei.

http://elm-chan.org/fsw/ff/00index_e.html

http://elm-chan.org/fsw/ff/ffsample.zip

von .. (Gast)


Lesenswert?

1
/-------------------------------------------------------------------------*/
2
3
4
#include "diskio.h"    /* Common include file for FatFs and disk I/O layer */
5
6
7
/*-------------------------------------------------------------------------*/
8
/* Platform dependent macros and functions needed to be modified           */
9
/*-------------------------------------------------------------------------*/
10
11
#include <avr/io.h>      /* Include device specific declareation file here */
12
13
14
#define DO_INIT()          /* Initialize port for MMC DO as input */
15
#define DO      (PINB &  0x01)  /* Test for MMC DO ('H':true, 'L':false) */
16
17
#define DI_INIT()  DDRB  |= 0x02  /* Initialize port for MMC DI as output */
18
#define DI_H()    PORTB |= 0x02  /* Set MMC DI "high" */
19
#define DI_L()    PORTB &= 0xFD  /* Set MMC DI "low" */
20
21
#define CK_INIT()  DDRB  |= 0x04  /* Initialize port for MMC SCLK as output */
22
#define CK_H()    PORTB |= 0x04  /* Set MMC SCLK "high" */
23
#define  CK_L()    PORTB &= 0xFB  /* Set MMC SCLK "low" */
24
25
#define CS_INIT()  DDRB  |= 0x08  /* Initialize port for MMC CS as output */
26
#define  CS_H()    PORTB |= 0x08  /* Set MMC CS "high" */
27
#define CS_L()    PORTB &= 0xF7  /* Set MMC CS "low" */
28
29
30
static
31
void dly_us (UINT n)  /* Delay n microseconds (avr-gcc -Os) */
32
{
33
  do {
34
    PINB;
35
#if F_CPU >= 6000000
36
    PINB;
37
#endif
38
#if F_CPU >= 7000000
39
    PINB;
40
#endif
41
#if F_CPU >= 8000000
42
    PINB;
43
#endif
44
#if F_CPU >= 9000000
45
    PINB;
46
#endif
47
#if F_CPU >= 10000000
48
    PINB;
49
#endif
50
#if F_CPU >= 12000000
51
    PINB; PINB;
52
#endif
53
#if F_CPU >= 14000000
54
#error Too fast clock
55
#endif
56
  } while (--n);
57
}



Das Generic Beispiel bezieht sich auf einen AVR.
Bevor ich das versuche umzuschreiben, habe ich ein paar Fragen:

Was bedeutet das (PINB) :
1
..
2
#if F_CPU >= 10000000
3
    PINB;
4
#endif
5
6
#if F_CPU >= 12000000
7
    PINB; PINB;
8
#endif

Was geschieht durch "PINB" ?


Ich habe angefangen, es so umzuschreiben:
1
/-------------------------------------------------------------------------*/
2
3
4
// Versuche es für den ESP8266 umzuschreiben:
5
#include "osapi.h"
6
7
8
#include "diskio.h"    /* Common include file for FatFs and disk I/O layer */
9
10
11
/*-------------------------------------------------------------------------*/
12
/* Platform dependent macros and functions needed to be modified           */
13
/*-------------------------------------------------------------------------*/
14
15
// wird hier nicht benötigt
16
// #include <avr/io.h>      /* Include device specific declareation file here */
17
18
// ESP8266 Device Specific haben wir hier: 
19
#include "ets_sys.h"
20
21
// und GPIO wird gebraucht
22
#include "gpio.h"
23
24
/* das wird mein Wire Plan:
25
26
 GPIO13 MISO = DO
27
 GPIO12 MOSI = MMC DI
28
 GPIO05 CLK  = CLK
29
 GPIO16 CS   = CS
30
31
32
*/
33
34
35
// MISO ( GPIO13 )
36
37
// Bestand
38
// #define DO_INIT()          /* Initialize port for MMC DO as input */
39
40
// geändert in 
41
   #define DO_INIT()      {PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); PIN_PULLDWN_DIS(PERIPHS_IO_MUX_MTCK_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 1);}
42
43
// Bestand
44
// #define DO      (PINB &  0x01)  /* Test for MMC DO ('H':true, 'L':false) */
45
46
// geändert in
47
   #define DO      ((GPIO_INPUT_GET(13) & 0x01))
48
49
50
// MOSI ( GPIO 12 ) 
51
52
// Bestand
53
// #define DI_INIT()    DDRB  |= 0x02  /* Initialize port for MMC DI as output */
54
// geändert in 
55
   #define DI_INIT()    { PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); PIN_PULLDWN_DIS(PERIPHS_IO_MUX_MTDI_U);PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);}
56
57
// Bestand
58
// #define DI_H()    PORTB |= 0x02  /* Set MMC DI "high" */
59
// geändert in 
60
   #define DI_H()    GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1) // GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 0);} 
61
62
// Bestand
63
// #define DI_L()    PORTB &= 0xFD  /* Set MMC DI "low" */
64
// geändert in 
65
   #define DI_L()    GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0) // GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 1); gpio16_output_set(0); GPIO_OUTPUT_SET(GPIO_ID_PIN(5), 0);}
66
67
68
// Bestand     
69
// CLK ( GPIO 5 )
70
// #define CK_INIT()  DDRB  |= 0x04  /* Initialize port for MMC SCLK as output */
71
72
// geändert in 
73
   #define CK_INIT()    {PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO5_U); PIN_PULLDWN_DIS(PERIPHS_IO_MUX_GPIO5_U);PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5);}
74
// Bestand
75
// #define CK_H()    PORTB |= 0x04  /* Set MMC SCLK "high" */
76
// geändert in 
77
   #define CK_H()    GPIO_OUTPUT_SET(GPIO_ID_PIN(5), 1) // GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0); GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 0);}
78
// Bestand
79
// #define CK_L()    PORTB &= 0xFB  /* Set MMC SCLK "low" */
80
// geändert in
81
   #define CK_L()    GPIO_OUTPUT_SET(GPIO_ID_PIN(5), 0) // GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1); GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 1); gpio16_output_set(1);}
82
83
84
// CS ( GPIO16 )
85
// GPIO16 is "bit special", check gpio16.c
86
// Bestand
87
// #define CS_INIT()  DDRB  |= 0x08  /* Initialize port for MMC CS as output */
88
// geändert in 
89
   #define CS_INIT()  gpio16_output_conf()
90
// Bestand
91
// #define CS_H()    PORTB |= 0x08  /* Set MMC CS "high" */
92
// geändert in 
93
   #define CS_H()    gpio16_output_set(1) //  GPIO_OUTPUT_SET(GPIO_ID_PIN(5), 0); GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0); GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 0);}
94
// Bestand
95
// #define CS_L()    PORTB &= 0xF7  /* Set MMC CS "low" */
96
// geändert in   
97
   #define CS_L()    gpio16_output_set(0) //  GPIO_OUTPUT_SET(GPIO_ID_PIN(5), 1); GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1); GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 1);}
98
99
100
101
102
static
103
void dly_us (UINT n)  /* Delay n microseconds (avr-gcc -Os) */
104
{
105
  do {
106
//  if (n >= 10000) os_delay_us(10);
107
//  else 
108
// kurz und schmerzlos:
109
110
  os_delay_us(1);
111
112
    // Gedanke war quatsch..        
113
    //PINB;
114
    // 80MHz / 12 MHz = 7 ( 7 X 2 ) 
115
    //PINB;PINB;PINB;PINB;PINB;PINB;PINB;PINB;PINB;PINB;PINB;PINB;PINB;PINB;
116
    
117
/*
118
#if F_CPU >= 6000000
119
    PINB;
120
#endif
121
#if F_CPU >= 7000000
122
    PINB;
123
#endif
124
#if F_CPU >= 8000000
125
    PINB;
126
#endif
127
#if F_CPU >= 9000000
128
    PINB;
129
#endif
130
#if F_CPU >= 10000000
131
    PINB;
132
#endif
133
#if F_CPU >= 12000000
134
    PINB; PINB;
135
#endif
136
#if F_CPU >= 14000000
137
#error Too fast clock
138
#endif
139
*/    
140
    
141
  } while (--n);
142
}

Nachfolgend habe ich einige Debug Meldungen eingebaut
um den Status zu verfolgen, das läuft soweit das es:

a) die SDHC ( 16GB ) in den IDLE bringt
b) die SDHC antwortet dass es eine 2.7 - 3.6 V card ist

1
/*--------------------------------------------------------------------------
2
3
   Module Private Functions
4
5
---------------------------------------------------------------------------*/
6
7
/* MMC/SD command (SPI mode) */
8
#define CMD0  (0)      /* GO_IDLE_STATE */
9
#define CMD1  (1)      /* SEND_OP_COND */
10
#define  ACMD41  (0x80+41)  /* SEND_OP_COND (SDC) */
11
#define CMD8  (8)      /* SEND_IF_COND */
12
#define CMD9  (9)      /* SEND_CSD */
13
#define CMD10  (10)    /* SEND_CID */
14
#define CMD12  (12)    /* STOP_TRANSMISSION */
15
#define CMD13  (13)    /* SEND_STATUS */
16
#define ACMD13  (0x80+13)  /* SD_STATUS (SDC) */
17
#define CMD16  (16)    /* SET_BLOCKLEN */
18
#define CMD17  (17)    /* READ_SINGLE_BLOCK */
19
#define CMD18  (18)    /* READ_MULTIPLE_BLOCK */
20
#define CMD23  (23)    /* SET_BLOCK_COUNT */
21
#define  ACMD23  (0x80+23)  /* SET_WR_BLK_ERASE_COUNT (SDC) */
22
#define CMD24  (24)    /* WRITE_BLOCK */
23
#define CMD25  (25)    /* WRITE_MULTIPLE_BLOCK */
24
#define CMD32  (32)    /* ERASE_ER_BLK_START */
25
#define CMD33  (33)    /* ERASE_ER_BLK_END */
26
#define CMD38  (38)    /* ERASE */
27
#define CMD55  (55)    /* APP_CMD */
28
#define CMD58  (58)    /* READ_OCR */
29
30
31
static
32
DSTATUS Stat = STA_NOINIT;  /* Disk status */
33
34
static
35
BYTE CardType;      /* b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing */
36
37
38
39
/*-----------------------------------------------------------------------*/
40
/* Transmit bytes to the card (bitbanging)                               */
41
/*-----------------------------------------------------------------------*/
42
43
static
44
void ICACHE_FLASH_ATTR xmit_mmc (
45
  const BYTE* buff,  /* Data to be sent */
46
  UINT bc        /* Number of bytes to send */
47
)
48
{
49
  uart0_sendStr("global Debug: Transmit bytes to card \r\n");
50
  BYTE d;
51
52
53
  do {
54
    d = *buff++;  /* Get a byte to be sent */
55
    if (d & 0x80)DI_H() ;else DI_L();  /* bit7 */
56
    CK_H(); CK_L();
57
    if (d & 0x40)DI_H() ;else DI_L();   /* bit6 */
58
    CK_H(); CK_L();
59
    if (d & 0x20) DI_H() ; else DI_L();  /* bit5 */
60
    CK_H(); CK_L();
61
    if (d & 0x10) DI_H() ;else DI_L();  /* bit4 */
62
    CK_H(); CK_L();
63
    if (d & 0x08) DI_H() ;else DI_L();  /* bit3 */
64
    CK_H(); CK_L();
65
    if (d & 0x04) DI_H(); else DI_L();  /* bit2 */
66
    CK_H(); CK_L();
67
    if (d & 0x02) DI_H(); else DI_L();  /* bit1 */
68
    CK_H(); CK_L();
69
    if (d & 0x01) DI_H(); else DI_L();  /* bit0 */
70
    CK_H(); CK_L();
71
  } while (--bc);
72
}
73
74
75
76
/*-----------------------------------------------------------------------*/
77
/* Receive bytes from the card (bitbanging)                              */
78
/*-----------------------------------------------------------------------*/
79
80
static
81
void ICACHE_FLASH_ATTR rcvr_mmc (
82
  BYTE *buff,  /* Pointer to read buffer */
83
  UINT bc    /* Number of bytes to receive */
84
)
85
{
86
  BYTE r;
87
88
  uart0_sendStr("global Debug: Receive bytes from card \r\n");
89
  DI_H();  /* Send 0xFF */
90
91
  do {
92
    r = 0;   if (DO) r++;  /* bit7 */
93
    CK_H(); CK_L();
94
    r <<= 1; if (DO) r++;  /* bit6 */
95
    CK_H(); CK_L();
96
    r <<= 1; if (DO) r++;  /* bit5 */
97
    CK_H(); CK_L();
98
    r <<= 1; if (DO) r++;  /* bit4 */
99
    CK_H(); CK_L();
100
    r <<= 1; if (DO) r++;  /* bit3 */
101
    CK_H(); CK_L();
102
    r <<= 1; if (DO) r++;  /* bit2 */
103
    CK_H(); CK_L();
104
    r <<= 1; if (DO) r++;  /* bit1 */
105
    CK_H(); CK_L();
106
    r <<= 1; if (DO) r++;  /* bit0 */
107
    CK_H(); CK_L();
108
    *buff++ = r;      /* Store a received byte */
109
  } while (--bc);
110
}
111
112
113
114
/*-----------------------------------------------------------------------*/
115
/* Wait for card ready                                                   */
116
/*-----------------------------------------------------------------------*/
117
118
static
119
int ICACHE_FLASH_ATTR wait_ready (void)  /* 1:OK, 0:Timeout */
120
{
121
  BYTE d;
122
  UINT tmr;
123
124
  uart0_sendStr("global Debug: Wait for card ready \r\n");
125
  for (tmr = 5000; tmr; tmr--) {  /* Wait for ready in timeout of 500ms */
126
    rcvr_mmc(&d, 1);
127
    if (d == 0xFF) break;
128
    dly_us(100);
129
  }
130
131
  return tmr ? 1 : 0;
132
}
133
134
135
136
/*-----------------------------------------------------------------------*/
137
/* Deselect the card and release SPI bus                                 */
138
/*-----------------------------------------------------------------------*/
139
140
static
141
void ICACHE_FLASH_ATTR deselect (void)
142
{
143
  uart0_sendStr("global Debug: deselect bus free \r\n");
144
#ifdef DEBI
145
  uart0_sendStr("Debug: deselect \r\n");
146
#endif
147
  BYTE d;
148
149
  CS_H();        /* Set CS# high */
150
  rcvr_mmc(&d, 1);  /* Dummy clock (force DO hi-z for multiple slave SPI) */
151
}
152
153
154
155
/*-----------------------------------------------------------------------*/
156
/* Select the card and wait for ready                                    */
157
/*-----------------------------------------------------------------------*/
158
159
static
160
int ICACHE_FLASH_ATTR select (void)  /* 1:OK, 0:Timeout */
161
{
162
  uart0_sendStr("Global Debug: select and wait for ready \r\n");
163
#ifdef DEBI
164
  uart0_sendStr("Debug: select \r\n");
165
#endif
166
167
  BYTE d;
168
169
  CS_L();        /* Set CS# low */
170
  rcvr_mmc(&d, 1);  /* Dummy clock (force DO enabled) */
171
  if (wait_ready()) return 1;  /* Wait for card ready */
172
173
  deselect();
174
  return 0;      /* Failed */
175
}
176
177
178
179
/*-----------------------------------------------------------------------*/
180
/* Receive a data packet from the card                                   */
181
/*-----------------------------------------------------------------------*/
182
183
static
184
int ICACHE_FLASH_ATTR rcvr_datablock (  /* 1:OK, 0:Failed */
185
  BYTE *buff,      /* Data buffer to store received data */
186
  UINT btr      /* Byte count */
187
)
188
{
189
  BYTE d[2];
190
  UINT tmr;
191
192
  uart0_sendStr("global Debug: Receive a data packet from card \r\n");
193
  for (tmr = 1000; tmr; tmr--) {  /* Wait for data packet in timeout of 100ms */
194
    rcvr_mmc(d, 1);
195
    if (d[0] != 0xFF) break;
196
    dly_us(100);
197
  }
198
  if (d[0] != 0xFE) return 0;    /* If not valid data token, return with error */
199
200
  rcvr_mmc(buff, btr);      /* Receive the data block into buffer */
201
  rcvr_mmc(d, 2);          /* Discard CRC */
202
203
  return 1;            /* Return with success */
204
}
205
206
207
208
/*-----------------------------------------------------------------------*/
209
/* Send a data packet to the card                                        */
210
/*-----------------------------------------------------------------------*/
211
212
static
213
int ICACHE_FLASH_ATTR xmit_datablock (  /* 1:OK, 0:Failed */
214
  const BYTE *buff,  /* 512 byte data block to be transmitted */
215
  BYTE token      /* Data/Stop token */
216
)
217
{
218
  uart0_sendStr("Debug: Send Data Packet to the Card \r\n");
219
  BYTE d[2];
220
221
222
  if (!wait_ready()) return 0;
223
224
  d[0] = token;
225
  xmit_mmc(d, 1);        /* Xmit a token */
226
  if (token != 0xFD) {    /* Is it data token? */
227
    xmit_mmc(buff, 512);  /* Xmit the 512 byte data block to MMC */
228
    rcvr_mmc(d, 2);      /* Xmit dummy CRC (0xFF,0xFF) */
229
    rcvr_mmc(d, 1);      /* Receive data response */
230
    if ((d[0] & 0x1F) != 0x05)  /* If not accepted, return with error */
231
      return 0;
232
  }
233
234
  return 1;
235
}
236
237
238
239
/*-----------------------------------------------------------------------*/
240
/* Send a command packet to the card                                     */
241
/*-----------------------------------------------------------------------*/
242
243
static
244
BYTE ICACHE_FLASH_ATTR send_cmd (    /* Returns command response (bit7==1:Send failed)*/
245
  BYTE cmd,    /* Command byte */
246
  DWORD arg    /* Argument */
247
)
248
{
249
  if ((GPIO_INPUT_GET(13) & 0x01)) uart0_sendStr("MISO: TRUE(1)\r\n"); else uart0_sendStr("MISO: FALSE(0)\r\n");
250
  
251
  uart0_sendStr("Debug: Send Command Packet to the card \r\n");
252
  BYTE n, d, buf[6];
253
254
255
  if (cmd & 0x80) {  /* ACMD<n> is the command sequense of CMD55-CMD<n> */
256
    cmd &= 0x7F;
257
    n = send_cmd(CMD55, 0);
258
    if (n > 1) return n;
259
  }
260
261
  /* Select the card and wait for ready except to stop multiple block read */
262
  if (cmd != CMD12) {
263
    deselect();
264
    if (!select()) return 0xFF;
265
  }
266
267
  /* Send a command packet */
268
  buf[0] = 0x40 | cmd;      /* Start + Command index */
269
  buf[1] = (BYTE)(arg >> 24);    /* Argument[31..24] */
270
  buf[2] = (BYTE)(arg >> 16);    /* Argument[23..16] */
271
  buf[3] = (BYTE)(arg >> 8);    /* Argument[15..8] */
272
  buf[4] = (BYTE)arg;        /* Argument[7..0] */
273
  n = 0x01;            /* Dummy CRC + Stop */
274
  if (cmd == CMD0) n = 0x95;    /* (valid CRC for CMD0(0)) */
275
  if (cmd == CMD8) n = 0x87;    /* (valid CRC for CMD8(0x1AA)) */
276
  buf[5] = n;
277
  xmit_mmc(buf, 6);
278
279
  /* Receive command response */
280
  if (cmd == CMD12) rcvr_mmc(&d, 1);  /* Skip a stuff byte when stop reading */
281
  n = 10;                /* Wait for a valid response in timeout of 10 attempts */
282
  do
283
    rcvr_mmc(&d, 1);
284
  while ((d & 0x80) && --n);
285
286
  return d;      /* Return with the response value */
287
}
288
289
290
291
/*--------------------------------------------------------------------------
292
293
   Public Functions
294
295
---------------------------------------------------------------------------*/
296
297
298
/*-----------------------------------------------------------------------*/
299
/* Get Disk Status                                                       */
300
/*-----------------------------------------------------------------------*/
301
302
DSTATUS ICACHE_FLASH_ATTR disk_status (
303
  BYTE drv      /* Drive number (always 0) */
304
)
305
{
306
  if (drv) return STA_NOINIT;
307
308
  return Stat;
309
}
310
311
312
313
/*-----------------------------------------------------------------------*/
314
/* Initialize Disk Drive                                                 */
315
/*-----------------------------------------------------------------------*/
316
317
DSTATUS ICACHE_FLASH_ATTR disk_initialize (
318
  BYTE drv    /* Physical drive nmuber (0) */
319
)
320
{
321
  uart0_sendStr("Debug: disk init \r\n");
322
  BYTE n, ty, cmd, buf[4];
323
  UINT tmr;
324
  DSTATUS s;
325
326
327
  if (drv) return RES_NOTRDY;
328
  uart0_sendStr("Debug: disk init delay 1 \r\n");
329
  
330
//  1 * 1000 * 1000 = 1 sec
331
//    1   * 1000 = 1 ms
332
//           1    = 1 us
333
  
334
  // dly_us(10000);      /* 10ms */
335
    os_delay_us(10 * 1000);
336
    
337
  uart0_sendStr("Debug: disk init delay 2 \r\n");
338
  CS_INIT(); CS_H();    /* Initialize port pin tied to CS */
339
  uart0_sendStr("Debug: CS init done \r\n");
340
  CK_INIT(); CK_L();    /* Initialize port pin tied to SCLK */
341
  uart0_sendStr("Debug: CK init done \r\n");
342
  DI_INIT();        /* Initialize port pin tied to DI */
343
  uart0_sendStr("Debug: DI init done \r\n");
344
  DO_INIT();        /* Initialize port pin tied to DO */
345
  uart0_sendStr("Debug: DO init done \r\n");
346
  uint8_t ccc[2]={0};
347
  uart0_sendStr("Debug: Try 80 dummy clocks ..\r\n");
348
  for (n = 10; n ; n--) {
349
        os_sprintf(ccc,"%i\r\n",n);
350
        uart0_sendStr(">: ");
351
        uart0_sendStr(ccc);
352
        rcvr_mmc(buf, 1);  /* Apply 80 dummy clocks and the card gets ready to receive command */
353
  }
354
355
  //  for (n = 10; n; n--) rcvr_mmc(buf, 1);  /* Apply 80 dummy clocks and the card gets ready to receive command */
356
    
357
  uart0_sendStr("Debug: 80 dummy clocks done\r\n");
358
    
359
  ty = 0;
360
  if (send_cmd(CMD0, 0) == 1) {      /* Enter Idle state */
361
    uart0_sendStr("global Debug: IDLE OK\r\n");
362
    if (send_cmd(CMD8, 0x1AA) == 1) {  /* SDv2? */
363
      rcvr_mmc(buf, 4);              /* Get trailing return value of R7 resp */
364
      if (buf[2] == 0x01 && buf[3] == 0xAA) {    /* The card can work at vdd range of 2.7-3.6V */
365
        uart0_sendStr("global Debug: Card works 2.7 - 3.6 V \r\n");
366
        for (tmr = 1000; tmr; tmr--) {      /* Wait for leaving idle state (ACMD41 with HCS bit) */
367
          if (send_cmd(ACMD41, 1UL << 30) == 0) break;
368
          dly_us(1000);
369
        }
370
        if (tmr && send_cmd(CMD58, 0) == 0) {  /* Check CCS bit in the OCR */
371
          rcvr_mmc(buf, 4);
372
          ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;  /* SDv2 */
373
        }
374
      }
375
    } else {              /* SDv1 or MMCv3 */
376
      if (send_cmd(ACMD41, 0) <= 1)   {
377
        ty = CT_SD1; cmd = ACMD41;  /* SDv1 */
378
      } else {
379
        ty = CT_MMC; cmd = CMD1;  /* MMCv3 */
380
      }
381
      for (tmr = 1000; tmr; tmr--) {      /* Wait for leaving idle state */
382
        if (send_cmd(cmd, 0) == 0) break;
383
        dly_us(1000);
384
      }
385
      if (!tmr || send_cmd(CMD16, 512) != 0)  /* Set R/W block length to 512 */
386
        ty = 0;
387
    }
388
  }
389
  CardType = ty;
390
  s = ty ? 0 : STA_NOINIT;
391
  Stat = s;
392
393
  deselect();
394
395
  return s;
396
}
397
398
399
400
/*-----------------------------------------------------------------------*/
401
/* Read Sector(s)                                                        */
402
/*-----------------------------------------------------------------------*/
403
404
DRESULT ICACHE_FLASH_ATTR disk_read (
405
  BYTE drv,      /* Physical drive nmuber (0) */
406
  BYTE *buff,      /* Pointer to the data buffer to store read data */
407
  DWORD sector,    /* Start sector number (LBA) */
408
  UINT count      /* Sector count (1..128) */
409
)
410
{
411
  uart0_sendStr("Debug: Disk read \r\n");
412
  BYTE cmd;
413
414
415
  if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
416
  if (!(CardType & CT_BLOCK)) sector *= 512;  /* Convert LBA to byte address if needed */
417
418
  cmd = count > 1 ? CMD18 : CMD17;      /*  READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
419
  if (send_cmd(cmd, sector) == 0) {
420
    do {
421
      if (!rcvr_datablock(buff, 512)) break;
422
      buff += 512;
423
    } while (--count);
424
    if (cmd == CMD18) send_cmd(CMD12, 0);  /* STOP_TRANSMISSION */
425
  }
426
  deselect();
427
428
  return count ? RES_ERROR : RES_OK;
429
}
430
431
432
433
/*-----------------------------------------------------------------------*/
434
/* Write Sector(s)                                                       */
435
/*-----------------------------------------------------------------------*/
436
437
DRESULT ICACHE_FLASH_ATTR disk_write (
438
  BYTE drv,      /* Physical drive nmuber (0) */
439
  const BYTE *buff,  /* Pointer to the data to be written */
440
  DWORD sector,    /* Start sector number (LBA) */
441
  UINT count      /* Sector count (1..128) */
442
)
443
{
444
  uart0_sendStr("Debug: Disk Write \r\n");
445
  if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
446
  if (!(CardType & CT_BLOCK)) sector *= 512;  /* Convert LBA to byte address if needed */
447
448
  if (count == 1) {  /* Single block write */
449
    if ((send_cmd(CMD24, sector) == 0)  /* WRITE_BLOCK */
450
      && xmit_datablock(buff, 0xFE))
451
      count = 0;
452
  }
453
  else {        /* Multiple block write */
454
    if (CardType & CT_SDC) send_cmd(ACMD23, count);
455
    if (send_cmd(CMD25, sector) == 0) {  /* WRITE_MULTIPLE_BLOCK */
456
      do {
457
        if (!xmit_datablock(buff, 0xFC)) break;
458
        buff += 512;
459
      } while (--count);
460
      if (!xmit_datablock(0, 0xFD))  /* STOP_TRAN token */
461
        count = 1;
462
    }
463
  }
464
  deselect();
465
466
  return count ? RES_ERROR : RES_OK;
467
}
468
469
470
/*-----------------------------------------------------------------------*/
471
/* Miscellaneous Functions                                               */
472
/*-----------------------------------------------------------------------*/
473
474
DRESULT ICACHE_FLASH_ATTR disk_ioctl (
475
  BYTE drv,    /* Physical drive nmuber (0) */
476
  BYTE ctrl,    /* Control code */
477
  void *buff    /* Buffer to send/receive control data */
478
)
479
{
480
  DRESULT res;
481
  BYTE n, csd[16];
482
  DWORD cs;
483
484
485
  if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;  /* Check if card is in the socket */
486
487
  res = RES_ERROR;
488
  switch (ctrl) {
489
    case CTRL_SYNC :    /* Make sure that no pending write process */
490
      if (select()) res = RES_OK;
491
      break;
492
493
    case GET_SECTOR_COUNT :  /* Get number of sectors on the disk (DWORD) */
494
      if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
495
        if ((csd[0] >> 6) == 1) {  /* SDC ver 2.00 */
496
          cs = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
497
          *(DWORD*)buff = cs << 10;
498
        } else {          /* SDC ver 1.XX or MMC */
499
          n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
500
          cs = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
501
          *(DWORD*)buff = cs << (n - 9);
502
        }
503
        res = RES_OK;
504
      }
505
      break;
506
507
    case GET_BLOCK_SIZE :  /* Get erase block size in unit of sector (DWORD) */
508
      *(DWORD*)buff = 128;
509
      res = RES_OK;
510
      break;
511
512
    default:
513
      res = RES_PARERR;
514
  }
515
516
  deselect();
517
518
  return res;
519
}


Den Versuch ( Auszug user_main.c ) , ein File anzulegen, darauf zu 
schreiben will nicht klappen
1
UINT bw;
2
     uint8_t what;
3
     uint8_t www[10] = {0};
4
     uart0_sendStr("global Debug: Try f_mount\r\n");
5
     
6
     what = f_mount(&FatFs, "", 0); // "", 0;    // Give a work area to the default drive 
7
     os_sprintf(www,"Mount: %i\r\n", what);
8
     uart0_sendStr(www);   
9
         
10
           
11
        uart0_sendStr("global Debug: Try f_open \r\n");
12
       if (f_open(&Fil, "newfile.txt", FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) {  //  Create a file 
13
       
14
         uart0_sendStr("global Debug: Try f_write \r\n");
15
         f_write(&Fil, "It works!\r\n", 11, &bw);  // Write data to the file 
16
         
17
         uart0_sendStr("global Debug: Try f_close \r\n");
18
         f_close(&Fil);                // Close the file 
19
20
     
21
     // led brauche ich noch keine..
22
       //*  if (bw == 11) {    // Lights green LED if data written well 
23
           // DDRB |= 0x10; PORTB |= 0x10;  /* Set PB4 high 
24
           // GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 0);
25
         }
26
    //*   }
27
    for (;;);



Ich denke, dass 80 MHz (80 000 000 ) zu schnell für Bit Banged ist, was 
meint ihr?

von .. (Gast)


Angehängte Dateien:

Lesenswert?

Anbei SDHC -
an der Wire Technik kann es normal nicht liegen, gleiches funktioniert 
mit anderen Ansätzen einwandfrei. Wäre schön wenn "Elm Chan" Ansatz noch 
klappen würde.

von Leo C. (rapid)


Lesenswert?

.. schrieb:
> Was geschieht durch "PINB" ?
1
$ echo '#include <avr/io.h>^M PINB; /*PINB*/' | avr-gcc -mmcu=atmega8 -E -C - |grep PINB
2
/* PINB */
3
 (*(volatile uint8_t *)((0x16) + 0x20)); /*PINB*/

von .. (Gast)


Lesenswert?

Leo C. schrieb:
>
1
> /* PINB */
2
>  (*(volatile uint8_t *)((0x16) + 0x20)); /*PINB*/
3
>

Danke dir Leo für deine Mühe + Hilfe!

Ok - habe es nun hinbekommen mit dem Ansatz von 'Elm Chan'.
Beide Sachen laufen - Bit Banging / SPI Mode.
Wobei mir der SPI Mode jetzt doch besser passt für 'Elm Chan'.
Dabei sind für den ESP8266 ein paar zusätzliche Anpassungen nötig.
Halt euch auf den laufenden.

@Falk Brunner
Du scheinst ja auch Stunden damit vollbracht zu haben;
im Gegensatz zu der Meinung, die Beispiele sind sofort brauchbar,
hast du selber erst erkennen müssen, dass noch einiges umgeschrieben
werden muss - ich habe die gleiche Erfahrung heute Nacht machen müssen 
:)

Ist war das ein Grauss ( ESP bedingt ) -
aber jetzt läuft es.

;-)

von Falk B. (falk)


Lesenswert?

@ .. (Gast)

>Du scheinst ja auch Stunden damit vollbracht zu haben;

Nur beim ATXmega

>im Gegensatz zu der Meinung, die Beispiele sind sofort brauchbar,
>hast du selber erst erkennen müssen, dass noch einiges umgeschrieben
>werden muss

Da muss nichts umgeschireben werden, "nur" richtig hingeschrieben. Beim 
1. Versuch ging es sofort, dort war es ein normaler ATmega ohne 
FIFO. Der FIFO beim ATXmega (USART im SPI Mode) war das Problem, 
dazu noch ein aktiver Interrupt.

>Ist war das ein Grauss ( ESP bedingt ) -
>aber jetzt läuft es.

Der Graus lag nicht am COntroller sondern vor der Tastatur.

von .. (Gast)


Lesenswert?

Falk B. schrieb:

> Der Graus lag nicht am COntroller sondern vor der Tastatur.

Ja ich kenn das Gefühl :)

von kettenrad (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab mal diesen Ansatz umgesetzt:
http://www.esp8266.com/viewtopic.php?f=34&t=2496&sid=d4c3e3a22a4419e110f58bc7e345c505

*.jpeg Bilder im Webbrowser von der SD-Karte am esp07;

von .. (Gast)


Lesenswert?

kettenrad schrieb:
> Ich hab mal diesen Ansatz umgesetzt:
> 
http://www.esp8266.com/viewtopic.php?f=34&t=2496&sid=d4c3e3a22a4419e110f58bc7e345c505
>
> *.jpeg Bilder im Webbrowser von der SD-Karte am esp07;

yeapp super! - hi kettenrad -
mit der arduino ide und dem esphttpd wifi server?

in der unof. luna mit mit toolchain ist das projekt 'esphttpd' noch 
nicht auf sd card umgestellt so weit ich mal gesehen habe.

auch sprite hat versucht, den elm chan einzubinden und ist gescheitert; 
in einem thread schreibt er auch, dass nur unsinn gelesen wurde  - 
daher mach ich mir nichts draus, wenn es bei mir nicht gleich geklappt 
hat beim esp - auch wenn hier 1000ende andere es schon gescvhafft haben 
( avr denke ich ) - ...

ich hab elm chan jetzt für xtensa ide von der pike auf und finde, dass 
elm chan doch eine gute ausgangsbasis ist - auch der server flutet 
besser, als der esphttpd der arduino ide; sobald ich meine database für 
den esp fertig habe, poste ich das komplette projekt.

lg
;-)

von .. (Gast)


Lesenswert?


von kettenrad (Gast)


Angehängte Dateien:

Lesenswert?

Vielleicht kann jemand helfen?

Ich benutze Arduino IDE 1.6.5 mit dem Beispiel SDWebServer.
compilieren --> kein Problem;
flashen --> wunderbar;
reset ;
Monitor - ausgabe zeigt, das das Webmodul(WIFI) nicht gestartet wird.
Pin GPIO15 (auf Bord) abgezogen und den Start und die Anmeldung auf 
Router(Fritz Box) abgewartet, Gpio 15 angesteckt und die SD- Karte 
initiiert.

Dann läuft auch z.B. der Editor zum Einfügen von Dateien...

Problem:
- mit dem Hinzufügen von
const int chipSelect = 2;
und/oder dem Ändern des pins_arduino.h mit:
#if defined(ESP8266)
static const uint8_t SS    = 2;
static const uint8_t MOSI  = 13;
static const uint8_t MISO  = 12;
static const uint8_t SCK   = 14;
#else
static const uint8_t SS    = 15;
static const uint8_t MOSI  = 13;
static const uint8_t MISO  = 12;
static const uint8_t SCK   = 14;
#endif  //  (ESP8266)
ist es nicht getan;

Irgentetwas macht Sprite noch anders, --- aber was?

http://www.esp8266.com/viewtopic.php?f=34&t=2496&sid=d4c3e3a22a4419e110f58bc7e345c505

Er hat erfolgreich den CS für die SD-Karte auf GPIO5 umgebogen, aber wo 
und wie ...?

von kettenrad (Gast)


Lesenswert?

!! gelöst  !!
- statt in den unendlichen Tiefen der lowlevel Funktionen rumzufummeln, 
habe ich nun im sketch SDWebServer.ino (fast am Ende) die Zeile 
geändert:

if (SD.begin(SS)){

in

if (SD.begin(2)){

... das war's ;

von kettenrad (Gast)


Lesenswert?

-- eleganter und richtiger ist:

if (SD.begin(chipSelect)){

den weiter oben definierten "chipSelect" anzugeben ..

von .. (Gast)


Lesenswert?

..zu spät..
aber genau das wars ;-)
..

von .. (Gast)


Lesenswert?

da ja solved -
hier das base projekt:

elm chan ansatz mit dem esp8266 und (H)SPI

Beitrag "Re: IDE für ESP8266 mit vielen Example"

viel spass
;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.