Forum: Mikrocontroller und Digitale Elektronik Symbol redefined ?


von Mark M. (mom-jovi)


Lesenswert?

Ich hab hier beim Compilieren auf einen MSP430F1610 in CCE über 50 
Fehler von dieser Art:

symbol "fclose_" redefined: first defined in "./Z_fat16.obj"; redefined 
in "./main.obj"

Was ist das Problem?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mark M. schrieb:
> Was ist das Problem?
Vermutlich in deinem Sourcecode. Zeig den doch mal...

Ich würde jetzt mal über alle Projektdateien nach fclose suchen, ob da 
was zweimal definiert wurde...

von Mark M. (mom-jovi)


Lesenswert?

Die Suche nach fclose ergibt nur den Prototyp im Header und die Funktion 
im C-File:

Header:
1
extern void   fclose_(File *file);

C-File:
1
void fclose_(File *file)
2
{
3
  if(file != NULL)
4
  {
5
fflush_(file);                                    // save buffered data to the disk
6
  }
7
  FreeFilePointer(file);                                  // and free the filepointer.
8
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Linker gibt ja aus, wo das Symbol gefunden wird:

in main.obj (erzeugt aus main.c)

und in Z_fat16.obj (erzeugt aus Z_fat16.c). Wenn Du so eine Datei gar 
nicht in Deinem Projekt hast, dann wird Z_fat16.obj in einer von Dir 
gelinkten Library stecken.

Oder hast Du zufälligerweise ein #include "dateiname.c" irgendwo 
verwendet?

von Mark M. (mom-jovi)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Oder hast Du zufälligerweise ein #include "dateiname.c" irgendwo
> verwendet?

Ja, ich glaub da lag das Problem. Wenn ich den Header anstatt dem C-File 
inkludiere, verschwinden die Fehler.

Jetzt heißt es nur noch "unresolved symbol L_LSL_19, first referenced in 
./Z_sdc.obj"
Die obj-Datei besteht aber hauptsächlich aus Vierecken anstatt 
Buchstaben.

von Karl H. (kbuchegg)


Lesenswert?

Mark M. schrieb:

> Ja, ich glaub da lag das Problem. Wenn ich den Header anstatt dem C-File
> inkludiere, verschwinden die Fehler.

Man inkludiert niemals *.c Dateien!

Alle *.c Dateien, die gemeinsam ein Programm ergeben werden, werden 
getrennt compiliert. Jede für sich. Aus jeder *.c Datei entsteht eine 
(normalerweise) gleichnamige *.obj Datei.
Und all diese einzelnen *.obj Dateien werden (zusammen mit 
möglicherweise anderen Libraries) vom Linker zum eigentlichen Programm 
zusammengelinkt. Erst dann hat mein sein fertiges ausführbares Programm.

> Jetzt heißt es nur noch "unresolved symbol L_LSL_19, first referenced in
> ./Z_sdc.obj"
> Die obj-Datei besteht aber hauptsächlich aus Vierecken anstatt
> Buchstaben.

Auch das ist normal.
Aber die Datei Z_sdc.obj ist ja nicht einfach so auf einem Baum 
gewachsen sondern ist entstanden indem ein C-Source Code compiliert 
wurde. Und der wiederrum steht in einer Datei, die höchst wahrscheinlich 
Z_sdc.c heißt

von Mark M. (mom-jovi)


Lesenswert?

Ok danke erstmal, das erklärt einiges :)
Aber L_LSL_19 gibt es nicht in Z_sdc.c und auch in keiner anderen Datei.

Es handelt sich um ein FAT System für microSD, das für AVR-Controller 
implementiert ist, und ich für MSP modifiziert habe. Könnte L_LSL_19 
dann evtl. was mit AVR zu tun haben? Aber ich hab ja nichts 
AVR-spezifisches inkludiert.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mark M. schrieb:
> Aber L_LSL_19 gibt es nicht in Z_sdc.c
Dann untersuch mal die in Z_sdc.c eingebundenen Header...

Hier kann dir so keiner weiterhelfen, weil ja keiner deinen Code hat. 
Da mußt du schon selber suchen...

von Mark M. (mom-jovi)


Lesenswert?

Ok, ich poste hier mal den betreffenden Code. Wie gesagt, ich finde 
nichts, was auf L_LSL_19 hindeutet.
Die komplette Implementierung findet man auf der angegebenen Seite.
avr/io.h habe ICH auskommentiert, weil CCE das nicht kennt. In den 
restlichen Includes ist meiner Meinung nach nichts, was kein reines C 
ist.

