1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #7324 from MichelRottleuthner/sdcard_mtd

sdcard_spi: integrate to mtd interface
This commit is contained in:
MichelRottleuthner 2017-08-09 11:30:41 +02:00 committed by GitHub
parent 39426bba7d
commit e5baef3810
6 changed files with 203 additions and 7 deletions

View File

@ -159,6 +159,11 @@ ifneq (,$(filter mpu9150,$(USEMODULE)))
USEMODULE += xtimer
endif
ifneq (,$(filter mtd_sdcard,$(USEMODULE)))
USEMODULE += mtd
USEMODULE += sdcard_spi
endif
ifneq (,$(filter nrfmin,$(USEMODULE)))
FEATURES_REQUIRED += radio_nrfmin
FEATURES_REQUIRED += periph_cpuid

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2017 HAW-Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup drivers_mtd_sdcard mtd wrapper for sdcard_spi
* @ingroup drivers_storage
* @brief Driver for SD-cards using mtd interface
*
* @{
*
* @file
* @brief Interface definition for mtd_sdcard driver
*
* @author Michel Rottleuthner <michel.rottleuthner@haw-hamburg.de>
*/
#ifndef MTD_SDCARD_H
#define MTD_SDCARD_H
#include <stdint.h>
#include "sdcard_spi.h"
#include "mtd.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Device descriptor for mtd_sdcard device
*
* This is an extension of the @c mtd_dev_t struct
*/
typedef struct {
mtd_dev_t base; /**< inherit from mtd_dev_t object */
sdcard_spi_t *sd_card; /**< sdcard_spi dev descriptor */
const sdcard_spi_params_t *params; /**< params for sdcard_spi init */
} mtd_sdcard_t;
/**
* @brief sdcards handle sector erase internally so it's possible to directly
* write to the card without erasing the sector first.
* Attention: an erase call will therefore NOT touch the content,
* so disable this feature to ensure overriding the data.
*/
#ifndef MTD_SDCARD_SKIP_ERASE
#define MTD_SDCARD_SKIP_ERASE (1)
#endif
/**
* @brief sdcard device operations table for mtd
*/
extern const mtd_desc_t mtd_sdcard_driver;
#ifdef __cplusplus
}
#endif
#endif /* MTD_SDCARD_H */
/** @} */

View File

