You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
3.4 KiB
162 lines
3.4 KiB
#include "spi.h"
|
|
#include "hardwareDescription.h"
|
|
#include "hwd_spi.h"
|
|
#include "interrupt.h"
|
|
|
|
#define SPI_BASE ((SPI_TypeDef *)spiBase_Addr_List[spi_hw_ch])
|
|
|
|
void spiReset(spiCH_t spi_hw_ch)
|
|
{
|
|
if(spiBus_No[spi_hw_ch] == 1) {
|
|
RCC->APB1RSTR |= (1 << spiBus_Rst_bitPos[spi_hw_ch]);
|
|
RCC->APB1RSTR &= ~(1 << spiBus_Rst_bitPos[spi_hw_ch]);
|
|
return;
|
|
}
|
|
|
|
RCC->APB2RSTR |= (1 << spiBus_Rst_bitPos[spi_hw_ch]);
|
|
RCC->APB2RSTR &= ~(1 << spiBus_Rst_bitPos[spi_hw_ch]);
|
|
}
|
|
|
|
void spiEnableBus(spiCH_t spi_hw_ch)
|
|
{
|
|
if(spiBus_No[spi_hw_ch] == 1) {
|
|
RCC->APB1ENR |= (1 << spiBus_En_bitPos[spi_hw_ch]);
|
|
return;
|
|
}
|
|
|
|
RCC->APB2ENR |= (1 << spiBus_En_bitPos[spi_hw_ch]);
|
|
}
|
|
|
|
void spiEnable(spiCH_t spi_hw_ch)
|
|
{
|
|
SPI_BASE->CR1 |= SPI_CR1_SPE;
|
|
}
|
|
|
|
void spiDissable(spiCH_t spi_hw_ch)
|
|
{
|
|
// TODO: implement p.768 procedure for dissabling
|
|
//while(SPI_BASE->SR
|
|
SPI_BASE->CR1 &= ~SPI_CR1_SPE;
|
|
}
|
|
|
|
void spiSetMode(spiCH_t spi_hw_ch, spi_mode_t mode)
|
|
{
|
|
SPI_BASE->CR1 &= ~(mode << SPI_CR1_MSTR_Pos);
|
|
SPI_BASE->CR1 |= mode << SPI_CR1_MSTR_Pos;
|
|
|
|
// TODO: find out if this is the correct place to set the SSOE bit
|
|
SPI_BASE->CR2 &= ~SPI_CR2_SSOE;
|
|
if(mode == SPI_MASTER) {
|
|
SPI_BASE->CR2 |= SPI_CR2_SSOE;
|
|
}
|
|
}
|
|
|
|
void spiSetPolarity(spiCH_t spi_hw_ch, spi_clkPol_t clkPol)
|
|
{
|
|
// reset
|
|
SPI_BASE->CR1 &= ~SPI_CR1_CPOL;
|
|
// set
|
|
SPI_BASE->CR1 |= clkPol << SPI_CR1_CPOL_Pos;
|
|
}
|
|
|
|
void spiSetPhase(spiCH_t spi_hw_ch, spi_phase_t phase)
|
|
{
|
|
// reset
|
|
SPI_BASE->CR1 &= ~(phase << SPI_CR1_CPHA_Pos);
|
|
// set
|
|
SPI_BASE->CR1 |= phase << SPI_CR1_CPHA_Pos;
|
|
}
|
|
|
|
void spiSetBitFrameLength(spiCH_t spi_hw_ch, spi_framel_t framel)
|
|
{
|
|
|
|
SPI_BASE->CR2 &= ~(SPI_CR2_FRXTH | SPI_CR2_DS);
|
|
|
|
// using p.974 as example
|
|
if(framel == SPI_FRAME_LENGTH_8BIT) {
|
|
// set FIFO reception threshold to 8 bit
|
|
SPI_BASE->CR2 |= SPI_CR2_FRXTH;
|
|
// set transfer lwnght to 8 bit
|
|
SPI_BASE->CR2 |= SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;
|
|
return;
|
|
}
|
|
SPI_BASE->CR2 |= SPI_CR2_DS;
|
|
}
|
|
|
|
void spiSetFrameFormat(spiCH_t spi_hw_ch, spi_framef_t framef)
|
|
{
|
|
// reset
|
|
SPI_BASE->CR1 &= ~SPI_CR1_LSBFIRST;
|
|
// set
|
|
SPI_BASE->CR1 |= framef << SPI_CR1_LSBFIRST_Pos;
|
|
}
|
|
|
|
spi_framef_t spiGetFrameFormat(spiCH_t spi_hw_ch)
|
|
{
|
|
return (spi_framef_t)(SPI_BASE->CR1 & SPI_CR1_LSBFIRST) >> SPI_CR1_LSBFIRST_Pos;
|
|
}
|
|
|
|
void spiSetClockPrescaler(spiCH_t spi_hw_ch, uint32_t clkDiv)
|
|
{
|
|
// reset
|
|
SPI_BASE->CR1 &= ~SPI_CR1_BR;
|
|
// set
|
|
SPI_BASE->CR1 |= (clkDiv << SPI_CR1_BR_Pos) & SPI_CR1_BR;
|
|
}
|
|
|
|
void spiSetComMode(spiCH_t spi_hw_ch, spi_comMode_t comMode)
|
|
{
|
|
// reset
|
|
SPI_BASE->CR1 &= ~SPI_CR1_RXONLY;
|
|
// set
|
|
SPI_BASE->CR1 |= comMode << SPI_CR1_RXONLY_Pos;
|
|
}
|
|
|
|
void spiSetSoftwareSlaveManagement(spiCH_t spi_hw_ch, uint8_t logic)
|
|
{
|
|
SPI_BASE->CR1 &= ~SPI_CR1_SSM;
|
|
|
|
if(logic){
|
|
SPI_BASE->CR1 |= SPI_CR1_SSM;
|
|
}
|
|
}
|
|
|
|
void spiSetInternalSlaveSelect(spiCH_t spi_hw_ch, uint8_t logic)
|
|
{
|
|
SPI_BASE->CR1 &= ~SPI_CR1_SSI;
|
|
|
|
if(logic) {
|
|
SPI_BASE->CR1 |= SPI_CR1_SSI;
|
|
}
|
|
}
|
|
|
|
uint8_t spiTrx8BitPolling(spiCH_t spi_hw_ch, uint8_t tx_data)
|
|
{
|
|
// wait for BSY bit to Reset -> This will indicate that SPI is not busy in communication
|
|
while (SPI_BASE->SR & SPI_SR_BSY);
|
|
|
|
// from example code p.975 f
|
|
// this masking must be done. otherwise 16bits frame will be used
|
|
*(uint8_t*)&(SPI_BASE->DR) = tx_data;
|
|
|
|
// Wait for RXNE to set -> This will indicate that the Rx buffer is not empty
|
|
while (!(SPI_BASE->SR &SPI_SR_RXNE));
|
|
|
|
|
|
// TODO: test read!
|
|
return *(uint8_t*)&(SPI_BASE->DR);
|
|
}
|
|
|
|
// Interrupt Service Routines
|
|
|
|
void SPI1_IRQHandle()
|
|
{
|
|
//HANDLE_INT_FLAG(SPI1->SR, );
|
|
}
|
|
|
|
void SPI2_IRQHandle()
|
|
{
|
|
|
|
}
|
|
|