Program Listing for File spi3w-esp32.cpp
↰ Return to documentation for file (src/framework/arduino/pal/spi3w-esp32.cpp)
/*
* \file spi3w-esp32-ino.cpp
* \brief ESP32 3wire SPI cover
* \author Infineon Technologies AG
* \version 4.0.0
* \copyright 2020-2024 Infineon Technologies AG
*
* \attention This code is normally not needed for ESP32 its clones.
* Under certain circumstances it might be usefull as this code uses the third
* SPI channel under VSPI. It only works on ESP32s up to the C2 version, but not
* for S2/S3 and higher.
* Before you use this code, try to set the correct SPI pin settings in pal-types-pin.hpp
* and the 1kOhm resistor between MISO and MOSI (see documentation) to get it running.
*
* SPDX-License-Identifier: MIT
*/
#include "spi3w-ino.hpp"
#include "pal-pin-types.hpp"
#if (SPI3W_INO == SPI3W_ESP32)
#include <driver/spi_master.h>
#include "sdkconfig.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
using namespace tle5012;
uint16_t tle5012b_spi_send_and_recv_uint16(spi_device_handle_t spi, uint16_t senddata)
{
uint8_t temp = 0;
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t));
uint8_t p_data[2];
p_data[0] = senddata >> 8;
p_data[1] = senddata;
t.length = 8 * 2;
t.tx_buffer = p_data;
t.flags = SPI_TRANS_USE_RXDATA;
ret = spi_device_polling_transmit(spi, &t);
assert(ret == ESP_OK);
temp = *t.rx_data;
*t.rx_data = *(t.rx_data + 1);
*(t.rx_data + 1) = temp;
return *(uint16_t*)t.rx_data;
}
SPIClass3W::SPIClass3W(uint8_t spiNum):SPIClass()
{
this->mCS = SS;
this->mMISO = MISO;
this->mMOSI = MOSI;
this->mSCK = SCK;
this->mSpiNum = spiNum;
spi_device_handle_t esp3Wire = NULL; // Some C structure and
this->e3Wire = &esp3Wire; // void pointer magic
}
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;
esp_err_t intError;
// bus config for the ESP-IDF driver
spi_bus_config_t bus_config = {};
bus_config.sclk_io_num = this->mSCK; // CLK
bus_config.mosi_io_num = this->mMOSI; // MOSI
bus_config.miso_io_num = this->mMISO; // no MISO setting for 3Wire but we use 4Wire
bus_config.quadwp_io_num = -1; // Not used
bus_config.quadhd_io_num = -1; // Not used
intError = spi_bus_initialize(SPI3_HOST, &bus_config, false); // use the VSPI of the ESP32 which is SPI3
// add device for the ESP-IDF driver
spi_device_interface_config_t dev_config = {}; // initializes all field to 0
dev_config.address_bits = 0;
dev_config.command_bits = 0;
dev_config.dummy_bits = 0;
dev_config.mode = 1;
dev_config.clock_speed_hz = SPEED;
dev_config.spics_io_num = -1; // we set CS external
// dev_config.flags = SPI_DEVICE_3WIRE;
dev_config.queue_size = 7;
dev_config.pre_cb = NULL;
dev_config.post_cb = NULL;
intError = spi_bus_add_device(SPI3_HOST, &dev_config, &(*(spi_device_handle_t*)this->e3Wire));
ESP_ERROR_CHECK(intError);
gpio_set_direction((gpio_num_t)this->mMOSI, GPIO_MODE_INPUT_OUTPUT_OD); // set the MOSI for INPUT and OUTPUT
gpio_set_pull_mode((gpio_num_t)this->mMOSI, GPIO_PULLUP_ONLY);
pinMode(this->mCS, OUTPUT);
digitalWrite(this->mCS, HIGH);
}
void SPIClass3W::setCSPin(uint8_t cs)
{
this->mCS = cs;
}
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;
// Command send
digitalWrite(this->mCS, LOW);
for (data_index = 0; data_index < size_of_sent_data; data_index++)
{
received_data[0] = tle5012b_spi_send_and_recv_uint16( (*(spi_device_handle_t*)this->e3Wire), sent_data[data_index]);
}
// Receive result
for(data_index = 0; data_index < size_of_received_data; data_index++)
{
received_data[data_index] = tle5012b_spi_send_and_recv_uint16( (*(spi_device_handle_t*)this->e3Wire), 0x0000);
}
digitalWrite(this->mCS, HIGH);
}
#endif /* SPI3W_INO */