Ich kann mir eigentlich nur vorstellen, dass dieser Code eben irgendwas 
aus avr/io.h braucht, was dann wieder auf L_LSL_19 verweist. Aber wenn 
dem so wäre, müsste CCE doch avr/io.h kennen, sonst könnte er nicht von 
L_LSL_19 "reden"?
1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
// + Copyright (c) 2008 Stephan Busker
3
// + Nur für den privaten Gebrauch
4
// + FOR NON COMMERCIAL USE ONLY
5
// + www.Mikro-control.de
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), 
8
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. 
9
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (stephan.busker@mikro-control.de) Kontakt 
10
// + bzgl. der Nutzungsbedingungen aufzunehmen. 
11
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
13
// + Benutzung auf eigene Gefahr
14
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
15
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16
// + Redistributions of source code (with or without modifications) must retain the above copyright notice, 
17
// + this list of conditions and the following disclaimer.
18
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
19
// +     from this software without specific prior written permission.
20
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permitted 
21
// +     for non-commercial use (directly or indirectly)
22
// +     Commercial use is only permitted with our written permission
23
//
24
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
// +  POSSIBILITY OF SUCH DAMAGE. 
35
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
36
37
38
#include <stdio.h>
39
#include <string.h>
40
//#include <avr/io.h>
41
#include "Z_sdc.h"
42
#include "Z_ssc.h"
43
#include "Z_crc16.h"
44
45
46
//________________________________________________________________________________________________________________________________________
47
// Module name:      sdc.c 
48
// Compiler used:    avr-gcc 3.4.5
49
// Last Modifikation:  08.06.2008
50
// Version:        1.07
51
// Authors:        Stephan Busker, Gregor Stobrawa   
52
// Description:      Source files for connecting to an sd-card using the SSC
53
//
54
//........................................................................................................................................
55
// Functions:      SD_Result_t     SDC_init(void);
56
//            u8           SDC_PutCommand (u8 *cmd);
57
//            SD_Result_t     SDC_PutSector(u32 addr,u8 *Buffer);
58
//            SD_Result_t     SDC_GetSector(u32 addr,u8 *Buffer);
59
//
60
////........................................................................................................................................
61
// ext. functions:    extern void SSC_Init(void);
62
//            extern u8   SSC_GetChar (void);
63
//            extern void SSC_PutChar (u8);
64
//            extern void SSC_Enable(void);
65
//            extern void SSC_Disable(void);
66
//            extern void  SSC_ClearRxFifo();
67
//........................................................................................................................................
68
//
69
// URL:          www.Mikro-Control.de
70
// mailto:        stephan.busker@mikro-control.de
71
//________________________________________________________________________________________________________________________________________
72
73
74
75
#define CMD_GO_IDLE_STATE    0x00  /* CMD00: response R1 */
76
#define CMD_SEND_OP_COND    0x01   /* CMD01: response R1 */
77
#define CMD_SEND_IF_COND    0x08  /* CMD08: response R7 */
78
#define CMD_SEND_CSD      0x09  /* CMD09: response R1 */
79
#define CMD_SEND_CID      0x0A   /* CMD10: response R1 */
80
#define CMD_SEND_STATUS      0x0D  /* CMD13: response R2 */
81
#define CMD_SET_BLOCKLEN    0x10  /* CMD16: arg0[31:0]: block length, response R1*/
82
#define CMD_READ_SINGLE_BLOCK   0x11  /* CMD17: arg0[31:0]: data address, response R1 */
83
#define CMD_WRITE_SINGLE_BLOCK  0x18  /* CMD24: arg0[31:0]: data address, response R1 */
84
#define CMD_APP_CMD        0x37  /* CMD55: response R1 */
85
#define CMD_READ_OCR       0x3A   /* CMD58: response R3 */
86
#define CMD_CRC_ON_OFF       0x3B   /* CMD59: arg0[31:1]: stuff bits, arg0[0:0]: crc option, response R1 */                    
87
#define ACMD_SEND_OP_COND    0x29  /* ACMD41: arg0[31]: stuff bits, arg0[30]: HCS, arg0[29:0] stuff bits*, response R1 */
88
89
#define R1_NO_ERR         0x00
90
#define R1_IDLE_STATE       0x01
91
#define R1_ERASE_RESET       0x02
92
#define R1_ILLEGAL_CMD       0x04
93
#define R1_COM_CRC_ERR       0x08
94
#define R1_ERASE_SEQUENCE_ERR  0x10
95
#define R1_ADDRESS_ERR       0x20
96
#define R1_PARAMETER_ERR     0x40
97
#define R1_BAD_RESPONSE     0x80
98
99
#define R2_NO_ERR         0x00
100
#define R2_CARD_LOCKED       0x01
101
#define R2_ERASE_WRITE_PROT_ERR  0x02
102
#define R2_UNKOWN_ERR      0x04
103
#define R2_CARD_CTRL_ERR     0x08
104
#define R2_CARD_ECC_ERR        0x10
105
#define R2_WRITE_PROT_ERR    0x20
106
#define R2_ERASE_PARAM_ERR     0x40
107
#define R2_OUT_OF_RANGE_ERR    0x80
108
109
#define DATA_START_TOKEN     0xFE
110
#define DATA_RESPONSE_MASK     0x1F 
111
#define DATA_RESPONSE_OK     0x05
112
#define DATA_RESPONSE_CRC_ERR  0x0B
113
#define DATA_RESPONSE_WRITE_ERR 0x1D
114
115
typedef enum
116
{
117
  VER_UNKNOWN,
118
   VER_1X,
119
  VER_20
120
} SDVersion_t;
121
122
typedef struct
123
{
124
  u8 Valid;
125
  SDVersion_t Version;  // HW-Version 
126
  u32 Capacity;      // Memory capacity  in bytes
127
  u8 CID[16];      // CID register
128
  u8 CSD[16];      // CSD register
129
} /* __attribute__((packed)) */ SDCardInfo_t;
130
131
volatile SDCardInfo_t SDCardInfo;
132
133
134
135
char text[50];
136
137
138
//________________________________________________________________________________________________________________________________________
139
// Function:   CRC7(u8* cmd, u32 len);
140
// 
141
// Description:  This function calculated the CRC7 checksum used in the last byte of a spi command frame. 
142
//        
143
//
144
// Returnvalue: the function returns the crc7 including bit 0 set to 1
145
//________________________________________________________________________________________________________________________________________
146
147
u8 CRC7(u8 * cmd, u32 len)
148
{
149
  u8 i, a;
150
  u8 crc, Data;
151
152
  crc = 0; // init CRC buffer
153
  for (a = 0; a < len ;a++) // for every byte in the msg
154
  {
155
    Data = cmd[a];
156
    for (i=0;i<8;i++) // for every bit in the byte
157
    {
158
      crc <<= 1; // shift crc
159
      if ((Data & 0x80)^(crc & 0x80))  crc ^=0x09;    //xor
160
      Data <<= 1;  // shift data  for next bit
161
    }
162
  }
163
  crc = (crc<<1)|1; // set terminating bit to 1
164
  return(crc);
165
}
166
167
u8 SDC_WaitForBusy(void)
168
{
169
  u8 rsp = 0;
170
  u16 timeout=0;
171
172
  SSC_ClearRxFifo();
173
  SSC_Enable();        // enable chipselect.
174
  do  
175
  {
176
    rsp = SSC_GetChar();
177
    if(timeout++>500) break;
178
  }while(rsp != 0xFF);    // wait while card is busy (data out low)
179
  return(rsp);
180
}
181
182
183
184
//________________________________________________________________________________________________________________________________________
185
// Function:   SDC_SendCMDR1(u8 CmdNo, u32 arg);
186
// 
187
// Description:  This function send a command frame to the SD-Card in spi-mode. 
188
//        
189
//
190
// Returnvalue: The function returns the first response byte like for R1 commands
191
//________________________________________________________________________________________________________________________________________
192
u8 SDC_SendCMDR1(u8 CmdNo, u32 arg)
193
{
194
  u8 r1;
195
  u16 Timeout = 0;
196
  u16 a;
197
  u8 cmd[6];
198
199
  SSC_ClearRxFifo();  // clear the rx fifo
200
  SSC_Enable();    // enable chipselect.
201
  SDC_WaitForBusy();
202
  SSC_ClearRxFifo();  // clear the rx fifo
203
  SSC_GetChar();      // dummy to sync
204
205
  /* Send cmd10 (SEND_CID) */;
206
  cmd[0] = 0x40|CmdNo; // set command index
207
  cmd[1] = (arg & 0xFF000000)>>24;
208
  cmd[2] = (arg & 0x00FF0000)>>16;
209
  cmd[3] = (arg & 0x0000FF00)>>8;
210
     cmd[4] = (arg & 0x000000FF);
211
  cmd[5] = CRC7(cmd, 5); // update checksum 
212
  for (a = 0;a < 6; a++) // send the command sequence to the sdcard (6 bytes)
213
  {  
214
    SSC_PutChar(cmd[a]);
215
  }
216
  SSC_ClearRxFifo();  // clear the rx fifo to discard the bytes received during the transmission of the 6 command bytes
217
  do          
218
  {
219
    r1 = SSC_GetChar();       // get byte from sd-card
220
    if (Timeout++ > 500) return(r1);
221
  }while(r1 == 0xFF); // wait for the response byte from sd-card.
222
  return(r1);
223
}
224
225
226
//________________________________________________________________________________________________________________________________________
227
// Function:   SDC_SendACMDR1(u8 CmdNo, u32 arg);
228
// 
229
// Description:  This function send a application command frame to the SD-Card in spi-mode. 
230
//        
231
//
232
// Returnvalue: The function returns the first response byte like for R1 commands
233
//________________________________________________________________________________________________________________________________________
234
u8 SDC_SendACMDR1(u8 CmdNo, u32 arg)
235
{
236
    u8 r1 = 0xFF;
237
  r1 = SDC_SendCMDR1(CMD_APP_CMD, 0UL);
238
  if(r1 & R1_BAD_RESPONSE) return(r1);
239
  r1 = SDC_SendCMDR1(CmdNo, arg);
240
  return(r1);
241
}
242
243
244
//________________________________________________________________________________________________________________________________________
245
// Function:   SDC_GetData(u8 * cmd ,u8 *Buffer, u32 len);
246
// 
247
// Description:  This function sneds cmd an reads a datablock of len from the sd-card
248
//        
249
//
250
// Returnvalue: SD_Result_t
251
//________________________________________________________________________________________________________________________________________
252
253
SD_Result_t SDC_GetData(u8 CmdNo, u32 addr, u8 *Buffer, u32 len)
254
{
255
  u8 rsp;   
256
  u16 a, Crc16;
257
  SD_Result_t result = SD_ERROR_UNKNOWN;
258
259
  // send the command  
260
  rsp = SDC_SendCMDR1(CmdNo, addr);
261
  if (rsp != R1_NO_ERR) 
262
  {
263
    result = SD_ERROR_BAD_RESPONSE;
264
    goto end;
265
  }
266
  SSC_ClearRxFifo();
267
  do
268
  {
269
    rsp = SSC_GetChar();
270
    if((rsp & 0xF0) == 0x00) // data error token 
271
    {
272
      result = SD_ERROR_READ_DATA;
273
      goto end;
274
    }
275
//    if(timeout++>500) break;
276
  }while(rsp != DATA_START_TOKEN);
277
  // data start token received
278
  for (a = 0; a < len; a++)  // read the block from the SSC
279
  {
280
    Buffer[a] = SSC_GetChar();
281
  }
282
  // Read two bytes CRC16-Data checksum
283
  Crc16 = SSC_GetChar(); // highbyte fisrt  
284
  Crc16 = (Crc16<<8)|SSC_GetChar(); // lowbyte last
285
  result = SD_SUCCESS;
286
  
287
  end:
288
  return(result);
289
}
290
291
292
//________________________________________________________________________________________________________________________________________
293
// Function:   SDC_PrintCID(u8 * pCID);
294
// 
295
// Description:  This function prints the CIS register in a human readable format. 
296
//        
297
//
298
// Returnvalue: the function returns nothing
299
//________________________________________________________________________________________________________________________________________
300
301
void SDC_PrintCID(u8 * pCID)
302
{
303
/*  u8 pn[6];
304
  u16 temp1, temp2;
305
306
  sprintf(&text[0], "\r\nManufacturer ID: %i\r\n", pCID[0]);
307
  PutString(text);
308
  memcpy(pn, &pCID[1], 2);
309
  pn[2] = '\0'; // terminate string
310
  sprintf(&text[0], "Application ID: %s\r\n",pn);
311
  PutString(text);
312
  memcpy(pn, &pCID[3], 5);
313
  pn[5] = '\0'; // terminate string
314
  sprintf(&text[0], "Product Name: %s\r\n",pn);
315
  PutString(text);
316
  sprintf(&text[0], "Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
317
  PutString(text);
318
  PutString("Serial No.: ");
319
  for(temp1 = 0; temp1<4; temp1++)
320
  {
321
    sprintf(&text[0],"%02X", pCID[9+temp1]);
322
    PutString(text);
323
  }
324
  PutString("\r\n");
325
  temp1 = pCID[14] & 0x0F;    // month 
326
  temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year 
327
  sprintf(&text[0], "Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
328
  PutString(text);
329
*/
330
}
331
332
//________________________________________________________________________________________________________________________________________
333
// Funtion:   SDC_GetCID(u8 * pCID);
334
// 
335
// Description:  This function reads the CIS register form the sd card in spi mode. 
336
//        
337
//
338
// Returnvalue: the function returns error state
339
//________________________________________________________________________________________________________________________________________
340
341
SD_Result_t SDC_GetCID(u8 * pCID) 
342
{
343
  return SDC_GetData(CMD_SEND_CID, 0UL, pCID, 16);
344
}
345
346
//________________________________________________________________________________________________________________________________________
347
// Funtion:   SDC_GetCSD(u8 * pCSD);
348
// 
349
// Description:  This function reads the CSD register form the sd card in spi mode. 
350
//        
351
//
352
// Returnvalue: the function returns error state
353
//________________________________________________________________________________________________________________________________________
354
355
SD_Result_t SDC_GetCSD(u8 * pCSD) 
356
{
357
  return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
358
}
359
360
361
//________________________________________________________________________________________________________________________________________
362
// Funtion:   SDC_Init(void);
363
// 
364
// Description:  This function initialises the SDCard to spi-mode. 
365
//        
366
//
367
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
368
//________________________________________________________________________________________________________________________________________
369
370
SD_Result_t SDC_Init(void)
371
{
372
  u32 Timeout = 0;
373
  u8 rsp[6]; // SD-SPI response buffer
374
  SD_Result_t result = SD_ERROR_UNKNOWN;
375
    
376
  if(1)//CARD_DETECT)                     // init only if the SD-Switch is indicating a card in the slot
377
  {
378
    u8 c_size_mult          // (M. Mark, Micronas GmbH)
379
    u8 read_bl_len;          // (M. Mark, Micronas GmbH)
380
    u32 c_size;            // (M. Mark, Micronas GmbH)
381
      SSC_Init();
382
    SDCardInfo.Valid = 0;
383
    /* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
384
    start to supply at least 74 SD clocks to the SD card with keeping cmd line to high. In case of SPI
385
    mode, CS shall be held to high during 74 clock cycles. */
386
    SSC_Disable(); // set SD_CS high
387
    SSC_ClearRxFifo();  // clear the rx fifo
388
  
389
    for (Timeout = 0; Timeout < 15; Timeout++)   // 15*8 = 120 cycles
390
    {
391
      SSC_PutChar(0xFF);
392
    }
393
  
394
    // switch to idle state
395
    while(!(SDC_SendCMDR1(CMD_GO_IDLE_STATE, 0UL) & R1_IDLE_STATE))            
396
    {
397
      if (Timeout++ > 20)
398
      {
399
        result = SD_ERROR_RESET;
400
        goto end;                     
401
      }
402
    }
403
    rsp[0] = SDC_SendCMDR1(CMD_SEND_IF_COND, 0x000001AA);
404
    // answer to cmd58 is an R7 response (R1+ 4Byte IFCond)
405
    if(rsp[0] & R1_BAD_RESPONSE)
406
    {
407
      result = SD_ERROR_BAD_RESPONSE;
408
      goto end;
409
    } 
410
    if(rsp[0] & R1_ILLEGAL_CMD)
411
    {
412
      //Ver1.X SD Memory Card or not a SD Memory Card
413
      SDCardInfo.Version = VER_1X;      
414
    }
415
    else
416
    {
417
       // Ver2.00 or later SD Memory Card
418
       // reading the remaining bytes of the R7 response
419
       SDCardInfo.Version = VER_20;
420
       for(Timeout = 1; Timeout < 5; Timeout++)
421
       {
422
        rsp[Timeout] = SSC_GetChar();
423
       }
424
       //check pattern
425
       if(rsp[4]!= 0xAA)
426
       {
427
        result = SD_ERROR_BAD_RESPONSE;
428
        goto end;
429
       }
430
       if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
431
       {
432
        result = SD_ERROR_BAD_VOLTAGE_RANGE;
433
        goto end;    
434
       } 
435
    }
436
  
437
    rsp[0] = SDC_SendCMDR1(CMD_READ_OCR, 0UL);
438
    // answer to cmd58 is an R3 response (R1 + 4Byte OCR)
439
    if(rsp[0] & R1_BAD_RESPONSE)
440
    {
441
      result = SD_ERROR_BAD_RESPONSE;
442
      goto end;
443
    }
444
    if(rsp[0] & R1_ILLEGAL_CMD)
445
    {
446
      result = SD_ERROR_NO_SDCARD;
447
      goto end;
448
    }
449
    // read 4 bytes of OCR register
450
    for(Timeout = 1; Timeout < 5; Timeout++)
451
    {
452
      rsp[Timeout] = SSC_GetChar();
453
    }
454
    //  NavicCtrl uses 3.3 V,  therefore check for bit 20 & 21 
455
    if((rsp[2] & 0x30) != 0x30)
456
    {
457
       // supply voltage is not supported by sd-card
458
      result = SD_ERROR_BAD_VOLTAGE_RANGE;
459
      goto end; 
460
    }
461
    
462
    // Initialize the sd-card sending continously ACMD_SEND_OP_COND (only supported by SD cards)
463
//    Timeout =  SetDelay(2000); // set timeout to 2000 ms (large cards tend to longer) 
464
    do
465
    {
466
      rsp[0] = SDC_SendACMDR1(ACMD_SEND_OP_COND, 0UL);
467
      if(rsp[0] & R1_BAD_RESPONSE)
468
      {
469
        result = SD_ERROR_BAD_RESPONSE;
470
        goto end;
471
      }
472
/*      if(CheckDelay(Timeout))
473
      {
474
        result = SD_ERROR_INITIALIZE;
475
        goto end;
476
      }*/
477
    } while(rsp[0] & R1_IDLE_STATE); // loop until idle state
478
    
479
    if(rsp[0] != R1_NO_ERR)
480
    {
481
       result = SD_ERROR_INITIALIZE;
482
      goto end;   
483
    }
484
    /* set block size to 512 bytes */
485
      if(SDC_SendCMDR1(CMD_SET_BLOCKLEN, 512UL) != R1_NO_ERR)
486
      {
487
       result = SD_ERROR_SET_BLOCKLEN;
488
      goto end;
489
      }
490
491
492
//    SSC_Init_High();  // init ssc in highspeed mode.
493
494
    // read CID register
495
    result = SDC_GetCID((u8 *)&SDCardInfo.CID);
496
    if(result != SD_SUCCESS)
497
    {
498
      goto end;
499
    }
500
  
501
    // read CSD register
502
    result = SDC_GetCSD((u8 *)&SDCardInfo.CSD);
503
    if(result != SD_SUCCESS)
504
    {
505
      goto end;
506
    }
507
  
508
    // u8 c_size_mult, read_bl_len;  u8 c_size_mult, read_bl_len;  // moved variable declaration to top of function (M. Mark, Micronas GmbH)
509
    //u32 c_size; // moved variable declaration to top of function (M. Mark, Micronas GmbH)
510
  
511
    switch(SDCardInfo.CSD[0]>>6) // check CSD Version
512
    {
513
    case 0x00: // if CSD is V1.0 structure (2GB limit)
514
  
515
      /*
516
      memory capacity = BLOCKNR * BLOCK_LEN
517
      BLOCKNR = (C_SIZE+1) * MULT
518
      MULT = 2^(C_SIZE_MULT+2)
519
      BLOCK_LEN = 2^READ_BL_LEN
520
    
521
      C_SIZE      is 12 bits [73:62] in CSD register
522
      C_SIZE_MULT is  3 bits [49:47] in CSD register
523
      READ_BL_LEN is  4 bits [83:80] in CSD register
524
      */
525
  
526
      read_bl_len = (SDCardInfo.CSD[5] & 0x0F);     //CSD[05] -> [87:80]
527
      c_size = ((u32)(SDCardInfo.CSD[6] & 0x03))<<10; //CSD[06] -> [79:72]
528
      c_size |= ((u32)SDCardInfo.CSD[7])<<2;      //CSD[07] -> [71:64]
529
      c_size |= (u32)(SDCardInfo.CSD[8]>>6);      //CSD[08] -> [63:56]
530
      c_size_mult = (SDCardInfo.CSD[9] & 0x03)<<1;    //CSD[09] -> [55:48]
531
      c_size_mult |=(SDCardInfo.CSD[10] & 0x80)>>7;  //CSD[10] -> [47:40]
532
      SDCardInfo.Capacity = (u32)(c_size+1)*(1L<<(c_size_mult+2))*(1L<<read_bl_len);
533
      break;
534
  
535
    case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB) 
536
  
537
      /*
538
      memory capacity = (C_SIZE+1) * 512K byte
539
      C_SIZE is 22 bits [69:48] in CSR register 
540
      */
541
  
542
      c_size = ((u32)(SDCardInfo.CSD[7] & 0x3F))<<16;  //CSD[07] -> [71:64]
543
      c_size |= ((u32)SDCardInfo.CSD[8])<<8;      //CSD[08] -> [63:56]
544
      c_size |= (u32)SDCardInfo.CSD[9];          //CSD[09] -> [55:48];
545
       SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
546
      break;
547
  
548
    default: //unknown CSD Version
549
      SDCardInfo.Capacity = 0;
550
      break;  
551
    }
552
  
553
/*    switch(SDCardInfo.Version)
554
    {
555
       case VER_1X:
556
        SerialPutString("  SD-CARD V1.x");
557
        break;
558
         case VER_20:
559
        SerialPutString("  SD-CARD V2.0 or later"); 
560
       default:
561
         break;
562
    }
563
*/
564
//    u16 mb_size = (u16)(SDCardInfo.Capacity/(1024L*1024L));  
565
//    s8 text[40];
566
//    sprintf(text,"\r\nsize: %d",mb_size);
567
//    PutString(text);
568
//    SDC_PrintCID((u8 *)&SDCardInfo.CID);
569
    SDCardInfo.Valid = 1;
570
      
571
    // jump point for error  condition before
572
    end:
573
    SSC_Disable();
574
  }
