2012-12-04 15:52:15 +02:00
|
|
|
/*
|
|
|
|
* fw/mmc-hw.c - MMC hardware interface
|
|
|
|
*
|
|
|
|
* Written 2012 by Werner Almesberger
|
|
|
|
* Copyright 2012 Werner Almesberger
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "io.h"
|
2012-12-05 16:30:50 +02:00
|
|
|
#include "delay.h"
|
2012-12-04 15:52:15 +02:00
|
|
|
#include "mmc-hw.h"
|
|
|
|
|
|
|
|
|
2012-12-04 16:56:56 +02:00
|
|
|
/*
|
|
|
|
* Pin assignment from
|
|
|
|
* http://alumni.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
|
|
|
|
*
|
|
|
|
* Pin SD mode SPI mode
|
|
|
|
* 1 DAT3 Chip Select (active low)
|
|
|
|
* 2 CMD MOSI
|
|
|
|
* 3 VSS VSS
|
|
|
|
* 4 VDD VDD
|
|
|
|
* 5 CLK Clock
|
|
|
|
* 6 VSS VSS
|
|
|
|
* 7 DAT0 MISO
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#define MMC_nCS CARD_DAT3
|
|
|
|
#define MMC_MOSI CARD_CMD
|
|
|
|
#define MMC_CLK CARD_CLK
|
|
|
|
#define MMC_MISO CARD_DAT0
|
|
|
|
|
|
|
|
|
2012-12-04 15:52:15 +02:00
|
|
|
void mmc_select(void)
|
|
|
|
{
|
2012-12-04 16:56:56 +02:00
|
|
|
CLR(MMC_nCS);
|
2012-12-04 15:52:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void mmc_deselect(void)
|
|
|
|
{
|
2012-12-04 16:56:56 +02:00
|
|
|
SET(MMC_nCS);
|
2012-12-04 15:52:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t mmc_recv(void)
|
|
|
|
{
|
2012-12-04 16:56:56 +02:00
|
|
|
uint8_t i, v = 0;
|
|
|
|
|
2012-12-05 15:58:26 +02:00
|
|
|
SET(MMC_MOSI);
|
2012-12-04 16:56:56 +02:00
|
|
|
for (i = 0; i != 8; i++) {
|
|
|
|
SET(MMC_CLK);
|
|
|
|
v = (v << 1) | PIN(MMC_MISO);
|
|
|
|
CLR(MMC_CLK);
|
|
|
|
}
|
|
|
|
return v;
|
2012-12-04 15:52:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mmc_send(uint8_t v)
|
|
|
|
{
|
2012-12-04 16:56:56 +02:00
|
|
|
uint8_t i;
|
|
|
|
|
|
|
|
for (i = 0; i != 8; i++) {
|
|
|
|
if (v & 0x80)
|
|
|
|
SET(MMC_MOSI);
|
|
|
|
else
|
|
|
|
CLR(MMC_MOSI);
|
|
|
|
SET(MMC_CLK);
|
|
|
|
CLR(MMC_CLK);
|
|
|
|
v <<= 1;
|
|
|
|
}
|
2012-12-04 15:52:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mmc_activate(void)
|
|
|
|
{
|
2012-12-04 16:56:56 +02:00
|
|
|
SET(MMC_nCS);
|
|
|
|
CLR(MMC_CLK);
|
|
|
|
OUT(MMC_nCS);
|
2012-12-05 15:35:27 +02:00
|
|
|
SET(MMC_MOSI);
|
|
|
|
SET(MMC_CLK); /* for pre-charging */
|
2012-12-04 16:56:56 +02:00
|
|
|
OUT(MMC_MOSI);
|
|
|
|
OUT(MMC_CLK);
|
|
|
|
IN(MMC_MISO);
|
|
|
|
|
2012-12-05 15:35:27 +02:00
|
|
|
_delay_ms(100); /* allow card to pre-charge, to limit inrush current */
|
|
|
|
|
2012-12-04 16:56:56 +02:00
|
|
|
CLR(CARD_nPWR);
|
|
|
|
|
|
|
|
_delay_ms(10);
|
2012-12-04 15:52:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mmc_deactivate(void)
|
|
|
|
{
|
2012-12-04 16:56:56 +02:00
|
|
|
CLR(MMC_CLK);
|
|
|
|
CLR(MMC_nCS);
|
|
|
|
CLR(MMC_MOSI);
|
|
|
|
CLR(MMC_MISO);
|
|
|
|
|
|
|
|
SET(CARD_nPWR);
|
|
|
|
_delay_ms(10);
|
|
|
|
|
|
|
|
OUT(MMC_MISO);
|
2012-12-04 15:52:15 +02:00
|
|
|
}
|