SpiPort_ARTERY_AT32/Src/SpiPortArtery.c

137 lines
4.0 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 "SpiPortArtery.h"
tSpiPortArtery vSpiPortInit(
spi_type *spi,
spi_frame_bit_num_type spiFrameBit,
spi_mclk_freq_div_type mclkDIV,
spi_clock_polarity_type clockPolarity,
spi_clock_phase_type clockPhase,
crm_periph_clock_type spiClock,
tGpioPin *chipSelect
) {
spi_i2s_reset(spi);
spi_init_type spi_init_struct;
crm_periph_clock_enable(spiClock, TRUE);
spi_default_para_init(&spi_init_struct);
spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
spi_init_struct.mclk_freq_division = mclkDIV;
spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
spi_init_struct.frame_bit_num = spiFrameBit;
// spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_LOW;
// spi_init_struct.clock_phase = SPI_CLOCK_PHASE_1EDGE;
spi_init_struct.clock_polarity = clockPolarity;
spi_init_struct.clock_phase = clockPhase;
spi_crc_polynomial_set(spi, 7);
spi_crc_enable(spi, TRUE);
spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
spi_init(spi, &spi_init_struct);
spi_enable(spi, TRUE);
tSpiPortArtery spiPort = {
.spi = spi,
.chipSelect = chipSelect
};
return spiPort;
}
static uint16_t vSpiPortReceive(tSpiPortArtery *env, uint16_t *data, uint32_t timeout) {
uint16_t received = 0;
uint32_t endMs = SystemGetMs() + timeout;
while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) {
// В буфере приемника еcть данные
if (spi_i2s_flag_get(env->spi, SPI_I2S_RDBF_FLAG)) {
*data = spi_i2s_data_receive(env->spi);
++received;
break;
}
}
return received;
}
static uint16_t vSpiPortTransmit(tSpiPortArtery *env, uint16_t *data, uint32_t timeout) {
uint16_t sent = 0;
uint32_t endMs = SystemGetMs() + timeout;
while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) {
// Буфер передатчика пуст
if (spi_i2s_flag_get(env->spi, SPI_I2S_TDBE_FLAG)) {
spi_i2s_data_transmit(env->spi, *data);
++sent;
break;
}
}
return sent;
}
static bool vSpiPortSovTransmit(tSpiPortArtery *env, const uint16_t *data, uint32_t timeout) {
uint32_t endMs = SystemGetMs() + timeout;
while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) {
// Буфер передатчика пуст
if (spi_i2s_flag_get(env->spi, SPI_I2S_TDBE_FLAG)) {
spi_i2s_data_transmit(env->spi, *data);vSpiPortReceive (env,data,timeout);
return true;
}
}
return false;
}
static bool vSpiPortSovReceive(tSpiPortArtery *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_flag_get(env->spi, SPI_I2S_RDBF_FLAG)) {
*data = spi_i2s_data_receive(env->spi);
return true;
}
}
return false;
}
//простая реализация chipSelect для одного утройства на шине
static bool vSpiPortChipSelectMono(tSpiPortArtery *env, uint32_t timeout) {
GpioPinEnable(env->chipSelect);
return true;
}
static bool vSpiPortChipReleaseMono(tSpiPortArtery *env, uint32_t timeout) {
GpioPinDisable(env->chipSelect);
return true;
}
tSpiPortIO vSpiPortGetIo(tSpiPortArtery *env) {
tSpiPortIO io = {
.env = env,
.receive = (SpiPortIOTransaction) vSpiPortSovReceive,
.transmit = (SpiPortIOTransaction) vSpiPortSovTransmit,
.chipSelect =(SpiPortChipArbitrage) vSpiPortChipSelectMono,
.chipRelease =(SpiPortChipArbitrage) vSpiPortChipReleaseMono
};
return io;
}