575
  else
576
  {
577
    SDCardInfo.Valid = 0;
578
    result = SD_ERROR_NOCARD;
579
  }
580
581
  return(result);
582
}
583
584
585
//________________________________________________________________________________________________________________________________________
586
// Funtion:   SDC_PutSector(void);
587
// 
588
// Description:  This function writes one sector of data to the SSC 
589
//        
590
//
591
// Returnvalue: SD_Result_t
592
//________________________________________________________________________________________________________________________________________
593
594
SD_Result_t SDC_PutSector(u32 addr, const u8 *Buffer)
595
{
596
  u8 rsp; 
597
  
598
  u16 timeout = 0;
599
  u16 a, Crc16;
600
  //u32 Timeout = 0;
601
  SD_Result_t result = SD_ERROR_UNKNOWN;
602
603
  addr = addr << 9; // convert sectoradress to byteadress
604
  rsp = SDC_SendCMDR1(CMD_WRITE_SINGLE_BLOCK, addr);
605
  if (rsp != R1_NO_ERR)
606
  {
607
    result = SD_ERROR_BAD_RESPONSE;
608
    goto end;
609
  }
610
  SSC_ClearRxFifo();    
611
  for (a=0;a<20;a++)          // at least one byte
612
  {
613
    SSC_GetChar();
614
  }
615
  Crc16 = CRC16(Buffer, 512);         // calc checksum for data block
616
  SSC_PutChar(DATA_START_TOKEN);    // send data start of header to the SSC  
617
  
618
  for (a=0;a<512;a++)          // transmit one sector (normaly 512bytes) of data to the sdcard.
619
  {
620
    SSC_PutChar(Buffer[a]);
621
  }
622
  // write two bytes of crc16 to the sdcard
623
  SSC_PutChar((u8)(Crc16>>8));     // write high byte first
624
  SSC_PutChar((u8)(0x00FF&Crc16));   // lowbyte last
625
  SSC_ClearRxFifo();
626
  do                    // wait for data response token
627
  {
628
     rsp = SSC_GetChar();
629
    if(timeout++>500) break;
630
  }while((rsp & 0x11) != 0x01 );
631
  // analyse data response token
632
  switch(rsp & DATA_RESPONSE_MASK)
633
  {
634
    case DATA_RESPONSE_OK:
635
      result = SD_SUCCESS;
636
      break;
637
    case DATA_RESPONSE_CRC_ERR:
638
      result = SD_ERROR_CRC_DATA;
639
      goto end;
640
      break;
641
    case DATA_RESPONSE_WRITE_ERR:
642
      result = SD_ERROR_WRITE_DATA;
643
      goto end;
644
      break;
645
    default:
646
      result = SD_ERROR_UNKNOWN;
647
      goto end;
648
      break;
649
650
  }
651
  // wait until the sdcard is busy.
652
  rsp = SDC_WaitForBusy();
653
  if(rsp != 0xFF)
654
  {
655
     result =  SD_ERROR_TIMEOUT;
656
     goto end;
657
  }
658
  // check card status
659
  rsp = SDC_SendCMDR1(CMD_SEND_STATUS, 0);
660
  if(rsp != R1_NO_ERR)
661
  {
662
    result =  SD_ERROR_BAD_RESPONSE;
663
    SSC_GetChar();
664
     goto end;
665
  }
666
  // 2nd byte of r2 response
667
  rsp = SSC_GetChar();
668
  if(rsp != R2_NO_ERR)
669
  {
670
    result =  SD_ERROR_WRITE_DATA;
671
    SSC_GetChar();
672
     goto end;
673
  }
674
  end:
675
  SSC_Disable();            // disable sdcard. WAR AUSKOMMENTIERT!
676
  return(result);
677
} 
678
679
680
//________________________________________________________________________________________________________________________________________
681
// Funtion:   SDC_GetSector(u32 addr,u8 *Buffer);
682
// 
683
// Description:  This function reads one sector of data from the SSC
684
//        
685
//
686
// Returnvalue: SD_Result_t
687
//________________________________________________________________________________________________________________________________________
688
689
SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer)
690
{
691
  addr = addr << 9; // convert sectoradress to byteadress
692
  return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
693
}

