#include "spi.h" #include "registers.h" void spi_init(spi_t* spi, spi_peripheral_t* peripheral) { spi->periph = peripheral; } void spi_master_configure_speed(spi_t *spi, uint8_t divider) { reg_write_bits(&spi->periph->CTRL, ((uint32_t)divider) << SPI_CTRL_DIV_SEL_POS, SPI_CTRL_DIV_SEL_MSK); } void spi_master_configure(spi_t *spi, bool clock_polarity, bool clock_phase, spi_frame_orientation_t orientation, spi_frame_format_t format) { reg_write_bits(&spi->periph->CTRL, (format << SPI_CTRL_SIZE_SEL_POS) | (orientation << SPI_CTRL_LSBFIRST_POS) | (1 << SPI_CTRL_RX_EN_POS) | (1 << SPI_CTRL_TX_EN_POS) | (1 << SPI_CTRL_MASTER_POS) | (clock_polarity << SPI_CTRL_CLOCK_POLARITY_POS) | (clock_phase << SPI_CTRL_CLOCK_PHASE_POS), SPI_CTRL_SIZE_SEL_MSK | SPI_CTRL_LSBFIRST_MSK | SPI_CTRL_RX_EN_MSK | SPI_CTRL_TX_EN_MSK | SPI_CTRL_MASTER_MSK | SPI_CTRL_CLOCK_POLARITY_MSK | SPI_CTRL_CLOCK_PHASE_MSK); } void spi_master_enable(spi_t *spi, bool enable) { reg_write_bits(&spi->periph->CTRL, enable << SPI_CTRL_EN_POS, SPI_CTRL_EN_MSK); } uint16_t spi_transmit(spi_t *spi, uint16_t *data, uint16_t size) { for (int16_t i = 0; i < size; i++) { while (!(spi->periph->STATUS & SPI_STATUS_TX_EMPTY_MSK)); uint16_t word = *(data++); spi->periph->DATA = word; } return size; } uint16_t spi_receive(spi_t *spi, uint16_t *buffer, uint16_t max_size) { uint16_t size = 0; while (size < max_size && (spi->periph->STATUS & SPI_STATUS_RX_FULL_MSK)) { *(buffer + (size++)) = (uint16_t)(spi->periph->DATA & SPI_DATA_MSK); } return size; } bool spi_can_transmit(spi_t *spi) { return (spi->periph->STATUS & SPI_STATUS_TX_EMPTY_MSK) != 0; } uint16_t spi_can_receive(spi_t *spi) { return ((spi->periph->STATUS & SPI_STATUS_RX_FULL_MSK) != 0) ? 1 : 0; } bool spi_enable_interrupt(spi_t *spi, bool tx, bool rx) { reg_write_bits(&spi->periph->INTMASK, (tx << SPI_INTMASK_TX_EMPTY_POS) | (rx << SPI_INTMASK_RX_FULL_POS), SPI_INTMASK_RX_FULL_MSK | SPI_INTMASK_TX_EMPTY_MSK); return true; }