Na verdade, a maioria das informações / códigos que você pode encontrar na inicialização do SD é datada ou imprecisa, pois antecede o SDHC e o SDXC por anos. Atualmente, o procedimento é mais complicado, pois obriga a lidar com o hardware antigo de uma maneira compatível com versões anteriores.
Em primeiro lugar, como mencionado por outros, selecione uma baixa taxa de clock inicial (geralmente na faixa de 100 kHz - 400 kHz; use 400 kHz, se possível); você poderá mudar para um relógio mais alto mais tarde, se o dispositivo permitir. Enquanto os novos cartões podem suportar com segurança o clock do MHz, os mais velhos reclamam (ou seja, não se comunicam ou devolvem lixo).
A próxima coisa é que você não deve usar CMD1
para inicializar cartões SD / SDHC / SDXC, a menos que seu cartão não reconheça CMD55
/ ACMD41
; como dito na especificação do cartão SD:
Em qualquer um dos casos, o CMD1 não é recomendado porque pode ser difícil para o host distinguir entre o MultiMediaCard e o cartão de memória SD.
Alguns controladores (placas de maior capacidade e mais novos) simplesmente permanecerão inativos se você emitir CMD1
para eles. Você deve emitir primeiro CMD8 0x1AA
após a redefinição ( CMD0
) e depois tentar usar CMD55 + ACMD41
. Se e somente se isso falhar, use CMD1
.
tl; dr para inicializar o cartão no modo SPI, você deve:
CMD0
arg:, 0x0
CRC: 0x95
(response 0x01
:) - observe que, no caso de uma 0xFF
resposta ilegível, você deve simplesmente repetir esta etapa; Veja abaixo para mais informações.
CMD8
arg:, 0x000001AA
CRC: 0x87
(resposta 0x01
:, seguida por eco de arg, neste caso 0x000001AA
) - embora possa parecer que este comando seja opcional, é completamente obrigatório para placas mais recentes. Embora 0x1AA
seja um valor de argumento comum aqui, você também pode passar outros valores; consulte "Tabela 7-5: Operação da placa para CMD8 no modo SPI", p. 108 na especificação para detalhes.
3a. CMD55
arg:, 0x0
CRC: any, 0x65
na verdade (resposta 0x01
:; CMD55
sendo o prefixo de todos ACMD
; se a resposta for 0x05
, você tem um cartão antigo - repita CMD1
com arg 0x0
[CRC 0xF9
] em vez de CMD55
/ ACMD41
)
3b ACMD41
, arg:, 0x40000000
CRC: any, 0x77
na verdade (observe que esse argumento assume que o cartão é um HCS, o que geralmente é o caso; use 0x0
arg [CRC 0xE5
] para cartões mais antigos). Se a resposta for 0x0
, você está bem; se for 0x01
, vá para 3a; se for 0x05
, veja a nota acima (em 3a.); se não estiver, algo está errado com isso (veja também abaixo).
CMD1
CMD0
CMD8
CMD55
ACMD41
CMD55
ACMD41
CMD0
CMD8
CMD1
CMD1
CMD55
ACMD41
CMD1
0x05
nn0
0xFF
CMD0
nCMD0
0xFF
0x01
CMD8
Observe que as respostas que possuem o MSB definido, mas 0xFF
geralmente não sugerem que o seu SPI tenha uma alteração no relógio (como resultado, por exemplo, da queda de Vcc, que ocorre rotineiramente quando você está usando hotplugs SD). Para corrigi-lo, você pode tentar redefinir completamente o dispositivo (ligar / desligar, desativar / confirmar S̲S̲ etc.); que normalmente funciona.
Além disso, a especificação diz
Após a última transação de barramento do cartão de memória SD, é necessário que o host forneça 8 (oito) ciclos de relógio para o cartão concluir a operação antes de desligar o relógio.
Poderia funcionar sem ele, mas como 8 ciclos = 1 byte de saída SPI, não vai doer muito e é bom tê-lo.
Observe que você deve declarar S̲S̲ (também conhecido como CS) baixo pelo menos antes e depois de cada um CMD
- é totalmente obrigatório no caso de CMD0
(o dispositivo não liga sem ele) e, na realidade, necessário para todos os outros CMD
se você tiver um padrão compatível com cartão SD. Conectar o S̲S̲ do cartão ao GND permanentemente pode parecerpara ser uma boa idéia se o cartão for o único cliente SPI ao qual o host se conectará, pois isso poupará o pino de saída do uC e a necessidade de gerenciá-lo por código, e porque o cartão deve assumir que está selecionado todos do tempo. Na realidade, algumas cartas (se não a maioria delas) realmente esperam que uma inclinação de alto a baixo acenda em vez de simplesmente detectarem baixa e, portanto, ficam com raiva se você não alternar o bit S̲S̲ e depois ficar relógios ou cuspir lixo; alguns cartões (geralmente mais novos) devem funcionar, outros (mais antigos) podem não funcionar, YMMV (mais uma vez). Ainda assim, para qualquer configuração SPI mais robusta (> 1 dispositivo escravo), lembre-se de declarar o pino baixo antes de qualquer transação real com o cartão SD fornecido.
Além disso, enquanto as especificações dizem que apenas CMD0
e CMD8
devem ter CRC no modo SPI, alguns cartões SD (como os da Transcend) parecem exigir CRC adequado para CMD55
/ ACMD41
- se você quer estar do lado seguro, basta usar um valor pré-calculado para eles.
Além disso, embora o SPI não exija pullups / downs por si só, lançar um pullup de 47k no MISO pode ser uma boa idéia; alguns dispositivos deixam seu pino DO alto Z em circunstâncias específicas (não inicializadas, por exemplo), e os pinos flutuantes sempre podem ser uma fonte de problemas estranhos. Se o seu uC possui 3,3 Vcc, você pode usar pullups internos; se for 5V, não faça isso, a menos que sua linha MISO já tenha uma tradução lógica de 5-> 3.3V adequada.
Leitura adicional:
Como usar o MMC / SDC
SD Especificações Parte 1 Simplificado Física Camada Especificação Simplificado - mais importante seções 6.4.1 Poder-se e 7.2.1 Seleção do Modo e inicialização com Figura 7-1 : Cartão de Memória SD Diagrama Estado (modo SPI)
CMD8
lançados sem emissão prévia. Além disso, o relógio geralmente não é um problema, desde que esteja dentro do alcance sensato.Talvez seja tarde demais, mas a resposta do cartão está OK! Após o CMD0, a resposta deve ser 0x01 - isso significa que o cartão ESTÁ no estado Ocioso e pronto para o trabalho. Se você tiver algo como 0b00000101, o 1 no 2º lugar diz que este é um comando ilegal e o 1 no 0-s diz que o sard ainda está no estado Ocioso e pronto para o trabalho. Se a resposta for 0x00, significa que o cartão NÃO ESTÁ no estado Ocioso e você deve enviar outro comando RESET.
fonte
I tried this, but I am getting 01 even for CDM1
- ficando IDLE em resposta aCMD1
em NÃO OK. Você não está abordando o verdadeiro problema dele com sua "resposta".