update IDF libs and includes

This commit is contained in:
me-no-dev
2017-01-16 16:03:13 +02:00
parent 49a476c5f0
commit 3b874d51e8
127 changed files with 8996 additions and 331 deletions

View File

@ -401,7 +401,7 @@ esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period);
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t i2s_get_period(i2c_port_t i2c_num, int* high_period, int* low_period);
esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period);
/**
* @brief set I2C master start signal timing

View File

@ -16,9 +16,6 @@
#define _DRIVER_LEDC_H_
#include "esp_err.h"
#include "soc/soc.h"
#include "soc/ledc_reg.h"
#include "soc/ledc_reg.h"
#include "soc/ledc_struct.h"
#include "driver/gpio.h"
#include "driver/periph_ctrl.h"
#include "esp_intr_alloc.h"
@ -68,6 +65,7 @@ typedef enum {
LEDC_CHANNEL_5, /*!< LEDC channel 5 */
LEDC_CHANNEL_6, /*!< LEDC channel 6 */
LEDC_CHANNEL_7, /*!< LEDC channel 7 */
LEDC_CHANNEL_MAX,
} ledc_channel_t;
typedef enum {
@ -79,6 +77,11 @@ typedef enum {
LEDC_TIMER_15_BIT = 15, /*!< LEDC PWM depth 15Bit */
} ledc_timer_bit_t;
typedef enum {
LEDC_FADE_NO_WAIT = 0, /*!< LEDC fade function will return immediately */
LEDC_FADE_WAIT_DONE, /*!< LEDC fade function will block until fading to the target duty*/
LEDC_FADE_MAX,
} ledc_fade_mode_t;
/**
* @brief Configuration parameters of LEDC channel for ledc_channel_config function
*/
@ -104,43 +107,39 @@ typedef struct {
typedef intr_handle_t ledc_isr_handle_t;
/**
* @brief LEDC channel configuration
* @brief LEDC channel configuration
* Configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth
*
* User this Function, configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth
* @param ledc_conf Pointer of LEDC channel configure struct
*
* @param ledc_conf Pointer of LEDC channel configure struct
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*
*/
esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf);
/**
* @brief LEDC timer configuration
*
* User this Function, configure LEDC timer with the given source timer/frequency(Hz)/bit_num
* @brief LEDC timer configuration
* Configure LEDC timer with the given source timer/frequency(Hz)/bit_num
*
* @param timer_conf Pointer of LEDC timer configure struct
*
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num.
*
*/
esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf);
/**
* @brief LEDC update channel parameters
* @brief LEDC update channel parameters
* Call this function to activate the LEDC updated parameters.
* After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings.
*
* Call this function to activate the LEDC updated parameters.
* After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings.
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param channel LEDC channel(0-7), select from ledc_channel_t
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode,
* now we only support high-speed mode.
* We will access low-speed mode in next version
* @param channel LEDC channel(0-7), select from ledc_channel_t
*
* @return
* - ESP_OK Success
@ -150,14 +149,11 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf);
esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
/**
* @brief LEDC stop
*
* Disable LEDC output, and set idle level
* @brief LEDC stop.
* Disable LEDC output, and set idle level
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param channel LEDC channel(0-7), select from ledc_channel_t
*
* @param idle_level Set output idle level after LEDC stops.
*
* @return
@ -167,14 +163,10 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level);
/**
* @brief LEDC set channel frequency(Hz)
*
* Set LEDC frequency(Hz)
* @brief LEDC set channel frequency(Hz)
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param timer_num LEDC timer index(0-3), select from ledc_timer_t
*
* @param freq_hz Set the LEDC frequency
*
* @return
@ -188,25 +180,20 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t
* @brief LEDC get channel frequency(Hz)
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param timer_num LEDC timer index(0-3), select from ledc_timer_t
*
* @return
* - 0 error
* - Others Current LEDC frequency
*
*/
uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num);
/**
* @brief LEDC set duty
*
* Set LEDC duty, After the function calls the ledc_update_duty function, the function can take effect.
* @brief LEDC set duty
* Only after calling ledc_update_duty will the duty update.
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param channel LEDC channel(0-7), select from ledc_channel_t
*
* @param duty Set the LEDC duty, the duty range is [0, (2**bit_num) - 1]
*
* @return
@ -216,37 +203,27 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num);
esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty);
/**
* @brief LEDC get duty
* @brief LEDC get duty
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param channel LEDC channel(0-7), select from ledc_channel_t
*
*
* @return
* - (-1) parameter error
* - Others Current LEDC duty
*
*/
int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
/**
* @brief LEDC set gradient
*
* Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect.
* @brief LEDC set gradient
* Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect.
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param channel LEDC channel(0-7), select from ledc_channel_t
*
* @param duty Set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1]
*
* @param gradule_direction Set the direction of the gradient
*
* @param step_num Set the number of the gradient
*
* @param duty_cyle_num Set how many LEDC tick each time the gradient lasts
*
* @param duty_scale Set gradient change amplitude
*
* @return
@ -257,16 +234,16 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t
uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale);
/**
* @brief register LEDC interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
* @brief Register LEDC interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
*
* @param fn Interrupt handler function.
* @param arg User-supplied argument passed to the handler function.
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
* @param arg Parameter for handler function
* @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will
* be returned here.
* @param fn Interrupt handler function.
* @param arg User-supplied argument passed to the handler function.
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
* @param arg Parameter for handler function
* @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will
* be returned here.
*
* @return
* - ESP_OK Success
@ -275,48 +252,38 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t
esp_err_t ledc_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, ledc_isr_handle_t *handle);
/**
* @brief configure LEDC settings
* @brief Configure LEDC settings
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param timer_sel Timer index(0-3), there are 4 timers in LEDC module
*
* @param div_num Timer clock divide number, the timer clock is divided from the selected clock source
*
* @param bit_num The count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1)
*
* @param clk_src Select LEDC source clock.
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
* @param timer_sel Timer index(0-3), there are 4 timers in LEDC module
* @param div_num Timer clock divide number, the timer clock is divided from the selected clock source
* @param bit_num The count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1)
* @param clk_src Select LEDC source clock.
*
* @return
* - (-1) Parameter error
* - Other Current LEDC duty
*
*/
esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src);
/**
* @brief reset LEDC timer
* @brief Reset LEDC timer
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
*
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*
*/
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
/**
* @brief pause LEDC timer counter
* @brief Pause LEDC timer counter
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
*
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
@ -325,104 +292,96 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel);
/**
* @brief pause LEDC timer resume
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
* @brief Resume LEDC timer
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
* @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*
*/
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel);
/**
* @brief bind LEDC channel with the selected timer
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
* @param channel LEDC channel index(0-7), select from ledc_channel_t
*
* @param timer_idx LEDC timer index(0-3), select from ledc_timer_t
* @brief Bind LEDC channel with the selected timer
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
* @param channel LEDC channel index(0-7), select from ledc_channel_t
* @param timer_idx LEDC timer index(0-3), select from ledc_timer_t
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx);
/**
* @brief Set LEDC fade function. Should call ledc_fade_func_install() before calling this function.
* Call ledc_fade_start() after this to start fading.
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode,
* For now we only support high-speed mode. We will access low-speed mode soon.
* @param channel LEDC channel index(0-7), select from ledc_channel_t
* @param target_duty Target duty of fading.( 0 - (2 ** bit_num - 1)))
* @param scale Controls the increase or decrease step scale.
* @param cycle_num increase or decrease the duty every cycle_num cycles
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fade function not installed.
*/
esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel, int target_duty, int scale, int cycle_num);
/**
* @brief Set LEDC fade function, with a limited time. Should call ledc_fade_func_install() before calling this function.
* Call ledc_fade_start() after this to start fading.
*
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode,
* For now we only support high-speed mode. We will access low-speed mode soon.
* @param channel LEDC channel index(0-7), select from ledc_channel_t
* @param target_duty Target duty of fading.( 0 - (2 ** bit_num - 1)))
* @param max_fade_time_ms The maximum time of the fading ( ms ).
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fade function not installed.
*/
esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, int target_duty, int max_fade_time_ms);
/**
* @brief Install ledc fade function. This function will occupy interrupt of LEDC module.
*
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
*
* @return
* - ESP_ERR_NO_MEM No enough memory
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fade function already installed.
*/
esp_err_t ledc_fade_func_install(int intr_alloc_flags);
/**
* @brief Uninstall LEDC fade function.
*
*/
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t timer_idx);
void ledc_fade_func_uninstall();
/***************************EXAMPLE**********************************
/**
* @brief Start LEDC fading.
*
* @param channel LEDC channel number
* @param wait_done Whether to block until fading done.
*
* ----------------EXAMPLE OF LEDC SETTING ---------------------
* @code{c}
* //1. enable LEDC
* //enable LEDC module, or you can not set any register of it.
* periph_module_enable(PERIPH_LEDC_MODULE);
* @endcode
*
* @code{c}
* //2. set LEDC timer
* ledc_timer_config_t timer_conf = {
* .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number
* .freq_hz = 1000, //set frequency of pwm, here, 1000Hz
* .speed_mode = LEDC_HIGH_SPEED_MODE, //timer mode,
* .timer_num = LEDC_TIMER_0, //timer number
* };
* ledc_timer_config(&timer_conf); //setup timer.
* @endcode
*
* @code{c}
* //3. set LEDC channel
* ledc_channel_config_t ledc_conf = {
* .channel = LEDC_CHANNEL_0; //set LEDC channel 0
* .duty = 1000; //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1)
* .gpio_num = 16; //GPIO number
* .intr_type = LEDC_INTR_FADE_END; //GPIO INTR TYPE, as an example, we enable fade_end interrupt here.
* .speed_mode = LEDC_HIGH_SPEED_MODE; //set LEDC mode, from ledc_mode_t
* .timer_sel = LEDC_TIMER_0; //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same
* }
* ledc_channel_config(&ledc_conf); //setup the configuration
*
* ----------------EXAMPLE OF SETTING DUTY --- -----------------
* @code{c}
* ledc_channel_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73)
* uint32_t duty = 2000; //duty range is 0 ~ ((2**bit_num)-1)
* LEDC_set_duty(LEDC_HIGH_SPEED_MODE, ledc_channel, duty); //set speed mode, channel, and duty.
* ledc_update_duty(LEDC_HIGH_SPEED_MODE, ledc_channel); //after set duty, we need to call ledc_update_duty to update the settings.
* @endcode
*
* ----------------EXAMPLE OF LEDC INTERRUPT ------------------
* @code{c}
* //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here.
* ledc_isr_register(ledc_isr_handler, NULL, 0); //hook the isr handler for LEDC interrupt
* @endcode
*
* ----------------EXAMPLE OF INTERRUPT HANDLER ---------------
* @code{c}
* #include "esp_attr.h"
* void IRAM_ATTR ledc_isr_handler(void* arg) //we should add 'IRAM_ATTR' attribution when we declare the isr function
* {
* uint32_t intr_st = LEDC.int_st.val; //read LEDC interrupt status.
*
* //you will find which channels have triggered fade_end interrupt here,
* //then, you can post some event to RTOS queue to process the event.
* //later we will add a queue in the driver code.
*
* LEDC.int_clr.val = intr_st; //clear LEDC interrupt status.
* }
* @endcode
*
*--------------------------END OF EXAMPLE --------------------------
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fade function not installed.
* - ESP_ERR_INVALID_ARG Parameter error.
*/
esp_err_t ledc_fade_start(ledc_channel_t channel, ledc_fade_mode_t wait_done);
#ifdef __cplusplus
}

