SpiPort_NATION_N32G45X/Src/SpiPortNation.c

111 lines
3.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by cfif on 16.09.22.
//
#include <SystemDelayInterface.h>
#include "SpiPortNation.h"
tSpiPortNation SpiPort_Init(
SPI_Module *spi,
uint16_t spiFrameBit,
tGpioPin *chipSelect
) {
SPI_InitType spi_init_struct;
spi_init_struct.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
spi_init_struct.SpiMode = SPI_MODE_MASTER;
spi_init_struct.DataLen = spiFrameBit;
spi_init_struct.CLKPOL = SPI_CLKPOL_LOW;
spi_init_struct.CLKPHA = SPI_CLKPHA_FIRST_EDGE;
spi_init_struct.NSS = SPI_NSS_SOFT;
spi_init_struct.BaudRatePres = SPI_BR_PRESCALER_8;
spi_init_struct.FirstBit = SPI_FB_MSB;
SPI_Init(spi, &spi_init_struct);
SPI_Enable(spi, ENABLE);
tSpiPortNation spiPort = {
.spi = spi,
.chipSelect = chipSelect
};
return spiPort;
}
static bool vSpiPortTransmit(tSpiPortNation *env, const uint16_t *data, uint32_t timeout) {
uint32_t endMs = SystemGetMs() + timeout;
while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) {
// Буфер передатчика пуст
if (SPI_I2S_GetStatus(env->spi, SPI_I2S_TE_FLAG)) {
SPI_I2S_TransmitData(env->spi, *data);
return true;
}
}
return false;
}
static bool vSpiPortReceive(tSpiPortNation *env, uint16_t *data, uint32_t timeout) {
uint32_t endMs = SystemGetMs() + timeout;
while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) {
// В буфере приемника еcть данные
if (SPI_I2S_GetStatus(env->spi, SPI_I2S_RNE_FLAG)) {
*data = SPI_I2S_ReceiveData(env->spi);
return true;
}
}
return false;
}
static bool vSpiPortSovTransmit(tSpiPortNation *env, const uint16_t *data, uint32_t timeout) {
uint32_t endMs = SystemGetMs() + timeout;
while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) {
// Буфер передатчика пуст
if (SPI_I2S_GetStatus(env->spi, SPI_I2S_TE_FLAG)) {
SPI_I2S_TransmitData(env->spi, *data);vSpiPortReceive (env,data,timeout);
return true;
}
}
return false;
}
static bool vSpiPortSovReceive(tSpiPortNation *env, uint16_t *data, uint32_t timeout) {
uint32_t endMs = SystemGetMs() + timeout;
vSpiPortTransmit (env,data,timeout);
while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) {
// В буфере приемника еcть данные
if (SPI_I2S_GetStatus(env->spi, SPI_I2S_RNE_FLAG)) {
*data = SPI_I2S_ReceiveData(env->spi);
return true;
}
}
return false;
}
//простая реализация chipSelect для одного утройства на шине
static bool vSpiPortChipSelectMono(tSpiPortNation *env, uint32_t timeout) {
GpioPinEnable(env->chipSelect);
return true;
}
static bool vSpiPortChipReleaseMono(tSpiPortNation *env, uint32_t timeout) {
GpioPinDisable(env->chipSelect);
return true;
}
tSpiPortIO SpiPort_GetIo(tSpiPortNation *env) {
tSpiPortIO io = {
.env = env,
.receive = (SpiPortIOTransaction) vSpiPortSovReceive,
.transmit = (SpiPortIOTransaction) vSpiPortSovTransmit,
.chipSelect =(SpiPortChipArbitrage) vSpiPortChipSelectMono,
.chipRelease =(SpiPortChipArbitrage) vSpiPortChipReleaseMono,
};
return io;
}