Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
retryit:
r=initMedia();
if(r){ //card init failed - 1 blink
for(i=0;i<3;i++){
LED=1;
delay_ms(200);
LED=0;
delay_s(1);
}
goto retryit;
}
#include <p18f2550.h>
#include <stdio.h>
#include <delays.h>
#pragma config WDT = OFF, FOSC = 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, LBA 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 a,char *,char *);
int readSector(LBA a, char *, char *);
char data1[256];
char data2[256];
char buffer1[256];
char buffer2[256];
#define CSel LATCbits.LATC6
#define LED LATBbits.LATB2
#define LEDOk LATBbits.LATB3
//*******************************************
void main(void)
{
LBA addr;
int i,r;
TRISB=0b00000001;
TRISC = 0;
CSel=1; //init chip select (active low)
LED=0; //LED off
LEDOk = 0;
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;
}
retryit:
r=initMedia();
if(r){ //card init failed - 1 blink
for(i=0;i<3;i++){
LED=1;
delay_ms(200);
LED=0;
delay_s(1);
}
goto retryit;
}
if(!r){ //write card
LEDOk = 1;
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);
}
}
}
LEDOk = 0;
while(1);
}
int initMedia(void)
{
int i,r;
CSel=1; //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; //disable SD
writeSPI(0xff);
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; //disable SD
writeSPI(0xff);
if(r) break;
}while(--i > 0);
if(i==0) //time out error 0x85
return 0x85;
SSPCON1 = 0x30;
return 0;
}
int sendSDCmd(unsigned char c, LBA 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 *p1,char *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);
}
What a pain when you don't have a proper datasheet, huh? I updated my web-site, so if you want to refer to my working code it's posted there.Um Here is my setup for some reason still wont initialize now.
You mean RGB, right? I've never seen or heard of a RGY LED.as you can see i added a 3 color led (r/g/y)
Ah! That's a two color (bicolor) red/green LED. Gotcha.well its Red and Green and when both on its like yellow/orange
Fun, huh? It all has to be just so or it doesn't work. I guess you don't have a copy of "Learning to Fly the PIC24"? Just about everything is pretty well explained in there.I got it to initialize but now bad data write lol
There's not much timing involved. "you will find that... SD/MMC connector, can easily sustain a clock rate as high as 8MHz." SPI is pretty fast. Basically just jiggle the clock line really quick and shift bits through the SPI shift register just as fast as it goes out/comes in. It's very reliable.seems to write now but stuck on read lol the issue has to be timing because i have it loop bCK ON FAIL until it passes and works
Reading should be almost instant. Go sleep.the read data is supposed to be the same as the data1 i assume. The issue isnt writing its reading lol. I can write it out quick now. But reading sux. Ah man its 2am here time for bed i work in 10 hours.
Enable all. The pullups are necessary.Are my jumpers set ok?
You said before that writing was quick. Really? If so that probably means it's NOT writing. If you can't read, you can't confirm it anyway. But it really should take a while.Its weird it write and initializes ok But reading a no go?
If it writes and init's ok ten i assume wiring is ok.
Oh ya, that's what you say now.lol i used the sd to take the pic lol It was there.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPLink.exe" /l"C:\MCC18\lib" "..\..\..\MCC18\lkr\18f4620.lkr" "sdcard.o" "C:\MCC18\lib\p18f4620.lib" /z__MPLAB_BUILD=1 /o"sdcard.cof" /M"sdcard.map" /W
MPLINK 4.16, Linker
Copyright (c) 2008 Microchip Technology Inc.
Error - section '.udata_sdcard.o' can not fit the section. Section '.udata_sdcard.o' length=0x00000401
Errors : 1
Link step failed.
unsigned char var;
#pragma udata data1
char data1[256];
#pragma udata data2
char data2[256];
#pragma udata buffer1
char buffer1[256];
#pragma udata buffer2
char buffer2[256];
// File: 18f4620.lkr
// Sample linker script for the PIC18F4620 processor
// Modded by AtomSoft
LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f4620.lib
CODEPAGE NAME=page START=0x0 END=0xFFFF
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=0xF003FF PROTECTED
ACCESSBANK NAME=accessram START=0x0 END=0x7F
DATABANK NAME=gpr0 START=0x80 END=0xF7F
//DATABANK NAME=gpr1 START=0x100 END=0x1FF
//DATABANK NAME=gpr2 START=0x200 END=0x2FF
//DATABANK NAME=gpr3 START=0x300 END=0x3FF
//DATABANK NAME=gpr4 START=0x400 END=0x4FF
//DATABANK NAME=gpr5 START=0x500 END=0x5FF
//DATABANK NAME=gpr6 START=0x600 END=0x6FF
//DATABANK NAME=gpr7 START=0x700 END=0x7FF
//DATABANK NAME=gpr8 START=0x800 END=0x8FF
//DATABANK NAME=gpr9 START=0x900 END=0x9FF
//DATABANK NAME=gpr10 START=0xA00 END=0xAFF
//DATABANK NAME=gpr11 START=0xB00 END=0xBFF
//DATABANK NAME=gpr12 START=0xC00 END=0xCFF
//DATABANK NAME=gpr13 START=0xD00 END=0xDFF
//DATABANK NAME=gpr14 START=0xE00 END=0xEFF
//DATABANK NAME=gpr15 START=0xF00 END=0xF7F
ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED
SECTION NAME=CONFIG ROM=config
STACK SIZE=0x100 RAM=gpr0
No you don't. Just define a udata for each large buffer. It's pretty well covered in the manual.You need to mod the linker give me asec ill mod it and post it
Cool. Free is good.I got that book but from a friend and no cd kinda beat up but heh free for now lol ill buy it when i get paid
#include <p18f4620.h>
#include <delays.h>
#pragma config OSC = INTIO67, WDT = OFF, LVP = OFF
typedef unsigned long LBA;
void set_wren(void);
int initMedia(void);
int sendSDCmd(unsigned char,LBA);
void delay_s(unsigned char);
void delay_ms(unsigned char);
void delay_us(unsigned char);
unsigned char writeSPI(unsigned char);
int writeSector(LBA a,char *,char *);
int readSector(LBA a, char *, char *);
unsigned char var;
#pragma udata data1
char data1[256];
#pragma udata data2
char data2[256];
#pragma udata buffer1
char buffer1[256];
#pragma udata buffer2
char buffer2[256];
#define CSel LATDbits.LATD2
#define LED LATDbits.LATD1
void main(void)
{
LBA addr;
int i,r;
TRISC=0b00010000;
TRISD = 0;
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;
buffer1[i]=0; //and clear the receive buffers
buffer2[i]=0;
}
r=initMedia();
[COLOR="Red"] if(r){ //card init failed - 1 blink
[/COLOR] 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(200);
LED=0;
delay_s(1);
}
}
}
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(200);
LED=0;
delay_ms(200);
LED=1;
delay_ms(200);
LED=0;
delay_ms(200);
LED=1;
delay_ms(200);
LED=0;
delay_s(1);
}
}
if(memcmp(data1,buffer1,256)||memcmp(data2,buffer2,256)){ //verify
while(1){ //mismatch - 4 blinks
LED=1;
delay_ms(150);
LED=0;
delay_ms(150);
LED=1;
delay_ms(150);
LED=0;
delay_ms(150);
LED=1;
delay_ms(150);
LED=0;
delay_ms(150);
LED=1;
delay_ms(150);
LED=0;
delay_s(1);
}
}
}
}
while(1){ //success!
LED=1;
delay_s(1);
LED=0;
delay_s(1);
}
}
int writeSector(LBA a,char *p1,char *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);
}
int initMedia(void)
{
int i,r;
CSel=1; //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, LBA a)
{
int i,r;
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);
}
unsigned char writeSPI(unsigned char send)
{
SSPBUF=send;
while(!SSPSTATbits.BF);
return SSPBUF;
}
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();
}
}