Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

SD Card Project

Status
Not open for further replies.
yeah i just noticed it. Um You have full version (standard) of BoostC? I cant seem to get data into the rom variables. It stays empty. And then the buffer doesnt return nothing back. So i was thinking about getting boostc since its not that expensive.

My Error:
Code:
Copyright (c) 2008 Microchip Technology Inc.
Error - section '.udata_sd.o' can not fit the section. Section '.udata_sd.o' length=0x00000401
Errors    : 1
 
Last edited:
Um You have full version (standard) of BoostC? I cant seem to get data into the rom variables. It stays empty. And then the buffer doesnt return nothing back. So i was thinking about getting boostc since its not that expensive.
About $75. Dirt cheap. Worth every penny.

You're trying to write to EEPROM? Or store stuff in flash? Anything in those is not really a variable, to be precise. It's just storage.
 
I'm using rom variables in the free/Lite version of BoostC without problems (so far).

Mike

<added>

Oops! Or coarse I meant "rom constant" arrays (grin)...
 
Last edited:
ok cool. The issue is i have a 448 and it has 16k of flash. I cant seem to access ROM. You know the Data Variables you used above (also the buffers). It says i dont have enough space or i cant fit it into my memory for some reason. Im using MCC18. And i cant get it to store the looped variables into the data1 and data2. But it doesnt go in for some reason.

So im thinking to avoid the headache i feel like buying a boostc license to at least follow along and creat from here on.

