Files
Upsilon/ion/src/device/sd_card.cpp
Romain Goyet 081f2ce40a Remove warnings
Change-Id: Ibe5c0a0b937cd595983317a8c08ff38ffee5977d
2017-04-10 16:01:35 +02:00

96 lines
2.5 KiB
C++

#include "sd_card.h"
#include "regs/regs.h"
extern "C" {
#include <assert.h>
}
namespace Ion {
namespace SDCard {
namespace Device {
void init() {
initGPIO();
initCard();
}
void initGPIO() {
// Configure GPIOs to use AF
GPIOA.MODER()->setMode(8, GPIO::MODER::Mode::AlternateFunction);
GPIOB.MODER()->setMode(4, GPIO::MODER::Mode::AlternateFunction);
GPIOB.MODER()->setMode(5, GPIO::MODER::Mode::AlternateFunction);
GPIOB.MODER()->setMode(15, GPIO::MODER::Mode::AlternateFunction);
GPIOC.MODER()->setMode(10, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(2, GPIO::MODER::Mode::AlternateFunction);
// More precisely, AF12 which correspond to SDIO alternate functions
GPIOA.AFR()->setAlternateFunction(8, GPIO::AFR::AlternateFunction::AF12);
GPIOB.AFR()->setAlternateFunction(4, GPIO::AFR::AlternateFunction::AF12);
GPIOB.AFR()->setAlternateFunction(5, GPIO::AFR::AlternateFunction::AF12);
GPIOB.AFR()->setAlternateFunction(15, GPIO::AFR::AlternateFunction::AF12);
GPIOC.AFR()->setAlternateFunction(10, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(2, GPIO::AFR::AlternateFunction::AF12);
}
void initCard() {
// Power on
SDIO.POWER()->setPWRCTRL(SDIO::POWER::PWRCTRL::On);
while (SDIO.POWER()->getPWRCTRL() != SDIO::POWER::PWRCTRL::On) {
}
// Clock set
SDIO.CLKCR()->setCLKDIV(254);
SDIO.CLKCR()->setCLKEN(true);
sendCommand(0, 0);
// CMD8 : 0b0001 = 2.7 - 3.6V
// 0xB7 = Pattern to see back in response
sendCommand(8, 0x1B7);
assert(SDIO.RESP(1)->get() == 0x1B7);
}
void sendCommand(uint32_t cmd, uint32_t arg) {
class SDIO::ICR icr(0);
icr.setCCRCFAILC(true);
icr.setCTIMEOUTC(true);
icr.setCMDRENDC(true);
icr.setCMDSENTC(true);
SDIO.ICR()->set(icr);
SDIO.ARG()->set(arg);
SDIO::CMD::WAITRESP responseType = SDIO::CMD::WAITRESP::Short;
switch (cmd) {
case 0:
responseType = SDIO::CMD::WAITRESP::None;
break;
case 2:
case 9:
case 10:
responseType = SDIO::CMD::WAITRESP::Long;
default:
break;
}
class SDIO::CMD command(0);
command.setCMDINDEX(cmd);
command.setCPSMEN(true);
command.setWAITRESP(responseType);
SDIO.CMD()->set(command);
if (responseType == SDIO::CMD::WAITRESP::None) {
// Wait for timeout or command sent
while (!SDIO.STA()->getCTIMEOUT() && !SDIO.STA()->getCMDSENT()) {
}
} else {
while (!SDIO.STA()->getCTIMEOUT() && !SDIO.STA()->getCMDREND() && !SDIO.STA()->getCCRCFAIL()) {
}
}
}
}
}
}