AgIsoStack++
A control-function-focused implementation of the major ISOBUS and J1939 protocols
Loading...
Searching...
No Matches
spi_interface_esp.cpp
Go to the documentation of this file.
1//================================================================================================
8//================================================================================================
9
12#include "isobus/utility/to_string.hpp"
13
14#include <cstring>
15
16namespace isobus
17{
18 SPIInterfaceESP::SPIInterfaceESP(const spi_device_interface_config_t *deviceConfig, const spi_host_device_t hostDevice) :
19 deviceConfig(deviceConfig),
20 hostDevice(hostDevice),
21 spiMutex(xSemaphoreCreateMutex()),
22 initialized(false),
23 success(true) {}
24
26 {
27 deinit();
28 vSemaphoreDelete(spiMutex);
29 }
30
32 {
33 esp_err_t error = spi_bus_add_device(hostDevice, deviceConfig, &spiDevice);
34 if (ESP_OK == error)
35 {
36 initialized = true;
37 }
38 else
39 {
40 LOG_CRITICAL("[SPI-ESP] Failed to add SPI device: " + isobus::to_string(esp_err_to_name(error)));
41 }
42
43 return ESP_OK == error;
44 }
45
47 {
48 esp_err_t error = spi_bus_remove_device(spiDevice);
49 if (ESP_OK != error)
50 {
51 LOG_ERROR("[SPI-ESP] Failed to remove SPI device: " + isobus::to_string(esp_err_to_name(error)));
52 }
53 if (ESP_ERR_INVALID_STATE == error || ESP_OK == error)
54 {
55 initialized = false;
56 }
57 }
58
60 {
61 if (initialized)
62 {
63 if (xSemaphoreTake(spiMutex, MAX_TIME_TO_WAIT) == pdTRUE)
64 {
65 spi_transaction_t transaction;
66 std::memset(&transaction, 0, sizeof(transaction));
67
68 transaction.length = frame->get_tx_buffer()->size() * 8;
69 transaction.tx_buffer = frame->get_tx_buffer()->data();
70 if (frame->get_is_read())
71 {
72 frame->get_rx_buffer().resize(frame->get_tx_buffer()->size());
73 transaction.rx_buffer = frame->get_rx_buffer().data();
74 }
75 else
76 {
77 transaction.rx_buffer = nullptr;
78 }
79
80 esp_err_t error = spi_device_transmit(spiDevice, &transaction);
81 if (ESP_OK != error)
82 {
83 success = false;
84 LOG_WARNING("[SPI-ESP] Failed to transmit SPI transaction frame: " + isobus::to_string(esp_err_to_name(error)));
85 }
86 xSemaphoreGive(spiMutex);
87 }
88 else
89 {
90 success = false;
91 LOG_ERROR("[SPI-ESP] Failed to obtain SPI mutex in transmit().");
92 }
93 }
94 else
95 {
96 success = false;
97 LOG_CRITICAL("[SPI-ESP] SPI device not initialized, pherhaps you forgot to call init()?");
98 }
99 }
100
102 {
103 bool retVal = success;
104 success = true; // Reset success flag for next transaction
105 return retVal;
106 }
107}
A class that acts as a logging sink. The intent is that someone could make their own derived class of...
void transmit(SPITransactionFrame *frame) override
Write (and read) a frame to the SPI bus.
bool init()
Initialize the SPI device.
bool success
The status of the current transaction.
void deinit()
Deinitialize the SPI device.
bool end_transaction() override
End the transaction. This function returns the status since the last end_transaction().
virtual ~SPIInterfaceESP()
Destructor of a SPI device on an ESP platform.
const SemaphoreHandle_t spiMutex
A mutex to prevent concurrent access to the SPI bus.
bool initialized
The status of the device.
spi_device_handle_t spiDevice
A handle to the SPI device.
SPIInterfaceESP(const spi_device_interface_config_t *deviceConfig, const spi_host_device_t hostDevice)
Constructor of a SPI device on an ESP platform.
const spi_device_interface_config_t * deviceConfig
The configuration of the SPI device.
static constexpr std::uint32_t MAX_TIME_TO_WAIT
timeout of 5 seconds for spi related calls, mostly arbitrary.
const spi_host_device_t hostDevice
The host spi device.
A class containing the data for a single SPI transaction.
const std::vector< std::uint8_t > * get_tx_buffer() const
Get the buffer to transmit.
bool get_is_read() const
Get whether the interface should read the response to the write operation.
std::vector< std::uint8_t > & get_rx_buffer()
Get the buffer to store the response in.
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
A (synchronous) implementation for SPI communication with (CAN) hardware devices on ESP platforms.