1
0
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 (commit bfc2a51f70)
- the documentation was changed to fit the 100 characters per line. (commit 36f0162b34)

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:
bors[bot] 2023-05-02 13:37:57 +00:00 committed by GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 92 additions and 76 deletions

View File

@ -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

View File

@ -4,6 +4,6 @@ endif
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += saul_gpio
USEMODULE += l3g4200d
USEMODULE += l3gxxxx l3g4200d_ng
USEMODULE += lsm303dlhc
endif

View File

@ -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.

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -31,6 +31,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "modules.h"
#include "timex.h"
#ifdef MODULE_CORE_MSG
#include "msg.h"

View File

@ -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 = {

View File

@ -8,6 +8,8 @@
#include <limits.h>
#include "container.h"
#include "embUnit.h"
#include "mbox.h"