von Karl H. (kbuchegg)


Lesenswert?

Was ist mit denen hier?
1
#include "Z_sdc.h"
2
#include "Z_ssc.h"
3
#include "Z_crc16.h"

eventuell in einem der Header?

> Ich kann mir eigentlich nur vorstellen, dass dieser Code eben
> irgendwas aus avr/io.h braucht, was dann wieder auf L_LSL_19 verweist

L_LSL_19 erinnert mich an nichts, was auf einem AVR vorkommt.

Hast du kein Werkzeug, mit dem du alle Dateien (*.c, *.h) auf einem 
bestimmten Verzeichnis nach einem String durchsuchen lassen kannst?


> Aber wenn dem so wäre, müsste CCE doch avr/io.h kennen, sonst könnte
> er nicht von L_LSL_19 "reden"?

Das ist eine Fehlermeldung vom Linker. Der interessiert sich nicht für 
*.c oder *.h Files.

In Z_sdc.obj kommt dieses Symbol vor. Wie dieses Symbol beim Compilieren 
da rein gekommen ist, über welche Include Files, ist dem Linker 
schnuppe.

von Mark M. (mom-jovi)


Lesenswert?

Karl heinz Buchegger schrieb:
> Hast du kein Werkzeug, mit dem du alle Dateien (*.c, *.h) auf einem
> bestimmten Verzeichnis nach einem String durchsuchen lassen kannst?

