for DISCO-F469NI based on BD_SD_DISCO_F746NG library by Roy Krikke

Dependents:   DISCO-F469NI_BD_SD_Card_Control USBDevice_microSD_RW_F469NI DISCO-F469NI_BD_SD_Card_Control

Fork of BD_SD_DISCO_F769NI by Kenji Arai

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Sat Apr 07 02:06:27 2018 +0000
Child:
1:d01aa82597cb
Commit message:
for DISCO-F769NI based on BD_SD_DISCO_F746NG library by Roy Krikke

Changed in this revision

SDBlockDeviceDISCOF769NI.cpp Show annotated file Show diff for this revision Revisions of this file
SDBlockDeviceDISCOF769NI.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDBlockDeviceDISCOF769NI.cpp	Sat Apr 07 02:06:27 2018 +0000
@@ -0,0 +1,271 @@
+/* SD/MMC Block device Library for MBED-OS
+ * Copyright 2017 Roy Krikke
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/*
+    Original Library by Roy Krikke
+    https://os.mbed.com/users/roykrikke/code/BD_SD_DISCO_F746NG/
+    https://os.mbed.com/users/roykrikke/
+
+    Modified by K.Arai / JH1PJL     April 5th, 2018
+    
+    All of following keywords are changed
+    F746NG  -> F769NI
+    32746g  -> 32f769i
+ */
+
+#include "SDBlockDeviceDISCOF769NI.h"
+#include "mbed_debug.h"
+
+/* Required version: 5.5.0 and above */
+#if defined(MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5
+#if (MBED_VERSION < MBED_ENCODE_VERSION(5,5,0))
+#error "Incompatible mbed-os version detected! Required 5.5.0 and above"
+#endif
+#else
+#warning "mbed-os version 5.5.0 or above required"
+#endif
+
+/* Required version: 5.5.0 and above */
+#warning "Block device class BD_SD_DISCO_F769NI is depending on BSP_DISCO_F769NI libary (Revision 3:145e71 with date 06 Jul 2017)"
+
+#define SD_DBG 0 /*!< 1 - Enable debugging */
+
+/** Enum of standard error codes
+ *
+ *  @enum bd_sd_error
+ */
+enum bd_sd_error {
+    SD_BLOCK_DEVICE_OK = 0,             /*!< no error */
+    SD_BLOCK_DEVICE_ERROR = -5000,      /*!< device specific error */
+    //SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK = -5001,  /*!< operation would block */
+    //SD_BLOCK_DEVICE_ERROR_UNSUPPORTED = -5002,  /*!< unsupported operation */
+    SD_BLOCK_DEVICE_ERROR_PARAMETER = -5003,    /*!< invalid parameter */
+    SD_BLOCK_DEVICE_ERROR_NO_INIT = -5004,      /*!< uninitialized */
+    SD_BLOCK_DEVICE_ERROR_NO_DEVICE = -5005,    /*!< device is missing or not connected */
+    //SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED = -5006,    /*!< write protected */
+    //SD_BLOCK_DEVICE_ERROR_UNUSABLE = -5007,           /*!< unusable card */
+    //SD_BLOCK_DEVICE_ERROR_NO_RESPONSE = -5008,        /*!< No response from device */
+    //SD_BLOCK_DEVICE_ERROR_CRC = -5009,                /*!< CRC error */
+    SD_BLOCK_DEVICE_ERROR_ERASE = -5010,        /*!< Erase error */
+    SD_BLOCK_DEVICE_ERROR_READ = -5011,         /*!< Read error */
+    SD_BLOCK_DEVICE_ERROR_PROGRAM = -5012,      /*!< Program error */
+};
+
+#define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes  */
+
+SDBlockDeviceDISCOF769NI::SDBlockDeviceDISCOF769NI() :
+    _read_size (BLOCK_SIZE_HC), _program_size (BLOCK_SIZE_HC),
+    _erase_size(BLOCK_SIZE_HC), _block_size (BLOCK_SIZE_HC),
+    _capacity_in_blocks (0)
+{
+    _timeout = 1000;
+}
+
+SDBlockDeviceDISCOF769NI::~SDBlockDeviceDISCOF769NI()
+{
+    if(_is_initialized) {
+        deinit ();
+    }
+}
+
+int SDBlockDeviceDISCOF769NI::init()
+{
+    lock();
+    _sd_state = BSP_SD_Init();
+
+    if(_sd_state != MSD_OK) {
+        if(_sd_state == MSD_ERROR_SD_NOT_PRESENT) {
+            debug_if(SD_DBG, "SD card is missing or not connected\n");
+            unlock ();
+            return SD_BLOCK_DEVICE_ERROR_NO_DEVICE;
+        } else {
+            debug_if(SD_DBG, "SD card initialization failed\n");
+            unlock();
+            return SD_BLOCK_DEVICE_ERROR_NO_INIT;
+        }
+    }
+    BSP_SD_GetCardInfo(&_current_card_info);
+
+    _card_type = _current_card_info.CardType;
+    _read_size = _current_card_info.BlockSize;
+    _program_size = _current_card_info.BlockSize;
+    _erase_size = _current_card_info.BlockSize;
+    _block_size = _current_card_info.BlockSize;
+    _capacity_in_blocks = _current_card_info.BlockNbr;
+
+    debug_if(SD_DBG, "Card Type: %i\n", _current_card_info.CardType);
+    debug_if(SD_DBG, "Card Version: %i\n", _current_card_info.CardVersion);
+    debug_if(SD_DBG, "Class: %i\n", _current_card_info.Class);
+    debug_if(SD_DBG, "Relative Card Address: %x\n", _current_card_info.RelCardAdd);
+    debug_if(SD_DBG, "Card Capacity in blocks: %i\n", _current_card_info.BlockNbr);
+    debug_if(SD_DBG, "One block size in bytes: %i\n", _current_card_info.BlockSize);
+    debug_if(SD_DBG, "Card logical Capacity in blocks: %i\n", _current_card_info.LogBlockNbr);
+    debug_if(SD_DBG, "Logical block size in bytes: %i\n", _current_card_info.LogBlockSize);
+    debug_if(SD_DBG, "Timeout: %i\n", _timeout);
+
+    _is_initialized = true;
+    unlock();
+    return SD_BLOCK_DEVICE_OK;
+}
+
+int SDBlockDeviceDISCOF769NI::deinit()
+{
+    lock();
+    _sd_state = BSP_SD_DeInit ();
+    if(_sd_state != MSD_OK) {
+        debug_if (SD_DBG, "SD card deinitialization failed\n");
+        return SD_BLOCK_DEVICE_ERROR;
+    }
+    _is_initialized = false;
+    unlock();
+    return BD_ERROR_OK;
+}
+
+int SDBlockDeviceDISCOF769NI::read(void *b, bd_addr_t addr, bd_size_t size)
+{
+    if(!is_valid_read (addr, size)) {
+        return SD_BLOCK_DEVICE_ERROR_PARAMETER;
+    }
+
+    lock();
+    if(!_is_initialized) {
+        unlock();
+        return SD_BLOCK_DEVICE_ERROR_NO_INIT;
+    }
+
+    uint32_t *buffer = static_cast<uint32_t *> (b);
+    int status = SD_BLOCK_DEVICE_OK;
+
+    // Get block address
+    uint32_t block_addr = addr / _block_size;
+    // Get block count
+    uint32_t block_cnt = size / _block_size;
+
+    debug_if(
+        SD_DBG,
+        "BD_SD_DISCO_F769NI::read addr: 0x%x, block_addr: %i size: %lu block count: %i\n",
+        addr, block_addr, size, block_cnt);
+
+    if(BSP_SD_ReadBlocks (buffer, block_addr, block_cnt, _timeout) != MSD_OK) {
+        status = SD_BLOCK_DEVICE_ERROR_READ;
+    }
+
+    // Wait until SD card is ready to use for new operation
+    while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
+    }
+
+    unlock ();
+    return status;
+}
+
+int SDBlockDeviceDISCOF769NI::program(const void *b, bd_addr_t addr, bd_size_t size)
+{
+    if(!is_valid_program (addr, size)) {
+        return SD_BLOCK_DEVICE_ERROR_PARAMETER;
+    }
+
+    lock();
+    if(!_is_initialized) {
+        unlock ();
+        return SD_BLOCK_DEVICE_ERROR_NO_INIT;
+    }
+
+    uint32_t* buffer =
+        const_cast<uint32_t*> (reinterpret_cast<const uint32_t*> (b));
+    int status = SD_BLOCK_DEVICE_OK;
+
+    // Get block address
+    uint32_t block_addr = addr / _block_size;
+    // Get block count
+    uint32_t block_cnt = size / _block_size;
+
+    debug_if (
+        SD_DBG,
+        "BD_SD_DISCO_F769NI::program addr: 0x%x, block_addr: %i size: %lu block count: %i\n",
+        addr, block_addr, size, block_cnt);
+
+    if(BSP_SD_WriteBlocks (buffer, block_addr, block_cnt, _timeout) != MSD_OK) {
+        status = SD_BLOCK_DEVICE_ERROR_PROGRAM;
+    }
+
+    // Wait until SD card is ready to use for new operation
+    while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
+    }
+
+    unlock();
+    return status;
+}
+
+int SDBlockDeviceDISCOF769NI::erase(bd_addr_t addr, bd_size_t size)
+{
+    if (!is_valid_erase(addr, size)) {
+        return SD_BLOCK_DEVICE_ERROR_PARAMETER;
+    }
+
+    lock();
+    if(!_is_initialized) {
+        unlock();
+        return SD_BLOCK_DEVICE_ERROR_NO_INIT;
+    }
+
+    size -= _block_size;
+
+    int status = SD_BLOCK_DEVICE_OK;
+    uint32_t start_addr = addr;
+    uint32_t end_addr = start_addr + size;
+
+    // Get block count
+    uint32_t block_start_addr = start_addr / _block_size;
+    // Get block address
+    uint32_t block_end_addr = end_addr / _block_size;
+
+    debug_if(
+        SD_DBG,
+        "BD_SD_DISCO_F769NI::erase start_addr: 0x%x, block_start_addr: %i | end_addr: 0x%x, block_end_addr: %i size: %lu\n",
+        start_addr, block_start_addr, end_addr, block_end_addr, size);
+
+    if(BSP_SD_Erase (block_start_addr, block_end_addr) != MSD_OK) {
+        status = SD_BLOCK_DEVICE_ERROR_ERASE;
+    }
+
+    /* Wait until SD card is ready to use for new operation */
+    while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
+    }
+
+    unlock();
+    return status;
+}
+
+bd_size_t SDBlockDeviceDISCOF769NI::get_read_size() const
+{
+    return _read_size;
+}
+
+bd_size_t SDBlockDeviceDISCOF769NI::get_program_size() const
+{
+    return _program_size;
+}
+
+bd_size_t SDBlockDeviceDISCOF769NI::get_erase_size() const
+{
+    return _erase_size;
+}
+
+bd_size_t SDBlockDeviceDISCOF769NI::size() const
+{
+    return (_block_size * _capacity_in_blocks);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDBlockDeviceDISCOF769NI.h	Sat Apr 07 02:06:27 2018 +0000
@@ -0,0 +1,209 @@
+/* SD/MMC Block device Library for MBED-OS
+ * Copyright 2017 Roy Krikke
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/*
+    Original Library by Roy Krikke
+    https://os.mbed.com/users/roykrikke/code/BD_SD_DISCO_F746NG/
+    https://os.mbed.com/users/roykrikke/
+
+    Modified by K.Arai / JH1PJL     April 5th, 2018
+    
+    All of following keywords are changed
+    F746NG  -> F769NI
+    32746g  -> 32f769i
+ */
+
+#ifndef BD_SD_DISCO_F769NI_H
+#define BD_SD_DISCO_F769NI_H
+
+#include "mbed.h"
+#include "BlockDevice.h"
+#include "platform/PlatformMutex.h"
+#include "stm32f769i_discovery_sd.h"
+
+#define BD_SD_DISCO_F769NI_MAJOR_VERSION 1
+#define BD_SD_DISCO_F769NI_MINOR_VERSION 0
+#define BD_SD_DISCO_F769NI_PATCH_VERSION 0
+
+/**
+ * BD_SD_DISCO_F769NI class.
+ *  Block device class for creating a block device to access a SD/MMC card via SD/MMC interface on DISCO_F769NI
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "SDBlockDeviceDISCOF769NI.h"
+ *
+ * DigitalOut led (LED1);
+ *
+ * // Instantiate the Block Device for sd card on DISCO-F769NI
+ * SDBlockDeviceDISCOF769NI bd;
+ * uint8_t block[512] = "Hello World!\n";
+ *
+ * int
+ * main () {
+ *   Serial pc(SERIAL_TX, SERIAL_RX);
+ *   pc.baud (115200);
+ *   printf("Start\n");
+ *
+ *   // Call the SDBlockDevice-DISCO-F769NI instance initialisation method.
+ *   printf("sd card init...\n");
+ *   if (0 != bd.init ()) {
+ *     printf("Init failed \n");
+ *     return -1;
+ *   }
+ *
+ *   printf("sd size: %llu\n", bd.size ());
+ *   printf("sd read size: %llu\n", bd.get_read_size ());
+ *   printf("sd program size: %llu\n", bd.get_program_size ());
+ *   printf("sd erase size: %llu\n\n", bd.get_erase_size ());
+ *
+ *   printf("sd erase...\n");
+ *   if (0 != bd.erase (0, bd.get_erase_size ())) {
+ *     printf ("Error Erasing block \n");
+ *   }
+ *
+ *   // Write some the data block to the device
+ *   printf("sd write: %s\n", block);
+ *   if (0 == bd.program (block, 0, 512)) {
+ *     // read the data block from the device
+ *     printf ("sd read: ");
+ *     if (0 == bd.read (block, 0, 512)) {
+ *       // print the contents of the block
+ *       printf ("%s", block);
+ *     }
+ *   }
+ *
+ *   // Call the BD_SD_DISCO_F769NI instance de-initialisation method.
+ *   printf("sd card deinit...\n");
+ *   if(0 != bd.deinit ()) {
+ *     printf ("Deinit failed \n");
+ *     return -1;
+ *   }
+ *
+ *   // Blink led with 2 Hz
+ *   while(true) {
+ *     led = !led;
+ *     wait (0.5);
+ *   }
+ * }
+ * @endcode
+ *
+ */
+class SDBlockDeviceDISCOF769NI : public BlockDevice
+{
+public:
+
+    /** Lifetime of the memory block device
+     *
+     * Only a block size of 512 bytes is supported
+     *
+     */
+    SDBlockDeviceDISCOF769NI();
+    virtual ~SDBlockDeviceDISCOF769NI();
+
+    /** Initialize a block device
+     *
+     *  @return         0 on success or a negative error code on failure
+     */
+    virtual int init();
+
+    /** Deinitialize a block device
+     *
+     *  @return         0 on success or a negative error code on failure
+     */
+    virtual int deinit();
+
+    /** Read blocks from a block device
+     *
+     *  @param buffer   Buffer to read blocks into
+     *  @param addr     Address of block to begin reading from
+     *  @param size     Size to read in bytes, must be a multiple of read block size
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual int read(void *buffer, bd_addr_t addr, bd_size_t size);
+
+    /** Program blocks to a block device
+     *
+     *  The blocks must have been erased prior to being programmed
+     *
+     *  @param buffer   Buffer of data to write to blocks
+     *  @param addr     Address of block to begin writing to
+     *  @param size     Size to write in bytes, must be a multiple of program block size
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size);
+
+    /** Erase blocks on a block device
+     *
+     *  The state of an erased block is undefined until it has been programmed
+     *
+     *  @param addr     Address of block to begin erasing
+     *  @param size     Size to erase in bytes, must be a multiple of erase block size
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual int erase(bd_addr_t addr, bd_size_t size);
+
+    /** Get the size of a readable block
+     *
+     *  @return         Size of a readable block in bytes
+     */
+    virtual bd_size_t get_read_size() const;
+
+    /** Get the size of a programable block
+     *
+     *  @return         Size of a programable block in bytes
+     */
+    virtual bd_size_t get_program_size() const;
+
+    /** Get the size of a eraseable block
+     *
+     *  @return         Size of a eraseable block in bytes
+     */
+    virtual bd_size_t get_erase_size() const;
+
+    /** Get the total size of the underlying device
+     *
+     *  @return         Size of the underlying device in bytes
+     */
+    virtual bd_size_t size() const;
+
+private:
+    uint8_t _card_type;
+    bd_size_t _read_size;
+    bd_size_t _program_size;
+    bd_size_t _erase_size;
+    bd_size_t _block_size;
+    bd_size_t _capacity_in_blocks;
+    BSP_SD_CardInfo _current_card_info;
+    uint8_t _sd_state;
+    uint32_t _timeout;
+    PlatformMutex _mutex;
+    bool _is_initialized;
+
+    virtual void
+    lock () {
+        _mutex.lock();
+    }
+
+    virtual void
+    unlock() {
+        _mutex.unlock ();
+    }
+
+};
+
+#endif /* BD_SD_DISCO_F769NI_H */