Advantech / Mbed OS pelion-example-common

This example is known to work great on the following platforms:

Example Functionality

This example showcases the following device functionality:

  • On timer button increment, simulate Pelion LWM2M button resource change

Use this example with Mbed CLI

1. Import the application into your desktop:

mbed import https://os.mbed.com/teams/Advantech/code/pelion-example-common
cd pelion-example-common

2. Download your developer certificate from pelion portal

3. Compile the program

mbed compile -t <toolchain> -m <TARGET_BOARD>

(supported toolchains : GCC_ARM / ARM / IAR)

4. Copy the binary file pelion-example-common.bin to your mbed device.

Committer:
chuanga
Date:
Tue Mar 12 13:48:39 2019 +0800
Revision:
0:43ff9e3bc244
copying sources from github repository

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chuanga 0:43ff9e3bc244 1 /* mbed Microcontroller Library
chuanga 0:43ff9e3bc244 2 * Copyright (c) 2015-2016 Nuvoton
chuanga 0:43ff9e3bc244 3 *
chuanga 0:43ff9e3bc244 4 * Licensed under the Apache License, Version 2.0 (the "License");
chuanga 0:43ff9e3bc244 5 * you may not use this file except in compliance with the License.
chuanga 0:43ff9e3bc244 6 * You may obtain a copy of the License at
chuanga 0:43ff9e3bc244 7 *
chuanga 0:43ff9e3bc244 8 * http://www.apache.org/licenses/LICENSE-2.0
chuanga 0:43ff9e3bc244 9 *
chuanga 0:43ff9e3bc244 10 * Unless required by applicable law or agreed to in writing, software
chuanga 0:43ff9e3bc244 11 * distributed under the License is distributed on an "AS IS" BASIS,
chuanga 0:43ff9e3bc244 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
chuanga 0:43ff9e3bc244 13 * See the License for the specific language governing permissions and
chuanga 0:43ff9e3bc244 14 * limitations under the License.
chuanga 0:43ff9e3bc244 15 */
chuanga 0:43ff9e3bc244 16
chuanga 0:43ff9e3bc244 17 /* Nuvoton mbed enabled targets which support SD card of SD bus mode */
chuanga 0:43ff9e3bc244 18 #if TARGET_NUVOTON
chuanga 0:43ff9e3bc244 19
chuanga 0:43ff9e3bc244 20 #include "NuSDBlockDevice.h"
chuanga 0:43ff9e3bc244 21 #include "PeripheralPins.h"
chuanga 0:43ff9e3bc244 22 #include "mbed_debug.h"
chuanga 0:43ff9e3bc244 23 #include "nu_modutil.h"
chuanga 0:43ff9e3bc244 24 #include "mbed_critical.h"
chuanga 0:43ff9e3bc244 25 #include "mbed_toolchain.h"
chuanga 0:43ff9e3bc244 26
chuanga 0:43ff9e3bc244 27 /* SD DMA compatible buffer if user buffer doesn't meet requirements
chuanga 0:43ff9e3bc244 28 *
chuanga 0:43ff9e3bc244 29 * SD DMA buffer location requires to be:
chuanga 0:43ff9e3bc244 30 * (1) Word-aligned
chuanga 0:43ff9e3bc244 31 * (2) Located in 0x2xxxxxxx/0x3xxxxxxx region. Check linker files to ensure global/static
chuanga 0:43ff9e3bc244 32 * variables are placed in this region.
chuanga 0:43ff9e3bc244 33 *
chuanga 0:43ff9e3bc244 34 * SD DMA buffer size DMA_BUF_SIZE must be a multiple of 512-byte block size.
chuanga 0:43ff9e3bc244 35 * Its value is estimated to trade memory footprint off against performance.
chuanga 0:43ff9e3bc244 36 *
chuanga 0:43ff9e3bc244 37 */
chuanga 0:43ff9e3bc244 38 #define DMA_BUFF_SIZE 512
chuanga 0:43ff9e3bc244 39 MBED_ALIGN(4) static uint8_t dma_buff[DMA_BUFF_SIZE];
chuanga 0:43ff9e3bc244 40
chuanga 0:43ff9e3bc244 41 /* Check if specified buffer is SD DMA-compatible */
chuanga 0:43ff9e3bc244 42 static bool sd_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to);
chuanga 0:43ff9e3bc244 43
chuanga 0:43ff9e3bc244 44 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 45 #define NU_SDH_DAT0 PF_5
chuanga 0:43ff9e3bc244 46 #define NU_SDH_DAT1 PF_4
chuanga 0:43ff9e3bc244 47 #define NU_SDH_DAT2 PF_3
chuanga 0:43ff9e3bc244 48 #define NU_SDH_DAT3 PF_2
chuanga 0:43ff9e3bc244 49 #define NU_SDH_CMD PF_7
chuanga 0:43ff9e3bc244 50 #define NU_SDH_CLK PF_8
chuanga 0:43ff9e3bc244 51 #define NU_SDH_CDn PF_6
chuanga 0:43ff9e3bc244 52
chuanga 0:43ff9e3bc244 53 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487
chuanga 0:43ff9e3bc244 54 #define NU_SDH_DAT0 PE_2
chuanga 0:43ff9e3bc244 55 #define NU_SDH_DAT1 PE_3
chuanga 0:43ff9e3bc244 56 #define NU_SDH_DAT2 PB_4
chuanga 0:43ff9e3bc244 57 #define NU_SDH_DAT3 PB_5
chuanga 0:43ff9e3bc244 58 #define NU_SDH_CMD PE_7
chuanga 0:43ff9e3bc244 59 #define NU_SDH_CLK PE_6
chuanga 0:43ff9e3bc244 60 #define NU_SDH_CDn PD_13
chuanga 0:43ff9e3bc244 61
chuanga 0:43ff9e3bc244 62 #elif TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 63 #define NU_SDH_DAT0 PE_2
chuanga 0:43ff9e3bc244 64 #define NU_SDH_DAT1 PE_3
chuanga 0:43ff9e3bc244 65 #define NU_SDH_DAT2 PE_4
chuanga 0:43ff9e3bc244 66 #define NU_SDH_DAT3 PE_5
chuanga 0:43ff9e3bc244 67 #define NU_SDH_CMD PE_7
chuanga 0:43ff9e3bc244 68 #define NU_SDH_CLK PE_6
chuanga 0:43ff9e3bc244 69 #define NU_SDH_CDn PD_13
chuanga 0:43ff9e3bc244 70
chuanga 0:43ff9e3bc244 71 #endif
chuanga 0:43ff9e3bc244 72
chuanga 0:43ff9e3bc244 73 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 74 extern DISK_DATA_T SD_DiskInfo0;
chuanga 0:43ff9e3bc244 75 extern DISK_DATA_T SD_DiskInfo1;
chuanga 0:43ff9e3bc244 76 extern SD_INFO_T SD0,SD1;
chuanga 0:43ff9e3bc244 77 extern int sd0_ok,sd1_ok;
chuanga 0:43ff9e3bc244 78
chuanga 0:43ff9e3bc244 79 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487
chuanga 0:43ff9e3bc244 80 extern int SDH_ok;
chuanga 0:43ff9e3bc244 81 extern SDH_INFO_T SD0, SD1;
chuanga 0:43ff9e3bc244 82
chuanga 0:43ff9e3bc244 83 #elif TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 84 extern int SDH_ok;
chuanga 0:43ff9e3bc244 85 extern SDH_INFO_T SD0;
chuanga 0:43ff9e3bc244 86
chuanga 0:43ff9e3bc244 87 #endif
chuanga 0:43ff9e3bc244 88
chuanga 0:43ff9e3bc244 89
chuanga 0:43ff9e3bc244 90 static const struct nu_modinit_s sdh_modinit_tab[] = {
chuanga 0:43ff9e3bc244 91 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 92 {SD_0_0, SDH_MODULE, CLK_CLKSEL0_SDHSEL_PLL, CLK_CLKDIV0_SDH(2), SDH_RST, SD_IRQn, NULL},
chuanga 0:43ff9e3bc244 93 {SD_0_1, SDH_MODULE, CLK_CLKSEL0_SDHSEL_PLL, CLK_CLKDIV0_SDH(2), SDH_RST, SD_IRQn, NULL},
chuanga 0:43ff9e3bc244 94 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487
chuanga 0:43ff9e3bc244 95 {SD_0, SDH0_MODULE, CLK_CLKSEL0_SDH0SEL_HCLK, CLK_CLKDIV0_SDH0(2), SDH0_RST, SDH0_IRQn, NULL},
chuanga 0:43ff9e3bc244 96 {SD_1, SDH1_MODULE, CLK_CLKSEL0_SDH1SEL_HCLK, CLK_CLKDIV3_SDH1(2), SDH1_RST, SDH1_IRQn, NULL},
chuanga 0:43ff9e3bc244 97 #elif TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 98 {SD_0, SDH0_MODULE, CLK_CLKSEL0_SDH0SEL_HCLK, CLK_CLKDIV0_SDH0(2), SDH0_RST, SDH0_IRQn, NULL},
chuanga 0:43ff9e3bc244 99 #endif
chuanga 0:43ff9e3bc244 100
chuanga 0:43ff9e3bc244 101 {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
chuanga 0:43ff9e3bc244 102 };
chuanga 0:43ff9e3bc244 103
chuanga 0:43ff9e3bc244 104
chuanga 0:43ff9e3bc244 105
chuanga 0:43ff9e3bc244 106 #define SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */
chuanga 0:43ff9e3bc244 107 #define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */
chuanga 0:43ff9e3bc244 108 #define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */
chuanga 0:43ff9e3bc244 109 #define SD_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */
chuanga 0:43ff9e3bc244 110 #define SD_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */
chuanga 0:43ff9e3bc244 111 #define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */
chuanga 0:43ff9e3bc244 112
chuanga 0:43ff9e3bc244 113
chuanga 0:43ff9e3bc244 114 NuSDBlockDevice::NuSDBlockDevice() :
chuanga 0:43ff9e3bc244 115 _sectors(0),
chuanga 0:43ff9e3bc244 116 _dbg(false),
chuanga 0:43ff9e3bc244 117 _sdh_modinit(NULL),
chuanga 0:43ff9e3bc244 118 _sdh((SDName) NC),
chuanga 0:43ff9e3bc244 119 _sdh_base(NULL),
chuanga 0:43ff9e3bc244 120 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 121 _sdh_port((uint32_t) -1),
chuanga 0:43ff9e3bc244 122 #endif
chuanga 0:43ff9e3bc244 123 _sdh_irq_thunk(this, &NuSDBlockDevice::_sdh_irq),
chuanga 0:43ff9e3bc244 124 _sd_dat0(NU_SDH_DAT0),
chuanga 0:43ff9e3bc244 125 _sd_dat1(NU_SDH_DAT1),
chuanga 0:43ff9e3bc244 126 _sd_dat2(NU_SDH_DAT2),
chuanga 0:43ff9e3bc244 127 _sd_dat3(NU_SDH_DAT3),
chuanga 0:43ff9e3bc244 128 _sd_cmd(NU_SDH_CMD),
chuanga 0:43ff9e3bc244 129 _sd_clk(NU_SDH_CLK),
chuanga 0:43ff9e3bc244 130 _sd_cdn(NU_SDH_CDn),
chuanga 0:43ff9e3bc244 131 _is_initialized(false),
chuanga 0:43ff9e3bc244 132 _init_ref_count(0)
chuanga 0:43ff9e3bc244 133 {
chuanga 0:43ff9e3bc244 134 }
chuanga 0:43ff9e3bc244 135
chuanga 0:43ff9e3bc244 136 NuSDBlockDevice::NuSDBlockDevice(PinName sd_dat0, PinName sd_dat1, PinName sd_dat2, PinName sd_dat3,
chuanga 0:43ff9e3bc244 137 PinName sd_cmd, PinName sd_clk, PinName sd_cdn) :
chuanga 0:43ff9e3bc244 138 _sectors(0),
chuanga 0:43ff9e3bc244 139 _dbg(false),
chuanga 0:43ff9e3bc244 140 _sdh_modinit(NULL),
chuanga 0:43ff9e3bc244 141 _sdh((SDName) NC),
chuanga 0:43ff9e3bc244 142 _sdh_base(NULL),
chuanga 0:43ff9e3bc244 143 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 144 _sdh_port((uint32_t) -1),
chuanga 0:43ff9e3bc244 145 #endif
chuanga 0:43ff9e3bc244 146 _sdh_irq_thunk(this, &NuSDBlockDevice::_sdh_irq),
chuanga 0:43ff9e3bc244 147 _is_initialized(false),
chuanga 0:43ff9e3bc244 148 _init_ref_count(0)
chuanga 0:43ff9e3bc244 149 {
chuanga 0:43ff9e3bc244 150 _sd_dat0 = sd_dat0;
chuanga 0:43ff9e3bc244 151 _sd_dat1 = sd_dat1;
chuanga 0:43ff9e3bc244 152 _sd_dat2 = sd_dat2;
chuanga 0:43ff9e3bc244 153 _sd_dat3 = sd_dat3;
chuanga 0:43ff9e3bc244 154 _sd_cmd = sd_cmd;
chuanga 0:43ff9e3bc244 155 _sd_clk = sd_clk;
chuanga 0:43ff9e3bc244 156 _sd_cdn = sd_cdn;
chuanga 0:43ff9e3bc244 157 }
chuanga 0:43ff9e3bc244 158
chuanga 0:43ff9e3bc244 159 NuSDBlockDevice::~NuSDBlockDevice()
chuanga 0:43ff9e3bc244 160 {
chuanga 0:43ff9e3bc244 161 if (_is_initialized) {
chuanga 0:43ff9e3bc244 162 deinit();
chuanga 0:43ff9e3bc244 163 }
chuanga 0:43ff9e3bc244 164 }
chuanga 0:43ff9e3bc244 165
chuanga 0:43ff9e3bc244 166 int NuSDBlockDevice::init()
chuanga 0:43ff9e3bc244 167 {
chuanga 0:43ff9e3bc244 168 _lock.lock();
chuanga 0:43ff9e3bc244 169 int err = BD_ERROR_OK;
chuanga 0:43ff9e3bc244 170
chuanga 0:43ff9e3bc244 171 do {
chuanga 0:43ff9e3bc244 172 if (_is_initialized) {
chuanga 0:43ff9e3bc244 173 _init_ref_count ++;
chuanga 0:43ff9e3bc244 174 break;
chuanga 0:43ff9e3bc244 175 } else {
chuanga 0:43ff9e3bc244 176 _init_ref_count = 0;
chuanga 0:43ff9e3bc244 177 }
chuanga 0:43ff9e3bc244 178
chuanga 0:43ff9e3bc244 179 err = _init_sdh();
chuanga 0:43ff9e3bc244 180 if (err != BD_ERROR_OK) {
chuanga 0:43ff9e3bc244 181 break;
chuanga 0:43ff9e3bc244 182 }
chuanga 0:43ff9e3bc244 183
chuanga 0:43ff9e3bc244 184 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 185 SD_Open(_sdh_port | CardDetect_From_GPIO);
chuanga 0:43ff9e3bc244 186 SD_Probe(_sdh_port);
chuanga 0:43ff9e3bc244 187
chuanga 0:43ff9e3bc244 188 switch (_sdh_port) {
chuanga 0:43ff9e3bc244 189 case SD_PORT0:
chuanga 0:43ff9e3bc244 190 _is_initialized = sd0_ok && (SD0.CardType != SD_TYPE_UNKNOWN);
chuanga 0:43ff9e3bc244 191 break;
chuanga 0:43ff9e3bc244 192
chuanga 0:43ff9e3bc244 193 case SD_PORT1:
chuanga 0:43ff9e3bc244 194 _is_initialized = sd1_ok && (SD1.CardType != SD_TYPE_UNKNOWN);
chuanga 0:43ff9e3bc244 195 break;
chuanga 0:43ff9e3bc244 196 }
chuanga 0:43ff9e3bc244 197
chuanga 0:43ff9e3bc244 198 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487
chuanga 0:43ff9e3bc244 199 MBED_ASSERT(_sdh_modinit != NULL);
chuanga 0:43ff9e3bc244 200
chuanga 0:43ff9e3bc244 201 NVIC_SetVector(_sdh_modinit->irq_n, _sdh_irq_thunk.entry());
chuanga 0:43ff9e3bc244 202 NVIC_EnableIRQ(_sdh_modinit->irq_n);
chuanga 0:43ff9e3bc244 203
chuanga 0:43ff9e3bc244 204 SDH_Open(_sdh_base, CardDetect_From_GPIO);
chuanga 0:43ff9e3bc244 205 SDH_Probe(_sdh_base);
chuanga 0:43ff9e3bc244 206
chuanga 0:43ff9e3bc244 207 switch (NU_MODINDEX(_sdh)) {
chuanga 0:43ff9e3bc244 208 case 0:
chuanga 0:43ff9e3bc244 209 _is_initialized = SDH_ok && (SD0.CardType != SDH_TYPE_UNKNOWN);
chuanga 0:43ff9e3bc244 210 break;
chuanga 0:43ff9e3bc244 211
chuanga 0:43ff9e3bc244 212 case 1:
chuanga 0:43ff9e3bc244 213 _is_initialized = SDH_ok && (SD1.CardType != SDH_TYPE_UNKNOWN);
chuanga 0:43ff9e3bc244 214 break;
chuanga 0:43ff9e3bc244 215 }
chuanga 0:43ff9e3bc244 216
chuanga 0:43ff9e3bc244 217 #elif TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 218 MBED_ASSERT(_sdh_modinit != NULL);
chuanga 0:43ff9e3bc244 219
chuanga 0:43ff9e3bc244 220 NVIC_SetVector(_sdh_modinit->irq_n, _sdh_irq_thunk.entry());
chuanga 0:43ff9e3bc244 221 NVIC_EnableIRQ(_sdh_modinit->irq_n);
chuanga 0:43ff9e3bc244 222
chuanga 0:43ff9e3bc244 223 SDH_Open(_sdh_base, CardDetect_From_GPIO);
chuanga 0:43ff9e3bc244 224 SDH_Probe(_sdh_base);
chuanga 0:43ff9e3bc244 225
chuanga 0:43ff9e3bc244 226 switch (NU_MODINDEX(_sdh)) {
chuanga 0:43ff9e3bc244 227 case 0:
chuanga 0:43ff9e3bc244 228 _is_initialized = SDH_ok && (SD0.CardType != SDH_TYPE_UNKNOWN);
chuanga 0:43ff9e3bc244 229 break;
chuanga 0:43ff9e3bc244 230 }
chuanga 0:43ff9e3bc244 231 #endif
chuanga 0:43ff9e3bc244 232
chuanga 0:43ff9e3bc244 233 if (_is_initialized) {
chuanga 0:43ff9e3bc244 234 _init_ref_count = 1;
chuanga 0:43ff9e3bc244 235 } else {
chuanga 0:43ff9e3bc244 236 debug_if(_dbg, "Fail to initialize card\n");
chuanga 0:43ff9e3bc244 237 err = BD_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 238 }
chuanga 0:43ff9e3bc244 239 debug_if(_dbg, "init card = %d\n", _is_initialized);
chuanga 0:43ff9e3bc244 240 _sectors = _sd_sectors();
chuanga 0:43ff9e3bc244 241
chuanga 0:43ff9e3bc244 242 } while (0);
chuanga 0:43ff9e3bc244 243
chuanga 0:43ff9e3bc244 244 _lock.unlock();
chuanga 0:43ff9e3bc244 245
chuanga 0:43ff9e3bc244 246 return err;
chuanga 0:43ff9e3bc244 247 }
chuanga 0:43ff9e3bc244 248
chuanga 0:43ff9e3bc244 249 int NuSDBlockDevice::deinit()
chuanga 0:43ff9e3bc244 250 {
chuanga 0:43ff9e3bc244 251 _lock.lock();
chuanga 0:43ff9e3bc244 252 int err = BD_ERROR_OK;
chuanga 0:43ff9e3bc244 253
chuanga 0:43ff9e3bc244 254 do {
chuanga 0:43ff9e3bc244 255 if (_is_initialized && _init_ref_count > 1) {
chuanga 0:43ff9e3bc244 256 _init_ref_count --;
chuanga 0:43ff9e3bc244 257 break;
chuanga 0:43ff9e3bc244 258 } else if (! _is_initialized) {
chuanga 0:43ff9e3bc244 259 _init_ref_count = 0;
chuanga 0:43ff9e3bc244 260 break;
chuanga 0:43ff9e3bc244 261 }
chuanga 0:43ff9e3bc244 262
chuanga 0:43ff9e3bc244 263 if (_sdh_modinit) {
chuanga 0:43ff9e3bc244 264 #if defined(DOMAIN_NS) && DOMAIN_NS
chuanga 0:43ff9e3bc244 265 CLK_DisableModuleClock_S(_sdh_modinit->clkidx);
chuanga 0:43ff9e3bc244 266 #else
chuanga 0:43ff9e3bc244 267 CLK_DisableModuleClock(_sdh_modinit->clkidx);
chuanga 0:43ff9e3bc244 268 #endif
chuanga 0:43ff9e3bc244 269 }
chuanga 0:43ff9e3bc244 270
chuanga 0:43ff9e3bc244 271 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 272 // TODO
chuanga 0:43ff9e3bc244 273 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487
chuanga 0:43ff9e3bc244 274 // TODO
chuanga 0:43ff9e3bc244 275 #elif TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 276 // TODO
chuanga 0:43ff9e3bc244 277 #endif
chuanga 0:43ff9e3bc244 278
chuanga 0:43ff9e3bc244 279 _is_initialized = false;
chuanga 0:43ff9e3bc244 280 _init_ref_count = 0;
chuanga 0:43ff9e3bc244 281 } while (0);
chuanga 0:43ff9e3bc244 282
chuanga 0:43ff9e3bc244 283 _lock.unlock();
chuanga 0:43ff9e3bc244 284
chuanga 0:43ff9e3bc244 285 return err;
chuanga 0:43ff9e3bc244 286 }
chuanga 0:43ff9e3bc244 287
chuanga 0:43ff9e3bc244 288 int NuSDBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
chuanga 0:43ff9e3bc244 289 {
chuanga 0:43ff9e3bc244 290 if (! is_valid_program(addr, size)) {
chuanga 0:43ff9e3bc244 291 return SD_BLOCK_DEVICE_ERROR_PARAMETER;
chuanga 0:43ff9e3bc244 292 }
chuanga 0:43ff9e3bc244 293
chuanga 0:43ff9e3bc244 294 _lock.lock();
chuanga 0:43ff9e3bc244 295 int err = BD_ERROR_OK;
chuanga 0:43ff9e3bc244 296
chuanga 0:43ff9e3bc244 297 do {
chuanga 0:43ff9e3bc244 298 if (! _is_initialized) {
chuanga 0:43ff9e3bc244 299 err = SD_BLOCK_DEVICE_ERROR_NO_INIT;
chuanga 0:43ff9e3bc244 300 break;
chuanga 0:43ff9e3bc244 301 }
chuanga 0:43ff9e3bc244 302
chuanga 0:43ff9e3bc244 303 /* Check if user buffer is SD DMA-compatible */
chuanga 0:43ff9e3bc244 304 if (sd_dma_buff_compat(b, static_cast<size_t>(size), 512)) {
chuanga 0:43ff9e3bc244 305 /* User buffer is DMA-compatible. We can transfer directly. */
chuanga 0:43ff9e3bc244 306 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 307 if (SD_Write(_sdh_port, (uint8_t*)b, addr / 512, size / 512) != 0) {
chuanga 0:43ff9e3bc244 308 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487 || TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 309 if (SDH_Write(_sdh_base, (uint8_t*)b, addr / 512, size / 512) != 0) {
chuanga 0:43ff9e3bc244 310 #endif
chuanga 0:43ff9e3bc244 311 err = BD_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 312 }
chuanga 0:43ff9e3bc244 313 } else {
chuanga 0:43ff9e3bc244 314 /* User buffer is not SD DMA-compatible. We must transfer via DMA intermediate buffer. */
chuanga 0:43ff9e3bc244 315 const uint8_t *b_pos = static_cast<const uint8_t *>(b);
chuanga 0:43ff9e3bc244 316 bd_addr_t addr_pos = addr;
chuanga 0:43ff9e3bc244 317 bd_size_t rmn = size;
chuanga 0:43ff9e3bc244 318
chuanga 0:43ff9e3bc244 319 while (rmn) {
chuanga 0:43ff9e3bc244 320 size_t todo_size = (rmn >= DMA_BUFF_SIZE) ? DMA_BUFF_SIZE : static_cast<size_t>(rmn);
chuanga 0:43ff9e3bc244 321 memcpy(dma_buff, b_pos, todo_size);
chuanga 0:43ff9e3bc244 322
chuanga 0:43ff9e3bc244 323 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 324 if (SD_Write(_sdh_port, const_cast<uint8_t*>(dma_buff), static_cast<uint32_t>(addr_pos / 512), static_cast<uint32_t>(todo_size / 512)) != 0) {
chuanga 0:43ff9e3bc244 325 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487 || TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 326 if (SDH_Write(_sdh_base, const_cast<uint8_t*>(dma_buff), static_cast<uint32_t>(addr_pos / 512), static_cast<uint32_t>(todo_size / 512)) != 0) {
chuanga 0:43ff9e3bc244 327 #endif
chuanga 0:43ff9e3bc244 328 err = BD_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 329 break;
chuanga 0:43ff9e3bc244 330 }
chuanga 0:43ff9e3bc244 331
chuanga 0:43ff9e3bc244 332 b_pos += todo_size;
chuanga 0:43ff9e3bc244 333 addr_pos += todo_size;
chuanga 0:43ff9e3bc244 334 rmn -= todo_size;
chuanga 0:43ff9e3bc244 335 }
chuanga 0:43ff9e3bc244 336 }
chuanga 0:43ff9e3bc244 337 } while (0);
chuanga 0:43ff9e3bc244 338
chuanga 0:43ff9e3bc244 339 _lock.unlock();
chuanga 0:43ff9e3bc244 340
chuanga 0:43ff9e3bc244 341 return err;
chuanga 0:43ff9e3bc244 342 }
chuanga 0:43ff9e3bc244 343
chuanga 0:43ff9e3bc244 344 int NuSDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
chuanga 0:43ff9e3bc244 345 {
chuanga 0:43ff9e3bc244 346 if (! is_valid_read(addr, size)) {
chuanga 0:43ff9e3bc244 347 return SD_BLOCK_DEVICE_ERROR_PARAMETER;
chuanga 0:43ff9e3bc244 348 }
chuanga 0:43ff9e3bc244 349
chuanga 0:43ff9e3bc244 350 _lock.lock();
chuanga 0:43ff9e3bc244 351 int err = BD_ERROR_OK;
chuanga 0:43ff9e3bc244 352
chuanga 0:43ff9e3bc244 353 do {
chuanga 0:43ff9e3bc244 354 if (! _is_initialized) {
chuanga 0:43ff9e3bc244 355 err = SD_BLOCK_DEVICE_ERROR_NO_INIT;
chuanga 0:43ff9e3bc244 356 break;
chuanga 0:43ff9e3bc244 357 }
chuanga 0:43ff9e3bc244 358
chuanga 0:43ff9e3bc244 359 /* Check if user buffer is SD DMA-compatible */
chuanga 0:43ff9e3bc244 360 if (sd_dma_buff_compat(b, static_cast<size_t>(size), 512)) {
chuanga 0:43ff9e3bc244 361 /* User buffer is SD DMA-compatible. We can transfer directly. */
chuanga 0:43ff9e3bc244 362 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 363 if (SD_Read(_sdh_port, (uint8_t*)b, addr / 512, size / 512) != 0) {
chuanga 0:43ff9e3bc244 364 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487 || TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 365 if (SDH_Read(_sdh_base, (uint8_t*)b, addr / 512, size / 512) != 0) {
chuanga 0:43ff9e3bc244 366 #endif
chuanga 0:43ff9e3bc244 367 err = BD_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 368 }
chuanga 0:43ff9e3bc244 369 } else {
chuanga 0:43ff9e3bc244 370 /* User buffer is not SD DMA-compatible. We must transfer via DMA intermediate buffer. */
chuanga 0:43ff9e3bc244 371 uint8_t *b_pos = static_cast<uint8_t *>(b);
chuanga 0:43ff9e3bc244 372 bd_addr_t addr_pos = addr;
chuanga 0:43ff9e3bc244 373 bd_size_t rmn = size;
chuanga 0:43ff9e3bc244 374
chuanga 0:43ff9e3bc244 375 while (rmn) {
chuanga 0:43ff9e3bc244 376 size_t todo_size = (rmn >= DMA_BUFF_SIZE) ? DMA_BUFF_SIZE : static_cast<size_t>(rmn);
chuanga 0:43ff9e3bc244 377
chuanga 0:43ff9e3bc244 378 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 379 if (SD_Read(_sdh_port, static_cast<uint8_t*>(dma_buff), static_cast<uint32_t>(addr_pos / 512), static_cast<uint32_t>(todo_size / 512)) != 0) {
chuanga 0:43ff9e3bc244 380 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487 || TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 381 if (SDH_Read(_sdh_base, static_cast<uint8_t*>(dma_buff), static_cast<uint32_t>(addr_pos / 512), static_cast<uint32_t>(todo_size / 512)) != 0) {
chuanga 0:43ff9e3bc244 382 #endif
chuanga 0:43ff9e3bc244 383 err = BD_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 384 break;
chuanga 0:43ff9e3bc244 385 }
chuanga 0:43ff9e3bc244 386
chuanga 0:43ff9e3bc244 387 memcpy(b_pos, dma_buff, todo_size);
chuanga 0:43ff9e3bc244 388
chuanga 0:43ff9e3bc244 389 b_pos += todo_size;
chuanga 0:43ff9e3bc244 390 addr_pos += todo_size;
chuanga 0:43ff9e3bc244 391 rmn -= todo_size;
chuanga 0:43ff9e3bc244 392 }
chuanga 0:43ff9e3bc244 393 }
chuanga 0:43ff9e3bc244 394 } while (0);
chuanga 0:43ff9e3bc244 395
chuanga 0:43ff9e3bc244 396 _lock.unlock();
chuanga 0:43ff9e3bc244 397
chuanga 0:43ff9e3bc244 398 return err;
chuanga 0:43ff9e3bc244 399 }
chuanga 0:43ff9e3bc244 400
chuanga 0:43ff9e3bc244 401 int NuSDBlockDevice::erase(bd_addr_t addr, bd_size_t size)
chuanga 0:43ff9e3bc244 402 {
chuanga 0:43ff9e3bc244 403 if (! _is_initialized) {
chuanga 0:43ff9e3bc244 404 return SD_BLOCK_DEVICE_ERROR_NO_INIT;
chuanga 0:43ff9e3bc244 405 }
chuanga 0:43ff9e3bc244 406
chuanga 0:43ff9e3bc244 407 return BD_ERROR_OK;
chuanga 0:43ff9e3bc244 408 }
chuanga 0:43ff9e3bc244 409
chuanga 0:43ff9e3bc244 410 bd_size_t NuSDBlockDevice::get_read_size() const
chuanga 0:43ff9e3bc244 411 {
chuanga 0:43ff9e3bc244 412 return 512;
chuanga 0:43ff9e3bc244 413 }
chuanga 0:43ff9e3bc244 414
chuanga 0:43ff9e3bc244 415 bd_size_t NuSDBlockDevice::get_program_size() const
chuanga 0:43ff9e3bc244 416 {
chuanga 0:43ff9e3bc244 417 return 512;
chuanga 0:43ff9e3bc244 418 }
chuanga 0:43ff9e3bc244 419
chuanga 0:43ff9e3bc244 420 bd_size_t NuSDBlockDevice::get_erase_size() const
chuanga 0:43ff9e3bc244 421 {
chuanga 0:43ff9e3bc244 422 return 512;
chuanga 0:43ff9e3bc244 423 }
chuanga 0:43ff9e3bc244 424
chuanga 0:43ff9e3bc244 425 bd_size_t NuSDBlockDevice::get_erase_size(bd_addr_t addr) const
chuanga 0:43ff9e3bc244 426 {
chuanga 0:43ff9e3bc244 427 return 512;
chuanga 0:43ff9e3bc244 428 }
chuanga 0:43ff9e3bc244 429
chuanga 0:43ff9e3bc244 430 bd_size_t NuSDBlockDevice::size() const
chuanga 0:43ff9e3bc244 431 {
chuanga 0:43ff9e3bc244 432 if (! _is_initialized) {
chuanga 0:43ff9e3bc244 433 return SD_BLOCK_DEVICE_ERROR_NO_INIT;
chuanga 0:43ff9e3bc244 434 }
chuanga 0:43ff9e3bc244 435
chuanga 0:43ff9e3bc244 436 return 512 * _sectors;
chuanga 0:43ff9e3bc244 437 }
chuanga 0:43ff9e3bc244 438
chuanga 0:43ff9e3bc244 439 void NuSDBlockDevice::debug(bool dbg)
chuanga 0:43ff9e3bc244 440 {
chuanga 0:43ff9e3bc244 441 _dbg = dbg;
chuanga 0:43ff9e3bc244 442 }
chuanga 0:43ff9e3bc244 443
chuanga 0:43ff9e3bc244 444 int NuSDBlockDevice::_init_sdh()
chuanga 0:43ff9e3bc244 445 {
chuanga 0:43ff9e3bc244 446 debug_if(_dbg, "SD MPF Setting & Enable SD IP Clock\n");
chuanga 0:43ff9e3bc244 447
chuanga 0:43ff9e3bc244 448 // Check if all pins belong to the same SD module
chuanga 0:43ff9e3bc244 449 // Merge SD DAT0/1/2/3
chuanga 0:43ff9e3bc244 450 uint32_t sd_dat0_mod = pinmap_peripheral(_sd_dat0, PinMap_SD_DAT0);
chuanga 0:43ff9e3bc244 451 uint32_t sd_dat1_mod = pinmap_peripheral(_sd_dat1, PinMap_SD_DAT1);
chuanga 0:43ff9e3bc244 452 uint32_t sd_dat2_mod = pinmap_peripheral(_sd_dat2, PinMap_SD_DAT2);
chuanga 0:43ff9e3bc244 453 uint32_t sd_dat3_mod = pinmap_peripheral(_sd_dat3, PinMap_SD_DAT3);
chuanga 0:43ff9e3bc244 454 uint32_t sd_dat01_mod = (SDName) pinmap_merge(sd_dat0_mod, sd_dat1_mod);
chuanga 0:43ff9e3bc244 455 uint32_t sd_dat23_mod = (SDName) pinmap_merge(sd_dat2_mod, sd_dat3_mod);
chuanga 0:43ff9e3bc244 456 uint32_t sd_dat0123_mod = (SDName) pinmap_merge(sd_dat01_mod, sd_dat23_mod);
chuanga 0:43ff9e3bc244 457 // Merge SD CMD/CLK/CDn
chuanga 0:43ff9e3bc244 458 uint32_t sd_cmd_mod = pinmap_peripheral(_sd_cmd, PinMap_SD_CMD);
chuanga 0:43ff9e3bc244 459 uint32_t sd_clk_mod = pinmap_peripheral(_sd_clk, PinMap_SD_CLK);
chuanga 0:43ff9e3bc244 460 uint32_t sd_cdn_mod = pinmap_peripheral(_sd_cdn, PinMap_SD_CD);
chuanga 0:43ff9e3bc244 461 uint32_t sd_cmdclk_mod = (SDName) pinmap_merge(sd_cmd_mod, sd_clk_mod);
chuanga 0:43ff9e3bc244 462 uint32_t sd_cmdclkcdn_mod = (SDName) pinmap_merge(sd_cmdclk_mod, sd_cdn_mod);
chuanga 0:43ff9e3bc244 463 // Merge SD DAT0/1/2/3 and SD CMD/CLK/CDn
chuanga 0:43ff9e3bc244 464 uint32_t sd_mod = (SDName) pinmap_merge(sd_dat0123_mod, sd_cmdclkcdn_mod);
chuanga 0:43ff9e3bc244 465
chuanga 0:43ff9e3bc244 466 if (sd_mod == (uint32_t) NC) {
chuanga 0:43ff9e3bc244 467 debug("SD pinmap error\n");
chuanga 0:43ff9e3bc244 468 return BD_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 469 }
chuanga 0:43ff9e3bc244 470
chuanga 0:43ff9e3bc244 471 _sdh_modinit = get_modinit(sd_mod, sdh_modinit_tab);
chuanga 0:43ff9e3bc244 472 MBED_ASSERT(_sdh_modinit != NULL);
chuanga 0:43ff9e3bc244 473 MBED_ASSERT(_sdh_modinit->modname == sd_mod);
chuanga 0:43ff9e3bc244 474
chuanga 0:43ff9e3bc244 475
chuanga 0:43ff9e3bc244 476 // Configure SD multi-function pins
chuanga 0:43ff9e3bc244 477 pinmap_pinout(_sd_dat0, PinMap_SD_DAT0);
chuanga 0:43ff9e3bc244 478 pinmap_pinout(_sd_dat1, PinMap_SD_DAT1);
chuanga 0:43ff9e3bc244 479 pinmap_pinout(_sd_dat2, PinMap_SD_DAT2);
chuanga 0:43ff9e3bc244 480 pinmap_pinout(_sd_dat3, PinMap_SD_DAT3);
chuanga 0:43ff9e3bc244 481 pinmap_pinout(_sd_cmd, PinMap_SD_CMD);
chuanga 0:43ff9e3bc244 482 pinmap_pinout(_sd_clk, PinMap_SD_CLK);
chuanga 0:43ff9e3bc244 483 pinmap_pinout(_sd_cdn, PinMap_SD_CD);
chuanga 0:43ff9e3bc244 484
chuanga 0:43ff9e3bc244 485 // Configure SD IP clock
chuanga 0:43ff9e3bc244 486 #if defined(DOMAIN_NS) && DOMAIN_NS
chuanga 0:43ff9e3bc244 487 SYS_UnlockReg_S();
chuanga 0:43ff9e3bc244 488 #else
chuanga 0:43ff9e3bc244 489 SYS_UnlockReg();
chuanga 0:43ff9e3bc244 490 #endif
chuanga 0:43ff9e3bc244 491
chuanga 0:43ff9e3bc244 492 // Determine SDH port dependent on passed-in pins
chuanga 0:43ff9e3bc244 493 _sdh = (SDName) sd_mod;
chuanga 0:43ff9e3bc244 494 _sdh_base = (SDH_T *) NU_MODBASE(_sdh);
chuanga 0:43ff9e3bc244 495 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 496 switch (NU_MODSUBINDEX(_sdh)) {
chuanga 0:43ff9e3bc244 497 case 0:
chuanga 0:43ff9e3bc244 498 _sdh_port = SD_PORT0;
chuanga 0:43ff9e3bc244 499 break;
chuanga 0:43ff9e3bc244 500
chuanga 0:43ff9e3bc244 501 case 1:
chuanga 0:43ff9e3bc244 502 _sdh_port = SD_PORT1;
chuanga 0:43ff9e3bc244 503 break;
chuanga 0:43ff9e3bc244 504 }
chuanga 0:43ff9e3bc244 505 #endif
chuanga 0:43ff9e3bc244 506
chuanga 0:43ff9e3bc244 507 #if defined(DOMAIN_NS) && DOMAIN_NS
chuanga 0:43ff9e3bc244 508 SYS_ResetModule_S(_sdh_modinit->rsetidx);
chuanga 0:43ff9e3bc244 509 #else
chuanga 0:43ff9e3bc244 510 SYS_ResetModule(_sdh_modinit->rsetidx);
chuanga 0:43ff9e3bc244 511 #endif
chuanga 0:43ff9e3bc244 512
chuanga 0:43ff9e3bc244 513 #if defined(DOMAIN_NS) && DOMAIN_NS
chuanga 0:43ff9e3bc244 514 CLK_SetModuleClock_S(_sdh_modinit->clkidx, _sdh_modinit->clksrc, _sdh_modinit->clkdiv);
chuanga 0:43ff9e3bc244 515 #else
chuanga 0:43ff9e3bc244 516 CLK_SetModuleClock(_sdh_modinit->clkidx, _sdh_modinit->clksrc, _sdh_modinit->clkdiv);
chuanga 0:43ff9e3bc244 517 #endif
chuanga 0:43ff9e3bc244 518
chuanga 0:43ff9e3bc244 519 #if defined(DOMAIN_NS) && DOMAIN_NS
chuanga 0:43ff9e3bc244 520 CLK_EnableModuleClock_S(_sdh_modinit->clkidx);
chuanga 0:43ff9e3bc244 521 #else
chuanga 0:43ff9e3bc244 522 CLK_EnableModuleClock(_sdh_modinit->clkidx);
chuanga 0:43ff9e3bc244 523 #endif
chuanga 0:43ff9e3bc244 524
chuanga 0:43ff9e3bc244 525 #if defined(DOMAIN_NS) && DOMAIN_NS
chuanga 0:43ff9e3bc244 526 SYS_LockReg_S();
chuanga 0:43ff9e3bc244 527 #else
chuanga 0:43ff9e3bc244 528 SYS_LockReg();
chuanga 0:43ff9e3bc244 529 #endif
chuanga 0:43ff9e3bc244 530
chuanga 0:43ff9e3bc244 531 return BD_ERROR_OK;
chuanga 0:43ff9e3bc244 532 }
chuanga 0:43ff9e3bc244 533
chuanga 0:43ff9e3bc244 534 uint32_t NuSDBlockDevice::_sd_sectors()
chuanga 0:43ff9e3bc244 535 {
chuanga 0:43ff9e3bc244 536 _lock.lock();
chuanga 0:43ff9e3bc244 537
chuanga 0:43ff9e3bc244 538 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 539 switch (_sdh_port) {
chuanga 0:43ff9e3bc244 540 case SD_PORT0:
chuanga 0:43ff9e3bc244 541 _sectors = SD_DiskInfo0.totalSectorN;
chuanga 0:43ff9e3bc244 542 break;
chuanga 0:43ff9e3bc244 543 case SD_PORT1:
chuanga 0:43ff9e3bc244 544 _sectors = SD_DiskInfo1.totalSectorN;
chuanga 0:43ff9e3bc244 545 break;
chuanga 0:43ff9e3bc244 546 }
chuanga 0:43ff9e3bc244 547
chuanga 0:43ff9e3bc244 548 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487
chuanga 0:43ff9e3bc244 549 switch (NU_MODINDEX(_sdh)) {
chuanga 0:43ff9e3bc244 550 case 0:
chuanga 0:43ff9e3bc244 551 _sectors = SD0.totalSectorN;
chuanga 0:43ff9e3bc244 552 break;
chuanga 0:43ff9e3bc244 553 case 1:
chuanga 0:43ff9e3bc244 554 _sectors = SD1.totalSectorN;
chuanga 0:43ff9e3bc244 555 break;
chuanga 0:43ff9e3bc244 556 }
chuanga 0:43ff9e3bc244 557
chuanga 0:43ff9e3bc244 558 #elif TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 559 switch (NU_MODINDEX(_sdh)) {
chuanga 0:43ff9e3bc244 560 case 0:
chuanga 0:43ff9e3bc244 561 _sectors = SD0.totalSectorN;
chuanga 0:43ff9e3bc244 562 break;
chuanga 0:43ff9e3bc244 563 }
chuanga 0:43ff9e3bc244 564
chuanga 0:43ff9e3bc244 565 #endif
chuanga 0:43ff9e3bc244 566
chuanga 0:43ff9e3bc244 567 _lock.unlock();
chuanga 0:43ff9e3bc244 568
chuanga 0:43ff9e3bc244 569 return _sectors;
chuanga 0:43ff9e3bc244 570 }
chuanga 0:43ff9e3bc244 571
chuanga 0:43ff9e3bc244 572 void NuSDBlockDevice::_sdh_irq()
chuanga 0:43ff9e3bc244 573 {
chuanga 0:43ff9e3bc244 574 #if TARGET_NUMAKER_PFM_NUC472
chuanga 0:43ff9e3bc244 575 // TODO: Support IRQ
chuanga 0:43ff9e3bc244 576
chuanga 0:43ff9e3bc244 577 #elif TARGET_NUMAKER_PFM_M487 || TARGET_NUMAKER_IOT_M487
chuanga 0:43ff9e3bc244 578 // FMI data abort interrupt
chuanga 0:43ff9e3bc244 579 if (_sdh_base->GINTSTS & SDH_GINTSTS_DTAIF_Msk) {
chuanga 0:43ff9e3bc244 580 _sdh_base->GINTSTS = SDH_GINTSTS_DTAIF_Msk;
chuanga 0:43ff9e3bc244 581 /* ResetAllEngine() */
chuanga 0:43ff9e3bc244 582 _sdh_base->GCTL |= SDH_GCTL_GCTLRST_Msk;
chuanga 0:43ff9e3bc244 583 }
chuanga 0:43ff9e3bc244 584
chuanga 0:43ff9e3bc244 585 //----- SD interrupt status
chuanga 0:43ff9e3bc244 586 if (_sdh_base->INTSTS & SDH_INTSTS_BLKDIF_Msk) {
chuanga 0:43ff9e3bc244 587 // block down
chuanga 0:43ff9e3bc244 588 extern uint8_t volatile _SDH_SDDataReady;
chuanga 0:43ff9e3bc244 589 _SDH_SDDataReady = TRUE;
chuanga 0:43ff9e3bc244 590 _sdh_base->INTSTS = SDH_INTSTS_BLKDIF_Msk;
chuanga 0:43ff9e3bc244 591 }
chuanga 0:43ff9e3bc244 592
chuanga 0:43ff9e3bc244 593 // NOTE: On M487, there are two SDH instances which each support port 0 and don't support port 1.
chuanga 0:43ff9e3bc244 594 // Port 0 (support): INTEN.CDIEN0, INTEN.CDSRC0, INTSTS.CDIF0, INTSTS.CDSTS0
chuanga 0:43ff9e3bc244 595 // Port 1 (no support): INTEN.CDIEN1, INTEN.CDSRC1, INTSTS.CDIF1, INTSTS.CDSTS1
chuanga 0:43ff9e3bc244 596 if (_sdh_base->INTSTS & SDH_INTSTS_CDIF_Msk) { // port 0 card detect
chuanga 0:43ff9e3bc244 597 _sdh_base->INTSTS = SDH_INTSTS_CDIF_Msk;
chuanga 0:43ff9e3bc244 598 // TBD: Support PnP
chuanga 0:43ff9e3bc244 599 }
chuanga 0:43ff9e3bc244 600
chuanga 0:43ff9e3bc244 601 // CRC error interrupt
chuanga 0:43ff9e3bc244 602 if (_sdh_base->INTSTS & SDH_INTSTS_CRCIF_Msk) {
chuanga 0:43ff9e3bc244 603 _sdh_base->INTSTS = SDH_INTSTS_CRCIF_Msk; // clear interrupt flag
chuanga 0:43ff9e3bc244 604 }
chuanga 0:43ff9e3bc244 605
chuanga 0:43ff9e3bc244 606 if (_sdh_base->INTSTS & SDH_INTSTS_DITOIF_Msk) {
chuanga 0:43ff9e3bc244 607 _sdh_base->INTSTS = SDH_INTSTS_DITOIF_Msk;
chuanga 0:43ff9e3bc244 608 }
chuanga 0:43ff9e3bc244 609
chuanga 0:43ff9e3bc244 610 // Response in timeout interrupt
chuanga 0:43ff9e3bc244 611 if (_sdh_base->INTSTS & SDH_INTSTS_RTOIF_Msk) {
chuanga 0:43ff9e3bc244 612 _sdh_base->INTSTS |= SDH_INTSTS_RTOIF_Msk;
chuanga 0:43ff9e3bc244 613 }
chuanga 0:43ff9e3bc244 614
chuanga 0:43ff9e3bc244 615 #elif TARGET_NUMAKER_PFM_M2351
chuanga 0:43ff9e3bc244 616 // FMI data abort interrupt
chuanga 0:43ff9e3bc244 617 if (_sdh_base->GINTSTS & SDH_GINTSTS_DTAIF_Msk) {
chuanga 0:43ff9e3bc244 618 _sdh_base->GINTSTS = SDH_GINTSTS_DTAIF_Msk;
chuanga 0:43ff9e3bc244 619 /* ResetAllEngine() */
chuanga 0:43ff9e3bc244 620 _sdh_base->GCTL |= SDH_GCTL_GCTLRST_Msk;
chuanga 0:43ff9e3bc244 621 }
chuanga 0:43ff9e3bc244 622
chuanga 0:43ff9e3bc244 623 //----- SD interrupt status
chuanga 0:43ff9e3bc244 624 if (_sdh_base->INTSTS & SDH_INTSTS_BLKDIF_Msk) {
chuanga 0:43ff9e3bc244 625 // block down
chuanga 0:43ff9e3bc244 626 extern uint8_t volatile g_u8SDDataReadyFlag;
chuanga 0:43ff9e3bc244 627 g_u8SDDataReadyFlag = TRUE;
chuanga 0:43ff9e3bc244 628 _sdh_base->INTSTS = SDH_INTSTS_BLKDIF_Msk;
chuanga 0:43ff9e3bc244 629 }
chuanga 0:43ff9e3bc244 630
chuanga 0:43ff9e3bc244 631 if (_sdh_base->INTSTS & SDH_INTSTS_CDIF_Msk) { // port 0 card detect
chuanga 0:43ff9e3bc244 632 _sdh_base->INTSTS = SDH_INTSTS_CDIF_Msk;
chuanga 0:43ff9e3bc244 633 // TBD: Support PnP
chuanga 0:43ff9e3bc244 634 }
chuanga 0:43ff9e3bc244 635
chuanga 0:43ff9e3bc244 636 // CRC error interrupt
chuanga 0:43ff9e3bc244 637 if (_sdh_base->INTSTS & SDH_INTSTS_CRCIF_Msk) {
chuanga 0:43ff9e3bc244 638 _sdh_base->INTSTS = SDH_INTSTS_CRCIF_Msk; // clear interrupt flag
chuanga 0:43ff9e3bc244 639 }
chuanga 0:43ff9e3bc244 640
chuanga 0:43ff9e3bc244 641 if (_sdh_base->INTSTS & SDH_INTSTS_DITOIF_Msk) {
chuanga 0:43ff9e3bc244 642 _sdh_base->INTSTS = SDH_INTSTS_DITOIF_Msk;
chuanga 0:43ff9e3bc244 643 }
chuanga 0:43ff9e3bc244 644
chuanga 0:43ff9e3bc244 645 // Response in timeout interrupt
chuanga 0:43ff9e3bc244 646 if (_sdh_base->INTSTS & SDH_INTSTS_RTOIF_Msk) {
chuanga 0:43ff9e3bc244 647 _sdh_base->INTSTS |= SDH_INTSTS_RTOIF_Msk;
chuanga 0:43ff9e3bc244 648 }
chuanga 0:43ff9e3bc244 649
chuanga 0:43ff9e3bc244 650 #endif
chuanga 0:43ff9e3bc244 651 }
chuanga 0:43ff9e3bc244 652
chuanga 0:43ff9e3bc244 653 static bool sd_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
chuanga 0:43ff9e3bc244 654 {
chuanga 0:43ff9e3bc244 655 uint32_t buff_ = (uint32_t) buff;
chuanga 0:43ff9e3bc244 656
chuanga 0:43ff9e3bc244 657 return (((buff_ & 0x03) == 0) && // Word-aligned buffer base address
chuanga 0:43ff9e3bc244 658 ((buff_size & (size_aligned_to - 1)) == 0) && // 'size_aligned_to'-aligned buffer size
chuanga 0:43ff9e3bc244 659 #if TARGET_NUMAKER_PFM_M2351 && (defined(DOMAIN_NS) && DOMAIN_NS)
chuanga 0:43ff9e3bc244 660 (((buff_ >> 28) == 0x3) && (buff_size <= (0x40000000 - buff_)))); // 0x30000000-0x3FFFFFFF
chuanga 0:43ff9e3bc244 661 #else
chuanga 0:43ff9e3bc244 662 (((buff_ >> 28) == 0x2) && (buff_size <= (0x30000000 - buff_)))); // 0x20000000-0x2FFFFFFF
chuanga 0:43ff9e3bc244 663 #endif
chuanga 0:43ff9e3bc244 664 }
chuanga 0:43ff9e3bc244 665
chuanga 0:43ff9e3bc244 666 const char *NuSDBlockDevice::get_type() const
chuanga 0:43ff9e3bc244 667 {
chuanga 0:43ff9e3bc244 668 return "NUSD";
chuanga 0:43ff9e3bc244 669 }
chuanga 0:43ff9e3bc244 670
chuanga 0:43ff9e3bc244 671 #endif /* TARGET_NUVOTON */