Doch habe ich. Aber wie gesagt, der String kommt nicht vor.
Ich hab in einem AVR-Datenblatt "LSL" gefunden, ein Linksshift. Aber das 
passt auch nicht: 
http://www.atmel.com/dyn/resources/prod_documents/doc2503.pdf (Seite 
330)

von Karl H. (kbuchegg)


Lesenswert?

Daran hab ich auch schon gedacht.

L_LSL_19

könnte, mit der Betonung auf könnte, ein Links Shift um 19 Bits sein. 
Allerdings findet sich keiner im Code.


Ich denke wir müssen zu Plan B übergehen.
Kommentiere mal den kompletten Inhalt der Funktion SDC_Init aus. 
SDC_Init weil es die größte der Funktionen ist.

UNgefähr so:
1
SD_Result_t SDC_Init(void)
2
{
3
#ifdef TEST
4
5
  .... Hier bleibt der Code so wie er ist
6
7
#endif
8
}

Dann kompilierst und linkst du wieder.
Dass der Code nicht lauffähig sein wird, brauch ich nicht zu betonen. 
Aber darum geht es nicht. Wir wollen nur wissen, ob dadurch die 
Fehlermeldung verschwindet.

Wenn sie das tut, dann kommt L_LSL_19 irgendwo in diesem Code vor. Dann 
setzt du das #ifdef etwas tiefer, eventuell das #endif etwas hoch, so 
dass die { - } Hierarchie wieder stimmt und probierst wieder. Solange 
bis die Fehlermeldung wieder auftaucht.

