#include "stm32g4xx.h" #include "gpio.h" #include "spi.h" static void Init(SPI_TypeDef* SPI) { SPI->CR1 = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_SSI | SPI_CR1_SSM | (SPI_CR1_BR_0 | SPI_CR1_BR_1) | SPI_CR1_MSTR; SPI->CR2 = SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2 | SPI_CR2_FRXTH; SPI->CR1 |= SPI_CR1_SPE; } //------------------------------------------------------------------------------ void SPI1_Init() { if(RCC->APB2ENR & RCC_APB2ENR_SPI1EN) return; RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; GPIO_InitPin(GPIO_PIN_5 | GPIO_PORT_A | GPIO_ALTER | GPIO_AF5 | GPIO_OSPEED_HIGH); // SCK GPIO_InitPin(GPIO_PIN_6 | GPIO_PORT_A | GPIO_ALTER | GPIO_AF5 | GPIO_OSPEED_HIGH); // MISO GPIO_InitPin(GPIO_PIN_7 | GPIO_PORT_A | GPIO_ALTER | GPIO_AF5 | GPIO_OSPEED_HIGH); // MOSI GPIO_InitPin(GPIO_PIN_4 | GPIO_PORT_A | GPIO_OUTPUT | GPIO_OSPEED_HIGH | GPIO_SET); // NCS -> PMW3901 Init(SPI1); } //------------------------------------------------------------------------------ static void Trans(SPI_TypeDef* SPI, const void* WriteData, void* ReadData, unsigned long Size) { unsigned char* dr=(unsigned char*)ReadData; unsigned char* dw=(unsigned char*)WriteData; volatile char& DR = *((volatile char*)&(SPI->DR)); while (Size--) { while (!(SPI->SR & SPI_SR_TXE)) { asm volatile("NOP"); } if (dw) DR = *(dw++); else DR = 0x00; while (!(SPI->SR & SPI_SR_RXNE)) { asm volatile("NOP"); } if (dr) *(dr++) = DR; else volatile char t = DR; } while (SPI->SR & SPI_SR_BSY) { asm volatile("NOP"); } } //------------------------------------------------------------------------------ static inline void CS_IMU(bool En) { if(En) GPIOA->BSRR = GPIO_BSRR_BR_4; else GPIOA->BSRR = GPIO_BSRR_BS_4; for (unsigned long a = 0; a < 21; a++) { asm volatile("NOP"); } } //------------------------------------------------------------------------------ void SPI1_TransferCons(const void* WriteData, unsigned long WriteSize, void* ReadData, unsigned long ReadSize) { CS_IMU(true); Trans(SPI1, WriteData, 0, WriteSize); Trans(SPI1, 0, ReadData, ReadSize); CS_IMU(false); } //------------------------------------------------------------------------------ void SPI1_TransferParallel(const void* WriteData, void* ReadData, unsigned long Size) { CS_IMU(true); Trans(SPI1, WriteData, ReadData, Size); CS_IMU(false); } //------------------------------------------------------------------------------