#ifndef _SPI_M_SYNC_H_ #define _SPI_M_SYNC_H_ #include "compiler.h" #include "sd_mmc_protocol.h" #include "hal_spi_m_sync.h" #include #ifdef __cplusplus extern "C" { #endif // lazy define #define SD_MMC_SPI_DEBUG (1) #ifdef SD_MMC_SPI_DEBUG #include "pdebug.h" #define sd_mmc_spi_debug(...) printf(__VA_ARGS__) #else #define sd_mmc_spi_debug(...) #endif //! Type of return error code typedef uint8_t sd_mmc_spi_errno_t; //! \name Return error codes //! @{ #define SD_MMC_SPI_NO_ERR 0 //! No error #define SD_MMC_SPI_ERR 1 //! General or an unknown error #define SD_MMC_SPI_ERR_RESP_TIMEOUT 2 //! Timeout during command #define SD_MMC_SPI_ERR_RESP_BUSY_TIMEOUT 3 //! Timeout on busy signal of R1B response #define SD_MMC_SPI_ERR_READ_TIMEOUT 4 //! Timeout during read operation #define SD_MMC_SPI_ERR_WRITE_TIMEOUT 5 //! Timeout during write operation #define SD_MMC_SPI_ERR_RESP_CRC 6 //! Command CRC error #define SD_MMC_SPI_ERR_READ_CRC 7 //! CRC error during read operation #define SD_MMC_SPI_ERR_WRITE_CRC 8 //! CRC error during write operation #define SD_MMC_SPI_ERR_ILLEGAL_COMMAND 9 //! Command not supported #define SD_MMC_SPI_ERR_WRITE 10 //! Error during write operation #define SD_MMC_SPI_ERR_OUT_OF_RANGE 11 //! Data access out of range //! @} /** \brief Return the maximum bus width of a slot * * \param slot Selected slot * * \return 1, 4 or 8 lines. */ static __inline__ uint8_t spi_m_sync_get_bus_width(struct spi_m_sync_descriptor* spi, uint8_t slot) { UNUSED(spi); UNUSED(slot); return 1; } /** \brief Return the high speed capability of the driver * * \return true, if the high speed is supported */ static __inline__ bool spi_m_sync_is_high_speed_capable(struct spi_m_sync_descriptor* spi) { UNUSED(spi); return false; } static __inline__ void spi_m_sync_get_response_128(struct spi_m_sync_descriptor* spi, uint8_t *resp) { UNUSED(spi); UNUSED(resp); return; } /////// PENGUIN START /** \brief Send a command on the selected slot * * \param cmd Command definition * \param arg Argument of the command * * \return true if success, otherwise false */ bool spi_m_sync_send_cmd(struct spi_m_sync_descriptor* spi, uint32_t cmd, uint32_t arg); /** \brief Send a adtc command on the selected slot * A adtc command is used for read/write access. * * \param cmd Command definition * \param arg Argument of the command * \param block_size Block size used for the transfer * \param nb_block Total number of block for this transfer * \param access_block if true, the x_read_blocks() and x_write_blocks() * functions must be used after this function. * If false, the mci_read_word() and mci_write_word() * functions must be used after this function. * * \return true if success, otherwise false */ bool spi_m_sync_adtc_start(struct spi_m_sync_descriptor *spi, uint32_t cmd, uint32_t arg, uint16_t block_size, uint16_t nb_block, bool access_block); /** \brief Send a command to stop a adtc command on the selected slot * * \param cmd Command definition * \param arg Argument of the command * * \return true if success, otherwise false */ bool spi_m_sync_adtc_stop(struct spi_m_sync_descriptor* spi, uint32_t cmd, uint32_t arg); /** \brief Start a read blocks transfer on the line * Note: The driver will use the DMA available to speed up the transfer. * * \param dest Pointer on the buffer to fill * \param nb_block Number of block to transfer * * \return true if started, otherwise false */ bool spi_m_sync_start_read_blocks(struct spi_m_sync_descriptor *spi, void *dst, uint16_t nb_block); /** \brief Start a write blocks transfer on the line * Note: The driver will use the DMA available to speed up the transfer. * * \param src Pointer on the buffer to send * \param nb_block Number of block to transfer * * \return true if started, otherwise false */ bool spi_m_sync_start_write_blocks(struct spi_m_sync_descriptor *spi, const void *src, uint16_t nb_block); /** \brief Wait the end of transfer initiated by mci_start_write_blocks() * * \return true if success, otherwise false */ bool spi_m_sync_wait_end_of_write_blocks(struct spi_m_sync_descriptor* spi); /** \brief Wait the end of transfer initiated by mci_start_read_blocks() * * \return true if success, otherwise false */ bool spi_m_sync_wait_end_of_read_blocks(struct spi_m_sync_descriptor* spi); /** \brief Write a word on the line * * \param value Word to send * * \return true if success, otherwise false */ bool spi_m_sync_write_word(struct spi_m_sync_descriptor* spi, uint32_t value); /** \brief Read a word on the line * * \param value Pointer on a word to fill * * \return true if success, otherwise false */ bool spi_m_sync_read_word(struct spi_m_sync_descriptor* spi, uint32_t* value); /** \brief Return the 32 bits response of the last command * * \return 32 bits response */ uint32_t spi_m_sync_get_response(struct spi_m_sync_descriptor* spi); /** \brief Send 74 clock cycles on the line of selected slot * Note: It is required after card plug and before card install. */ void spi_m_sync_send_clock(struct spi_m_sync_descriptor* spi); /** * \brief Select a slot and initialize it * * \param slot Selected slot * \param clock Maximum clock to use (Hz) * \param bus_width Bus width to use (1, 4 or 8) * \param high_speed true, to enable high speed mode */ int32_t spi_m_sync_select_device(struct spi_m_sync_descriptor* spi, uint8_t slot, uint32_t clock, uint8_t bus_width, bool high_speed); /** * \brief Deselect a slot * * \param slot Selected slot */ int32_t spi_m_sync_deselect_device(struct spi_m_sync_descriptor* spi, uint8_t slot); #ifdef __cpluscplus } #endif #endif