Ist durch das Auskommentieren des kompletten INhalts der Funktion die 
Fehlermeldung nicht verschwunden, dann machst du dasselbe mit einer 
anderen Funktion.

Auf die Art kann man identifizieren, welcher Code dafür verantwortlich 
ist.
Und dann sehen wir weiter.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mark M. schrieb:
> Die komplette Implementierung findet man auf der angegebenen Seite.

Auf 
http://www.mikro-control.de/Joomla/index.php?option=com_weblinks&catid=20&Itemid=29 
findet man zwar Sourcecode, der Deinem ähnelt, aber der enthält keine 
Datei Z_sdc.*

Hast Du die nur umbenannt (wenn ja, warum?), oder hast Du Deine Sourcen 
doch aus einer anderen Quelle?

von Mark M. (mom-jovi)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Hast Du die nur umbenannt (wenn ja, warum?)

Ich hab sie umbenannt und das Z vorangestellt, damit ich in der 
Exploreransicht mehr Überblick habe. Das hab ich aber bei allen Includes 
berücksichtigt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hast Du die Suche nach Deinem Problem jetzt schon aufgegeben, oder was 
soll das hier:

Beitrag "MSP430 mit Circuit Cillar Code für FAT16 - fehlende Funktionen"

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Rufus Τ. Firefly schrieb:
> oder was soll das hier
Ja, ich denke mal, die Denkweise dahinter ist:
Von den 20 FAT-Treibern im Netzt wird wohl schon mindestens einer 
gehen...

