Blame view

epsilon-master/ion/src/device/sd_card.cpp 2.46 KB
6663b6c9   adorian   projet complet av...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  #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()) {
      }
    }
  
  }
  
  }
  }
  }