diff --git a/libraries/SPI/src/HW_SPI.cpp b/libraries/SPI/src/HW_SPI.cpp index 40a67bc1..a08c315c 100644 --- a/libraries/SPI/src/HW_SPI.cpp +++ b/libraries/SPI/src/HW_SPI.cpp @@ -1,106 +1,53 @@ /* - * SPI Master library. - * Copyright (c) 2015 Arduino LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Copyright (c) 2018 Infineon Technologies AG - * This library has been modified for the XMC microcontroller series. + * SPI Master library implementation for XMC microcontrollers. */ -//**************************************************************************** -// @Project Includes -//**************************************************************************** +// Add operator delete override for embedded environments +extern "C" void operator delete(void *ptr) noexcept { + // No-op for embedded systems +} + #include "SPI.h" -#if !defined(USE_SW_SPI) - #include "Wire.h" - - // swap SPI_default and SPI_for_xmc_SD if desired by user - #if defined(USE_XMC_RELAX_KIT_SD) && defined(XMC_SPI_for_xmc_SD) -SPIClass SPI(&XMC_SPI_default); -SPIClass SPI1(&XMC_SPI_for_xmc_SD); - #else // normal behaviour -SPIClass SPI(&XMC_SPI_default); - #if (NUM_SPI > 1) -SPIClass SPI1(&XMC_SPI_1); - #endif - #endif + uint8_t SS = PIN_SPI_SS; uint8_t MOSI = PIN_SPI_MOSI; uint8_t MISO = PIN_SPI_MISO; uint8_t SCK = PIN_SPI_SCK; - #if (NUM_SPI > 2) -SPIClass SPI2(&XMC_SPI_2); - #if (NUM_SPI > 3) -SPIClass SPI3(&XMC_SPI_3); - #if (NUM_SPI > 4) -SPIClass SPI4(&XMC_SPI_4); - #endif - #endif - #endif - -SPISettings DEFAULT_SPI_SETTINGS; - -//**************************************************************************** -// @Local Functions -//**************************************************************************** - -// Public Methods ////////////////////////////////////////////////////////////// +// Constructor +XMC_SPIClass::XMC_SPIClass(XMC_SPI_t *spiConfig) + : XMC_SPI_Config(spiConfig), + initialized(false) {} -void SPIClass::begin() { - // Check if desire USIC channel is already in use - if ((XMC_SPI_config->channel->CCR & USIC_CH_CCR_MODE_Msk) == XMC_USIC_CH_OPERATING_MODE_I2C) { - Wire.end(); - } +// Explicitly empty destructor +XMC_SPIClass::~XMC_SPIClass() { + // Explicitly empty - no dynamic memory used +} +// SPI API: Begin +void XMC_SPIClass::begin() { + if (initialized) + return; init(); - - setBitOrder(DEFAULT_SPI_SETTINGS.bitOrder); - - setDataMode(DEFAULT_SPI_SETTINGS.dataMode); - - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, DEFAULT_SPI_SETTINGS.clockFreq); } -void SPIClass::init() { - if (initialized) { +// Internal SPI Initialization +void XMC_SPIClass::init() { + if (initialized) return; - } - - /* LLD initialization */ - XMC_SPI_CH_Init(XMC_SPI_config->channel, &(XMC_SPI_config->channel_config)); - - /* Configure the data input line selected */ - XMC_SPI_CH_SetInputSource(XMC_SPI_config->channel, XMC_SPI_CH_INPUT_DIN0, - (uint8_t)XMC_SPI_config->input_source); - /* Start the SPI_Channel */ - XMC_SPI_CH_Start(XMC_SPI_config->channel); + // Initialize hardware SPI + XMC_SPI_CH_Init(XMC_SPI_Config->channel, &(XMC_SPI_Config->channel_config)); + XMC_SPI_CH_SetInputSource(XMC_SPI_Config->channel, XMC_SPI_CH_INPUT_DIN0, + (uint8_t)XMC_SPI_Config->input_source); - /* Initialize SPI SCLK out pin */ - XMC_GPIO_Init((XMC_GPIO_PORT_t *)XMC_SPI_config->sclkout.port, - (uint8_t)XMC_SPI_config->sclkout.pin, &(XMC_SPI_config->sclkout_config)); - - /* Configure the input pin properties */ - XMC_GPIO_Init((XMC_GPIO_PORT_t *)XMC_SPI_config->miso.port, (uint8_t)XMC_SPI_config->miso.pin, - &(XMC_SPI_config->miso_config)); - - /* Configure the output pin properties */ - XMC_GPIO_Init((XMC_GPIO_PORT_t *)XMC_SPI_config->mosi.port, (uint8_t)XMC_SPI_config->mosi.pin, - &(XMC_SPI_config->mosi_config)); + // Configure GPIO pins + XMC_GPIO_Init((XMC_GPIO_PORT_t *)XMC_SPI_Config->sclkout.port, + (uint8_t)XMC_SPI_Config->sclkout.pin, &(XMC_SPI_Config->sclkout_config)); + XMC_GPIO_Init((XMC_GPIO_PORT_t *)XMC_SPI_Config->miso.port, (uint8_t)XMC_SPI_Config->miso.pin, + &(XMC_SPI_Config->miso_config)); + XMC_GPIO_Init((XMC_GPIO_PORT_t *)XMC_SPI_Config->mosi.port, (uint8_t)XMC_SPI_Config->mosi.pin, + &(XMC_SPI_Config->mosi_config)); interruptMode = SPI_IMODE_NONE; interruptSave = 0; @@ -108,116 +55,52 @@ void SPIClass::init() { initialized = true; } -void SPIClass::end() { - // Only disable HW when USIC is used for SPI - if ((XMC_SPI_config->channel->CCR & USIC_CH_CCR_MODE_Msk) == XMC_USIC_CH_OPERATING_MODE_SPI) { - XMC_SPI_CH_Stop(XMC_SPI_config->channel); +// SPI API: End +void XMC_SPIClass::end() { + if (!initialized) + return; - XMC_SPI_config->channel->DXCR[XMC_USIC_CH_INPUT_DX0] = - (uint32_t)(XMC_SPI_config->channel->DXCR[XMC_USIC_CH_INPUT_DX0] | + // Stop SPI hardware if in SPI mode + if ((XMC_SPI_Config->channel->CCR & USIC_CH_CCR_MODE_Msk) == XMC_USIC_CH_OPERATING_MODE_SPI) { + XMC_SPI_CH_Stop(XMC_SPI_Config->channel); + XMC_SPI_Config->channel->DXCR[XMC_USIC_CH_INPUT_DX0] = + (uint32_t)(XMC_SPI_Config->channel->DXCR[XMC_USIC_CH_INPUT_DX0] | (USIC_CH_DX0CR_DSEN_Msk)) & (~USIC_CH_DX0CR_INSW_Msk); - XMC_USIC_CH_SetInputSource(XMC_SPI_config->channel, XMC_USIC_CH_INPUT_DX0, XMC_INPUT_A); + XMC_USIC_CH_SetInputSource(XMC_SPI_Config->channel, XMC_USIC_CH_INPUT_DX0, XMC_INPUT_A); } initialized = false; } -/* -// Function not used here -void SPIClass::usingInterrupt(int interruptNumber) -{ - -} -*/ - -void SPIClass::beginTransaction(SPISettings settings) { - // Check if desire USIC channel is already in use - if ((XMC_SPI_config->channel->CCR & USIC_CH_CCR_MODE_Msk) != XMC_USIC_CH_OPERATING_MODE_SPI) { - SPI.begin(); - } - setBitOrder(settings.bitOrder); - setDataMode(settings.dataMode); - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, settings.clockFreq); - - // TODO: Do sth with SS? -} - -void SPIClass::endTransaction(void) { - // TODO: inTransactionFlag and interrupt not use -} - -void SPIClass::setBitOrder(uint8_t order) { - if (order == LSBFIRST) { - XMC_SPI_CH_SetBitOrderLsbFirst(XMC_SPI_config->channel); - } else { - XMC_SPI_CH_SetBitOrderMsbFirst(XMC_SPI_config->channel); - } -} - -void SPIClass::setDataMode(uint8_t mode) { - switch (mode) { - case SPI_MODE0: - // Low if inactive, transmit on falling clock, receive on raising clock edge - XMC_SPI_CH_ConfigureShiftClockOutput( - XMC_SPI_config->channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_ENABLED, - XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); - break; - - case SPI_MODE1: - // Low if inactive, transmit on rising clock, receive on falling clock edge - XMC_SPI_CH_ConfigureShiftClockOutput( - XMC_SPI_config->channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_DISABLED, - XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); - break; - - case SPI_MODE2: - // High if inactive, transmit on rising clock, receive on falling clock edge - XMC_SPI_CH_ConfigureShiftClockOutput( - XMC_SPI_config->channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_ENABLED, - XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); - break; - - case SPI_MODE3: - // High if inactive, transmit on falling clock, receive on raising clock edge - XMC_SPI_CH_ConfigureShiftClockOutput( - XMC_SPI_config->channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_DISABLED, - XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); - break; - - default: - break; - } -} - -void SPIClass::setClockDivider(uint8_t div) { +void XMC_SPIClass::setClockDivider(uint8_t div) { switch (div) { case SPI_CLOCK_DIV2: - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, 8000000U); + XMC_SPI_CH_SetBaudrate(XMC_SPI_Config->channel, 8000000U); break; case SPI_CLOCK_DIV4: - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, 4000000U); + XMC_SPI_CH_SetBaudrate(XMC_SPI_Config->channel, 4000000U); break; case SPI_CLOCK_DIV8: - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, 2000000U); + XMC_SPI_CH_SetBaudrate(XMC_SPI_Config->channel, 2000000U); break; case SPI_CLOCK_DIV16: - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, 1000000U); + XMC_SPI_CH_SetBaudrate(XMC_SPI_Config->channel, 1000000U); break; case SPI_CLOCK_DIV32: - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, 500000U); + XMC_SPI_CH_SetBaudrate(XMC_SPI_Config->channel, 500000U); break; case SPI_CLOCK_DIV64: - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, 250000U); + XMC_SPI_CH_SetBaudrate(XMC_SPI_Config->channel, 250000U); break; case SPI_CLOCK_DIV128: - XMC_SPI_CH_SetBaudrate(XMC_SPI_config->channel, 125000U); + XMC_SPI_CH_SetBaudrate(XMC_SPI_Config->channel, 125000U); break; default: @@ -225,46 +108,107 @@ void SPIClass::setClockDivider(uint8_t div) { } } -uint8_t SPIClass::transfer(uint8_t data_out) { +// SPI API: Transfer single byte +uint8_t XMC_SPIClass::transfer(uint8_t data) { uint8_t data_in = 0; - /* Clear RBF0 */ - (void)XMC_SPI_CH_GetReceivedData(XMC_SPI_config->channel); - /* Clear RBF1 */ - (void)XMC_SPI_CH_GetReceivedData(XMC_SPI_config->channel); - - /*Sending a byte*/ - XMC_SPI_CH_Transmit(XMC_SPI_config->channel, data_out, XMC_SPI_CH_MODE_STANDARD); + (void)XMC_SPI_CH_GetReceivedData(XMC_SPI_Config->channel); + (void)XMC_SPI_CH_GetReceivedData(XMC_SPI_Config->channel); + // Send data via SPI + XMC_SPI_CH_Transmit(XMC_SPI_Config->channel, data, XMC_SPI_CH_MODE_STANDARD); - /*Wait till the byte has been transmitted*/ - while ((XMC_SPI_CH_GetStatusFlag(XMC_SPI_config->channel) & + // Wait for data transmission to complete + while ((XMC_SPI_CH_GetStatusFlag(XMC_SPI_Config->channel) & XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U) ; - XMC_SPI_CH_ClearStatusFlag(XMC_SPI_config->channel, + XMC_SPI_CH_ClearStatusFlag(XMC_SPI_Config->channel, XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION); - while (XMC_USIC_CH_GetReceiveBufferStatus(XMC_SPI_config->channel) == 0U) + // Wait for data reception + while (XMC_USIC_CH_GetReceiveBufferStatus(XMC_SPI_Config->channel) == 0U) ; + data_in = XMC_SPI_CH_GetReceivedData(XMC_SPI_Config->channel); - data_in = XMC_SPI_CH_GetReceivedData(XMC_SPI_config->channel); - - XMC_SPI_CH_ClearStatusFlag(XMC_SPI_config->channel, + XMC_SPI_CH_ClearStatusFlag(XMC_SPI_Config->channel, ((uint32_t)XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION | (uint32_t)XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION)); - return data_in; } -void SPIClass::attachInterrupt() { - // Should be enableInterrupt() +// SPI API: Transfer 16-bit data +uint16_t XMC_SPIClass::transfer16(uint16_t data) { + uint8_t msb = transfer((data >> 8) & 0xFF); + uint8_t lsb = transfer(data & 0xFF); + return (msb << 8) | lsb; +} + +// SPI API: Transfer buffer +void XMC_SPIClass::transfer(void *buf, size_t count) { + uint8_t *buffer = (uint8_t *)buf; + for (size_t i = 0; i < count; i++) { + buffer[i] = transfer(buffer[i]); + } +} + +// SPI API: Begin Transaction +void XMC_SPIClass::beginTransaction(arduino::SPISettings settings) { + if ((XMC_SPI_Config->channel->CCR & USIC_CH_CCR_MODE_Msk) != XMC_USIC_CH_OPERATING_MODE_SPI) { + SPI.begin(); + } + + setBitOrder(settings.getBitOrder()); + setDataMode(settings.getDataMode()); + XMC_SPI_CH_SetBaudrate(XMC_SPI_Config->channel, settings.getClockFreq()); } -void SPIClass::detachInterrupt() { - // Should be disableInterrupt() +// SPI API: End Transaction +void XMC_SPIClass::endTransaction() { + // Placeholder for endTransaction logic } -#endif +// SPI API: Set Bit Order +void XMC_SPIClass::setBitOrder(uint8_t bitOrder) { + if (bitOrder == LSBFIRST) { + XMC_SPI_CH_SetBitOrderLsbFirst(XMC_SPI_Config->channel); + } else { + XMC_SPI_CH_SetBitOrderMsbFirst(XMC_SPI_Config->channel); + } +} + +// SPI API: Set Data Mode +void XMC_SPIClass::setDataMode(uint8_t dataMode) { + switch (dataMode) { + case SPI_MODE0: + XMC_SPI_CH_ConfigureShiftClockOutput( + XMC_SPI_Config->channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_ENABLED, + XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); + break; + case SPI_MODE1: + XMC_SPI_CH_ConfigureShiftClockOutput( + XMC_SPI_Config->channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_DISABLED, + XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); + break; + case SPI_MODE2: + XMC_SPI_CH_ConfigureShiftClockOutput( + XMC_SPI_Config->channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_ENABLED, + XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); + break; + case SPI_MODE3: + XMC_SPI_CH_ConfigureShiftClockOutput( + XMC_SPI_Config->channel, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_DISABLED, + XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); + break; + } +} + +// Interrupt Methods +void XMC_SPIClass::attachInterrupt() {} + +void XMC_SPIClass::detachInterrupt() {} + +void XMC_SPIClass::usingInterrupt(int interruptNumber) {} + +void XMC_SPIClass::notUsingInterrupt(int interruptNumber) {} -//**************************************************************************** -// END OF FILE -//**************************************************************************** +// Global SPI object +XMC_SPIClass SPI(&XMC_SPI_default); diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index b4854595..3709d5f4 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -1,57 +1,18 @@ /* - * SPI Master library. - * Copyright (c) 2015 Arduino LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Copyright (c) 2018 Infineon Technologies AG - * This library has been modified for the XMC microcontroller series. + * SPI Master library for XMC microcontrollers. + * Inherits from Arduino's HardwareSPI. */ #ifndef _SPI_H_INCLUDED #define _SPI_H_INCLUDED -//**************************************************************************** -// @Project Includes -//**************************************************************************** #include - -//**************************************************************************** -// @Defines -//**************************************************************************** -// Define USE_SW_SPI to use the software SPI(not verified) -// #define USE_SW_SPI - -// Define USE_XMC_RELAX_KIT_SD allows to use the SD Lib to communicate with a SD Card over -// the on-board SD Card slot. This feature is only available on KIT_XMC47_RELAX kits. -#if defined(KIT_XMC47_RELAX) - #define USE_XMC_RELAX_KIT_SD -#endif - -#define SPI_MODE0 0x00 -#define SPI_MODE1 0x01 -#define SPI_MODE2 0x02 -#define SPI_MODE3 0x03 +#include // Base HardwareSPI class provided by Arduino core for XMC #define SPI_IMODE_NONE 0x00 -#define MSBFIRST 0x00 -#define LSBFIRST 0x01 - +// SPI Clock Dividers #define ARDUINO_SPI_CLOCK 16000000U - #define SPI_CLOCK_DIV2 2 #define SPI_CLOCK_DIV4 4 #define SPI_CLOCK_DIV8 8 @@ -60,121 +21,45 @@ #define SPI_CLOCK_DIV64 64 #define SPI_CLOCK_DIV128 128 -#if defined(USE_SW_SPI) - #include "SW_SPI.h" -#endif - -// #define pin_cs 10 -// -// #if defined(KIT_XMC_2GO_XMC1100_V1) || defined(XMC1100_H_BRIDGE2GO) -// #define pin_cs 3 - -// #elif defined(KIT_XMC_PLT2GO_XMC4200) -/// #define pin_cs_slot_1 95 -// #define pin_cs_slot_2 96 - -// #endif - -//**************************************************************************** -// @Class Definitions -//**************************************************************************** -class SPISettings { -public: - SPISettings(uint32_t cF, uint8_t bO, uint8_t dM) { - clockFreq = cF; - bitOrder = bO; - dataMode = dM; - } - - SPISettings() { - clockFreq = 4000000; - bitOrder = MSBFIRST; - dataMode = SPI_MODE0; - } - - uint32_t clockFreq; - uint8_t bitOrder; - uint8_t dataMode; -}; - -class SPIClass { +// Custom SPI implementation class +class XMC_SPIClass : public arduino::HardwareSPI { public: -// Constructors for HW SPI -#if !defined(USE_SW_SPI) - SPIClass() { - // default SPI - XMC_SPI_config = &XMC_SPI_default; - } - - SPIClass(XMC_SPI_t *conf) { XMC_SPI_config = conf; } - -// Constructors for SW SPI -#else - SPIClass() { - // default SPI - spi_settings = SPISettings(); - - mosi_pin = MOSI; - miso_pin = MISO; - clk_pin = SCK; - } - - SPIClass(SPISettings settings) { - spi_settings = settings; - - mosi_pin = MOSI; - miso_pin = MISO; - clk_pin = SCK; - } - - SPIClass(SPISettings settings, uint8_t mosi, uint8_t miso, uint8_t sck) { - spi_settings = settings; - - mosi_pin = mosi; - miso_pin = miso; - clk_pin = sck; - } -#endif - - uint8_t transfer(uint8_t data); - inline uint16_t transfer16(uint16_t data); - inline void transfer(void *buf, size_t count); - - // Transaction Functions - // Function not used here - // void usingInterrupt(int interruptNumber); - void beginTransaction(SPISettings settings); - void endTransaction(void); - - // SPI Configuration methods - void attachInterrupt(); - void detachInterrupt(); - - static void usingInterrupt(uint8_t interruptNumber) {}; - static void notUsingInterrupt(uint8_t interruptNumber) {}; - - void begin(); - void end(); - - void setBitOrder(uint8_t order); - void setDataMode(uint8_t mode); + // Constructor + XMC_SPIClass(XMC_SPI_t *spiConfig); + + // Destructor + ~XMC_SPIClass(); + + // Implement required methods from HardwareSPI + void begin() override; + void end() override; + uint8_t transfer(uint8_t data) override; + uint16_t transfer16(uint16_t data) override; + void transfer(void *buf, size_t count) override; + + // Interrupt-related methods + void attachInterrupt() override; + void detachInterrupt() override; + + // Transaction-related methods + void usingInterrupt(int interruptNumber) override; + void notUsingInterrupt(int interruptNumber) override; + void beginTransaction(arduino::SPISettings settings) override; + void endTransaction() override; + + // SPI configuration methods + void setBitOrder(uint8_t bitOrder); + void setDataMode(uint8_t dataMode); void setClockDivider(uint8_t div); private: - void init(); -// Config for HW SPI -#if !defined(USE_SW_SPI) - - XMC_SPI_t *XMC_SPI_config; + void init(); // Internal initialization logic -// Config for SW SPI -#else - uint8_t mosi_pin; - uint8_t miso_pin; - uint8_t clk_pin; + XMC_SPI_t *XMC_SPI_Config; // XMC-specific SPI configuration + arduino::SPISettings const DEFAULT_SPI_SETTINGS = + arduino::SPISettings(ARDUINO_SPI_CLOCK, MSBFIRST, arduino::SPI_MODE0); - SPISettings spi_settings; -#endif + arduino::SPISettings _settings = arduino::SPISettings(); bool initialized; uint8_t interruptMode; @@ -182,35 +67,6 @@ class SPIClass { uint32_t interruptMask; }; -extern SPIClass SPI; -#if (NUM_SPI > 1) -extern SPIClass SPI1; - #if (NUM_SPI > 2) -extern SPIClass SPI2; - #if (NUM_SPI > 3) -extern SPIClass SPI3; - #if (NUM_SPI > 4) -extern SPIClass SPI4; - #endif - #endif - #endif -#endif - -void SPIClass::transfer(void *buf, size_t count) { - uint8_t *buffer = (uint8_t *)buf; - for (size_t index = 0; index < count; index++) { - buffer[index] = transfer(buffer[index]); - } -} - -uint16_t SPIClass::transfer16(uint16_t data) { - uint8_t data_out_msb = (uint8_t)((data >> 8) & 0xFF); - uint8_t data_out_lsb = (uint8_t)(data & 0xFF); - - uint8_t data_in_msb = transfer(data_out_msb); - uint8_t data_in_lsb = transfer(data_out_lsb); - - return (uint16_t)(((uint16_t)data_in_msb << 8) | (data_in_lsb)); -} +extern XMC_SPIClass SPI; #endif /* _SPI_H_INCLUDED */ diff --git a/variants/XMC4700/config/KIT_XMC47_RELAX/pins_arduino.h b/variants/XMC4700/config/KIT_XMC47_RELAX/pins_arduino.h index 4979befe..23d64ec8 100644 --- a/variants/XMC4700/config/KIT_XMC47_RELAX/pins_arduino.h +++ b/variants/XMC4700/config/KIT_XMC47_RELAX/pins_arduino.h @@ -426,150 +426,120 @@ Uart Serial(&XMC_UART_0); // On-Board port Uart Serial1(&XMC_UART_1); -// // Three SPI instances possible -// XMC_SPI_t XMC_SPI_0 = { -// .channel = XMC_SPI2_CH0, -// .channel_config = {.baudrate = 20003906U, -// .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, -// .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, -// .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE}, -// .mosi = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)8}, -// .mosi_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, -// .miso = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)7}, -// .miso_config = -// { -// .mode = XMC_GPIO_MODE_INPUT_TRISTATE, -// }, -// .input_source = XMC_INPUT_C, -// .sclkout = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)9}, -// .sclkout_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, -// }; - -// XMC_SPI_t XMC_SPI_1 = { -// .channel = XMC_SPI0_CH1, -// .channel_config = {.baudrate = 20003906U, -// .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, -// .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, -// .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE}, -// .mosi = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)5}, -// .mosi_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, -// .miso = {.port = (XMC_GPIO_PORT_t *)PORT4_BASE, .pin = (uint8_t)0}, -// .miso_config = -// { -// .mode = XMC_GPIO_MODE_INPUT_TRISTATE, -// }, -// .input_source = XMC_INPUT_E, -// .sclkout = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)6}, -// .sclkout_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, -// }; - -// XMC_SPI_t XMC_SPI_2 = { -// .channel = XMC_SPI2_CH1, -// .channel_config = {.baudrate = 20003906U, -// .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, -// .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, -// .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE}, -// .mosi = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)11}, -// .mosi_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, -// .miso = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)12}, -// .miso_config = -// { -// .mode = XMC_GPIO_MODE_INPUT_TRISTATE, -// }, -// .input_source = XMC_INPUT_D, -// .sclkout = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)13}, -// .sclkout_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, -// }; +// Three SPI instances possible +XMC_SPI_t XMC_SPI_0 = { + .channel = XMC_SPI2_CH0, + .channel_config = {.baudrate = 20003906U, + .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, + .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, + .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE}, + .mosi = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)8}, + .mosi_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, + .miso = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)7}, + .miso_config = + { + .mode = XMC_GPIO_MODE_INPUT_TRISTATE, + }, + .input_source = XMC_INPUT_C, + .sclkout = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)9}, + .sclkout_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, +}; + +XMC_SPI_t XMC_SPI_1 = { + .channel = XMC_SPI0_CH1, + .channel_config = {.baudrate = 20003906U, + .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, + .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, + .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE}, + .mosi = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)5}, + .mosi_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, + .miso = {.port = (XMC_GPIO_PORT_t *)PORT4_BASE, .pin = (uint8_t)0}, + .miso_config = + { + .mode = XMC_GPIO_MODE_INPUT_TRISTATE, + }, + .input_source = XMC_INPUT_E, + .sclkout = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)6}, + .sclkout_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, +}; + +XMC_SPI_t XMC_SPI_2 = { + .channel = XMC_SPI2_CH1, + .channel_config = {.baudrate = 20003906U, + .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, + .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, + .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE}, + .mosi = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)11}, + .mosi_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, + .miso = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)12}, + .miso_config = + { + .mode = XMC_GPIO_MODE_INPUT_TRISTATE, + }, + .input_source = XMC_INPUT_D, + .sclkout = {.port = (XMC_GPIO_PORT_t *)PORT3_BASE, .pin = (uint8_t)13}, + .sclkout_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, +}; // Only two serial objects are possible: Serial and Serial1 so anymore serial interfaces has to // overwrite/reuse the existing serial objects // Will overwrite Serial -// XMC_SPI_t XMC_SPI_3 = -//{ -// .channel = XMC_SPI0_CH0, -// .channel_config = { -// .baudrate = 20003906U, -// .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, -// .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, -// .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE -// }, -// .mosi = { -// .port = (XMC_GPIO_PORT_t*)PORT5_BASE, -// .pin = (uint8_t)1 -// }, -// .mosi_config = { -// .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM -// }, -// .miso = { -// .port = (XMC_GPIO_PORT_t*)PORT5_BASE, -// .pin = (uint8_t)0 -// }, -// .miso_config = { -// .mode = XMC_GPIO_MODE_INPUT_TRISTATE, -// }, -// .input_source = XMC_INPUT_D, -// .sclkout = { -// .port = (XMC_GPIO_PORT_t*)PORT0_BASE, -// .pin = (uint8_t)8 -// }, -// .sclkout_config = { -// .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM -// }, -// }; +XMC_SPI_t XMC_SPI_3 = { + .channel = XMC_SPI0_CH0, + .channel_config = {.baudrate = 20003906U, + .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, + .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, + .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE}, + .mosi = {.port = (XMC_GPIO_PORT_t *)PORT5_BASE, .pin = (uint8_t)1}, + .mosi_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, + .miso = {.port = (XMC_GPIO_PORT_t *)PORT5_BASE, .pin = (uint8_t)0}, + .miso_config = + { + .mode = XMC_GPIO_MODE_INPUT_TRISTATE, + }, + .input_source = XMC_INPUT_D, + .sclkout = {.port = (XMC_GPIO_PORT_t *)PORT0_BASE, .pin = (uint8_t)8}, + .sclkout_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, +}; // Will overwrite Serial1 -// XMC_SPI_t XMC_SPI_4 = -//{ -// .channel = XMC_SPI1_CH0, -// .channel_config = { -// .baudrate = 20003906U, -// .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, -// .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, -// .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE -// }, -// .mosi = { -// .port = (XMC_GPIO_PORT_t*)PORT0_BASE, -// .pin = (uint8_t)5 -// }, -// .mosi_config = { -// .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM -// }, -// .miso = { -// .port = (XMC_GPIO_PORT_t*)PORT0_BASE, -// .pin = (uint8_t)4 -// }, -// .miso_config = { -// .mode = XMC_GPIO_MODE_INPUT_TRISTATE, -// }, -// .input_source = XMC_INPUT_A, -// .sclkout = { -// .port = (XMC_GPIO_PORT_t*)PORT0_BASE, -// .pin = (uint8_t)11 -// }, -// .sclkout_config = { -// .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2, -// .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, -// .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM -// }, -//}; +XMC_SPI_t XMC_SPI_4 = { + .channel = XMC_SPI1_CH0, + .channel_config = {.baudrate = 20003906U, + .bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER, + .selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS, + .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE}, + .mosi = {.port = (XMC_GPIO_PORT_t *)PORT0_BASE, .pin = (uint8_t)5}, + .mosi_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, + .miso = {.port = (XMC_GPIO_PORT_t *)PORT0_BASE, .pin = (uint8_t)4}, + .miso_config = + { + .mode = XMC_GPIO_MODE_INPUT_TRISTATE, + }, + .input_source = XMC_INPUT_A, + .sclkout = {.port = (XMC_GPIO_PORT_t *)PORT0_BASE, .pin = (uint8_t)11}, + .sclkout_config = {.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2, + .output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM}, +}; // Two I2C instances possible XMC_I2C_t XMC_I2C_0 = {.channel = XMC_I2C1_CH1,