von Karl H. (kbuchegg)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Hast Du die Suche nach Deinem Problem jetzt schon aufgegeben, oder was
> soll das hier:
>
> Beitrag "MSP430 mit Circuit Cillar Code für FAT16 - fehlende Funktionen"

Huch!
Der gibt aber schnell auf. Man könnte ja bei der Fehlersuche auch etwas 
lernen. Und sei es nur wie man Fehlern, die man zunächst nicht versteht, 
auf den Grund gehen kann.
Ich versteh die Fehlermeldung ja auch noch nicht und ich denke dass das 
hier noch keiner tut. Aber das ist doch noch lange kein Grund, gleich 
das Handtuch zu werfen. Solche Dinge kommen immer wieder mal vor, wenn 
man Code aus Fremdquellen übernimmt. Da muss man sich dann eben zu 
helfen wissen. Nur: Wenn man es nie macht, lernt man es auch nicht.

von Mark M. (mom-jovi)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Hast Du die Suche nach Deinem Problem jetzt schon aufgegeben, oder was
> soll das hier:
>
> Beitrag "MSP430 mit Circuit Cillar Code für FAT16 - fehlende Funktionen"

Lothar Miller schrieb:
> Rufus Τ. Firefly schrieb:
>> oder was soll das hier
> Ja, ich denke mal, die Denkweise dahinter ist:
> Von den 20 FAT-Treibern im Netzt wird wohl schon mindestens einer
> gehen...