EDIT: I hate working lol . I got to goto work. I didnt even notice the time :( Cya later. Oh yeah here is my code:
Code:
#include <p18cxxx.h>
#include <stdio.h>
#include <delays.h>

#pragma config WDT = OFF, OSC = HS, LVP = OFF

// FUNCTION Prototypes

unsigned char var;
typedef unsigned long LBA;

void main(void);
void set_wren(void);
int initMedia(void);
int sendSDCmd(unsigned char c, unsigned long a);
void delay_s(unsigned char x);
void delay_ms(unsigned char x);
void delay_us(unsigned char x);
unsigned char writeSPI(unsigned char send);
int writeSector(LBA,char rom *,char rom *);
int readSector(LBA a, char *p1, char *p2);

char data1[256];
char data2[256];
char buffer1[256];
char buffer2[256];

#define CSel LATDbits.LATD0
#define LED LATDbits.LATD1

//*******************************************


void main(void)
{
	LBA addr;
	int i,r;
	TRISD=0;
	TRISC=0b00010000;
	CSel=1;						//init chip select (active low)
	LED=0;						//LED off

	SSPSTAT = 0b00000000;				//SMP(7)=0, CKE(6)=0 (clock edge idle to active), others don't care
	SSPCON1 = 0b00010010;				//CKP(4)=1 clock polarity (idle high)
							//SSPM3:SSPM0(3:0)=010 spi clock FOSC/64 (<400kHz)
	SSPCON1bits.SSPEN=1;				//SSPEN(5)=1 enable SPI
	for(i=0;i<256;i++){				//fill the buffers
		data1[i]=i;
		data2[i]=i;

    }

	r=initMedia();
	if(r){						//card init failed - 1 blink
		while(1){
			LED=1;
			delay_ms(200);
			LED=0;
			delay_s(1);
		}

    } else {						//write card
		addr = 10000;
		for(i=0;i<1000;i++){
			if(!writeSector(addr+i,data1,data2)){
				while(1){		//write failed - 2 blinks
					LED=1;
					delay_ms(200);
					LED=0;
					delay_ms(200);
					LED=1;
					delay_ms(150);
					LED=0;
					delay_s(2);
                    
				}
			}
		}
    }
		addr=10000;				//verify write
		for(i=0;i<1000;i++){
			if(!readSector(addr+i,buffer1,buffer2)){
				while(1){		//verify failed - 3 blinks
					LED=1;
					delay_ms(75);
					LED=0;
					delay_ms(75);
					LED=1;
					delay_ms(75);
					LED=0;
					delay_ms(75);
					LED=1;
					delay_ms(75);
					LED=0;
					delay_s(1);
				}
			}
        }

    while(1);
}


int initMedia(void)
{
	int i,r;
	CSel=1;writeSPI(0xff);			//while card is not selected
	for(i=0;i<16;i++)				//send 80 clock cycles to start up
		writeSPI(0xff);
	CSel=0;							//then select the card
	r = sendSDCmd(0,0);				//send reset command to enter SPI mode
	CSel=1;writeSPI(0xff);			//disable SD
	if(r != 1)						//error check - need 1
		return 0x84;
	i = 10000;						//send init for up to 0.3s
	CSel=0;
	do{
		r = sendSDCmd(1,0);			//send init command
		CSel=1;writeSPI(0xff);		//disable SD
		if(!r) break;
	}while(--i > 0);
	if(i==0)						//time out error 0x85
		return 0x85;

    SSPCON1 = 0x30;
	return 0;
}

int sendSDCmd(unsigned char c, unsigned long a)
{
	int i,r,x;
	CSel=0;						//send command packet (6 bytes)
	writeSPI(c|0x40);				//send command & frame bit
	writeSPI(a>>24);				//send 32-bit address
	writeSPI(a>>16);
	writeSPI(a>>8);
	writeSPI(a);
	writeSPI(0x95);	

	i=9;	
					//wait for response
	do{
		r=writeSPI(0xff);			//check if ready
		if(r != 0xff)
			break;
	}while(--i > 0);

	return(r);
}


void delay_s(unsigned char x)
{
    char var1;
	for(var1=0;var1<x;var1++)
	{				
        Delay10KTCYx(200);
	} 
}

void delay_ms(unsigned char x)
{
    char var1;
	for(var1=0;var1<x;var1++)
	{				
        Delay1KTCYx(2);
	} 
}

void delay_us(unsigned char x)
{
    char var1;
	for(var1=0;var1<x;var1++)
	{				
        //Delay10TCYx(2);
        Delay1TCY();
        Delay1TCY();
	} 
}
unsigned char writeSPI(unsigned char send)
{
	SSPBUF=send;
	while(!SSPSTATbits.BF);
	return SSPBUF;
}

int writeSector(LBA a,char rom *p1,char rom *p2)
{
	unsigned r,i;
	LED=1;						//turn on write LED
	r=sendSDCmd(24,(a<<9));
	if(r==0){
		writeSPI(0xfe);				//send Data Start byte
		for(i=0;i<256;i++)			//first 256 bytes
			writeSPI(*p1++);
		for(i=0;i<256;i++)			//second 256 bytes
			writeSPI(*p2++);
		writeSPI(0xff);				//send dummy CRC
		writeSPI(0xff);
		if((r=writeSPI(0xff) & 0x0f) == 0x05){	//check if data accepted
			for(i=10000;i>0;i--){
				if(r=writeSPI(0xff))
					break;
			}
		}
		else
			r=0;				//fail
	}
	CSel=1;writeSPI(0xff);				//disable SD
	LED = 0;					//LED off
	return(r);
}

int readSector(LBA a, char *p1, char *p2)
{
	int r,i;
	LED = 1;					//turn on read LED
	r = sendSDCmd(17,(a<<9));
	if(r==0){					//check if command was accepted
		i=10000;				//wait for a response
		do{
			r = writeSPI(0xff);
			if(r==0xfe)
				break;
		}while(--i > 0);
		if(i){					//if no timeout, read 512 byte sector
			for(i=0;i<256;i++)
				*p1++ = writeSPI(0xff);
			for(i=0;i<256;i++)
				*p2++ = writeSPI(0xff);
			writeSPI(0xff);			//ignore CRC
			writeSPI(0xff);
		}
	}
	CSel=1;writeSPI(0xff);				//disable SD
	LED = 0;					//read LED off
	return(r == 0xfe);
}
 
Last edited:
ok cool. The issue is i have a 448 and it has 16k of flash.
What you're getting at is that you don't have enough RAM. I just grabbed the datasheet for the 18F448. Only 768 bytes of RAM! :eek: My 4620 has 4K.

I cant seem to access ROM.
You mean EEPROM? Have you written/read EEPROM before? There is a trick to it, but it's well described in the datasheet (Chapter 5.0).

You know the Data Variables you used above (also the buffers). It says i don't have enough space or I can't fit it into my memory for some reason.
The reason is that you just don't have enough RAM. I've got 512 bytes of output buffer (unnecessary in this case) and 512 bytes of input buffer. As I said, your 18F448 has only 768 bytes of RAM, and some of that is needed by the program even without buffers.

An easy cure for this test program is to just generate the output data on the fly. Just use the write loop value as the value to write. Saves you 512 bytes of RAM. Of course it's totally useless, but this is just a test. Later you can figure out a way to do it all for real.

So im thinking to avoid the headache i feel like buying a boostc license to at least follow along and creat from here on.
It's a good deal, but it won't fix your problem. :p
 
just seen that post futz. Ill try it now

EDIT:
Code:
		for(i=0;i<1000;i++){
			if(!writeSector(addr+i,data1,data2)){

Why does it write 1000 Times? Isnt it supposed to be 512?
 
Last edited:
Ok i havent read or well seen much of sector sizes. Can i set it to like 256?
The problem isn't sector sizes. You can set the sector size to anything you want, but if you want to do FAT16 later (trust me, you DO want to!) stick with 512 byte sectors.

Just figure a way to make that too small amount of RAM work for what you're doing. Use the same 512 bytes of buffer as both a write and read buffer. No problem at all. Once you've written, you no longer need the data in the buffer. Clear it (or don't) and use it as a read buffer. Very simple.
 
Last edited:
Wow My PGC Pin broke on the 2550 But i didnt give up. I soldered a LED Lead to it and works 100% :D
I remember why i never use this with C. How the heck do i set the config for this? I tried OSC = HS no good.

EDIT:
FOSC = HS
?
 
Last edited:
Possibly lol. Now another issue lol:

Error [1205] unknown member 'LATC4' in '__tag_42'

For:
Code:
#define CSel LATCbits.LATC4

and

CSel=1;

I bet i cant use those lol ill use LATC 6 and 7
 
Last edited:
Yo im getting upset now. It still says that stupid error:
Code:
MPLINK 4.20, Linker
Copyright (c) 2008 Microchip Technology Inc.
Error - section '.udata_sd.o' can not fit the section. Section '.udata_sd.o' length=0x00000160
Errors    : 1

Im on microchips forum and it might be the linker so i see a quick fix ill try it
 
Last edited:
My New Linker:
Code:
// File: 18f2550.lkr
// Sample linker script for the PIC18F2550 processor

LIBPATH .

FILES c018i.o
FILES clib.lib
FILES p18f2550.lib

CODEPAGE   NAME=page       START=0x0               END=0x7FFF
CODEPAGE   NAME=idlocs     START=0x200000          END=0x200007       PROTECTED
CODEPAGE   NAME=config     START=0x300000          END=0x30000D       PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED
CODEPAGE   NAME=eedata     START=0xF00000          END=0xF000FF       PROTECTED

ACCESSBANK NAME=accessram  START=0x0            END=0x5F
DATABANK   NAME=gpr0       START=0x60           END=0xFF
DATABANK   NAME=gpr1       START=0x100          END=0xF5F
//DATABANK   NAME=gpr2       START=0x200          END=0x2FF
//DATABANK   NAME=gpr3       START=0x300          END=0x3FF
//DATABANK   NAME=usb4       START=0x400          END=0x4FF          PROTECTED
//DATABANK   NAME=usb5       START=0x500          END=0x5FF          PROTECTED
//DATABANK   NAME=usb6       START=0x600          END=0x6FF          PROTECTED
//DATABANK   NAME=usb7       START=0x700          END=0x7FF          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED

SECTION    NAME=CONFIG     ROM=config

STACK SIZE=0x100 RAM=gpr1
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top