Cartao SD

Boa Noite pessoal,
Estou tentando acessar um cartão microSD de 1 GB. Estou utilizando mikroC e dsPIC.
Preciso acessar na unha para poder fazer o acesso dirigido por interrupções a fim de poder realizar outras coisas enquanto guardo os dados.
Estou ainda na rotina de inicialização, mas não consigo fazer o cartão entrar em modo SPI de jeito algum. A inicialização não precisa ser dirigida por interrupções, uma vez que é feita só uma vez.
Já procurei em vários locais e tudo parece estar correto. De toda maneira aqui vão algumas referências:
http://elm-chan.org/docs/mmc/mmc_e.html
http://www.microchip.com/forums/m530149.aspx
http://www.microchip.com/forums/m429711-print.aspx
http://dlnmh9ip6v2uc.cloudfront.net/dat ... SDSpec.pdf
E o meu código :
A parte de EnviaPacote e #include "comunicacao.h" são somente para tentar debugar. Tanto por elas, quanto pelo osciloscopio eu vejo que o cartão não entra em modo SPI.
No osciloscopio o cartão sequer respeita o clock, vive mudando de estado logo em cima da borda de subida do clock, o que não está correto.
Muito Obrigado pela ajuda pessoal
Estou tentando acessar um cartão microSD de 1 GB. Estou utilizando mikroC e dsPIC.
Preciso acessar na unha para poder fazer o acesso dirigido por interrupções a fim de poder realizar outras coisas enquanto guardo os dados.
Estou ainda na rotina de inicialização, mas não consigo fazer o cartão entrar em modo SPI de jeito algum. A inicialização não precisa ser dirigida por interrupções, uma vez que é feita só uma vez.
Já procurei em vários locais e tudo parece estar correto. De toda maneira aqui vão algumas referências:
http://elm-chan.org/docs/mmc/mmc_e.html
http://www.microchip.com/forums/m530149.aspx
http://www.microchip.com/forums/m429711-print.aspx
http://dlnmh9ip6v2uc.cloudfront.net/dat ... SDSpec.pdf
E o meu código :
- Código: Selecionar todos
//============================================================================\\
// Rotinas de Comunicação com cartão SD \\
// Ultima Modificação 17/12/2012 - 19:07 \\
// Por : Emilio Eduardo \\
//============================================================================\\
#include "cartao.h"
#include "comunicacao.h"
const car_cmd_spi[6] = {0x40,0x00,0x00,0x00,0x00,0x95};
void car_ConfiguraSPI(){
TRISBbits.TRISB8 = 0; //Slave select como saída
CAR_DESATIVASLAVE; //CS = 1 (off)
IFS0bits.SPI1IF = 0; //Limpa flags de interrupção
IEC0bits.SPI1IE = 0; //Desabilita interrupção
IPC2bits.SPI1IP = 2; //Seta prioridade
SPI1CON1bits.MSTEN = 1; //Modo Master
SPI1STAT.SPIROV = 0; //Limpando over-flow
SPI1CON1bits.SPRE = 0b000; //Prescaler Secundario = 8
SPI1CON1bits.PPRE = 0b01; //Prescaler Primário = 16
SPI1CON1bits.DISSCK = 0; //Clock interno habilitado
SPI1CON1bits.DISSDO = 0; //Pino SDO1 controlado pelo SPI1
SPI1CON1bits.MODE16 = 0; //Comunicação em 8bits
SPI1CON1bits.SMP = 0; //Input sampleado no meio do pulso
SPI1CON1bits.CKE = 1; //Dados na saída mudam no idle-to-active
SPI1CON1bits.CKP = 0; //Idle = Low, Active = High
SPI1STATbits.SPIEN = 1; //SPI habilitado
IFS0bits.SPI1IF = 0; //Limpa flags de interrupção
}
void car_IniciaCartao(){
char i;
volatile unsigned int temp;
car_ConfiguraSPI();
IEC0bits.SPI1IE = 0; //Desativa interrupções para comunicar ok
delay_ms(10);
LATB8_bit = 1;
com_EnviaPacote(1,"Cartao Iniciando1",17,0);
for(i=0;i<10;i++){
car_EnviaSPI(0xFF); //Restarta cartao
}
com_EnviaPacote(1,"Ativando SPI",12,0);
LATB8_bit = 0;
for(i=0;i<6;i++){
car_EnviaSPI(car_cmd_spi[i]); //Seta SPI
}
if(car_PedeResposta(0x01) == 1){
com_EnviaPacote(1,"Cartao nao Iniciado",19,0);
return;
}
com_EnviaPacote(1,"Cartao Iniciado",14,0);
i = 0;
while((i < 255) && (car_PedeResposta(0x00)==1)) //Deve continuar enviando comando se houver resposta
{
car_EnviaSPI(0x41); //Envia o comando 1 para retirá-lo do Idle
car_EnviaSPI(0x00); //Todos os argumentos sao 1
car_EnviaSPI(0x00);
car_EnviaSPI(0x00);
car_EnviaSPI(0x00);
car_EnviaSPI(0xFF); //Checksum nao e mais necessario
i++;
}
if(i >= 254) return; //Se >= 254 houve um timeout aguardando resposta
com_EnviaPacote(1,"Cartao saiu do Idle",19,0);
CAR_DESATIVASLAVE;
car_EnviaSPI(0xFF);
CAR_ATIVASLAVE;
car_EnviaSPI(0x10); //Envia comando para setar comprimento do bloco
car_EnviaSPI(0x00);
car_EnviaSPI(0x00);
car_EnviaSPI(0x02); //512 bytes
car_EnviaSPI(0x00);
car_EnviaSPI(0xFF);
if((car_PedeResposta(0x00))==1) return; //Se não retornar erro
CAR_DESATIVASLAVE;
com_EnviaPacote(1,"Configurou Bloco",16,0);
IEC0bits.SPI1IE = 1; //Ativa interrupções novamente
}
void car_EnviaSPI(char b){ //Envia um byte pela SPI e espera terminar
volatile char temp;
SPI1BUF = b;
while(!SPIRBF_bit){
asm{
NOP
}
}
temp = SPI1BUF; //Le só por ler, para zerar o flag de recebimento
}
char car_LeSPI(char b){ //Envia b, aguarda e devolve a resposta
char temp;
SPI1BUF = b;
while(!SPIRBF_bit){
asm{
NOP
}
}
temp = SPI1BUF; //Lê valor
return temp;
}
char car_PedeResposta(char b){ //Aguarda por resposta b
unsigned long contador = 0xFFFF;
while(car_LeSPI(0xFF) != b && --contador > 0);
if(contador == 0) return 1; //Retorna 1 se houve timeout
else return 0;
}
A parte de EnviaPacote e #include "comunicacao.h" são somente para tentar debugar. Tanto por elas, quanto pelo osciloscopio eu vejo que o cartão não entra em modo SPI.
No osciloscopio o cartão sequer respeita o clock, vive mudando de estado logo em cima da borda de subida do clock, o que não está correto.
Muito Obrigado pela ajuda pessoal