Ich arbeite parallel an den beiden Projekten. Die FAT in "MSP430 mit 
Circuit Cillar Code für FAT16 - fehlende Funktionen" läuft schon seit 
gestern, nur fehlen mir da einige Funktionen. Deshalb hab ich mir die in 
diesem Thread angeschaut. Jetzt bin ich eben nochmal zurück, und 
schreibe mir eigene Funktionen.
Ich muss langsam mal zu Potte kommen hier.
Aber danke für die Tipps, bei Zeiten schau ich mir das nochmal an!

Außerdem habe ich bis jetzt nur 2 FAT Treiber gefunden, wo es doch "so 
viele" gibt. Aber das reicht auch.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mark M. schrieb:
> Außerdem habe ich bis jetzt nur 2 FAT Treiber gefunden, wo es doch "so
> viele" gibt.
Da hast du aber noch nicht allzu gut gesucht...
http://lmgtfy.com/?q=fat16+c-code+sd-card

> Jetzt bin ich eben nochmal zurück, und schreibe mir eigene Funktionen.
Dann gibts ja noch mal einen...  ;-)

von Mark M. (mom-jovi)


Lesenswert?

Lothar Miller schrieb:
>> Jetzt bin ich eben nochmal zurück, und schreibe mir eigene Funktionen.
> Dann gibts ja noch mal einen...  ;-)

Das ist der zweite von den 2, die ich erwähnt habe.

von Mark M. (mom-jovi)


Lesenswert?

Karl heinz Buchegger schrieb:
> Ich denke wir müssen zu Plan B übergehen.
> Kommentiere mal den kompletten Inhalt der Funktion SDC_Init aus.
> SDC_Init weil es die größte der Funktionen ist.

Ok, das habe ich jetzt gemacht. Der Fehler liegt in der ersten großen 
if-Abfrage. Ich habe dort entdeckt, dass einige Male
1
goto end;
2
//und später:
3
end:
4
SSC_Disable();
drin steht.

Ich dachte, goto gibt es in C nicht? Wenn das der Fehler wäre, käme man 
aber ja mit Auskommentieren nicht weiter, weil goto mehrere Male drin 
steht.
Oder liegt es daran nicht?

von Mark M. (mom-jovi)


Lesenswert?

Ich hab die scheinbar fehlerhafte Zeile gefunden:

Sie steckt ziemlich am Ende in der Switch-Struktur von SDC_Init:
1
SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;

SDCardInfo.Capacity und c_size sind beide unsigned long int . Was 
könnte nun sein?

Nochmal der Fehler, der angezeigt wird:
> unresolved symbol L_LSL_19, first referenced in ./Z_sdc.obj

Und muss ich die GOTO-Geschichte ändern?

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.