Implement Multi-Bus CAN Interfaces
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
idf_component_register(SRCS "esp_implementation_init.cpp"
|
||||
"esp_implementation_cmd.cpp"
|
||||
"esp_implementation_int.cpp"
|
||||
"esp_implementation_bus.cpp"
|
||||
"esp_implementation_bus_factory.cpp"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES driver)
|
||||
@@ -0,0 +1,58 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#include "mcp2521_hardware_esp_bus.hpp"
|
||||
#include "mcp2521_hardware_esp.hpp"
|
||||
|
||||
MCP2521_HardwareHandle_ESPBus::MCP2521_HardwareHandle_ESPBus(
|
||||
QueueHandle_t send_queue,
|
||||
spi_host_device_t spi_host,
|
||||
spi_bus_config_t * bus_config,
|
||||
gpio_num_t cs,
|
||||
gpio_num_t int_pin
|
||||
) : MCP2521_HardwareHandle_ESP(spi_host, bus_config, cs, int_pin) {
|
||||
this->send_queue = send_queue;
|
||||
this->receive_queue = xQueueCreate(3, sizeof(spi_message_t));
|
||||
}
|
||||
|
||||
void MCP2521_HardwareHandle_ESPBus::spi_transmit(spi_transaction_t *t) {
|
||||
spi_message_t message = {
|
||||
.transaction = t,
|
||||
.queue = send_queue,
|
||||
.spi_device_handle = spi_device_handle
|
||||
};
|
||||
|
||||
xQueueSend(send_queue, &message, portMAX_DELAY);
|
||||
xQueueReceive(receive_queue, &message, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void MCP2521_HardwareHandle_ESPBus::initPins(
|
||||
gpio_num_t int_pin
|
||||
) {
|
||||
canInterruptSemaphore = xSemaphoreCreateBinary();
|
||||
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_NEGEDGE;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pin_bit_mask = 1 << int_pin;
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
gpio_isr_handler_add(int_pin, gpio_isr_can_handler, this);
|
||||
|
||||
char taskName[32];
|
||||
sprintf(taskName, "canInterruptTask_%d", int_pin);
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
(TaskFunction_t)&handleInteruptTaskCallerFn,
|
||||
taskName,
|
||||
2048,
|
||||
this,
|
||||
5,
|
||||
&canInterruptTaskHandle,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#include "mcp2521_hardware_esp_bus_factory.hpp"
|
||||
#include "mcp2521_hardware_esp_bus.hpp"
|
||||
#include "mcp2521_hardware_esp.hpp"
|
||||
|
||||
void transactionTaskWrapperFn(void *pvParameters) {
|
||||
MCP2521_HardwareHandleFactory_ESPBus *factory = (MCP2521_HardwareHandleFactory_ESPBus *)pvParameters;
|
||||
factory->transactionTaskFn();
|
||||
|
||||
}
|
||||
|
||||
MCP2521_HardwareHandleFactory_ESPBus::MCP2521_HardwareHandleFactory_ESPBus(
|
||||
spi_host_device_t spi_host,
|
||||
gpio_num_t mosi,
|
||||
gpio_num_t miso,
|
||||
gpio_num_t sclk
|
||||
) {
|
||||
this->spi_host = spi_host;
|
||||
this->mosi = mosi;
|
||||
this->miso = miso;
|
||||
this->sclk = sclk;
|
||||
|
||||
|
||||
gpio_install_isr_service(0);
|
||||
|
||||
MCP2521_HardwareHandle_ESP::initSPIBus(spi_host, mosi, miso, sclk, &bus_config);
|
||||
|
||||
spi_queue = xQueueCreate(12, sizeof(spi_message_t));
|
||||
xTaskCreatePinnedToCore(
|
||||
(TaskFunction_t)&transactionTaskWrapperFn,
|
||||
"transactionTask",
|
||||
2048,
|
||||
this,
|
||||
3,
|
||||
&transactionTaskHandle,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
void MCP2521_HardwareHandleFactory_ESPBus::transactionTaskFn() {
|
||||
spi_message_t message;
|
||||
|
||||
while(true) {
|
||||
xQueueReceive(spi_queue, &message, portMAX_DELAY);
|
||||
spi_device_transmit(message.spi_device_handle, message.transaction);
|
||||
}
|
||||
}
|
||||
|
||||
MCP2521_HardwareHandle_ESPBus MCP2521_HardwareHandleFactory_ESPBus::create(
|
||||
gpio_num_t int_pin,
|
||||
gpio_num_t cs
|
||||
) {
|
||||
return MCP2521_HardwareHandle_ESPBus(
|
||||
spi_queue,
|
||||
spi_host,
|
||||
&bus_config,
|
||||
cs,
|
||||
int_pin
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
const uint8_t null_buffer[32] = {0};
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::spi_transmit(spi_transaction_t *t) {
|
||||
void MCP2521_HardwareHandle_ESP::spi_transmit(spi_transaction_t *t) {
|
||||
xSemaphoreTake(spiMutex, portMAX_DELAY);
|
||||
spi_device_transmit(this->spi_device_handle, t);
|
||||
xSemaphoreGive(spiMutex);
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::execute(uint8_t cmd) {
|
||||
void MCP2521_HardwareHandle_ESP::execute(uint8_t cmd) {
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
@@ -30,7 +30,7 @@ void MCP2521_Hardware_Handle_ESP::execute(uint8_t cmd) {
|
||||
spi_transmit((spi_transaction_t*)(&t));
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::execute(uint8_t cmd, uint8_t address) {
|
||||
void MCP2521_HardwareHandle_ESP::execute(uint8_t cmd, uint8_t address) {
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
@@ -49,7 +49,7 @@ void MCP2521_Hardware_Handle_ESP::execute(uint8_t cmd, uint8_t address) {
|
||||
spi_transmit((spi_transaction_t*)(&t));
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::read(uint8_t cmd, uint8_t *data, size_t length, uint8_t address) {
|
||||
void MCP2521_HardwareHandle_ESP::read(uint8_t cmd, uint8_t *data, size_t length, uint8_t address) {
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
@@ -68,7 +68,7 @@ void MCP2521_Hardware_Handle_ESP::read(uint8_t cmd, uint8_t *data, size_t length
|
||||
spi_transmit((spi_transaction_t*)(&t));
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::read(uint8_t cmd, uint8_t *data, size_t length) {
|
||||
void MCP2521_HardwareHandle_ESP::read(uint8_t cmd, uint8_t *data, size_t length) {
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
@@ -87,7 +87,7 @@ void MCP2521_Hardware_Handle_ESP::read(uint8_t cmd, uint8_t *data, size_t length
|
||||
spi_transmit((spi_transaction_t*)(&t));
|
||||
}
|
||||
|
||||
uint8_t MCP2521_Hardware_Handle_ESP::read(uint8_t cmd, uint8_t address) {
|
||||
uint8_t MCP2521_HardwareHandle_ESP::read(uint8_t cmd, uint8_t address) {
|
||||
uint8_t result = 0;
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
@@ -108,7 +108,7 @@ uint8_t MCP2521_Hardware_Handle_ESP::read(uint8_t cmd, uint8_t address) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t MCP2521_Hardware_Handle_ESP::read(uint8_t cmd) {
|
||||
uint8_t MCP2521_HardwareHandle_ESP::read(uint8_t cmd) {
|
||||
uint8_t result;
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
@@ -129,7 +129,7 @@ uint8_t MCP2521_Hardware_Handle_ESP::read(uint8_t cmd) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::write(uint8_t cmd, uint8_t *data, size_t length, uint8_t address) {
|
||||
void MCP2521_HardwareHandle_ESP::write(uint8_t cmd, uint8_t *data, size_t length, uint8_t address) {
|
||||
uint8_t result;
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
@@ -149,7 +149,7 @@ void MCP2521_Hardware_Handle_ESP::write(uint8_t cmd, uint8_t *data, size_t lengt
|
||||
spi_transmit((spi_transaction_t*)(&t));
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::write(uint8_t cmd, uint8_t *data, size_t length) {
|
||||
void MCP2521_HardwareHandle_ESP::write(uint8_t cmd, uint8_t *data, size_t length) {
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
@@ -168,7 +168,7 @@ void MCP2521_Hardware_Handle_ESP::write(uint8_t cmd, uint8_t *data, size_t lengt
|
||||
spi_transmit((spi_transaction_t*)(&t));
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::write(uint8_t cmd, uint8_t data, uint8_t address) {
|
||||
void MCP2521_HardwareHandle_ESP::write(uint8_t cmd, uint8_t data, uint8_t address) {
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
@@ -187,7 +187,7 @@ void MCP2521_Hardware_Handle_ESP::write(uint8_t cmd, uint8_t data, uint8_t addre
|
||||
spi_transmit((spi_transaction_t*)(&t));
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::write(uint8_t cmd, uint8_t data) {
|
||||
void MCP2521_HardwareHandle_ESP::write(uint8_t cmd, uint8_t data) {
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
MCP2521_Hardware_Handle_ESP::MCP2521_Hardware_Handle_ESP(
|
||||
MCP2521_HardwareHandle_ESP::MCP2521_HardwareHandle_ESP(
|
||||
spi_host_device_t spi_host,
|
||||
spi_bus_config_t *bus_config,
|
||||
gpio_num_t mosi,
|
||||
@@ -23,7 +23,7 @@ MCP2521_Hardware_Handle_ESP::MCP2521_Hardware_Handle_ESP(
|
||||
initSPIDevice(spi_host, cs);
|
||||
}
|
||||
|
||||
MCP2521_Hardware_Handle_ESP::MCP2521_Hardware_Handle_ESP(
|
||||
MCP2521_HardwareHandle_ESP::MCP2521_HardwareHandle_ESP(
|
||||
spi_host_device_t spi_host,
|
||||
spi_bus_config_t *bus_config,
|
||||
gpio_num_t cs,
|
||||
@@ -34,11 +34,11 @@ MCP2521_Hardware_Handle_ESP::MCP2521_Hardware_Handle_ESP(
|
||||
initSPIDevice(spi_host, cs);
|
||||
}
|
||||
|
||||
MCP2521_Hardware_Handle_ESP::~MCP2521_Hardware_Handle_ESP() {
|
||||
MCP2521_HardwareHandle_ESP::~MCP2521_HardwareHandle_ESP() {
|
||||
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::initSPIBus(
|
||||
void MCP2521_HardwareHandle_ESP::initSPIBus(
|
||||
spi_host_device_t spi_host,
|
||||
gpio_num_t mosi,
|
||||
gpio_num_t miso,
|
||||
@@ -57,7 +57,7 @@ void MCP2521_Hardware_Handle_ESP::initSPIBus(
|
||||
spi_bus_initialize(spi_host, bus_config, SPI_DMA_CH_AUTO);
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::initSPIDevice(
|
||||
void MCP2521_HardwareHandle_ESP::initSPIDevice(
|
||||
spi_host_device_t spi_host,
|
||||
gpio_num_t cs
|
||||
) {
|
||||
@@ -85,7 +85,7 @@ void MCP2521_Hardware_Handle_ESP::initSPIDevice(
|
||||
spiMutex = xSemaphoreCreateMutex();
|
||||
}
|
||||
|
||||
spi_bus_config_t * MCP2521_Hardware_Handle_ESP::getSPI_bus_config() {
|
||||
spi_bus_config_t * MCP2521_HardwareHandle_ESP::getSPI_bus_config() {
|
||||
return this->spi_bus_config;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
#include "mcp2521_hardware_esp.hpp"
|
||||
|
||||
static void IRAM_ATTR gpio_isr_can_handler(void* arg) {
|
||||
MCP2521_Hardware_Handle_ESP * handle = (MCP2521_Hardware_Handle_ESP *)arg;
|
||||
MCP2521_HardwareHandle_ESP * handle = (MCP2521_HardwareHandle_ESP *)arg;
|
||||
handle->isr_can_interrupt();
|
||||
}
|
||||
|
||||
static void handleInteruptTaskCallerFn(void *arg) {
|
||||
MCP2521_Hardware_Handle_ESP * handle = (MCP2521_Hardware_Handle_ESP *)arg;
|
||||
MCP2521_HardwareHandle_ESP * handle = (MCP2521_HardwareHandle_ESP *)arg;
|
||||
handle->handleIntteruptTaskFn();
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::initPins(
|
||||
void MCP2521_HardwareHandle_ESP::initPins(
|
||||
gpio_num_t int_pin
|
||||
) {
|
||||
canInterruptSemaphore = xSemaphoreCreateBinary();
|
||||
@@ -31,24 +31,25 @@ void MCP2521_Hardware_Handle_ESP::initPins(
|
||||
gpio_install_isr_service(0);
|
||||
gpio_isr_handler_add(int_pin, gpio_isr_can_handler, this);
|
||||
|
||||
xTaskCreate(
|
||||
xTaskCreatePinnedToCore(
|
||||
(TaskFunction_t)&handleInteruptTaskCallerFn,
|
||||
"canInterruptTask",
|
||||
2048,
|
||||
this,
|
||||
5,
|
||||
&canInterruptTaskHandle
|
||||
&canInterruptTaskHandle,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::handleIntteruptTaskFn() {
|
||||
void MCP2521_HardwareHandle_ESP::handleIntteruptTaskFn() {
|
||||
while(true) {
|
||||
xSemaphoreTake(canInterruptSemaphore, portMAX_DELAY);
|
||||
intHandler(intHandlerArg);
|
||||
}
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::isr_can_interrupt() {
|
||||
void MCP2521_HardwareHandle_ESP::isr_can_interrupt() {
|
||||
BaseType_t wokenTask = pdFALSE;
|
||||
xSemaphoreGiveFromISR(canInterruptSemaphore, &wokenTask);
|
||||
|
||||
@@ -57,7 +58,7 @@ void MCP2521_Hardware_Handle_ESP::isr_can_interrupt() {
|
||||
}
|
||||
}
|
||||
|
||||
void MCP2521_Hardware_Handle_ESP::registerIntHandler(intHandlerFunction_t handler, void * arg) {
|
||||
void MCP2521_HardwareHandle_ESP::registerIntHandler(intHandlerFunction_t handler, void * arg) {
|
||||
intHandlerArg = arg;
|
||||
intHandler = handler;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/**
|
||||
* @file mcp2521_hardware_esp.hpp
|
||||
* @author AlexanderHD27
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2024-11-16
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "mcp2521_hardware_handle.hpp"
|
||||
|
||||
@@ -8,24 +18,48 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
class MCP2521_Hardware_Handle_ESP : public MCP2521_Hardware_Handle {
|
||||
char spi_tmp_buffer;
|
||||
|
||||
spi_bus_config_t * spi_bus_config;
|
||||
spi_device_interface_config_t spi_device_config;
|
||||
spi_device_handle_t spi_device_handle;
|
||||
static void handleInteruptTaskCallerFn(void *arg);
|
||||
static void IRAM_ATTR gpio_isr_can_handler(void* arg);
|
||||
|
||||
/**
|
||||
* @brief Hardware handle for MCP2521 over SPI on ESP32
|
||||
* This is should not be used if multiple MCP2521 are on the same SPI bus
|
||||
*/
|
||||
class MCP2521_HardwareHandle_ESP : public I_MCP2521_HardwareHandle {
|
||||
protected:
|
||||
void spi_transmit(spi_transaction_t *t);
|
||||
|
||||
/**
|
||||
* @brief Sempahore, that is set every time the MCP2521 triggers an interrupt by the canInterruptTaskHandle
|
||||
*/
|
||||
SemaphoreHandle_t canInterruptSemaphore = NULL;
|
||||
SemaphoreHandle_t spiMutex = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle to task that handles the MCP2521 interrupt
|
||||
* A Handle can be registered via the registerIntHandler method
|
||||
*/
|
||||
TaskHandle_t canInterruptTaskHandle = NULL;
|
||||
|
||||
void spi_transmit(spi_transaction_t *t);
|
||||
spi_device_handle_t spi_device_handle;
|
||||
|
||||
private:
|
||||
spi_bus_config_t * spi_bus_config;
|
||||
char spi_tmp_buffer;
|
||||
|
||||
spi_device_interface_config_t spi_device_config;
|
||||
|
||||
/**
|
||||
* @brief Sempahore, that protects the SPI bus from being accessed by multiple tasks at the same time
|
||||
*
|
||||
*/
|
||||
SemaphoreHandle_t spiMutex = NULL;
|
||||
|
||||
void * intHandlerArg = NULL;
|
||||
intHandlerFunction_t intHandler = NULL;
|
||||
|
||||
public:
|
||||
MCP2521_Hardware_Handle_ESP(
|
||||
MCP2521_HardwareHandle_ESP(
|
||||
spi_host_device_t spi_host,
|
||||
spi_bus_config_t *bus_config,
|
||||
gpio_num_t mosi,
|
||||
@@ -35,7 +69,7 @@ public:
|
||||
gpio_num_t int_pin
|
||||
);
|
||||
|
||||
MCP2521_Hardware_Handle_ESP(
|
||||
MCP2521_HardwareHandle_ESP(
|
||||
spi_host_device_t spi_host,
|
||||
spi_bus_config_t *bus_config,
|
||||
gpio_num_t cs,
|
||||
@@ -59,12 +93,22 @@ public:
|
||||
gpio_num_t int_pin
|
||||
);
|
||||
|
||||
~MCP2521_Hardware_Handle_ESP();
|
||||
~MCP2521_HardwareHandle_ESP();
|
||||
|
||||
spi_bus_config_t * getSPI_bus_config();
|
||||
|
||||
// ISR Stuff
|
||||
/**
|
||||
* @brief This function is called by the ISR, that is triggered by the MCP2521
|
||||
* This function just set the canInterruptSemaphore, that then unblocks the canInterruptTaskHandle.
|
||||
* So this function should be as short as possible, let the reset of the work be done in the canInterruptTaskHandle
|
||||
*/
|
||||
void isr_can_interrupt();
|
||||
|
||||
/**
|
||||
* This is the methode run as canInterruptTaskHandle.
|
||||
* It should continously aquire the canInterruptSemaphore and then call the intHandler
|
||||
*/
|
||||
void handleIntteruptTaskFn();
|
||||
|
||||
// Inherited from MCP2521_Hardware_Handle
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include "mcp2521_hardware_esp.hpp"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
struct spi_message_t {
|
||||
spi_transaction_t *transaction;
|
||||
QueueHandle_t queue;
|
||||
spi_device_handle_t spi_device_handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Hardware handle for MCP2521 over SPI in a multi-Bus-Setup on ESP32
|
||||
* This should not be created directly, use the MCP2521_HardwareHandleFactory_ESPBus instead
|
||||
*/
|
||||
class MCP2521_HardwareHandle_ESPBus : public MCP2521_HardwareHandle_ESP {
|
||||
using MCP2521_HardwareHandle_ESP::MCP2521_HardwareHandle_ESP;
|
||||
private:
|
||||
QueueHandle_t send_queue;
|
||||
QueueHandle_t receive_queue;
|
||||
|
||||
/**
|
||||
* @brief Wrapper around the spi_transmit function, that locks the spiMutex before calling spi_transmit.
|
||||
* The muxtex is shared with all other MCP2521_HardwareHandle_ESPBus instances created by the same MCP2521_HardwareHandleFactory_ESPBus
|
||||
* @overload
|
||||
*
|
||||
* @param t ESP32 SPI Transaction struct
|
||||
*/
|
||||
void spi_transmit(spi_transaction_t *t);
|
||||
public:
|
||||
MCP2521_HardwareHandle_ESPBus(
|
||||
QueueHandle_t send_queue,
|
||||
spi_host_device_t spi_host,
|
||||
spi_bus_config_t * bus_config,
|
||||
gpio_num_t cs,
|
||||
gpio_num_t int_pin
|
||||
);
|
||||
|
||||
void initPins(
|
||||
gpio_num_t int_pin
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "mcp2521_hardware_handle.hpp"
|
||||
#include "mcp2521_hardware_esp_bus.hpp"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
class MCP2521_HardwareHandleFactory_ESPBus {
|
||||
private:
|
||||
spi_bus_config_t bus_config;
|
||||
spi_host_device_t spi_host;
|
||||
|
||||
gpio_num_t mosi;
|
||||
gpio_num_t miso;
|
||||
gpio_num_t sclk;
|
||||
|
||||
QueueHandle_t spi_queue;
|
||||
TaskHandle_t transactionTaskHandle;
|
||||
|
||||
public:
|
||||
MCP2521_HardwareHandleFactory_ESPBus(
|
||||
spi_host_device_t spi_host,
|
||||
gpio_num_t mosi,
|
||||
gpio_num_t miso,
|
||||
gpio_num_t sclk
|
||||
);
|
||||
|
||||
void transactionTaskFn();
|
||||
|
||||
MCP2521_HardwareHandle_ESPBus create(
|
||||
gpio_num_t int_pin,
|
||||
gpio_num_t cs
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,23 +2,118 @@
|
||||
#include <cstdint>
|
||||
#include <strings.h>
|
||||
|
||||
/**
|
||||
* @brief Handler function pointer type
|
||||
*
|
||||
*/
|
||||
typedef void (*intHandlerFunction_t)(void *);
|
||||
|
||||
class MCP2521_Hardware_Handle {
|
||||
/**
|
||||
* @brief Hardware handle for MCP2521
|
||||
* @interface
|
||||
* This is an abstraction over the sepific hardware setup, eg. SPI@ESP32 or RP2040
|
||||
*
|
||||
*/
|
||||
class I_MCP2521_HardwareHandle {
|
||||
public:
|
||||
/**
|
||||
* @brief Registeres a function that is called when the MCP2521 triggers an interrupt
|
||||
*
|
||||
* @param handler This function is called when the MCP2521 triggers an interrupt
|
||||
* @param arg Arguments passed to the handler-function
|
||||
*/
|
||||
virtual void registerIntHandler(intHandlerFunction_t handler, void * arg) = 0;
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @brief justed sends a 8bit command to the MCP2521
|
||||
*
|
||||
* @param cmd command to send
|
||||
*/
|
||||
virtual void execute(uint8_t cmd) = 0;
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @brief executes a command (8 bit) with an address (8 bit)
|
||||
*
|
||||
* @param cmd 8 bit command
|
||||
* @param address 8 bit address
|
||||
*/
|
||||
virtual void execute(uint8_t cmd, uint8_t address) = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Executes a read from the MCP2521 with command, data buffer, length and address
|
||||
* @overload
|
||||
*
|
||||
* @param cmd Command to MCP2521
|
||||
* @param data Data buffer to store the read data
|
||||
* @param length How many bytes to read
|
||||
* @param address Address to read from
|
||||
*/
|
||||
virtual void read(uint8_t cmd, uint8_t *data, size_t length, uint8_t address) = 0;
|
||||
|
||||
/**
|
||||
* @brief Executes a read from the MCP2521 with command, data buffer and length
|
||||
* @overload
|
||||
*
|
||||
* @param cmd Command to MCP2521
|
||||
* @param data Data buffer to store the read data
|
||||
* @param length How many bytes to read
|
||||
*/
|
||||
virtual void read(uint8_t cmd, uint8_t *data, size_t length) = 0;
|
||||
|
||||
/**
|
||||
* @brief Executes a read from the MCP2521 with command and address, returns just one byte
|
||||
*
|
||||
* @param cmd Command to MCP2521
|
||||
* @param address Address to read from
|
||||
* @return uint8_t
|
||||
*/
|
||||
virtual uint8_t read(uint8_t cmd, uint8_t address) = 0;
|
||||
|
||||
/**
|
||||
* @brief Executes a read from the MCP2521 with command, returns just one byte
|
||||
*
|
||||
* @param cmd Command to MCP2521
|
||||
* @return uint8_t
|
||||
*/
|
||||
virtual uint8_t read(uint8_t cmd) = 0;
|
||||
|
||||
/**
|
||||
* @brief Writes data to the MCP2521 with command, data buffer, length and address
|
||||
*
|
||||
* @param cmd Command to MCP2521
|
||||
* @param data Data buffer to write
|
||||
* @param length Length of the data buffer
|
||||
* @param address Where to write the data
|
||||
*/
|
||||
virtual void write(uint8_t cmd, uint8_t *data, size_t length, uint8_t address) = 0;
|
||||
|
||||
/**
|
||||
* @brief Wirites data to the MCP2521 with command, data buffer and length
|
||||
*
|
||||
* @param cmd Command to MCP2521
|
||||
* @param data Data buffer to write
|
||||
* @param length Length of the data buffer
|
||||
*/
|
||||
virtual void write(uint8_t cmd, uint8_t *data, size_t length) = 0;
|
||||
|
||||
/**
|
||||
* @brief Writes data to the MCP2521 with command, data (on byte) and address
|
||||
*
|
||||
* @param cmd Command to MCP2521
|
||||
* @param data Data byte to write
|
||||
* @param address Where to write the data
|
||||
*/
|
||||
virtual void write(uint8_t cmd, uint8_t data, uint8_t address) = 0;
|
||||
|
||||
/**
|
||||
* @brief Writes to the MCP2521 with command and data (one byte)
|
||||
*
|
||||
* @param cmd Command to MCP2521
|
||||
* @param data Data byte to write
|
||||
*/
|
||||
virtual void write(uint8_t cmd, uint8_t data) = 0;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user