#include "spi.h"
#include "registers.h"
void spi_init(spi_t* spi, SPI_TypeDef* peripheral, uint8_t idx) {
spi->periph = peripheral;
spi->idx = idx;
}
void spi_master_configure_speed(spi_t *spi,
uint8_t divider) {
reg_write_bits(&spi->periph->CR1, divider << SPI_CR1_BR_Pos, SPI_CR1_BR_Msk);
}
void spi_master_configure(spi_t *spi, bool sw_nss, bool clock_polarity,
bool clock_phase, spi_frame_orientation_t orientation, spi_frame_format_t format) {
reg_write_bits(&spi->periph->CR1,
(sw_nss << SPI_CR1_SSM_Pos) | (format << SPI_CR1_DFF_Pos) |
(orientation << SPI_CR1_LSBFIRST_Pos) |
(1 << SPI_CR1_BIDIMODE_Pos) | (1 << SPI_CR1_MSTR_Msk) |
(clock_polarity << SPI_CR1_CPOL_Msk) | (clock_phase << SPI_CR1_CPHA_Msk),
SPI_CR1_SSM_Msk | SPI_CR1_DFF_Msk | SPI_CR1_LSBFIRST_Msk | SPI_CR1_BIDIMODE_Msk | SPI_CR1_MSTR_Msk | SPI_CR1_CPOL_Msk | SPI_CR1_CPHA_Msk);
}
void spi_master_enable(spi_t *spi, bool enable) {
reg_set_bits(&spi->periph->CR1, SPI_CR1_SPE);
}
uint16_t spi_transmit(spi_t *spi, uint16_t *data, uint16_t size) {
for (int16_t i = 0; i < size; i++) {
char byte = *(data++);
while (!(spi->periph->SR & USART_SR_TXE));
spi->periph->DR = byte;
}
return size;
}
uint16_t spi_receive(spi_t *spi, uint16_t *buffer, uint16_t max_size) {
uint16_t size = 0;
while (size < max_size - 1 && (spi->periph->SR & USART_SR_RXNE)) {
*(buffer + (size++)) = (char)(spi->periph->DR & USART_DR_DR_Msk);
}
return size;
}
bool spi_can_transmit(spi_t *spi) {
return (spi->periph->SR & SPI_SR_TXE) != 0;
}
bool spi_can_receive(spi_t *spi) {
return (spi->periph->SR & SPI_SR_RXNE) != 0;
}