132 lines
3.5 KiB
C++
132 lines
3.5 KiB
C++
/**
|
|
* @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"
|
|
|
|
#ifdef ESP_PLATFORM
|
|
|
|
#include "driver/gpio.h"
|
|
#include "driver/spi_master.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
|
|
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;
|
|
|
|
|
|
/**
|
|
* @brief Handle to task that handles the MCP2521 interrupt
|
|
* A Handle can be registered via the registerIntHandler method
|
|
*/
|
|
TaskHandle_t canInterruptTaskHandle = NULL;
|
|
|
|
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_HardwareHandle_ESP(
|
|
spi_host_device_t spi_host,
|
|
spi_bus_config_t *bus_config,
|
|
gpio_num_t mosi,
|
|
gpio_num_t miso,
|
|
gpio_num_t sclk,
|
|
gpio_num_t cs,
|
|
gpio_num_t int_pin
|
|
);
|
|
|
|
MCP2521_HardwareHandle_ESP(
|
|
spi_host_device_t spi_host,
|
|
spi_bus_config_t *bus_config,
|
|
gpio_num_t cs,
|
|
gpio_num_t int_pin
|
|
);
|
|
|
|
static void initSPIBus(
|
|
spi_host_device_t spi_host,
|
|
gpio_num_t mosi,
|
|
gpio_num_t miso,
|
|
gpio_num_t sclk,
|
|
spi_bus_config_t *bus_config
|
|
);
|
|
|
|
void initSPIDevice(
|
|
spi_host_device_t spi_host,
|
|
gpio_num_t cs
|
|
);
|
|
|
|
void initPins(
|
|
gpio_num_t int_pin
|
|
);
|
|
|
|
~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
|
|
void execute(uint8_t cmd);
|
|
void execute(uint8_t cmd, uint8_t address);
|
|
|
|
void read(uint8_t cmd, uint8_t *data, size_t length, uint8_t address);
|
|
void read(uint8_t cmd, uint8_t *data, size_t length);
|
|
uint8_t read(uint8_t cmd, uint8_t address);
|
|
uint8_t read(uint8_t cmd);
|
|
|
|
void write(uint8_t cmd, uint8_t *data, size_t length, uint8_t address);
|
|
void write(uint8_t cmd, uint8_t *data, size_t length);
|
|
void write(uint8_t cmd, uint8_t data, uint8_t address);
|
|
void write(uint8_t cmd, uint8_t data);
|
|
|
|
void registerIntHandler(intHandlerFunction_t handler, void * arg);
|
|
};
|
|
|
|
#endif
|