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.
KED/ked/drivers/spi.c

279 lines
6.3 KiB

#include "spi.h"
// generic implementation of spi channel class
void spiInitMaster(spiCH_t spi_hw_ch,
spi_clkPol_t clockPolarity,
spi_phase_t phase,
spi_framef_t frameFormat,
spi_comMode_t comMode,
uint32_t prescaler)
{
// TODO: step by step implementation
#if 0
RCC->APB2ENR |= (1<<12); // Enable SPI1 CLock
SPI1->CR1 |= (1<<0)|(1<<1); // CPOL=1, CPHA=1
//SPI_BASE->CR1 |= (1<<0) | (1 << 1);
SPI1->CR1 |= (1<<2); // Master Mode
//SPI_BASE->CR1 |= (1 << 2);
SPI1->CR1 |= (3<<3); // BR[2:0] = 011: fPCLK/16, PCLK2 = 80MHz, SPI clk = 5MHz
//SPI_BASE-> CR1 |= (3<<3);
SPI1->CR1 &= ~(1<<7); // LSBFIRST = 0, MSB first
//SPI_BASE->CR1 &= ~(1<<7);
SPI1->CR1 |= (1<<8) | (1<<9); // SSM=1, SSi=1 -> Software Slave Management
//SPI_BASE->CR1 |= (1 << 8) | (1 << 9);
SPI1->CR1 &= ~(1<<10); // RXONLY = 0, full-duplex
//SPI_BASE->CR1 &= ~(1<<10);
SPI1->CR1 &= ~(1<<11); // CRCL =0, 8 bit data
//SPI_BASE->CR1 &= ~(1 << 11);
#endif
#if 1
//RCC->APB2ENR |= (1<<12); // Enable SPI1 CLock
spiEnableBus(spi_hw_ch);
//SPI1->CR1 |= (1<<0)|(1<<1); // CPOL=1, CPHA=1
//SPI_BASE->CR1 |= (1<<0) | (1 << 1);
spiSetPolarity(spi_hw_ch,clockPolarity);
spiSetPhase(spi_hw_ch,phase);
//SPI1->CR1 |= (1<<2); // Master Mode
//SPI_BASE->CR1 |= (1 << 2);
spiSetMode(spi_hw_ch, SPI_MASTER);
//SPI1->CR1 |= (3<<3); // BR[2:0] = 011: fPCLK/16, PCLK2 = 80MHz, SPI clk = 5MHz
//SPI_BASE-> CR1 |= (3<<3);
spiSetClockPrescaler(spi_hw_ch, prescaler);
//SPI1->CR1 &= ~(1<<7); // LSBFIRST = 0, MSB first
//SPI_BASE->CR1 &= ~(1<<7);
spiSetFrameFormat(spi_hw_ch,frameFormat);
//SPI1->CR1 |= (1<<8) | (1<<9); // SSM=1, SSi=1 -> Software Slave Management
SPI_BASE->CR1 |= (1 << 8) | (1 << 9);
//spiSetSoftwareSlaveManagement(spi_hw_ch,1);
//SPI1->CR1 &= ~(1<<10); // RXONLY = 0, full-duplex
SPI_BASE->CR1 &= ~(1<<10);
//spiSetComMode(spi_hw_ch, comMode);
//SPI1->CR1 &= ~(1<<11); // CRCL =0, 8 bit data
SPI_BASE->CR1 |= SPI_CR1_CRCL;
SPI_BASE->CR2 = SPI_CR2_SSOE | SPI_CR2_RXNEIE | SPI_CR2_FRXTH | SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;
//spiDissable(spi_hw_ch);
#endif
//SPI1->CR2 = 0;
//SPI_BASE->CR2 = 0;
/*
spiReset(spi_ch);
spiEnableBus(spi_ch);
spiSetPolarity(spi_ch, clockPolarity);
spiSetMode(spi_ch, mode);
spiSetPhase(spi_ch, phase);
spiSetFrameFormat(spi_ch, frameFormat);
spiSetClockPrescaler(spi_ch, prescaler);
spiDissable(spi_hw_ch);
*/
}
void spiSetupCH(spi_ch_t *ch, spiCH_t spi_hw_ch, pinNo_t chipselectPin)
{
ch->pin = chipselectPin;
ch->spi = spi_hw_ch;
pinWrite(chipselectPin, 0);
}
uint8_t spiReadReg(spi_ch_t *spi_ch,
uint8_t reg_address) {
uint8_t buf;
// select target device
pinWrite(spi_ch->pin,0);
// send address of target register
spiTrx(spi_ch->spi, reg_address);
// read from target register
buf = spiTrx(spi_ch->spi,0x00);
// release target device
pinWrite(spi_ch->pin,1);
return buf;
}
void spiAutoReadBlock(spi_ch_t *spi_ch,
uint8_t start_address,
uint8_t* buffer,
uint8_t buf_len) {
uint8_t i = 0;
// select target device
pinWrite(spi_ch->pin,0);
// send address of starting register
spiTrx(spi_ch->spi, start_address);
// read block from device
for(;i < buf_len;i++) {
buffer[i] = spiTrx(spi_ch->spi, 0x00);
}
// release target device
pinWrite(spi_ch->pin,1);
}
void spiWriteReg(spi_ch_t *spi_ch,
uint8_t reg_address,
uint8_t data) {
// select target device
pinWrite(spi_ch->pin,0);
// send address of target register
spiTrx(spi_ch->spi, reg_address);
// write to target register
spiTrx(spi_ch->spi, data);
// release target device
pinWrite(spi_ch->pin,1);
}
void spiWriteBlock(spi_ch_t *spi_ch,
uint8_t start_address,
const uint8_t *data,
uint8_t data_len) {
uint8_t i = 0;
// select target device
pinWrite(spi_ch->pin,0);
// send address of starting register
spiTrx(spi_ch->spi, start_address);
// read block from device
for(;i < data_len;i++) {
spiTrx(spi_ch->spi, data[i]);
}
// release target device
pinWrite(spi_ch->pin,1);
}
void spiWrite8bit(spi_ch_t *spi_ch,
uint8_t bits)
{
pinWrite(spi_ch->pin,0);
spiTrx(spi_ch->spi,bits);
pinWrite(spi_ch->pin,1);
}
uint8_t spiReadWrite8bit(spi_ch_t *spi_ch,
uint8_t bits)
{
uint8_t buf;
pinWrite(spi_ch->pin,0);
buf = spiTrx(spi_ch->spi,bits);
pinWrite(spi_ch->pin,1);
return buf;
}
void spiWrite16bit(spi_ch_t *spi_ch,
uint16_t bits)
{
pinWrite(spi_ch->pin,0);
if(spiGetFrameFormat(spi_ch->spi) == SPI_MSB_FIRST) {
spiTrx(spi_ch->spi,(uint8_t)(bits >> 8));
spiTrx(spi_ch->spi,(uint8_t)(bits));
} else {
spiTrx(spi_ch->spi,(uint8_t)(bits));
spiTrx(spi_ch->spi,(uint8_t)(bits >> 8));
}
pinWrite(spi_ch->pin,1);
}
uint16_t spiReadWrite16bit(spi_ch_t *spi_ch,
uint16_t bits)
{
uint16_t buf;
pinWrite(spi_ch->pin,0);
if(spiGetFrameFormat(spi_ch->spi) == SPI_LSB_FIRST) {
buf = spiTrx(spi_ch->spi,(uint8_t)(bits >> 8)) << 8;
buf |= spiTrx(spi_ch->spi,(uint8_t)(bits));
} else {
buf = spiTrx(spi_ch->spi,(uint8_t)(bits));
buf |= spiTrx(spi_ch->spi,(uint8_t)(bits >> 8)) << 8;
}
pinWrite(spi_ch->pin,1);
return buf;
}
void spiWrite32bit(spi_ch_t *spi_ch,
uint32_t bits)
{
pinWrite(spi_ch->pin,0);
if(spiGetFrameFormat(spi_ch->spi) == SPI_LSB_FIRST) {
spiTrx(spi_ch->spi,(uint8_t)(bits >> 24));
spiTrx(spi_ch->spi,(uint8_t)(bits >> 16));
spiTrx(spi_ch->spi,(uint8_t)(bits >> 8));
spiTrx(spi_ch->spi,(uint8_t)(bits));
} else {
spiTrx(spi_ch->spi,(uint8_t)(bits));
spiTrx(spi_ch->spi,(uint8_t)(bits >> 8));
spiTrx(spi_ch->spi,(uint8_t)(bits >> 16));
spiTrx(spi_ch->spi,(uint8_t)(bits >> 24));
}
pinWrite(spi_ch->pin,1);
}
uint32_t spiReadWrite32bit(spi_ch_t *spi_ch,
uint8_t bits)
{
uint32_t buf;
pinWrite(spi_ch->pin,0);
if(spiGetFrameFormat(spi_ch->spi) == SPI_LSB_FIRST) {
buf = spiTrx(spi_ch->spi,(uint8_t)(bits >> 24)) << 24;
buf |= spiTrx(spi_ch->spi,(uint8_t)(bits >> 16)) << 16;
buf |= spiTrx(spi_ch->spi,(uint8_t)(bits >> 8)) << 8;
buf |= spiTrx(spi_ch->spi,(uint8_t)(bits));
} else {
buf = spiTrx(spi_ch->spi,(uint8_t)(bits));
buf |= spiTrx(spi_ch->spi,(uint8_t)(bits >> 8)) >> 8;
buf |= spiTrx(spi_ch->spi,(uint8_t)(bits >> 16)) >> 16;
buf |= spiTrx(spi_ch->spi,(uint8_t)(bits >> 24)) >> 24;
}
pinWrite(spi_ch->pin,1);
return buf;
}