mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
19523: boards/iotlab-m3: enable l3g4200d_ng r=benpicco a=benpicco 19527: drivers/sdcard_spi: small cleanup r=benpicco a=gschorcht ### Contribution description This PR provides a small cleanup: - the copy of `sdcard_spi_params_t` is removed (commitbfc2a51f70
) - the documentation was changed to fit the 100 characters per line. (commit36f0162b34
) It is not necessary to hold a complete copy `sdcard_spi_params_t` in the device descriptor. Constant parameters can be used directly from ROM instead. This saves 24 bytes of RAM. ### Testing procedure Use any board with SD Card SPI interface. The driver test should still work, for example: ``` BOARD=esp32-wrover-kit make -j8 -C tests/driver_sdcard_spi flash term ``` ``` main(): This is RIOT! (Version: 2023.07-devel-176-g7213c-drivers/sdcard_spi_cleanup) SD-card spi driver test application insert SD-card and use 'init' command to set card to spi mode WARNING: using 'write' or 'copy' commands WILL overwrite data on your sd-card and almost for sure corrupt existing filesystems, partitions and contained data! > init Initializing SD-card at SPI_0... [OK] > ``` ### Issues/PRs references 19530: sys/xtimer: add missing "modules.h" include to `xtimer.h` r=benpicco a=kaspar030 19532: tests/unittests: tests-core-mbox: add missing `container.h` include r=benpicco a=kaspar030 19533: core: move macros/math.h to core/lib/include/macros r=benpicco a=kaspar030 19535: nanocoap_sock: defuse nanocoap_sock_get() API footgun r=benpicco a=benpicco Co-authored-by: Benjamin Valentin <benjamin.valentin@ml-pa.com> Co-authored-by: Gunar Schorcht <gunar@schorcht.net> Co-authored-by: Kaspar Schleiser <kaspar@schleiser.de>
This commit is contained in:
commit
c4b27d8241
@ -24,7 +24,7 @@ config BOARD_COMMON_IOTLAB
|
||||
|
||||
select HAVE_AT86RF231
|
||||
select HAVE_SAUL_GPIO
|
||||
select HAVE_L3G4200D
|
||||
select HAVE_L3G4200D_NG
|
||||
select HAVE_LSM303DLHC
|
||||
|
||||
config CLOCK_HSE
|
||||
|
@ -4,6 +4,6 @@ endif
|
||||
|
||||
ifneq (,$(filter saul_default,$(USEMODULE)))
|
||||
USEMODULE += saul_gpio
|
||||
USEMODULE += l3g4200d
|
||||
USEMODULE += l3gxxxx l3g4200d_ng
|
||||
USEMODULE += lsm303dlhc
|
||||
endif
|
||||
|
@ -976,7 +976,7 @@ extern "C"
|
||||
#include "l3gxxxx_regs.h"
|
||||
|
||||
#if !IS_USED(MODULE_L3GD20H) && !IS_USED(MODULE_L3GD20) \
|
||||
&& !IS_USED(MODULE_L3G4200_NG) \
|
||||
&& !IS_USED(MODULE_L3G4200D_NG) \
|
||||
&& !IS_USED(MODULE_A3G4250D) \
|
||||
&& !IS_USED(MODULE_I3G4250D)
|
||||
#error Please select your sensor variant by using the respective pseudomodule.
|
||||
|
@ -186,25 +186,27 @@ typedef struct {
|
||||
* @brief Device descriptor for sdcard_spi
|
||||
*/
|
||||
typedef struct {
|
||||
sdcard_spi_params_t params; /**< parameters for pin and spi config */
|
||||
spi_clk_t spi_clk; /**< active SPI clock speed */
|
||||
bool use_block_addr; /**< true if block addressing (vs. byte addressing) is used */
|
||||
bool init_done; /**< set to true once the init procedure completed successfully */
|
||||
sd_version_t card_type; /**< version of SD-card */
|
||||
int csd_structure; /**< version of the CSD register structure */
|
||||
cid_t cid; /**< CID register */
|
||||
csd_t csd; /**< CSD register */
|
||||
const sdcard_spi_params_t *params; /**< parameters for pin and spi config */
|
||||
spi_clk_t spi_clk; /**< active SPI clock speed */
|
||||
bool use_block_addr; /**< true if block addressing (vs. byte addressing) is used */
|
||||
bool init_done; /**< set to true once the init procedure completed successfully */
|
||||
sd_version_t card_type; /**< version of SD-card */
|
||||
int csd_structure; /**< version of the CSD register structure */
|
||||
cid_t cid; /**< CID register */
|
||||
csd_t csd; /**< CSD register */
|
||||
} sdcard_spi_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes the sd-card with the given parameters in sdcard_spi_t structure.
|
||||
* The init procedure also takes care of initializing the spi peripheral to master
|
||||
* mode and performing all necessary steps to set the sd-card to spi-mode. Reading
|
||||
* the CID and CSD registers is also done within this routine and their
|
||||
* values are copied to the given sdcard_spi_t struct.
|
||||
* @brief Initializes the sd-card with the given parameters in sdcard_spi_t structure.
|
||||
*
|
||||
* The init procedure also takes care of initializing the spi peripheral to
|
||||
* master mode and performing all necessary steps to set the sd-card to spi-mode.
|
||||
* Reading the CID and CSD registers is also done within this routine and their
|
||||
* values are copied to the given sdcard_spi_t struct.
|
||||
*
|
||||
* @param[out] card the device descriptor
|
||||
* @param[in] params parameters for this device (pins and spi device are initialized by this driver)
|
||||
* @param[in] params parameters for this device (pins and spi device are
|
||||
* initialized by this driver)
|
||||
*
|
||||
* @return 0 if the card could be initialized successfully
|
||||
* @return false if an error occurred while initializing the card
|
||||
@ -212,47 +214,54 @@ typedef struct {
|
||||
int sdcard_spi_init(sdcard_spi_t *card, const sdcard_spi_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Reads data blocks (usually multiples of 512 Bytes) from card to buffer.
|
||||
* @brief Reads data blocks (usually multiples of 512 Bytes) from card to buffer.
|
||||
*
|
||||
* @param[in] card Initialized sd-card struct
|
||||
* @param[in] blockaddr Start address to read from. Independent of the actual addressing scheme of
|
||||
* the used card the address needs to be given as block address
|
||||
* (e.g. 0, 1, 2... NOT: 0, 512... ). The driver takes care of mapping to
|
||||
* byte addressing if needed.
|
||||
* @param[out] data Buffer to store the read data in. The user is responsible for providing a
|
||||
* suitable buffer size.
|
||||
* @param[in] blocksize Size of data blocks. For now only 512 byte blocks are supported because
|
||||
* only older (SDSC) cards support variable blocksizes anyway.
|
||||
* With SDHC/SDXC-cards this is always fixed to 512 bytes. SDSC cards are
|
||||
* automatically forced to use 512 byte as blocksize by the init procedure.
|
||||
* @param[in] blockaddr Start address to read from. Independent of the actual
|
||||
* addressing scheme of the used card the address needs
|
||||
* to be given as block address (e.g. 0, 1, 2...
|
||||
* NOT: 0, 512... ). The driver takes care of mapping
|
||||
* to byte addressing if needed.
|
||||
* @param[out] data Buffer to store the read data in. The user is
|
||||
* responsible for providing a suitable buffer size.
|
||||
* @param[in] blocksize Size of data blocks. For now only 512 byte blocks
|
||||
* are supported because only older (SDSC) cards support
|
||||
* variable blocksizes anyway. With SDHC/SDXC-cards this
|
||||
* is always fixed to 512 bytes. SDSC cards are
|
||||
* automatically forced to use 512 byte as blocksize by
|
||||
* the init procedure.
|
||||
* @param[in] nblocks Number of blocks to read
|
||||
* @param[out] state Contains information about the error state if something went wrong
|
||||
* (if return value is lower than nblocks).
|
||||
* @param[out] state Contains information about the error state if
|
||||
* something went wrong (if return value is lower than nblocks).
|
||||
*
|
||||
* @return number of successfully read blocks (0 if no block was read).
|
||||
* @return number of successfully read blocks (0 if no block was read).
|
||||
*/
|
||||
int sdcard_spi_read_blocks(sdcard_spi_t *card, uint32_t blockaddr,
|
||||
void *data, uint16_t blocksize,
|
||||
uint16_t nblocks, sd_rw_response_t *state);
|
||||
|
||||
/**
|
||||
* @brief Writes data blocks (usually multiples of 512 Bytes) from buffer to card.
|
||||
* @brief Writes data blocks (usually multiples of 512 Bytes) from buffer to card.
|
||||
*
|
||||
* @param[in] card Initialized sd-card struct
|
||||
* @param[in] blockaddr Start address to read from. Independent of the actual addressing scheme of
|
||||
* the used card the address needs to be given as block address
|
||||
* (e.g. 0, 1, 2... NOT: 0, 512... ). The driver takes care of mapping to
|
||||
* @param[in] blockaddr Start address to read from. Independent of the actual
|
||||
* addressing scheme of the used card the address needs
|
||||
* to be given as block address (e.g. 0, 1, 2...
|
||||
* NOT: 0, 512... ). The driver takes care of mapping to
|
||||
* byte addressing if needed.
|
||||
* @param[out] data Buffer that contains the data to be sent.
|
||||
* @param[in] blocksize Size of data blocks. For now only 512 byte blocks are supported because
|
||||
* only older (SDSC) cards support variable blocksizes anyway.
|
||||
* With SDHC/SDXC-cards this is always fixed to 512 bytes. SDSC cards are
|
||||
* automatically forced to use 512 byte as blocksize by the init procedure.
|
||||
* @param[in] blocksize Size of data blocks. For now only 512 byte blocks
|
||||
* are supported because only older (SDSC) cards support
|
||||
* variable blocksizes anyway. With SDHC/SDXC-cards this
|
||||
* is always fixed to 512 bytes. SDSC cards are
|
||||
* automatically forced to use 512 byte as blocksize by
|
||||
* the init procedure.
|
||||
* @param[in] nblocks Number of blocks to write
|
||||
* @param[out] state Contains information about the error state if something went wrong
|
||||
* @param[out] state Contains information about the error state if
|
||||
* something went wrong
|
||||
* (if return value is lower than nblocks).
|
||||
*
|
||||
* @return number of successfully written blocks (0 if no block was written).
|
||||
* @return number of successfully written blocks (0 if no block was written).
|
||||
*/
|
||||
int sdcard_spi_write_blocks(sdcard_spi_t *card, uint32_t blockaddr,
|
||||
const void *data, uint16_t blocksize,
|
||||
|
@ -931,7 +931,7 @@ static int _is_available(l3gxxxx_t *dev)
|
||||
case L3GXXXX_CHIP_ID_L3GD20: dev->sensor = L3GD20;
|
||||
break;
|
||||
#endif
|
||||
#if IS_USED(MODULE_L3G4200D) || IS_USED(MODULE_I3G4250D) || IS_USED(MODULE_A3G4250D)
|
||||
#if IS_USED(MODULE_L3G4200D_NG) || IS_USED(MODULE_I3G4250D) || IS_USED(MODULE_A3G4250D)
|
||||
case L3GXXXX_CHIP_ID_X3G42XXD: dev->sensor = X3G42XXD;
|
||||
break;
|
||||
#endif
|
||||
|
@ -89,7 +89,7 @@ int sdcard_spi_init(sdcard_spi_t *card, const sdcard_spi_params_t *params)
|
||||
{
|
||||
sd_init_fsm_state_t state = SD_INIT_START;
|
||||
|
||||
card->params = *params;
|
||||
card->params = params;
|
||||
card->spi_clk = SD_CARD_SPI_SPEED_PREINIT;
|
||||
|
||||
do {
|
||||
@ -112,14 +112,14 @@ static sd_init_fsm_state_t _init_sd_fsm_step(sdcard_spi_t *card, sd_init_fsm_sta
|
||||
DEBUG("SD_INIT_START\n");
|
||||
|
||||
#ifdef MODULE_PERIPH_SPI_RECONFIGURE
|
||||
spi_deinit_pins(card->params.spi_dev);
|
||||
spi_deinit_pins(card->params->spi_dev);
|
||||
#endif
|
||||
if ((gpio_init(card->params.mosi, GPIO_OUT) == 0) &&
|
||||
(gpio_init(card->params.clk, GPIO_OUT) == 0) &&
|
||||
(gpio_init(card->params.cs, GPIO_OUT) == 0) &&
|
||||
(gpio_init(card->params.miso, GPIO_IN_PU) == 0) &&
|
||||
((!gpio_is_valid(card->params.power)) ||
|
||||
(gpio_init(card->params.power, GPIO_OUT) == 0))) {
|
||||
if ((gpio_init(card->params->mosi, GPIO_OUT) == 0) &&
|
||||
(gpio_init(card->params->clk, GPIO_OUT) == 0) &&
|
||||
(gpio_init(card->params->cs, GPIO_OUT) == 0) &&
|
||||
(gpio_init(card->params->miso, GPIO_IN_PU) == 0) &&
|
||||
((!gpio_is_valid(card->params->power)) ||
|
||||
(gpio_init(card->params->power, GPIO_OUT) == 0))) {
|
||||
|
||||
DEBUG("gpio_init(): [OK]\n");
|
||||
return SD_INIT_SPI_POWER_SEQ;
|
||||
@ -131,20 +131,20 @@ static sd_init_fsm_state_t _init_sd_fsm_step(sdcard_spi_t *card, sd_init_fsm_sta
|
||||
case SD_INIT_SPI_POWER_SEQ:
|
||||
DEBUG("SD_INIT_SPI_POWER_SEQ\n");
|
||||
|
||||
if (gpio_is_valid(card->params.power)) {
|
||||
gpio_write(card->params.power, card->params.power_act_high);
|
||||
if (gpio_is_valid(card->params->power)) {
|
||||
gpio_write(card->params->power, card->params->power_act_high);
|
||||
ztimer_sleep(ZTIMER_USEC, SD_CARD_WAIT_AFTER_POWER_UP_US);
|
||||
}
|
||||
|
||||
gpio_set(card->params.mosi);
|
||||
gpio_set(card->params.cs); /* unselect sdcard for power up sequence */
|
||||
gpio_set(card->params->mosi);
|
||||
gpio_set(card->params->cs); /* unselect sdcard for power up sequence */
|
||||
|
||||
/* powersequence: perform at least 74 clockcycles with mosi_pin being high
|
||||
* (same as sending dummy bytes with 0xFF) */
|
||||
for (int i = 0; i < SD_POWERSEQUENCE_CLOCK_COUNT; i += 1) {
|
||||
gpio_set(card->params.clk);
|
||||
gpio_set(card->params->clk);
|
||||
ztimer_sleep(ZTIMER_USEC, SD_CARD_PREINIT_CLOCK_PERIOD_US / 2);
|
||||
gpio_clear(card->params.clk);
|
||||
gpio_clear(card->params->clk);
|
||||
ztimer_sleep(ZTIMER_USEC, SD_CARD_PREINIT_CLOCK_PERIOD_US / 2);
|
||||
}
|
||||
return SD_INIT_SEND_CMD0;
|
||||
@ -152,21 +152,21 @@ static sd_init_fsm_state_t _init_sd_fsm_step(sdcard_spi_t *card, sd_init_fsm_sta
|
||||
case SD_INIT_SEND_CMD0:
|
||||
DEBUG("SD_INIT_SEND_CMD0\n");
|
||||
|
||||
gpio_clear(card->params.mosi);
|
||||
gpio_clear(card->params->mosi);
|
||||
|
||||
/* use soft-spi to perform init command to allow use of internal pull-ups on miso */
|
||||
_dyn_spi_rxtx_byte = &_sw_spi_rxtx_byte;
|
||||
|
||||
/* select sdcard for cmd0 */
|
||||
gpio_clear(card->params.cs);
|
||||
gpio_clear(card->params->cs);
|
||||
uint8_t cmd0_r1 = sdcard_spi_send_cmd(card, SD_CMD_0, SD_CMD_NO_ARG, INIT_CMD0_RETRY_US);
|
||||
gpio_set(card->params.cs);
|
||||
gpio_set(card->params->cs);
|
||||
|
||||
if (R1_VALID(cmd0_r1) && !R1_ERROR(cmd0_r1) && R1_IDLE_BIT_SET(cmd0_r1)) {
|
||||
DEBUG("CMD0: [OK]\n");
|
||||
|
||||
/* give control over SPI pins back to HW SPI device */
|
||||
spi_init_pins(card->params.spi_dev);
|
||||
spi_init_pins(card->params->spi_dev);
|
||||
/* switch to HW SPI since SD card is now in real SPI mode */
|
||||
_dyn_spi_rxtx_byte = &_hw_spi_rxtx_byte;
|
||||
return SD_INIT_ENABLE_CRC;
|
||||
@ -366,7 +366,7 @@ static inline bool _wait_for_token(sdcard_spi_t *card, uint8_t token, uint32_t r
|
||||
|
||||
do {
|
||||
uint8_t read_byte = 0;
|
||||
read_byte = spi_transfer_byte(card->params.spi_dev, SPI_CS_UNDEF, true,
|
||||
read_byte = spi_transfer_byte(card->params->spi_dev, SPI_CS_UNDEF, true,
|
||||
SD_CARD_DUMMY_BYTE);
|
||||
if (read_byte == token) {
|
||||
DEBUG("_wait_for_token: [MATCH]\n");
|
||||
@ -540,15 +540,15 @@ static inline uint8_t _wait_for_r1(sdcard_spi_t *card, uint32_t retry_us)
|
||||
|
||||
void _select_card_spi(sdcard_spi_t *card)
|
||||
{
|
||||
spi_acquire(card->params.spi_dev, SPI_CS_UNDEF,
|
||||
spi_acquire(card->params->spi_dev, SPI_CS_UNDEF,
|
||||
SD_CARD_SPI_MODE, card->spi_clk);
|
||||
gpio_clear(card->params.cs);
|
||||
gpio_clear(card->params->cs);
|
||||
}
|
||||
|
||||
void _unselect_card_spi(sdcard_spi_t *card)
|
||||
{
|
||||
gpio_set(card->params.cs);
|
||||
spi_release(card->params.spi_dev);
|
||||
gpio_set(card->params->cs);
|
||||
spi_release(card->params->spi_dev);
|
||||
}
|
||||
|
||||
static inline void _sw_spi_rxtx_byte(sdcard_spi_t *card, uint8_t out, uint8_t *in)
|
||||
@ -558,23 +558,23 @@ static inline void _sw_spi_rxtx_byte(sdcard_spi_t *card, uint8_t out, uint8_t *i
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
if (((out >> (i)) & 0x01) == 1) {
|
||||
gpio_set(card->params.mosi);
|
||||
gpio_set(card->params->mosi);
|
||||
}
|
||||
else {
|
||||
gpio_clear(card->params.mosi);
|
||||
gpio_clear(card->params->mosi);
|
||||
}
|
||||
ztimer_sleep(ZTIMER_USEC, SD_CARD_PREINIT_CLOCK_PERIOD_US / 2);
|
||||
gpio_set(card->params.clk);
|
||||
rx = (rx | ((gpio_read(card->params.miso) > 0) << i));
|
||||
gpio_set(card->params->clk);
|
||||
rx = (rx | ((gpio_read(card->params->miso) > 0) << i));
|
||||
ztimer_sleep(ZTIMER_USEC, SD_CARD_PREINIT_CLOCK_PERIOD_US / 2);
|
||||
gpio_clear(card->params.clk);
|
||||
gpio_clear(card->params->clk);
|
||||
}
|
||||
*in = rx;
|
||||
}
|
||||
|
||||
static inline void _hw_spi_rxtx_byte(sdcard_spi_t *card, uint8_t out, uint8_t *in)
|
||||
{
|
||||
*in = spi_transfer_byte(card->params.spi_dev, SPI_CS_UNDEF, true, out);
|
||||
*in = spi_transfer_byte(card->params->spi_dev, SPI_CS_UNDEF, true, out);
|
||||
}
|
||||
|
||||
static inline uint16_t _transfer_bytes(sdcard_spi_t *card, const uint8_t *out,
|
||||
@ -712,7 +712,7 @@ static sd_rw_response_t _write_data_packet(sdcard_spi_t *card, uint8_t token,
|
||||
const uint8_t *data, uint16_t size)
|
||||
{
|
||||
|
||||
spi_transfer_byte(card->params.spi_dev, SPI_CS_UNDEF, true, token);
|
||||
spi_transfer_byte(card->params->spi_dev, SPI_CS_UNDEF, true, token);
|
||||
|
||||
if (_transfer_bytes(card, data, 0, size) == size) {
|
||||
|
||||
@ -721,7 +721,7 @@ static sd_rw_response_t _write_data_packet(sdcard_spi_t *card, uint8_t token,
|
||||
|
||||
if (_transfer_bytes(card, crc, 0, sizeof(crc)) == sizeof(crc)) {
|
||||
|
||||
uint8_t data_response = spi_transfer_byte(card->params.spi_dev, SPI_CS_UNDEF,
|
||||
uint8_t data_response = spi_transfer_byte(card->params->spi_dev, SPI_CS_UNDEF,
|
||||
true, SD_CARD_DUMMY_BYTE);
|
||||
|
||||
DEBUG("_write_data_packet: DATA_RESPONSE: 0x%02x\n", data_response);
|
||||
@ -804,7 +804,7 @@ static uint16_t _write_blocks(sdcard_spi_t *card, uint8_t cmd_idx,
|
||||
/* if this is a multi-block write it is needed to issue a stop
|
||||
command */
|
||||
if (cmd_idx == SD_CMD_25) {
|
||||
spi_transfer_byte(card->params.spi_dev, SPI_CS_UNDEF, true,
|
||||
spi_transfer_byte(card->params->spi_dev, SPI_CS_UNDEF, true,
|
||||
SD_DATA_TOKEN_CMD_25_STOP);
|
||||
DEBUG("_write_blocks: write multi (%d) blocks: [OK]\n", nbl);
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "modules.h"
|
||||
#include "timex.h"
|
||||
#ifdef MODULE_CORE_MSG
|
||||
#include "msg.h"
|
||||
|
@ -369,9 +369,12 @@ static int _get_put_cb(void *arg, coap_pkt_t *pkt)
|
||||
|
||||
ssize_t nanocoap_sock_get(nanocoap_sock_t *sock, const char *path, void *buf, size_t len)
|
||||
{
|
||||
uint8_t *pktpos = buf;
|
||||
/* buffer for CoAP header */
|
||||
uint8_t buffer[CONFIG_NANOCOAP_BLOCK_HEADER_MAX];
|
||||
uint8_t *pktpos = buffer;
|
||||
|
||||
coap_pkt_t pkt = {
|
||||
.hdr = buf,
|
||||
.hdr = (void *)pktpos,
|
||||
};
|
||||
|
||||
struct iovec ctx = {
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "container.h"
|
||||
|
||||
#include "embUnit.h"
|
||||
|
||||
#include "mbox.h"
|
||||
|
Loading…
Reference in New Issue
Block a user