@ -252,7 +252,7 @@ int sdcard_spi_read_blocks(sdcard_spi_t *card, int blockaddr, char *data, int bl
*
* @return number of sucessfully written blocks (0 if no block was written).
*/
int sdcard_spi_write_blocks(sdcard_spi_t *card, int blockaddr, char *data, int blocksize,
int sdcard_spi_write_blocks(sdcard_spi_t *card, int blockaddr, const char *data, int blocksize,
int nblocks, sd_rw_response_t *state);
/**

View File

@ -0,0 +1,3 @@
MODULE = mtd_sdcard
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,121 @@
/*
* Copyright (C) 2017 HAW-Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/
/**
* @ingroup drivers_mtd_sdcard
* @{
*
* @file
* @brief Driver for using sdcard_spi via mtd interface
*
* @author Michel Rottleuthner <michel.rottleuthner@haw-hamburg.de>
*
* @}
*/
#define ENABLE_DEBUG (0)
#include "debug.h"
#include "mtd.h"
#include "mtd_sdcard.h"
#include "sdcard_spi.h"
#include "sdcard_spi_internal.h"
#include <stdint.h>
#include <errno.h>
static int mtd_sdcard_init(mtd_dev_t *mtd);
static int mtd_sdcard_read(mtd_dev_t *mtd, void *dest, uint32_t addr,
uint32_t size);
static int mtd_sdcard_write(mtd_dev_t *mtd, const void *src, uint32_t addr,
uint32_t size);
static int mtd_sdcard_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t size);
static int mtd_sdcard_power(mtd_dev_t *mtd, enum mtd_power_state power);
const mtd_desc_t mtd_sdcard_driver = {
.init = mtd_sdcard_init,
.read = mtd_sdcard_read,
.write = mtd_sdcard_write,
.erase = mtd_sdcard_erase,
.power = mtd_sdcard_power,
};
static int mtd_sdcard_init(mtd_dev_t *dev)
{
DEBUG("mtd_sdcard_init\n");
mtd_sdcard_t *mtd_sd = (mtd_sdcard_t*)dev;
if ((mtd_sd->sd_card->init_done == true) ||
(sdcard_spi_init(mtd_sd->sd_card, mtd_sd->params) == 0)) {
/* erasing whole sectors is handled internally by the card so you can
delete single blocks (i.e. pages) */
dev->pages_per_sector = 1;
dev->sector_count = sdcard_spi_get_sector_count(mtd_sd->sd_card);
/* sdcard_spi always uses the fixed block size of SD-HC cards */
dev->page_size = SD_HC_BLOCK_SIZE;
return 0;
}
return -EIO;
}
static int mtd_sdcard_read(mtd_dev_t *dev, void *buff, uint32_t addr,
uint32_t size)
{
DEBUG("mtd_sdcard_read: addr:%lu size:%lu\n", addr, size);
mtd_sdcard_t *mtd_sd = (mtd_sdcard_t*)dev;
sd_rw_response_t err;
int res = sdcard_spi_read_blocks(mtd_sd->sd_card, addr / SD_HC_BLOCK_SIZE,
buff, SD_HC_BLOCK_SIZE,
size / SD_HC_BLOCK_SIZE, &err);
if (err == SD_RW_OK) {
return res * SD_HC_BLOCK_SIZE;
}
return -EIO;
}
static int mtd_sdcard_write(mtd_dev_t *dev, const void *buff, uint32_t addr,
uint32_t size)
{
DEBUG("mtd_sdcard_write: addr:%lu size:%lu\n", addr, size);
mtd_sdcard_t *mtd_sd = (mtd_sdcard_t*)dev;
sd_rw_response_t err;
int res = sdcard_spi_write_blocks(mtd_sd->sd_card, addr / SD_HC_BLOCK_SIZE,
buff, SD_HC_BLOCK_SIZE,
size / SD_HC_BLOCK_SIZE, &err);
if (err == SD_RW_OK) {
return res * SD_HC_BLOCK_SIZE;
}
return -EIO;
}
static int mtd_sdcard_erase(mtd_dev_t *dev,
uint32_t addr,
uint32_t size)
{
DEBUG("mtd_sdcard_erase: addr:%lu size:%lu\n", addr, size);
(void)dev;
(void)addr;
(void)size;
#if MTD_SDCARD_SKIP_ERASE == 1
return 0;
#else
return -ENOTSUP; /* explicit erase currently not supported */
#endif
}
static int mtd_sdcard_power(mtd_dev_t *dev, enum mtd_power_state power)
{
(void)dev;
(void)power;
/* TODO: implement power down of sdcard in sdcard_spi
(make use of sdcard_spi_params_t.power pin) */
return -ENOTSUP; /* currently not supported */
}

View File

@ -40,7 +40,7 @@ static sd_init_fsm_state_t _init_sd_fsm_step(sdcard_spi_t *card, sd_init_fsm_sta
static sd_rw_response_t _read_cid(sdcard_spi_t *card);
static sd_rw_response_t _read_csd(sdcard_spi_t *card);
static sd_rw_response_t _read_data_packet(sdcard_spi_t *card, char token, char *data, int size);
static sd_rw_response_t _write_data_packet(sdcard_spi_t *card, char token, char *data, int size);
static sd_rw_response_t _write_data_packet(sdcard_spi_t *card, char token, const char *data, int size);
/* CRC-7 (polynomial: x^7 + x^3 + 1) LSB of CRC-7 in a 8-bit variable is always 1*/
static char _crc_7(const char *data, int n);
@ -49,7 +49,7 @@ static char _crc_7(const char *data, int n);
static uint16_t _crc_16(const char *data, size_t n);
/* use this transfer method instead of _transfer_bytes to force the use of 0xFF as dummy bytes */
static inline int _transfer_bytes(sdcard_spi_t *card, char *out, char *in, unsigned int length);
static inline int _transfer_bytes(sdcard_spi_t *card, const char *out, char *in, unsigned int length);
/* uses bitbanging for spi communication which allows to enable pull-up on the miso pin for
greater card compatibility on platforms that don't have a hw pull up installed */
@ -576,7 +576,7 @@ static inline int _hw_spi_rxtx_byte(sdcard_spi_t *card, char out, char *in){
return 1;
}
static inline int _transfer_bytes(sdcard_spi_t *card, char *out, char *in, unsigned int length){
static inline int _transfer_bytes(sdcard_spi_t *card, const char *out, char *in, unsigned int length){
int trans_ret;
unsigned trans_bytes = 0;
char in_temp;
@ -703,7 +703,7 @@ int sdcard_spi_read_blocks(sdcard_spi_t *card, int blockaddr, char *data, int bl
}
}
static sd_rw_response_t _write_data_packet(sdcard_spi_t *card, char token, char *data, int size)
static sd_rw_response_t _write_data_packet(sdcard_spi_t *card, char token, const char *data, int size)
{
spi_transfer_byte(card->params.spi_dev, GPIO_UNDEF, true, token);
@ -758,7 +758,7 @@ static sd_rw_response_t _write_data_packet(sdcard_spi_t *card, char token, char
}
}
static inline int _write_blocks(sdcard_spi_t *card, char cmd_idx, int bladdr, char *data, int blsz,
static inline int _write_blocks(sdcard_spi_t *card, char cmd_idx, int bladdr, const char *data, int blsz,
int nbl, sd_rw_response_t *state)
{
_select_card_spi(card);
@ -823,7 +823,7 @@ static inline int _write_blocks(sdcard_spi_t *card, char cmd_idx, int bladdr, ch
}
}
int sdcard_spi_write_blocks(sdcard_spi_t *card, int blockaddr, char *data, int blocksize,
int sdcard_spi_write_blocks(sdcard_spi_t *card, int blockaddr, const char *data, int blocksize,
int nblocks, sd_rw_response_t *state)
{
if (nblocks > 1) {