View File

@ -41,6 +41,9 @@ typedef enum {
PERIPH_UHCI1_MODULE,
PERIPH_RMT_MODULE,
PERIPH_PCNT_MODULE,
PERIPH_SPI_MODULE,
PERIPH_HSPI_MODULE,
PERIPH_VSPI_MODULE,
} periph_module_t;
/**

View File

@ -0,0 +1,303 @@
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
* Adaptations to ESP-IDF Copyright (c) 2016 Espressif Systems (Shanghai) PTE LTD
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SDMMC_DEFS_H_
#define _SDMMC_DEFS_H_
#include <stdint.h>
#include <limits.h>
/* MMC commands */ /* response type */
#define MMC_GO_IDLE_STATE 0 /* R0 */
#define MMC_SEND_OP_COND 1 /* R3 */
#define MMC_ALL_SEND_CID 2 /* R2 */
#define MMC_SET_RELATIVE_ADDR 3 /* R1 */
#define MMC_SWITCH 6 /* R1B */
#define MMC_SELECT_CARD 7 /* R1 */
#define MMC_SEND_EXT_CSD 8 /* R1 */
#define MMC_SEND_CSD 9 /* R2 */
#define MMC_STOP_TRANSMISSION 12 /* R1B */
#define MMC_SEND_STATUS 13 /* R1 */
#define MMC_SET_BLOCKLEN 16 /* R1 */
#define MMC_READ_BLOCK_SINGLE 17 /* R1 */
#define MMC_READ_BLOCK_MULTIPLE 18 /* R1 */
#define MMC_SET_BLOCK_COUNT 23 /* R1 */
#define MMC_WRITE_BLOCK_SINGLE 24 /* R1 */
#define MMC_WRITE_BLOCK_MULTIPLE 25 /* R1 */
#define MMC_APP_CMD 55 /* R1 */
/* SD commands */ /* response type */
#define SD_SEND_RELATIVE_ADDR 3 /* R6 */
#define SD_SEND_SWITCH_FUNC 6 /* R1 */
#define SD_SEND_IF_COND 8 /* R7 */
/* SD application commands */ /* response type */
#define SD_APP_SET_BUS_WIDTH 6 /* R1 */
#define SD_APP_OP_COND 41 /* R3 */
#define SD_APP_SEND_SCR 51 /* R1 */
/* OCR bits */
#define MMC_OCR_MEM_READY (1<<31) /* memory power-up status bit */
#define MMC_OCR_ACCESS_MODE_MASK 0x60000000 /* bits 30:29 */
#define MMC_OCR_SECTOR_MODE (1<<30)
#define MMC_OCR_BYTE_MODE (1<<29)
#define MMC_OCR_3_5V_3_6V (1<<23)
#define MMC_OCR_3_4V_3_5V (1<<22)
#define MMC_OCR_3_3V_3_4V (1<<21)
#define MMC_OCR_3_2V_3_3V (1<<20)
#define MMC_OCR_3_1V_3_2V (1<<19)
#define MMC_OCR_3_0V_3_1V (1<<18)
#define MMC_OCR_2_9V_3_0V (1<<17)
#define MMC_OCR_2_8V_2_9V (1<<16)
#define MMC_OCR_2_7V_2_8V (1<<15)
#define MMC_OCR_2_6V_2_7V (1<<14)
#define MMC_OCR_2_5V_2_6V (1<<13)
#define MMC_OCR_2_4V_2_5V (1<<12)
#define MMC_OCR_2_3V_2_4V (1<<11)
#define MMC_OCR_2_2V_2_3V (1<<10)
#define MMC_OCR_2_1V_2_2V (1<<9)
#define MMC_OCR_2_0V_2_1V (1<<8)
#define MMC_OCR_1_65V_1_95V (1<<7)
#define SD_OCR_SDHC_CAP (1<<30)
#define SD_OCR_VOL_MASK 0xFF8000 /* bits 23:15 */
/* R1 response type bits */
#define MMC_R1_READY_FOR_DATA (1<<8) /* ready for next transfer */
#define MMC_R1_APP_CMD (1<<5) /* app. commands supported */
/* 48-bit response decoding (32 bits w/o CRC) */
#define MMC_R1(resp) ((resp)[0])
#define MMC_R3(resp) ((resp)[0])
#define SD_R6(resp) ((resp)[0])
#define MMC_R1_CURRENT_STATE(resp) (((resp)[0] >> 9) & 0xf)
/* RCA argument and response */
#define MMC_ARG_RCA(rca) ((rca) << 16)
#define SD_R6_RCA(resp) (SD_R6((resp)) >> 16)
/* bus width argument */
#define SD_ARG_BUS_WIDTH_1 0
#define SD_ARG_BUS_WIDTH_4 2
/* EXT_CSD fields */
#define EXT_CSD_BUS_WIDTH 183 /* WO */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_SEC_COUNT 212 /* RO */
/* EXT_CSD field definitions */
#define EXT_CSD_CMD_SET_NORMAL (1U << 0)
#define EXT_CSD_CMD_SET_SECURE (1U << 1)
#define EXT_CSD_CMD_SET_CPSECURE (1U << 2)
/* EXT_CSD_HS_TIMING */
#define EXT_CSD_HS_TIMING_BC 0
#define EXT_CSD_HS_TIMING_HS 1
#define EXT_CSD_HS_TIMING_HS200 2
#define EXT_CSD_HS_TIMING_HS400 3
/* EXT_CSD_BUS_WIDTH */
#define EXT_CSD_BUS_WIDTH_1 0
#define EXT_CSD_BUS_WIDTH_4 1
#define EXT_CSD_BUS_WIDTH_8 2
#define EXT_CSD_BUS_WIDTH_4_DDR 5
#define EXT_CSD_BUS_WIDTH_8_DDR 6
/* EXT_CSD_CARD_TYPE */
/* The only currently valid values for this field are 0x01, 0x03, 0x07,
* 0x0B and 0x0F. */
#define EXT_CSD_CARD_TYPE_F_26M (1 << 0)
#define EXT_CSD_CARD_TYPE_F_52M (1 << 1)
#define EXT_CSD_CARD_TYPE_F_52M_1_8V (1 << 2)
#define EXT_CSD_CARD_TYPE_F_52M_1_2V (1 << 3)
#define EXT_CSD_CARD_TYPE_26M 0x01
#define EXT_CSD_CARD_TYPE_52M 0x03
#define EXT_CSD_CARD_TYPE_52M_V18 0x07
#define EXT_CSD_CARD_TYPE_52M_V12 0x0b
#define EXT_CSD_CARD_TYPE_52M_V12_18 0x0f
/* MMC_SWITCH access mode */
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits in value */
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits in value */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
/* MMC R2 response (CSD) */
#define MMC_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2)
#define MMC_CSD_CSDVER_1_0 1
#define MMC_CSD_CSDVER_2_0 2
#define MMC_CSD_CSDVER_EXT_CSD 3
#define MMC_CSD_MMCVER(resp) MMC_RSP_BITS((resp), 122, 4)
#define MMC_CSD_MMCVER_1_0 0 /* MMC 1.0 - 1.2 */
#define MMC_CSD_MMCVER_1_4 1 /* MMC 1.4 */
#define MMC_CSD_MMCVER_2_0 2 /* MMC 2.0 - 2.2 */
#define MMC_CSD_MMCVER_3_1 3 /* MMC 3.1 - 3.3 */
#define MMC_CSD_MMCVER_4_0 4 /* MMC 4 */
#define MMC_CSD_READ_BL_LEN(resp) MMC_RSP_BITS((resp), 80, 4)
#define MMC_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12)
#define MMC_CSD_CAPACITY(resp) ((MMC_CSD_C_SIZE((resp))+1) << \
(MMC_CSD_C_SIZE_MULT((resp))+2))
#define MMC_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3)
/* MMC v1 R2 response (CID) */
#define MMC_CID_MID_V1(resp) MMC_RSP_BITS((resp), 104, 24)
#define MMC_CID_PNM_V1_CPY(resp, pnm) \
do { \
(pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \
(pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \
(pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \
(pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \
(pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \
(pnm)[5] = MMC_RSP_BITS((resp), 56, 8); \
(pnm)[6] = MMC_RSP_BITS((resp), 48, 8); \
(pnm)[7] = '\0'; \
} while (0)
#define MMC_CID_REV_V1(resp) MMC_RSP_BITS((resp), 40, 8)
#define MMC_CID_PSN_V1(resp) MMC_RSP_BITS((resp), 16, 24)
#define MMC_CID_MDT_V1(resp) MMC_RSP_BITS((resp), 8, 8)
/* MMC v2 R2 response (CID) */
#define MMC_CID_MID_V2(resp) MMC_RSP_BITS((resp), 120, 8)
#define MMC_CID_OID_V2(resp) MMC_RSP_BITS((resp), 104, 16)
#define MMC_CID_PNM_V2_CPY(resp, pnm) \
do { \
(pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \
(pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \
(pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \
(pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \
(pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \
(pnm)[5] = MMC_RSP_BITS((resp), 56, 8); \
(pnm)[6] = '\0'; \
} while (0)
#define MMC_CID_PSN_V2(resp) MMC_RSP_BITS((resp), 16, 32)
/* SD R2 response (CSD) */
#define SD_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2)
#define SD_CSD_CSDVER_1_0 0
#define SD_CSD_CSDVER_2_0 1
#define SD_CSD_TAAC(resp) MMC_RSP_BITS((resp), 112, 8)
#define SD_CSD_TAAC_1_5_MSEC 0x26
#define SD_CSD_NSAC(resp) MMC_RSP_BITS((resp), 104, 8)
#define SD_CSD_SPEED(resp) MMC_RSP_BITS((resp), 96, 8)
#define SD_CSD_SPEED_25_MHZ 0x32
#define SD_CSD_SPEED_50_MHZ 0x5a
#define SD_CSD_CCC(resp) MMC_RSP_BITS((resp), 84, 12)
#define SD_CSD_CCC_BASIC (1 << 0) /* basic */
#define SD_CSD_CCC_BR (1 << 2) /* block read */
#define SD_CSD_CCC_BW (1 << 4) /* block write */
#define SD_CSD_CCC_ERASE (1 << 5) /* erase */
#define SD_CSD_CCC_WP (1 << 6) /* write protection */
#define SD_CSD_CCC_LC (1 << 7) /* lock card */
#define SD_CSD_CCC_AS (1 << 8) /*application specific*/
#define SD_CSD_CCC_IOM (1 << 9) /* I/O mode */
#define SD_CSD_CCC_SWITCH (1 << 10) /* switch */
#define SD_CSD_READ_BL_LEN(resp) MMC_RSP_BITS((resp), 80, 4)
#define SD_CSD_READ_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 79, 1)
#define SD_CSD_WRITE_BLK_MISALIGN(resp) MMC_RSP_BITS((resp), 78, 1)
#define SD_CSD_READ_BLK_MISALIGN(resp) MMC_RSP_BITS((resp), 77, 1)
#define SD_CSD_DSR_IMP(resp) MMC_RSP_BITS((resp), 76, 1)
#define SD_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12)
#define SD_CSD_CAPACITY(resp) ((SD_CSD_C_SIZE((resp))+1) << \
(SD_CSD_C_SIZE_MULT((resp))+2))
#define SD_CSD_V2_C_SIZE(resp) MMC_RSP_BITS((resp), 48, 22)
#define SD_CSD_V2_CAPACITY(resp) ((SD_CSD_V2_C_SIZE((resp))+1) << 10)
#define SD_CSD_V2_BL_LEN 0x9 /* 512 */
#define SD_CSD_VDD_R_CURR_MIN(resp) MMC_RSP_BITS((resp), 59, 3)
#define SD_CSD_VDD_R_CURR_MAX(resp) MMC_RSP_BITS((resp), 56, 3)
#define SD_CSD_VDD_W_CURR_MIN(resp) MMC_RSP_BITS((resp), 53, 3)
#define SD_CSD_VDD_W_CURR_MAX(resp) MMC_RSP_BITS((resp), 50, 3)
#define SD_CSD_VDD_RW_CURR_100mA 0x7
#define SD_CSD_VDD_RW_CURR_80mA 0x6
#define SD_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3)
#define SD_CSD_ERASE_BLK_EN(resp) MMC_RSP_BITS((resp), 46, 1)
#define SD_CSD_SECTOR_SIZE(resp) MMC_RSP_BITS((resp), 39, 7) /* +1 */
#define SD_CSD_WP_GRP_SIZE(resp) MMC_RSP_BITS((resp), 32, 7) /* +1 */
#define SD_CSD_WP_GRP_ENABLE(resp) MMC_RSP_BITS((resp), 31, 1)
#define SD_CSD_R2W_FACTOR(resp) MMC_RSP_BITS((resp), 26, 3)
#define SD_CSD_WRITE_BL_LEN(resp) MMC_RSP_BITS((resp), 22, 4)
#define SD_CSD_RW_BL_LEN_2G 0xa
#define SD_CSD_RW_BL_LEN_1G 0x9
#define SD_CSD_WRITE_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 21, 1)
#define SD_CSD_FILE_FORMAT_GRP(resp) MMC_RSP_BITS((resp), 15, 1)
#define SD_CSD_COPY(resp) MMC_RSP_BITS((resp), 14, 1)
#define SD_CSD_PERM_WRITE_PROTECT(resp) MMC_RSP_BITS((resp), 13, 1)
#define SD_CSD_TMP_WRITE_PROTECT(resp) MMC_RSP_BITS((resp), 12, 1)
#define SD_CSD_FILE_FORMAT(resp) MMC_RSP_BITS((resp), 10, 2)
/* SD R2 response (CID) */
#define SD_CID_MID(resp) MMC_RSP_BITS((resp), 120, 8)
#define SD_CID_OID(resp) MMC_RSP_BITS((resp), 104, 16)
#define SD_CID_PNM_CPY(resp, pnm) \
do { \
(pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \
(pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \
(pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \
(pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \
(pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \
(pnm)[5] = '\0'; \
} while (0)
#define SD_CID_REV(resp) MMC_RSP_BITS((resp), 56, 8)
#define SD_CID_PSN(resp) MMC_RSP_BITS((resp), 24, 32)
#define SD_CID_MDT(resp) MMC_RSP_BITS((resp), 8, 12)
/* SCR (SD Configuration Register) */
#define SCR_STRUCTURE(scr) MMC_RSP_BITS((scr), 60, 4)
#define SCR_STRUCTURE_VER_1_0 0 /* Version 1.0 */
#define SCR_SD_SPEC(scr) MMC_RSP_BITS((scr), 56, 4)
#define SCR_SD_SPEC_VER_1_0 0 /* Version 1.0 and 1.01 */
#define SCR_SD_SPEC_VER_1_10 1 /* Version 1.10 */
#define SCR_SD_SPEC_VER_2 2 /* Version 2.00 or Version 3.0X */
#define SCR_DATA_STAT_AFTER_ERASE(scr) MMC_RSP_BITS((scr), 55, 1)
#define SCR_SD_SECURITY(scr) MMC_RSP_BITS((scr), 52, 3)
#define SCR_SD_SECURITY_NONE 0 /* no security */
#define SCR_SD_SECURITY_1_0 1 /* security protocol 1.0 */
#define SCR_SD_SECURITY_1_0_2 2 /* security protocol 1.0 */
#define SCR_SD_BUS_WIDTHS(scr) MMC_RSP_BITS((scr), 48, 4)
#define SCR_SD_BUS_WIDTHS_1BIT (1 << 0) /* 1bit (DAT0) */
#define SCR_SD_BUS_WIDTHS_4BIT (1 << 2) /* 4bit (DAT0-3) */
#define SCR_SD_SPEC3(scr) MMC_RSP_BITS((scr), 47, 1)
#define SCR_EX_SECURITY(scr) MMC_RSP_BITS((scr), 43, 4)
#define SCR_SD_SPEC4(scr) MMC_RSP_BITS((scr), 42, 1)
#define SCR_RESERVED(scr) MMC_RSP_BITS((scr), 34, 8)
#define SCR_CMD_SUPPORT_CMD23(scr) MMC_RSP_BITS((scr), 33, 1)
#define SCR_CMD_SUPPORT_CMD20(scr) MMC_RSP_BITS((scr), 32, 1)
#define SCR_RESERVED2(scr) MMC_RSP_BITS((scr), 0, 32)
/* Status of Switch Function */
#define SFUNC_STATUS_GROUP(status, group) \
(__bitfield((uint32_t *)(status), 400 + (group - 1) * 16, 16))
#define SD_ACCESS_MODE_SDR12 0
#define SD_ACCESS_MODE_SDR25 1
#define SD_ACCESS_MODE_SDR50 2
#define SD_ACCESS_MODE_SDR104 3
#define SD_ACCESS_MODE_DDR50 4
static inline uint32_t MMC_RSP_BITS(uint32_t *src, int start, int len)
{
uint32_t mask = (len % 32 == 0) ? UINT_MAX : UINT_MAX >> (32 - (len % 32));
size_t word = 3 - start / 32;
size_t shift = start % 32;
uint32_t right = src[word] >> shift;
uint32_t left = (len + shift <= 32) ? 0 : src[word - 1] << ((32 - shift) % 32);
return (left | right) & mask;
}
#endif //_SDMMC_DEFS_H_

View File

@ -0,0 +1,165 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#pragma once
#include <stdint.h>
#include <stddef.h>
#include "esp_err.h"
#include "sdmmc_types.h"
#include "driver/gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SDMMC_HOST_SLOT_0 0 ///< SDMMC slot 0
#define SDMMC_HOST_SLOT_1 1 ///< SDMMC slot 1
/**
* @brief Default sdmmc_host_t structure initializer for SDMMC peripheral
*
* Uses SDMMC peripheral, with 4-bit mode enabled, and max frequency set to 20MHz
*/
#define SDMMC_HOST_DEFAULT() {\
.flags = SDMMC_HOST_FLAG_4BIT, \
.slot = SDMMC_HOST_SLOT_1, \
.max_freq_khz = SDMMC_FREQ_DEFAULT, \
.io_voltage = 3.3f, \
.init = &sdmmc_host_init, \
.set_bus_width = &sdmmc_host_set_bus_width, \
.set_card_clk = &sdmmc_host_set_card_clk, \
.do_transaction = &sdmmc_host_do_transaction, \
.deinit = &sdmmc_host_deinit, \
}
/**
* Extra configuration for SDMMC peripheral slot
*/
typedef struct {
gpio_num_t gpio_cd; ///< GPIO number of card detect signal
gpio_num_t gpio_wp; ///< GPIO number of write protect signal
} sdmmc_slot_config_t;
#define SDMMC_SLOT_NO_CD ((gpio_num_t) -1) ///< indicates that card detect line is not used
#define SDMMC_SLOT_NO_WP ((gpio_num_t) -1) ///< indicates that write protect line is not used
/**
* Macro defining default configuration of SDMMC host slot
*/
#define SDMMC_SLOT_CONFIG_DEFAULT() {\
.gpio_cd = SDMMC_SLOT_NO_CD, \
.gpio_wp = SDMMC_SLOT_NO_WP, \
}
/**
* @brief Initialize SDMMC host peripheral
*
* @note This function is not thread safe
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if sdmmc_host_init was already called
* - ESP_ERR_NO_MEM if memory can not be allocated
*/
esp_err_t sdmmc_host_init();
/**
* @brief Initialize given slot of SDMMC peripheral
*
* On the ESP32, SDMMC peripheral has two slots:
* - Slot 0: 8-bit wide, maps to HS1_* signals in PIN MUX
* - Slot 1: 4-bit wide, maps to HS2_* signals in PIN MUX
*
* Card detect and write protect signals can be routed to
* arbitrary GPIOs using GPIO matrix.
*
* @note This function is not thread safe
*
* @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1)
* @param slot_config additional configuration for the slot
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if host has not been initialized using sdmmc_host_init
*/
esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config);
/**
* @brief Select bus width to be used for data transfer
*
* SD/MMC card must be initialized prior to this command, and a command to set
* bus width has to be sent to the card (e.g. SD_APP_SET_BUS_WIDTH)
*
* @note This function is not thread safe
*
* @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1)
* @param width bus width (1, 4, or 8 for slot 0; 1 or 4 for slot 1)
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if slot number or width is not valid
*/
esp_err_t sdmmc_host_set_bus_width(int slot, size_t width);
/**
* @brief Set card clock frequency
*
* Currently only integer fractions of 40MHz clock can be used.
* For High Speed cards, 40MHz can be used.
* For Default Speed cards, 20MHz can be used.
*
* @note This function is not thread safe
*
* @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1)
* @param freq_khz card clock frequency, in kHz
* @return
* - ESP_OK on success
* - other error codes may be returned in the future
*/
esp_err_t sdmmc_host_set_card_clk(int slot, uint32_t freq_khz);
/**
* @brief Send command to the card and get response
*
* This function returns when command is sent and response is received,
* or data is transferred, or timeout occurs.
*
* @note This function is not thread safe w.r.t. init/deinit functions,
* and bus width/clock speed configuration functions. Multiple tasks
* can call sdmmc_host_do_transaction as long as other sdmmc_host_*
* functions are not called.
*
* @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1)
* @param cmdinfo pointer to structure describing command and data to transfer
* @return
* - ESP_OK on success
* - ESP_ERR_TIMEOUT if response or data transfer has timed out
* - ESP_ERR_INVALID_CRC if response or data transfer CRC check has failed
* - ESP_ERR_INVALID_RESPONSE if the card has sent an invalid response
*/
esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo);
/**
* @brief Disable SDMMC host and release allocated resources
*
* @note This function is not thread safe
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if sdmmc_host_init function has not been called
*/
esp_err_t sdmmc_host_deinit();
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
* Adaptations to ESP-IDF Copyright (c) 2016 Espressif Systems (Shanghai) PTE LTD
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SDMMC_TYPES_H_
#define _SDMMC_TYPES_H_
#include <stdint.h>
#include <stddef.h>
#include "esp_err.h"
/**
* Decoded values from SD card Card Specific Data register
*/
typedef struct {
int csd_ver; /*!< CSD structure format */
int mmc_ver; /*!< MMC version (for CID format) */
int capacity; /*!< total number of sectors */
int sector_size; /*!< sector size in bytes */
int read_block_len; /*!< block length for reads */
int card_command_class; /*!< Card Command Class for SD */
int tr_speed; /*!< Max transfer speed */
} sdmmc_csd_t;
/**
* Decoded values from SD card Card IDentification register
*/
typedef struct {
int mfg_id; /*!< manufacturer identification number */
int oem_id; /*!< OEM/product identification number */
char name[8]; /*!< product name (MMC v1 has the longest) */
int revision; /*!< product revision */
int serial; /*!< product serial number */
int date; /*!< manufacturing date */
} sdmmc_cid_t;
/**
* Decoded values from SD Configuration Register
*/
typedef struct {
int sd_spec; /*!< SD Physical layer specification version, reported by card */
int bus_width; /*!< bus widths supported by card: BIT(0) — 1-bit bus, BIT(2) — 4-bit bus */
} sdmmc_scr_t;
/**
* SD/MMC command response buffer
*/
typedef uint32_t sdmmc_response_t[4];
/**
* SD/MMC command information
*/
typedef struct {
uint32_t opcode; /*!< SD or MMC command index */
uint32_t arg; /*!< SD/MMC command argument */
sdmmc_response_t response; /*!< response buffer */
void* data; /*!< buffer to send or read into */
size_t datalen; /*!< length of data buffer */
size_t blklen; /*!< block length */
int flags; /*!< see below */
#define SCF_ITSDONE 0x0001 /*!< command is complete */
#define SCF_CMD(flags) ((flags) & 0x00f0)
#define SCF_CMD_AC 0x0000
#define SCF_CMD_ADTC 0x0010
#define SCF_CMD_BC 0x0020
#define SCF_CMD_BCR 0x0030
#define SCF_CMD_READ 0x0040 /*!< read command (data expected) */
#define SCF_RSP_BSY 0x0100
#define SCF_RSP_136 0x0200
#define SCF_RSP_CRC 0x0400
#define SCF_RSP_IDX 0x0800
#define SCF_RSP_PRESENT 0x1000
/* response types */
#define SCF_RSP_R0 0 /*!< none */
#define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R1B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
#define SCF_RSP_R2 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_136)
#define SCF_RSP_R3 (SCF_RSP_PRESENT)
#define SCF_RSP_R4 (SCF_RSP_PRESENT)
#define SCF_RSP_R5 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R5B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
#define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
esp_err_t error; /*!< error returned from transfer */
} sdmmc_command_t;
/**
* SD/MMC Host description
*
* This structure defines properties of SD/MMC host and functions
* of SD/MMC host which can be used by upper layers.
*/
typedef struct {
uint32_t flags; /*!< flags defining host properties */
#define SDMMC_HOST_FLAG_1BIT BIT(0) /*!< host supports 1-line SD and MMC protocol */
#define SDMMC_HOST_FLAG_4BIT BIT(1) /*!< host supports 4-line SD and MMC protocol */
#define SDMMC_HOST_FLAG_8BIT BIT(2) /*!< host supports 8-line MMC protocol */
#define SDMMC_HOST_FLAG_SPI BIT(3) /*!< host supports SPI protocol */
int slot; /*!< slot number, to be passed to host functions */
int max_freq_khz; /*!< max frequency supported by the host */
#define SDMMC_FREQ_DEFAULT 20000 /*!< SD/MMC Default speed (limited by clock divider) */
#define SDMMC_FREQ_HIGHSPEED 40000 /*!< SD High speed (limited by clock divider) */
#define SDMMC_FREQ_PROBING 4000 /*!< SD/MMC probing speed */
float io_voltage; /*!< I/O voltage used by the controller (voltage switching is not supported) */
esp_err_t (*init)(void); /*!< Host function to initialize the driver */
esp_err_t (*set_bus_width)(int slot, size_t width); /*!< host function to set bus width */
esp_err_t (*set_card_clk)(int slot, uint32_t freq_khz); /*!< host function to set card clock frequency */
esp_err_t (*do_transaction)(int slot, sdmmc_command_t* cmdinfo); /*!< host function to do a transaction */
esp_err_t (*deinit)(void); /*!< host function to deinitialize the driver */
} sdmmc_host_t;
/**
* SD/MMC card information structure
*/
typedef struct {
sdmmc_host_t host; /*!< Host with which the card is associated */
uint32_t ocr; /*!< OCR (Operation Conditions Register) value */
sdmmc_cid_t cid; /*!< decoded CID (Card IDentification) register value */
sdmmc_csd_t csd; /*!< decoded CSD (Card-Specific Data) register value */
sdmmc_scr_t scr; /*!< decoded SCR (SD card Configuration Register) value */
uint16_t rca; /*!< RCA (Relative Card Address) */
} sdmmc_card_t;
#endif // _SDMMC_TYPES_H_

View File

@ -0,0 +1,235 @@
// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _DRIVER_SPI_MASTER_H_
#define _DRIVER_SPI_MASTER_H_
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Enum with the three SPI peripherals that are software-accessible in it
*/
typedef enum {
SPI_HOST=0, ///< SPI1, SPI
HSPI_HOST=1, ///< SPI2, HSPI
VSPI_HOST=2 ///< SPI3, VSPI
} spi_host_device_t;
/**
* @brief This is a configuration structure for a SPI bus.
*
* You can use this structure to specify the GPIO pins of the bus. Normally, the driver will use the
* GPIO matrix to route the signals. An exception is made when all signals either can be routed through
* the IO_MUX or are -1. In that case, the IO_MUX is used, allowing for >40MHz speeds.
*/
typedef struct {
int mosi_io_num; ///< GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used.
int miso_io_num; ///< GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used.
int sclk_io_num; ///< GPIO pin for Spi CLocK signal, or -1 if not used.
int quadwp_io_num; ///< GPIO pin for WP (Write Protect) signal which is used as D2 in 4-bit communication modes, or -1 if not used.
int quadhd_io_num; ///< GPIO pin for HD (HolD) signal which is used as D3 in 4-bit communication modes, or -1 if not used.
} spi_bus_config_t;
#define SPI_DEVICE_TXBIT_LSBFIRST (1<<0) ///< Transmit command/address/data LSB first instead of the default MSB first
#define SPI_DEVICE_RXBIT_LSBFIRST (1<<1) ///< Receive data LSB first instead of the default MSB first
#define SPI_DEVICE_BIT_LSBFIRST (SPI_TXBIT_LSBFIRST|SPI_RXBIT_LSBFIRST); ///< Transmit and receive LSB first
#define SPI_DEVICE_3WIRE (1<<2) ///< Use spiq for both sending and receiving data
#define SPI_DEVICE_POSITIVE_CS (1<<3) ///< Make CS positive during a transaction instead of negative
#define SPI_DEVICE_HALFDUPLEX (1<<4) ///< Transmit data before receiving it, instead of simultaneously
#define SPI_DEVICE_CLK_AS_CS (1<<5) ///< Output clock on CS line if CS is active
typedef struct spi_transaction_t spi_transaction_t;
typedef void(*transaction_cb_t)(spi_transaction_t *trans);
/**
* @brief This is a configuration for a SPI slave device that is connected to one of the SPI buses.
*/
typedef struct {
uint8_t command_bits; ///< Amount of bits in command phase (0-16)
uint8_t address_bits; ///< Amount of bits in address phase (0-64)
uint8_t dummy_bits; ///< Amount of dummy bits to insert between address and data phase
uint8_t mode; ///< SPI mode (0-3)
uint8_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128.
uint8_t cs_ena_pretrans; ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions.
uint8_t cs_ena_posttrans; ///< Amount of SPI bit-cycles the cs should stay active after the transmission (0-16)
int clock_speed_hz; ///< Clock speed, in Hz
int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used
uint32_t flags; ///< Bitwise OR of SPI_DEVICE_* flags
int queue_size; ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time
transaction_cb_t pre_cb; ///< Callback to be called before a transmission is started. This callback is called within interrupt context.
transaction_cb_t post_cb; ///< Callback to be called after a transmission has completed. This callback is called within interrupt context.
} spi_device_interface_config_t;
#define SPI_TRANS_MODE_DIO (1<<0) ///< Transmit/receive data in 2-bit mode
#define SPI_TRANS_MODE_QIO (1<<1) ///< Transmit/receive data in 4-bit mode
#define SPI_TRANS_MODE_DIOQIO_ADDR (1<<2) ///< Also transmit address in mode selected by SPI_MODE_DIO/SPI_MODE_QIO
#define SPI_TRANS_USE_RXDATA (1<<2) ///< Receive into rx_data member of spi_transaction_t instead into memory at rx_buffer.
#define SPI_TRANS_USE_TXDATA (1<<3) ///< Transmit tx_data member of spi_transaction_t instead of data at tx_buffer. Do not set tx_buffer when using this.
/**
* This structure describes one SPI transaction
*/
struct spi_transaction_t {
uint32_t flags; ///< Bitwise OR of SPI_TRANS_* flags
uint16_t command; ///< Command data. Specific length was given when device was added to the bus.
uint64_t address; ///< Address. Specific length was given when device was added to the bus.
size_t length; ///< Total data length, in bits
size_t rxlength; ///< Total data length received, if different from length. (0 defaults this to the value of ``length``)
void *user; ///< User-defined variable. Can be used to store eg transaction ID.
union {
const void *tx_buffer; ///< Pointer to transmit buffer, or NULL for no MOSI phase
uint8_t tx_data[4]; ///< If SPI_USE_TXDATA is set, data set here is sent directly from this variable.
};
union {
void *rx_buffer; ///< Pointer to receive buffer, or NULL for no MISO phase
uint8_t rx_data[4]; ///< If SPI_USE_RXDATA is set, data is received directly to this variable
};
};
typedef struct spi_device_t* spi_device_handle_t; ///< Handle for a device on a SPI bus
/**
* @brief Initialize a SPI bus
*
* @warning For now, only supports HSPI and VSPI.
*
* @param host SPI peripheral that controls this bus
* @param bus_config Pointer to a spi_bus_config_t struct specifying how the host should be initialized
* @param dma_chan Either 1 or 2. A SPI bus used by this driver must have a DMA channel associated with
* it. The SPI hardware has two DMA channels to share. This parameter indicates which
* one to use.
* @return
* - ESP_ERR_INVALID_ARG if configuration is invalid
* - ESP_ERR_INVALID_STATE if host already is in use
* - ESP_ERR_NO_MEM if out of memory
* - ESP_OK on success
*/
esp_err_t spi_bus_initialize(spi_host_device_t host, spi_bus_config_t *bus_config, int dma_chan);
/**
* @brief Free a SPI bus
*
* @warning In order for this to succeed, all devices have to be removed first.
*
* @param host SPI peripheral to free
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_ERR_INVALID_STATE if not all devices on the bus are freed
* - ESP_OK on success
*/
esp_err_t spi_bus_free(spi_host_device_t host);
/**
* @brief Allocate a device on a SPI bus
*
* This initializes the internal structures for a device, plus allocates a CS pin on the indicated SPI master
* peripheral and routes it to the indicated GPIO. All SPI master devices have three CS pins and can thus control
* up to three devices.
*
* @param host SPI peripheral to allocate device on
* @param dev_config SPI interface protocol config for the device
* @param handle Pointer to variable to hold the device handle
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_ERR_NOT_FOUND if host doesn't have any free CS slots
* - ESP_ERR_NO_MEM if out of memory
* - ESP_OK on success
*/
esp_err_t spi_bus_add_device(spi_host_device_t host, spi_device_interface_config_t *dev_config, spi_device_handle_t *handle);
/**
* @brief Remove a device from the SPI bus
*
* @param handle Device handle to free
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_ERR_INVALID_STATE if device already is freed
* - ESP_OK on success
*/
esp_err_t spi_bus_remove_device(spi_device_handle_t handle);
/**
* @brief Queue a SPI transaction for execution
*
* @param handle Device handle obtained using spi_host_add_dev
* @param trans_desc Description of transaction to execute
* @param ticks_to_wait Ticks to wait until there's room in the queue; use portMAX_DELAY to
* never time out.
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait);
/**
* @brief Get the result of a SPI transaction queued earlier
*
* This routine will wait until a transaction to the given device (queued earlier with
* spi_device_queue_trans) has succesfully completed. It will then return the description of the
* completed transaction so software can inspect the result and e.g. free the memory or
* re-use the buffers.
*
* @param handle Device handle obtained using spi_host_add_dev
* @param trans_desc Pointer to variable able to contain a pointer to the description of the
* transaction that is executed
* @param ticks_to_wait Ticks to wait until there's a returned item; use portMAX_DELAY to never time
out.
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transaction_t **trans_desc, TickType_t ticks_to_wait);
/**
* @brief Do a SPI transaction
*
* Essentially does the same as spi_device_queue_trans followed by spi_device_get_trans_result. Do
* not use this when there is still a transaction queued that hasn't been finalized
* using spi_device_get_trans_result.
*
* @param handle Device handle obtained using spi_host_add_dev
* @param trans_desc Pointer to variable able to contain a pointer to the description of the
* transaction that is executed
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
esp_err_t spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *trans_desc);
#ifdef __cplusplus
}
#endif
#endif