/* * spi_master.c * * manage chip select externally. * * current version is BLOCKING. update later to use interrupt or DMA. */ #include "spi_master.h" void spim_init() { SPI_InitTypeDef spi = {0}; spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex; spi.SPI_Mode = SPI_Mode_Master; spi.SPI_DataSize = SPI_DataSize_8b; spi.SPI_CPOL = SPI_CPOL_High; spi.SPI_CPHA = SPI_CPHA_2Edge; spi.SPI_NSS = SPI_NSS_Soft; spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; spi.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI1, &spi); SPI_Cmd(SPI1, ENABLE); } void spim_write_raw(const uint8_t *data, uint16_t len) { // todo: make non-blocking, timeout and error checking while (len) { if (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)) { SPI_I2S_SendData(SPI1, *data); data++; len--; } } } void spim_write_reg8(uint8_t reg, const uint8_t *data, uint16_t len) { spim_write_raw(®, 1); spim_write_raw(data, len); } void spim_read_raw(uint8_t *data, uint16_t len) { // todo: non-blocking, timeout and error checking while (len) { while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)) {}; if (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)) { *data++ = SPI_I2S_ReceiveData(SPI1); len--; } SPI_I2S_SendData(SPI1, 0); } } void spim_read_reg8(uint8_t reg, uint8_t *data, uint16_t len) { spim_write_raw(®, 1); spim_read_raw(data, len); }