Modify the file main.cpp for M487

Dependencies:   BufferedSerial

Committer:
shliu1
Date:
Fri Sep 29 05:45:43 2017 +0000
Revision:
0:c89ccc69a48b
main.cpp adds the setting of TARGET_NUMAKER_PFM_M487 for M487

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shliu1 0:c89ccc69a48b 1 /* mbed Microcontroller Library
shliu1 0:c89ccc69a48b 2 * Copyright (c) 2015-2016 Nuvoton
shliu1 0:c89ccc69a48b 3 *
shliu1 0:c89ccc69a48b 4 * Licensed under the Apache License, Version 2.0 (the "License");
shliu1 0:c89ccc69a48b 5 * you may not use this file except in compliance with the License.
shliu1 0:c89ccc69a48b 6 * You may obtain a copy of the License at
shliu1 0:c89ccc69a48b 7 *
shliu1 0:c89ccc69a48b 8 * http://www.apache.org/licenses/LICENSE-2.0
shliu1 0:c89ccc69a48b 9 *
shliu1 0:c89ccc69a48b 10 * Unless required by applicable law or agreed to in writing, software
shliu1 0:c89ccc69a48b 11 * distributed under the License is distributed on an "AS IS" BASIS,
shliu1 0:c89ccc69a48b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
shliu1 0:c89ccc69a48b 13 * See the License for the specific language governing permissions and
shliu1 0:c89ccc69a48b 14 * limitations under the License.
shliu1 0:c89ccc69a48b 15 */
shliu1 0:c89ccc69a48b 16
shliu1 0:c89ccc69a48b 17 /* Nuvoton mbed enabled targets which support SD card of SD bus mode */
shliu1 0:c89ccc69a48b 18 #if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 19
shliu1 0:c89ccc69a48b 20 #include "NuSDBlockDevice.h"
shliu1 0:c89ccc69a48b 21 #include "PeripheralPins.h"
shliu1 0:c89ccc69a48b 22 #include "mbed_debug.h"
shliu1 0:c89ccc69a48b 23 #include "nu_modutil.h"
shliu1 0:c89ccc69a48b 24
shliu1 0:c89ccc69a48b 25 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 26 #define NU_SDH_DAT0 PF_5
shliu1 0:c89ccc69a48b 27 #define NU_SDH_DAT1 PF_4
shliu1 0:c89ccc69a48b 28 #define NU_SDH_DAT2 PF_3
shliu1 0:c89ccc69a48b 29 #define NU_SDH_DAT3 PF_2
shliu1 0:c89ccc69a48b 30 #define NU_SDH_CMD PF_7
shliu1 0:c89ccc69a48b 31 #define NU_SDH_CLK PF_8
shliu1 0:c89ccc69a48b 32 #define NU_SDH_CDn PF_6
shliu1 0:c89ccc69a48b 33
shliu1 0:c89ccc69a48b 34 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 35 #define NU_SDH_DAT0 PE_2
shliu1 0:c89ccc69a48b 36 #define NU_SDH_DAT1 PE_3
shliu1 0:c89ccc69a48b 37 #define NU_SDH_DAT2 PE_4
shliu1 0:c89ccc69a48b 38 #define NU_SDH_DAT3 PE_5
shliu1 0:c89ccc69a48b 39 #define NU_SDH_CMD PE_7
shliu1 0:c89ccc69a48b 40 #define NU_SDH_CLK PE_6
shliu1 0:c89ccc69a48b 41 #define NU_SDH_CDn PD_13
shliu1 0:c89ccc69a48b 42
shliu1 0:c89ccc69a48b 43 #endif
shliu1 0:c89ccc69a48b 44
shliu1 0:c89ccc69a48b 45 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 46 extern DISK_DATA_T SD_DiskInfo0;
shliu1 0:c89ccc69a48b 47 extern DISK_DATA_T SD_DiskInfo1;
shliu1 0:c89ccc69a48b 48 extern SD_INFO_T SD0,SD1;
shliu1 0:c89ccc69a48b 49 extern int sd0_ok,sd1_ok;
shliu1 0:c89ccc69a48b 50
shliu1 0:c89ccc69a48b 51 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 52 extern int SDH_ok;
shliu1 0:c89ccc69a48b 53 extern SDH_INFO_T SD0, SD1;
shliu1 0:c89ccc69a48b 54
shliu1 0:c89ccc69a48b 55 #endif
shliu1 0:c89ccc69a48b 56
shliu1 0:c89ccc69a48b 57
shliu1 0:c89ccc69a48b 58 static const struct nu_modinit_s sdh_modinit_tab[] = {
shliu1 0:c89ccc69a48b 59 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 60 {SD_0_0, SDH_MODULE, CLK_CLKSEL0_SDHSEL_PLL, CLK_CLKDIV0_SDH(2), SDH_RST, SD_IRQn, NULL},
shliu1 0:c89ccc69a48b 61 {SD_0_1, SDH_MODULE, CLK_CLKSEL0_SDHSEL_PLL, CLK_CLKDIV0_SDH(2), SDH_RST, SD_IRQn, NULL},
shliu1 0:c89ccc69a48b 62 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 63 {SD_0, SDH0_MODULE, CLK_CLKSEL0_SDH0SEL_HCLK, CLK_CLKDIV0_SDH0(2), SDH0_RST, SDH0_IRQn, NULL},
shliu1 0:c89ccc69a48b 64 {SD_1, SDH1_MODULE, CLK_CLKSEL0_SDH1SEL_HCLK, CLK_CLKDIV3_SDH1(2), SDH1_RST, SDH1_IRQn, NULL},
shliu1 0:c89ccc69a48b 65 #endif
shliu1 0:c89ccc69a48b 66
shliu1 0:c89ccc69a48b 67 {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
shliu1 0:c89ccc69a48b 68 };
shliu1 0:c89ccc69a48b 69
shliu1 0:c89ccc69a48b 70
shliu1 0:c89ccc69a48b 71
shliu1 0:c89ccc69a48b 72 #define SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */
shliu1 0:c89ccc69a48b 73 #define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */
shliu1 0:c89ccc69a48b 74 #define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */
shliu1 0:c89ccc69a48b 75 #define SD_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */
shliu1 0:c89ccc69a48b 76 #define SD_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */
shliu1 0:c89ccc69a48b 77 #define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */
shliu1 0:c89ccc69a48b 78
shliu1 0:c89ccc69a48b 79
shliu1 0:c89ccc69a48b 80 NuSDBlockDevice::NuSDBlockDevice() :
shliu1 0:c89ccc69a48b 81 _sectors(0),
shliu1 0:c89ccc69a48b 82 _is_initialized(false),
shliu1 0:c89ccc69a48b 83 _dbg(false),
shliu1 0:c89ccc69a48b 84 _sdh_modinit(NULL),
shliu1 0:c89ccc69a48b 85 _sdh((SDName) NC),
shliu1 0:c89ccc69a48b 86 _sdh_base(NULL),
shliu1 0:c89ccc69a48b 87 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 88 _sdh_port((uint32_t) -1),
shliu1 0:c89ccc69a48b 89 #endif
shliu1 0:c89ccc69a48b 90 _sdh_irq_thunk(this, &NuSDBlockDevice::_sdh_irq),
shliu1 0:c89ccc69a48b 91 _sd_dat0(NU_SDH_DAT0),
shliu1 0:c89ccc69a48b 92 _sd_dat1(NU_SDH_DAT1),
shliu1 0:c89ccc69a48b 93 _sd_dat2(NU_SDH_DAT2),
shliu1 0:c89ccc69a48b 94 _sd_dat3(NU_SDH_DAT3),
shliu1 0:c89ccc69a48b 95 _sd_cmd(NU_SDH_CMD),
shliu1 0:c89ccc69a48b 96 _sd_clk(NU_SDH_CLK),
shliu1 0:c89ccc69a48b 97 _sd_cdn(NU_SDH_CDn)
shliu1 0:c89ccc69a48b 98 {
shliu1 0:c89ccc69a48b 99 }
shliu1 0:c89ccc69a48b 100
shliu1 0:c89ccc69a48b 101 NuSDBlockDevice::NuSDBlockDevice(PinName sd_dat0, PinName sd_dat1, PinName sd_dat2, PinName sd_dat3,
shliu1 0:c89ccc69a48b 102 PinName sd_cmd, PinName sd_clk, PinName sd_cdn) :
shliu1 0:c89ccc69a48b 103 _sectors(0),
shliu1 0:c89ccc69a48b 104 _is_initialized(false),
shliu1 0:c89ccc69a48b 105 _dbg(false),
shliu1 0:c89ccc69a48b 106 _sdh_modinit(NULL),
shliu1 0:c89ccc69a48b 107 _sdh((SDName) NC),
shliu1 0:c89ccc69a48b 108 _sdh_base(NULL),
shliu1 0:c89ccc69a48b 109 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 110 _sdh_port((uint32_t) -1),
shliu1 0:c89ccc69a48b 111 #endif
shliu1 0:c89ccc69a48b 112 _sdh_irq_thunk(this, &NuSDBlockDevice::_sdh_irq)
shliu1 0:c89ccc69a48b 113 {
shliu1 0:c89ccc69a48b 114 _sd_dat0 = sd_dat0;
shliu1 0:c89ccc69a48b 115 _sd_dat1 = sd_dat1;
shliu1 0:c89ccc69a48b 116 _sd_dat2 = sd_dat2;
shliu1 0:c89ccc69a48b 117 _sd_dat3 = sd_dat3;
shliu1 0:c89ccc69a48b 118 _sd_cmd = sd_cmd;
shliu1 0:c89ccc69a48b 119 _sd_clk = sd_clk;
shliu1 0:c89ccc69a48b 120 _sd_cdn = sd_cdn;
shliu1 0:c89ccc69a48b 121 }
shliu1 0:c89ccc69a48b 122
shliu1 0:c89ccc69a48b 123 NuSDBlockDevice::~NuSDBlockDevice()
shliu1 0:c89ccc69a48b 124 {
shliu1 0:c89ccc69a48b 125 if (_is_initialized) {
shliu1 0:c89ccc69a48b 126 deinit();
shliu1 0:c89ccc69a48b 127 }
shliu1 0:c89ccc69a48b 128 }
shliu1 0:c89ccc69a48b 129
shliu1 0:c89ccc69a48b 130 int NuSDBlockDevice::init()
shliu1 0:c89ccc69a48b 131 {
shliu1 0:c89ccc69a48b 132 _lock.lock();
shliu1 0:c89ccc69a48b 133 int err = BD_ERROR_OK;
shliu1 0:c89ccc69a48b 134
shliu1 0:c89ccc69a48b 135 do {
shliu1 0:c89ccc69a48b 136 err = _init_sdh();
shliu1 0:c89ccc69a48b 137 if (err != BD_ERROR_OK) {
shliu1 0:c89ccc69a48b 138 break;
shliu1 0:c89ccc69a48b 139 }
shliu1 0:c89ccc69a48b 140
shliu1 0:c89ccc69a48b 141 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 142 SD_Open(_sdh_port | CardDetect_From_GPIO);
shliu1 0:c89ccc69a48b 143 SD_Probe(_sdh_port);
shliu1 0:c89ccc69a48b 144
shliu1 0:c89ccc69a48b 145 switch (_sdh_port) {
shliu1 0:c89ccc69a48b 146 case SD_PORT0:
shliu1 0:c89ccc69a48b 147 _is_initialized = sd0_ok && (SD0.CardType != SD_TYPE_UNKNOWN);
shliu1 0:c89ccc69a48b 148 break;
shliu1 0:c89ccc69a48b 149
shliu1 0:c89ccc69a48b 150 case SD_PORT1:
shliu1 0:c89ccc69a48b 151 _is_initialized = sd1_ok && (SD1.CardType != SD_TYPE_UNKNOWN);
shliu1 0:c89ccc69a48b 152 break;
shliu1 0:c89ccc69a48b 153 }
shliu1 0:c89ccc69a48b 154
shliu1 0:c89ccc69a48b 155 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 156 MBED_ASSERT(_sdh_modinit != NULL);
shliu1 0:c89ccc69a48b 157
shliu1 0:c89ccc69a48b 158 NVIC_SetVector(_sdh_modinit->irq_n, _sdh_irq_thunk.entry());
shliu1 0:c89ccc69a48b 159 NVIC_EnableIRQ(_sdh_modinit->irq_n);
shliu1 0:c89ccc69a48b 160
shliu1 0:c89ccc69a48b 161 SDH_Open(_sdh_base, CardDetect_From_GPIO);
shliu1 0:c89ccc69a48b 162 SDH_Probe(_sdh_base);
shliu1 0:c89ccc69a48b 163
shliu1 0:c89ccc69a48b 164 switch (NU_MODINDEX(_sdh)) {
shliu1 0:c89ccc69a48b 165 case 0:
shliu1 0:c89ccc69a48b 166 _is_initialized = SDH_ok && (SD0.CardType != SDH_TYPE_UNKNOWN);
shliu1 0:c89ccc69a48b 167 break;
shliu1 0:c89ccc69a48b 168
shliu1 0:c89ccc69a48b 169 case 1:
shliu1 0:c89ccc69a48b 170 _is_initialized = SDH_ok && (SD1.CardType != SDH_TYPE_UNKNOWN);
shliu1 0:c89ccc69a48b 171 break;
shliu1 0:c89ccc69a48b 172 }
shliu1 0:c89ccc69a48b 173 #endif
shliu1 0:c89ccc69a48b 174
shliu1 0:c89ccc69a48b 175 if (!_is_initialized) {
shliu1 0:c89ccc69a48b 176 debug_if(_dbg, "Fail to initialize card\n");
shliu1 0:c89ccc69a48b 177 err = BD_ERROR_DEVICE_ERROR;
shliu1 0:c89ccc69a48b 178 }
shliu1 0:c89ccc69a48b 179 debug_if(_dbg, "init card = %d\n", _is_initialized);
shliu1 0:c89ccc69a48b 180 _sectors = _sd_sectors();
shliu1 0:c89ccc69a48b 181
shliu1 0:c89ccc69a48b 182 } while (0);
shliu1 0:c89ccc69a48b 183
shliu1 0:c89ccc69a48b 184 _lock.unlock();
shliu1 0:c89ccc69a48b 185
shliu1 0:c89ccc69a48b 186 return err;
shliu1 0:c89ccc69a48b 187 }
shliu1 0:c89ccc69a48b 188
shliu1 0:c89ccc69a48b 189 int NuSDBlockDevice::deinit()
shliu1 0:c89ccc69a48b 190 {
shliu1 0:c89ccc69a48b 191 _lock.lock();
shliu1 0:c89ccc69a48b 192
shliu1 0:c89ccc69a48b 193 if (_sdh_modinit) {
shliu1 0:c89ccc69a48b 194 CLK_DisableModuleClock(_sdh_modinit->clkidx);
shliu1 0:c89ccc69a48b 195 }
shliu1 0:c89ccc69a48b 196
shliu1 0:c89ccc69a48b 197 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 198 // TODO
shliu1 0:c89ccc69a48b 199 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 200 // TODO
shliu1 0:c89ccc69a48b 201 #endif
shliu1 0:c89ccc69a48b 202
shliu1 0:c89ccc69a48b 203 _is_initialized = false;
shliu1 0:c89ccc69a48b 204
shliu1 0:c89ccc69a48b 205 _lock.unlock();
shliu1 0:c89ccc69a48b 206
shliu1 0:c89ccc69a48b 207 return BD_ERROR_OK;
shliu1 0:c89ccc69a48b 208 }
shliu1 0:c89ccc69a48b 209
shliu1 0:c89ccc69a48b 210 int NuSDBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
shliu1 0:c89ccc69a48b 211 {
shliu1 0:c89ccc69a48b 212 if (! is_valid_program(addr, size)) {
shliu1 0:c89ccc69a48b 213 return SD_BLOCK_DEVICE_ERROR_PARAMETER;
shliu1 0:c89ccc69a48b 214 }
shliu1 0:c89ccc69a48b 215
shliu1 0:c89ccc69a48b 216 _lock.lock();
shliu1 0:c89ccc69a48b 217 int err = BD_ERROR_OK;
shliu1 0:c89ccc69a48b 218
shliu1 0:c89ccc69a48b 219 do {
shliu1 0:c89ccc69a48b 220 if (! _is_initialized) {
shliu1 0:c89ccc69a48b 221 err = SD_BLOCK_DEVICE_ERROR_NO_INIT;
shliu1 0:c89ccc69a48b 222 }
shliu1 0:c89ccc69a48b 223
shliu1 0:c89ccc69a48b 224 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 225 if (SD_Write(_sdh_port, (uint8_t*)b, addr / 512, size / 512) != 0) {
shliu1 0:c89ccc69a48b 226 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 227 if (SDH_Write(_sdh_base, (uint8_t*)b, addr / 512, size / 512) != 0) {
shliu1 0:c89ccc69a48b 228 #endif
shliu1 0:c89ccc69a48b 229 err = BD_ERROR_DEVICE_ERROR;
shliu1 0:c89ccc69a48b 230 }
shliu1 0:c89ccc69a48b 231
shliu1 0:c89ccc69a48b 232 } while (0);
shliu1 0:c89ccc69a48b 233
shliu1 0:c89ccc69a48b 234 _lock.unlock();
shliu1 0:c89ccc69a48b 235
shliu1 0:c89ccc69a48b 236 return err;
shliu1 0:c89ccc69a48b 237 }
shliu1 0:c89ccc69a48b 238
shliu1 0:c89ccc69a48b 239 int NuSDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
shliu1 0:c89ccc69a48b 240 {
shliu1 0:c89ccc69a48b 241 if (! is_valid_read(addr, size)) {
shliu1 0:c89ccc69a48b 242 return SD_BLOCK_DEVICE_ERROR_PARAMETER;
shliu1 0:c89ccc69a48b 243 }
shliu1 0:c89ccc69a48b 244
shliu1 0:c89ccc69a48b 245 _lock.lock();
shliu1 0:c89ccc69a48b 246 int err = BD_ERROR_OK;
shliu1 0:c89ccc69a48b 247
shliu1 0:c89ccc69a48b 248 do {
shliu1 0:c89ccc69a48b 249 if (! _is_initialized) {
shliu1 0:c89ccc69a48b 250 err = SD_BLOCK_DEVICE_ERROR_NO_INIT;
shliu1 0:c89ccc69a48b 251 }
shliu1 0:c89ccc69a48b 252
shliu1 0:c89ccc69a48b 253 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 254 if (SD_Read(_sdh_port, (uint8_t*)b, addr / 512, size / 512) != 0) {
shliu1 0:c89ccc69a48b 255 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 256 if (SDH_Read(_sdh_base, (uint8_t*)b, addr / 512, size / 512) != 0) {
shliu1 0:c89ccc69a48b 257 #endif
shliu1 0:c89ccc69a48b 258 err = BD_ERROR_DEVICE_ERROR;
shliu1 0:c89ccc69a48b 259 }
shliu1 0:c89ccc69a48b 260
shliu1 0:c89ccc69a48b 261 } while (0);
shliu1 0:c89ccc69a48b 262
shliu1 0:c89ccc69a48b 263 _lock.unlock();
shliu1 0:c89ccc69a48b 264
shliu1 0:c89ccc69a48b 265 return err;
shliu1 0:c89ccc69a48b 266 }
shliu1 0:c89ccc69a48b 267
shliu1 0:c89ccc69a48b 268 int NuSDBlockDevice::erase(bd_addr_t addr, bd_size_t size)
shliu1 0:c89ccc69a48b 269 {
shliu1 0:c89ccc69a48b 270 return BD_ERROR_OK;
shliu1 0:c89ccc69a48b 271 }
shliu1 0:c89ccc69a48b 272
shliu1 0:c89ccc69a48b 273 bd_size_t NuSDBlockDevice::get_read_size() const
shliu1 0:c89ccc69a48b 274 {
shliu1 0:c89ccc69a48b 275 return 512;
shliu1 0:c89ccc69a48b 276 }
shliu1 0:c89ccc69a48b 277
shliu1 0:c89ccc69a48b 278 bd_size_t NuSDBlockDevice::get_program_size() const
shliu1 0:c89ccc69a48b 279 {
shliu1 0:c89ccc69a48b 280 return 512;
shliu1 0:c89ccc69a48b 281 }
shliu1 0:c89ccc69a48b 282
shliu1 0:c89ccc69a48b 283 bd_size_t NuSDBlockDevice::get_erase_size() const
shliu1 0:c89ccc69a48b 284 {
shliu1 0:c89ccc69a48b 285 return 512;
shliu1 0:c89ccc69a48b 286 }
shliu1 0:c89ccc69a48b 287
shliu1 0:c89ccc69a48b 288 bd_size_t NuSDBlockDevice::size() const
shliu1 0:c89ccc69a48b 289 {
shliu1 0:c89ccc69a48b 290 return 512 * _sectors;
shliu1 0:c89ccc69a48b 291 }
shliu1 0:c89ccc69a48b 292
shliu1 0:c89ccc69a48b 293 void NuSDBlockDevice::debug(bool dbg)
shliu1 0:c89ccc69a48b 294 {
shliu1 0:c89ccc69a48b 295 _dbg = dbg;
shliu1 0:c89ccc69a48b 296 }
shliu1 0:c89ccc69a48b 297
shliu1 0:c89ccc69a48b 298 int NuSDBlockDevice::_init_sdh()
shliu1 0:c89ccc69a48b 299 {
shliu1 0:c89ccc69a48b 300 debug_if(_dbg, "SD MPF Setting & Enable SD IP Clock\n");
shliu1 0:c89ccc69a48b 301
shliu1 0:c89ccc69a48b 302 // Check if all pins belong to the same SD module
shliu1 0:c89ccc69a48b 303 // Merge SD DAT0/1/2/3
shliu1 0:c89ccc69a48b 304 uint32_t sd_dat0_mod = pinmap_peripheral(_sd_dat0, PinMap_SD_DAT0);
shliu1 0:c89ccc69a48b 305 uint32_t sd_dat1_mod = pinmap_peripheral(_sd_dat1, PinMap_SD_DAT1);
shliu1 0:c89ccc69a48b 306 uint32_t sd_dat2_mod = pinmap_peripheral(_sd_dat2, PinMap_SD_DAT2);
shliu1 0:c89ccc69a48b 307 uint32_t sd_dat3_mod = pinmap_peripheral(_sd_dat3, PinMap_SD_DAT3);
shliu1 0:c89ccc69a48b 308 uint32_t sd_dat01_mod = (SDName) pinmap_merge(sd_dat0_mod, sd_dat1_mod);
shliu1 0:c89ccc69a48b 309 uint32_t sd_dat23_mod = (SDName) pinmap_merge(sd_dat2_mod, sd_dat3_mod);
shliu1 0:c89ccc69a48b 310 uint32_t sd_dat0123_mod = (SDName) pinmap_merge(sd_dat01_mod, sd_dat23_mod);
shliu1 0:c89ccc69a48b 311 // Merge SD CMD/CLK/CDn
shliu1 0:c89ccc69a48b 312 uint32_t sd_cmd_mod = pinmap_peripheral(_sd_cmd, PinMap_SD_CMD);
shliu1 0:c89ccc69a48b 313 uint32_t sd_clk_mod = pinmap_peripheral(_sd_clk, PinMap_SD_CLK);
shliu1 0:c89ccc69a48b 314 uint32_t sd_cdn_mod = pinmap_peripheral(_sd_cdn, PinMap_SD_CD);
shliu1 0:c89ccc69a48b 315 uint32_t sd_cmdclk_mod = (SDName) pinmap_merge(sd_cmd_mod, sd_clk_mod);
shliu1 0:c89ccc69a48b 316 uint32_t sd_cmdclkcdn_mod = (SDName) pinmap_merge(sd_cmdclk_mod, sd_cdn_mod);
shliu1 0:c89ccc69a48b 317 // Merge SD DAT0/1/2/3 and SD CMD/CLK/CDn
shliu1 0:c89ccc69a48b 318 uint32_t sd_mod = (SDName) pinmap_merge(sd_dat0123_mod, sd_cmdclkcdn_mod);
shliu1 0:c89ccc69a48b 319
shliu1 0:c89ccc69a48b 320 if (sd_mod == (uint32_t) NC) {
shliu1 0:c89ccc69a48b 321 debug("SD pinmap error\n");
shliu1 0:c89ccc69a48b 322 return BD_ERROR_DEVICE_ERROR;
shliu1 0:c89ccc69a48b 323 }
shliu1 0:c89ccc69a48b 324
shliu1 0:c89ccc69a48b 325 _sdh_modinit = get_modinit(sd_mod, sdh_modinit_tab);
shliu1 0:c89ccc69a48b 326 MBED_ASSERT(_sdh_modinit != NULL);
shliu1 0:c89ccc69a48b 327 MBED_ASSERT(_sdh_modinit->modname == sd_mod);
shliu1 0:c89ccc69a48b 328
shliu1 0:c89ccc69a48b 329
shliu1 0:c89ccc69a48b 330 // Configure SD multi-function pins
shliu1 0:c89ccc69a48b 331 pinmap_pinout(_sd_dat0, PinMap_SD_DAT0);
shliu1 0:c89ccc69a48b 332 pinmap_pinout(_sd_dat1, PinMap_SD_DAT1);
shliu1 0:c89ccc69a48b 333 pinmap_pinout(_sd_dat2, PinMap_SD_DAT2);
shliu1 0:c89ccc69a48b 334 pinmap_pinout(_sd_dat3, PinMap_SD_DAT3);
shliu1 0:c89ccc69a48b 335 pinmap_pinout(_sd_cmd, PinMap_SD_CMD);
shliu1 0:c89ccc69a48b 336 pinmap_pinout(_sd_clk, PinMap_SD_CLK);
shliu1 0:c89ccc69a48b 337 pinmap_pinout(_sd_cdn, PinMap_SD_CD);
shliu1 0:c89ccc69a48b 338
shliu1 0:c89ccc69a48b 339 // Configure SD IP clock
shliu1 0:c89ccc69a48b 340 SYS_UnlockReg();
shliu1 0:c89ccc69a48b 341
shliu1 0:c89ccc69a48b 342 // Determine SDH port dependent on passed-in pins
shliu1 0:c89ccc69a48b 343 _sdh = (SDName) sd_mod;
shliu1 0:c89ccc69a48b 344 _sdh_base = (SDH_T *) NU_MODBASE(_sdh);
shliu1 0:c89ccc69a48b 345 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 346 switch (NU_MODSUBINDEX(_sdh)) {
shliu1 0:c89ccc69a48b 347 case 0:
shliu1 0:c89ccc69a48b 348 _sdh_port = SD_PORT0;
shliu1 0:c89ccc69a48b 349 break;
shliu1 0:c89ccc69a48b 350
shliu1 0:c89ccc69a48b 351 case 1:
shliu1 0:c89ccc69a48b 352 _sdh_port = SD_PORT1;
shliu1 0:c89ccc69a48b 353 break;
shliu1 0:c89ccc69a48b 354 }
shliu1 0:c89ccc69a48b 355 #endif
shliu1 0:c89ccc69a48b 356
shliu1 0:c89ccc69a48b 357 SYS_ResetModule(_sdh_modinit->rsetidx);
shliu1 0:c89ccc69a48b 358 CLK_SetModuleClock(_sdh_modinit->clkidx, _sdh_modinit->clksrc, _sdh_modinit->clkdiv);
shliu1 0:c89ccc69a48b 359 CLK_EnableModuleClock(_sdh_modinit->clkidx);
shliu1 0:c89ccc69a48b 360
shliu1 0:c89ccc69a48b 361 SYS_LockReg();
shliu1 0:c89ccc69a48b 362
shliu1 0:c89ccc69a48b 363 return BD_ERROR_OK;
shliu1 0:c89ccc69a48b 364 }
shliu1 0:c89ccc69a48b 365
shliu1 0:c89ccc69a48b 366 uint32_t NuSDBlockDevice::_sd_sectors()
shliu1 0:c89ccc69a48b 367 {
shliu1 0:c89ccc69a48b 368 _lock.lock();
shliu1 0:c89ccc69a48b 369
shliu1 0:c89ccc69a48b 370 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 371 switch (_sdh_port) {
shliu1 0:c89ccc69a48b 372 case SD_PORT0:
shliu1 0:c89ccc69a48b 373 _sectors = SD_DiskInfo0.totalSectorN;
shliu1 0:c89ccc69a48b 374 break;
shliu1 0:c89ccc69a48b 375 case SD_PORT1:
shliu1 0:c89ccc69a48b 376 _sectors = SD_DiskInfo1.totalSectorN;
shliu1 0:c89ccc69a48b 377 break;
shliu1 0:c89ccc69a48b 378 }
shliu1 0:c89ccc69a48b 379
shliu1 0:c89ccc69a48b 380 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 381 switch (NU_MODINDEX(_sdh)) {
shliu1 0:c89ccc69a48b 382 case 0:
shliu1 0:c89ccc69a48b 383 _sectors = SD0.totalSectorN;
shliu1 0:c89ccc69a48b 384 break;
shliu1 0:c89ccc69a48b 385 case 1:
shliu1 0:c89ccc69a48b 386 _sectors = SD1.totalSectorN;
shliu1 0:c89ccc69a48b 387 break;
shliu1 0:c89ccc69a48b 388 }
shliu1 0:c89ccc69a48b 389
shliu1 0:c89ccc69a48b 390 #endif
shliu1 0:c89ccc69a48b 391
shliu1 0:c89ccc69a48b 392 _lock.unlock();
shliu1 0:c89ccc69a48b 393
shliu1 0:c89ccc69a48b 394 return _sectors;
shliu1 0:c89ccc69a48b 395 }
shliu1 0:c89ccc69a48b 396
shliu1 0:c89ccc69a48b 397 void NuSDBlockDevice::_sdh_irq()
shliu1 0:c89ccc69a48b 398 {
shliu1 0:c89ccc69a48b 399 #if defined(TARGET_NUMAKER_PFM_NUC472)
shliu1 0:c89ccc69a48b 400 // TODO: Support IRQ
shliu1 0:c89ccc69a48b 401
shliu1 0:c89ccc69a48b 402 #elif defined(TARGET_NUMAKER_PFM_M487)
shliu1 0:c89ccc69a48b 403 // FMI data abort interrupt
shliu1 0:c89ccc69a48b 404 if (_sdh_base->GINTSTS & SDH_GINTSTS_DTAIF_Msk) {
shliu1 0:c89ccc69a48b 405 _sdh_base->GINTSTS = SDH_GINTSTS_DTAIF_Msk;
shliu1 0:c89ccc69a48b 406 /* ResetAllEngine() */
shliu1 0:c89ccc69a48b 407 _sdh_base->GCTL |= SDH_GCTL_GCTLRST_Msk;
shliu1 0:c89ccc69a48b 408 }
shliu1 0:c89ccc69a48b 409
shliu1 0:c89ccc69a48b 410 //----- SD interrupt status
shliu1 0:c89ccc69a48b 411 if (_sdh_base->INTSTS & SDH_INTSTS_BLKDIF_Msk) {
shliu1 0:c89ccc69a48b 412 // block down
shliu1 0:c89ccc69a48b 413 extern uint8_t volatile _SDH_SDDataReady;
shliu1 0:c89ccc69a48b 414 _SDH_SDDataReady = TRUE;
shliu1 0:c89ccc69a48b 415 _sdh_base->INTSTS = SDH_INTSTS_BLKDIF_Msk;
shliu1 0:c89ccc69a48b 416 }
shliu1 0:c89ccc69a48b 417
shliu1 0:c89ccc69a48b 418 // NOTE: On M487, there are two SDH instances which each support port 0 and don't support port 1.
shliu1 0:c89ccc69a48b 419 // Port 0 (support): INTEN.CDIEN0, INTEN.CDSRC0, INTSTS.CDIF0, INTSTS.CDSTS0
shliu1 0:c89ccc69a48b 420 // Port 1 (no support): INTEN.CDIEN1, INTEN.CDSRC1, INTSTS.CDIF1, INTSTS.CDSTS1
shliu1 0:c89ccc69a48b 421 if (_sdh_base->INTSTS & SDH_INTSTS_CDIF_Msk) { // port 0 card detect
shliu1 0:c89ccc69a48b 422 _sdh_base->INTSTS = SDH_INTSTS_CDIF_Msk;
shliu1 0:c89ccc69a48b 423 // TBD: Support PnP
shliu1 0:c89ccc69a48b 424 }
shliu1 0:c89ccc69a48b 425
shliu1 0:c89ccc69a48b 426 // CRC error interrupt
shliu1 0:c89ccc69a48b 427 if (_sdh_base->INTSTS & SDH_INTSTS_CRCIF_Msk) {
shliu1 0:c89ccc69a48b 428 _sdh_base->INTSTS = SDH_INTSTS_CRCIF_Msk; // clear interrupt flag
shliu1 0:c89ccc69a48b 429 }
shliu1 0:c89ccc69a48b 430
shliu1 0:c89ccc69a48b 431 if (_sdh_base->INTSTS & SDH_INTSTS_DITOIF_Msk) {
shliu1 0:c89ccc69a48b 432 _sdh_base->INTSTS = SDH_INTSTS_DITOIF_Msk;
shliu1 0:c89ccc69a48b 433 }
shliu1 0:c89ccc69a48b 434
shliu1 0:c89ccc69a48b 435 // Response in timeout interrupt
shliu1 0:c89ccc69a48b 436 if (_sdh_base->INTSTS & SDH_INTSTS_RTOIF_Msk) {
shliu1 0:c89ccc69a48b 437 _sdh_base->INTSTS |= SDH_INTSTS_RTOIF_Msk;
shliu1 0:c89ccc69a48b 438 }
shliu1 0:c89ccc69a48b 439 #endif
shliu1 0:c89ccc69a48b 440 }
shliu1 0:c89ccc69a48b 441
shliu1 0:c89ccc69a48b 442
shliu1 0:c89ccc69a48b 443 #endif //#if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M487)