Program Listing for File spi3w-xmc.cpp
↰ Return to documentation for file (src/framework/arduino/pal/spi3w-xmc.cpp)
/*
* \file spi3w-xmc-ino.cpp
* \brief XMC 3wire SPI cover
* \author Infineon Technologies AG
* \version 4.0.0
* \copyright 2020-2024 Infineon Technologies AG
*
* SPDX-License-Identifier: MIT
*/
#include "spi3w-ino.hpp"
#include "Wire.h"
#if (SPI3W_INO == SPI3W_XMC)
using namespace tle5012;
SPIClass3W::SPIClass3W(uint8_t spiNum):SPIClass()
{
this->mCS = SS;
this->mMISO = MISO;
this->mMOSI = MOSI;
this->mSCK = SCK;
this->mSpiNum = spiNum;
}
SPIClass3W::~SPIClass3W()
{
}
void SPIClass3W::begin(uint8_t miso, uint8_t mosi, uint8_t sck, uint8_t cs)
{
setCSPin(cs);
this->mMOSI = mosi;
this->mMISO = miso;
this->mSCK = sck;
m3Wire.mosi = mapping_port_pin[this->mMOSI];
m3Wire.miso = mapping_port_pin[this->mMISO];
m3Wire.sck = mapping_port_pin[this->mSCK];
setupSPI();
initSpi();
}
void SPIClass3W::setCSPin(uint8_t cs)
{
this->mCS = cs;
m3Wire.cs = mapping_port_pin[this->mCS];
}
void SPIClass3W::setupSPI()
{
m3Wire.miso_open.mode = XMC_GPIO_MODE_INPUT_TRISTATE;
m3Wire.miso_close.mode = XMC_GPIO_MODE_INPUT_TRISTATE;
m3Wire.mosi_open.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
m3Wire.mosi_close.mode = XMC_GPIO_MODE_INPUT_TRISTATE;
m3Wire.sck_config.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
m3Wire.channel_config.baudrate = SPEED;
m3Wire.channel_config.bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER;
m3Wire.channel_config.selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS;
m3Wire.channel_config.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE;
m3Wire.cs_config.mode = OUTPUT;
m3Wire.cs_config.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW;
#if defined(XMC1100_XMC2GO) || defined(XMC1100_H_BRIDGE2GO)
m3Wire.channel = XMC_SPI0_CH1;
m3Wire.input_source = XMC_INPUT_C;
m3Wire.miso_open.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.miso_close.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.mosi_open.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT7;
m3Wire.mosi_open.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.sck_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT7;
m3Wire.sck_config.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
#elif defined(XMC1400_XMC2GO)
m3Wire.channel = XMC_SPI1_CH1;
m3Wire.input_source = XMC_INPUT_A;
m3Wire.miso_open.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.miso_close.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.mosi_open.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT9;
m3Wire.mosi_open.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.sck_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT8;
m3Wire.sck_config.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
#elif defined(XMC1100_Boot_Kit) || defined(XMC1300_Boot_Kit) || defined(XMC1400_Boot_Kit)
m3Wire.channel = XMC_SPI0_CH0;
m3Wire.input_source = XMC_INPUT_D;
m3Wire.miso_open.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.miso_close.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.mosi_open.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT6;
m3Wire.mosi_open.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
m3Wire.sck_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT6;
m3Wire.sck_config.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD;
#elif defined(XMC4400_Platform2GO) || defined(XMC4200_Platform2GO)
m3Wire.channel = XMC_SPI1_CH1;
m3Wire.miso_close.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.miso_open.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.mosi_open.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.mosi_open.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4;
m3Wire.sck_config.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.cs_config.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.sck_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4;
m3Wire.input_source = XMC_INPUT_D;
#elif defined(XMC4700_Relax_Kit)
m3Wire.miso_close.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.miso_open.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.mosi_open.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.sck_config.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
m3Wire.cs_config.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
if (mSpiNum == 1) {
m3Wire.channel = XMC_SPI1_CH1;
m3Wire.input_source = XMC_INPUT_D;
m3Wire.mosi_open.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2;
m3Wire.sck_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2;
}else if (mSpiNum == 2) {
m3Wire.channel = XMC_SPI2_CH1;
m3Wire.input_source = XMC_INPUT_D;
m3Wire.mosi_open.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1;
m3Wire.sck_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1;
}else {
m3Wire.channel = XMC_SPI2_CH0;
m3Wire.input_source = XMC_INPUT_C;
m3Wire.mosi_open.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1;
m3Wire.sck_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1;
}
#endif
}
void SPIClass3W::initSpi()
{
if((m3Wire.channel->CCR & USIC_CH_CCR_MODE_Msk) == XMC_USIC_CH_OPERATING_MODE_I2C)
{
Wire.end();
}
XMC_SPI_CH_EnableMasterClock(m3Wire.channel);
XMC_SPI_CH_Init(m3Wire.channel, &(m3Wire.channel_config));
XMC_SPI_CH_SetWordLength(m3Wire.channel, (uint8_t)16U);
XMC_SPI_CH_SetFrameLength(m3Wire.channel, (uint8_t)16U);
XMC_SPI_CH_SetInputSource(m3Wire.channel, XMC_SPI_CH_INPUT_DIN0, (uint8_t)m3Wire.input_source);
XMC_SPI_CH_ConfigureShiftClockOutput(m3Wire.channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_DISABLED, XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK);
XMC_SPI_CH_SetBaudrate(m3Wire.channel, (uint32_t)m3Wire.channel_config.baudrate);
XMC_SPI_CH_SetBitOrderMsbFirst(m3Wire.channel);
XMC_SPI_CH_Start(m3Wire.channel);
XMC_GPIO_Init(m3Wire.sck.port, m3Wire.sck.pin, &m3Wire.sck_config);
XMC_GPIO_Init(m3Wire.cs.port, m3Wire.cs.pin, &m3Wire.cs_config);
XMC_GPIO_SetOutputLevel( m3Wire.cs.port, m3Wire.cs.pin,XMC_GPIO_OUTPUT_LEVEL_HIGH);
}
void SPIClass3W::sendReceiveSpi(uint16_t* sent_data, uint16_t size_of_sent_data, uint16_t* received_data, uint16_t size_of_received_data)
{
uint32_t data_index = 0;
//send via TX
XMC_GPIO_Init(m3Wire.miso.port, m3Wire.miso.pin, &m3Wire.miso_close);
XMC_GPIO_Init(m3Wire.mosi.port, m3Wire.mosi.pin, &m3Wire.mosi_open);
XMC_GPIO_SetOutputLevel(m3Wire.cs.port, m3Wire.cs.pin,XMC_GPIO_OUTPUT_LEVEL_LOW);
for(data_index = 0; data_index < size_of_sent_data; data_index++)
{
XMC_SPI_CH_Transmit(m3Wire.channel, sent_data[data_index], XMC_SPI_CH_MODE_STANDARD);
while((XMC_SPI_CH_GetStatusFlag(m3Wire.channel) & XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U);
XMC_SPI_CH_ClearStatusFlag(m3Wire.channel, XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);
while (XMC_USIC_CH_GetReceiveBufferStatus(m3Wire.channel) == 0U);
received_data[0] = XMC_SPI_CH_GetReceivedData(m3Wire.channel);
}
// receive via RX
XMC_GPIO_Init(m3Wire.miso.port, m3Wire.miso.pin, &m3Wire.miso_open);
XMC_GPIO_Init(m3Wire.mosi.port, m3Wire.mosi.pin, &m3Wire.mosi_close);
delayMicroseconds(5);
for(data_index = 0; data_index < size_of_received_data; data_index++)
{
XMC_SPI_CH_Transmit(m3Wire.channel, 0x0000, XMC_SPI_CH_MODE_STANDARD);
while((XMC_SPI_CH_GetStatusFlag(m3Wire.channel) & XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U);
XMC_SPI_CH_ClearStatusFlag(m3Wire.channel, XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);
while (XMC_USIC_CH_GetReceiveBufferStatus(m3Wire.channel) == 0U);
received_data[data_index] = XMC_SPI_CH_GetReceivedData(m3Wire.channel);
}
XMC_GPIO_SetOutputLevel(m3Wire.cs.port, m3Wire.cs.pin,XMC_GPIO_OUTPUT_LEVEL_HIGH);
}
#endif /* SPI3W_INO */