SP8EBC-ParaTNC/system/include/drivers/spi.h

104 wiersze
3.3 KiB
C

/*
* spi.h
*
* This is a general interface of SPI driver. Please read notes
* in platform specific implementation. Each of them might have
* it's own limitations
*
* Created on: Sep 22, 2022
* Author: mateusz
*/
#ifndef INCLUDE_DRIVERS_SPI_H_
#define INCLUDE_DRIVERS_SPI_H_
#include <stdint.h>
/**
* Return codes
*/
#define SPI_OK 0 //!< Function has succeeded
#define SPI_BUSY_DIFF_SLAVE 10 //!< Communication has been requested for different slave than what transmission is ongoing for
#define SPI_BUSY 11 //!< SPI bus is currently busy and cannot be used for requested operation
#define SPI_TX_DATA_TO_LONG 20 //!< requested data is too long to fit in internal SPI tx buffer
#define SPI_WRONG_SLAVE_ID 30 //!< unknown SPI slave (missing chip select mapping)
#define SPI_UKNOWN 255 //!< undesignated SPI error
/**
* SPI transfer mode using for initialization
*/
typedef enum spi_transfer_mode_t {
SPI_MASTER_MOTOROLA,
SPI_MASTER_TI,
SPI_SLAVE_MOTOROLA,
SPI_SLAVE_TI
}spi_transfer_mode_t;
/**
* SPI clock mode using for initialization, look at CPOL and CPHA values for each enum values.
*/
typedef enum spi_clock_polarity_strobe_t {
CLOCK_NORMAL_FALLING, //!< CPOL 0, CPHA 1
CLOCK_NORMAL_RISING, //!< CPOL 0, CPHA 0
CLOCK_REVERSED_FALLING, //!< CPOL 1, CPHA 0
CLOCK_REVERSED_RISING //!< CPOL 1, CPHA 1
}spi_clock_polarity_strobe_t;
#define SPI_ENDIAN_LSB 0
#define SPI_ENDIAN_MSB 1
#define SPI_TX_FROM_INTERNAL 1
#define SPI_TX_FROM_EXTERNAL 2
#define SPI_USE_INTERNAL_RX_BUF 0
/**
* Current SPI reception state
*/
typedef enum spi_rx_state_t {
SPI_RX_IDLE, //!< SPI is configured and ready for operation
SPI_RX_RXING, //!< SPI is currently receiving
SPI_RX_DONE, //!< Reception is done
SPI_RX_WAITING_FOR_RX, //!< SPI is currently transmitting and reception is queued
SPI_RX_ERROR_OVERRUN, //!< Overrun had been detected and reception was terminated
SPI_RX_ERROR_MODF,
}spi_rx_state_t;
/**
* Current SPI transmission state
*/
typedef enum spi_tx_state_t {
SPI_TX_IDLE,
SPI_TX_TXING,
SPI_TX_DONE,
SPI_TX_ERROR_MODF
}spi_tx_state_t;
//! This function initializes SPI bus to work as full duplex two-wire connection, w/o DMA data flow
uint8_t spi_init_full_duplex_pio(spi_transfer_mode_t mode, spi_clock_polarity_strobe_t strobe, int speed, int endianess);
//! Sends data asynchronously to selected SPI slave, discards anything what will come in over MISO line
uint8_t spi_tx_data(uint32_t slave_id, uint8_t tx_from_internal, uint8_t * tx_buffer, uint16_t ln_to_tx);
//! Sends data synchronously to selected slave and after that receives data from it. Everything received before TX is finish is discarded.
uint8_t spi_rx_tx_data(uint32_t slave_id, uint8_t tx_from_internal, uint8_t * rx_buffer, uint8_t * tx_buffer, uint16_t ln_to_rx, uint16_t ln_to_tx);
//! Returns pointer to receive buffer and if reception is done resets RX state back to idle.
uint8_t * spi_get_rx_data(void);
//! Blocking wait until both RX and TX is done
uint8_t spi_wait_for_comms_done(void);
//! Resets all errors and reverts state back to IDLE
void spi_reset_errors(void);
spi_rx_state_t spi_get_rx_state(void);
spi_tx_state_t spi_get_tx_state(void);
//! Returns an ID of current SPI slave or zero if SPI is idle
uint32_t spi_get_current_slave(void);
void spi_irq_handler(void);
#endif /* INCLUDE_DRIVERS_SPI_H_ */