// // Created by cfif on 16.09.22. // #include #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; }