#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,
bool csn_pulse) {
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)
| (csn_pulse << SPI_CTRL_PULSE_CSN_POS),
SPI_CTRL_SIZE_SEL_MSK | SPI_CTRL_PULSE_CSN_POS | 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;
}