mirror of
https://github.com/lumapu/ahoy.git
synced 2025-07-19 01:07:15 +02:00
converted CMT to use same SPI as NRF (for fusion board)
This commit is contained in:
parent
7c62df071f
commit
25c9667633
12 changed files with 313 additions and 324 deletions
|
@ -40,7 +40,6 @@
|
||||||
|
|
||||||
typedef HmSystem<MAX_NUM_INVERTERS> HmSystemType;
|
typedef HmSystem<MAX_NUM_INVERTERS> HmSystemType;
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
typedef CmtRadio<esp32_3wSpi> CmtRadioType;
|
|
||||||
#endif
|
#endif
|
||||||
typedef Web<HmSystemType> WebType;
|
typedef Web<HmSystemType> WebType;
|
||||||
typedef RestApi<HmSystemType> RestApiType;
|
typedef RestApi<HmSystemType> RestApiType;
|
||||||
|
@ -322,7 +321,7 @@ class app : public IApp, public ah::Scheduler {
|
||||||
//Improv mImprov;
|
//Improv mImprov;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
CmtRadioType mCmtRadio;
|
CmtRadio<> mCmtRadio;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char mVersion[12];
|
char mVersion[12];
|
||||||
|
|
|
@ -94,7 +94,7 @@ enum {MQTT_STATUS_OFFLINE = 0, MQTT_STATUS_PARTIAL, MQTT_STATUS_ONLINE};
|
||||||
|
|
||||||
#define MQTT_MAX_PACKET_SIZE 384
|
#define MQTT_MAX_PACKET_SIZE 384
|
||||||
|
|
||||||
#define PLUGIN_DISPLAY
|
//#define PLUGIN_DISPLAY
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t rxFail;
|
uint32_t rxFail;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "spiPatcher.h"
|
#include "../utils/SpiPatcher.h"
|
||||||
|
|
||||||
#include <esp_rom_gpio.h>
|
#include <esp_rom_gpio.h>
|
||||||
#include <RF24_hal.h>
|
#include <RF24_hal.h>
|
||||||
|
@ -18,12 +18,14 @@
|
||||||
|
|
||||||
class nrfHal: public RF24_hal, public SpiPatcherHandle {
|
class nrfHal: public RF24_hal, public SpiPatcherHandle {
|
||||||
public:
|
public:
|
||||||
nrfHal() : mSpiPatcher(SPI2_HOST) {}
|
nrfHal() {
|
||||||
|
mSpiPatcher = SpiPatcher::getInstance(SPI2_HOST);
|
||||||
|
}
|
||||||
|
|
||||||
void patch() override {
|
void patch() override {
|
||||||
esp_rom_gpio_connect_out_signal(mPinMosi, spi_periph_signal[host_device].spid_out, false, false);
|
esp_rom_gpio_connect_out_signal(mPinMosi, spi_periph_signal[mHostDevice].spid_out, false, false);
|
||||||
esp_rom_gpio_connect_in_signal(mPinMiso, spi_periph_signal[host_device].spiq_in, false);
|
esp_rom_gpio_connect_in_signal(mPinMiso, spi_periph_signal[mHostDevice].spiq_in, false);
|
||||||
esp_rom_gpio_connect_out_signal(mPinClk, spi_periph_signal[host_device].spiclk_out, false, false);
|
esp_rom_gpio_connect_out_signal(mPinClk, spi_periph_signal[mHostDevice].spiclk_out, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unpatch() override {
|
void unpatch() override {
|
||||||
|
@ -32,40 +34,15 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle {
|
||||||
esp_rom_gpio_connect_out_signal(mPinClk, SIG_GPIO_OUT_IDX, false, false);
|
esp_rom_gpio_connect_out_signal(mPinClk, SIG_GPIO_OUT_IDX, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(int8_t mosi, int8_t miso, int8_t sclk, int8_t cs, int8_t en, int32_t speed = 0) {
|
void init(int8_t mosi, int8_t miso, int8_t sclk, int8_t cs, int8_t en, int32_t speed = NRF_DEFAULT_SPI_SPEED) {
|
||||||
DHEX(mosi);
|
mPinMosi = static_cast<gpio_num_t>(mosi);
|
||||||
DBGPRINT(" ");
|
|
||||||
DHEX(miso);
|
|
||||||
DBGPRINT(" ");
|
|
||||||
DHEX(sclk);
|
|
||||||
DBGPRINT(" ");
|
|
||||||
DHEX(cs);
|
|
||||||
DBGPRINT(" ");
|
|
||||||
DHEX(en);
|
|
||||||
DBGPRINTLN(" ");
|
|
||||||
delay(300);
|
|
||||||
mPinMosi = static_cast<>(mosi);
|
|
||||||
DBGPRINTLN("21");
|
|
||||||
delay(300);
|
|
||||||
mPinMiso = static_cast<gpio_num_t>(miso);
|
mPinMiso = static_cast<gpio_num_t>(miso);
|
||||||
DBGPRINTLN("22");
|
|
||||||
delay(300);
|
|
||||||
mPinClk = static_cast<gpio_num_t>(sclk);
|
mPinClk = static_cast<gpio_num_t>(sclk);
|
||||||
DBGPRINTLN("23");
|
|
||||||
delay(300);
|
|
||||||
mPinCs = static_cast<gpio_num_t>(cs);
|
mPinCs = static_cast<gpio_num_t>(cs);
|
||||||
DBGPRINTLN("24");
|
|
||||||
delay(300);
|
|
||||||
mPinEn = static_cast<gpio_num_t>(en);
|
mPinEn = static_cast<gpio_num_t>(en);
|
||||||
DBGPRINTLN("25");
|
|
||||||
delay(300);
|
|
||||||
mSpiSpeed = speed;
|
mSpiSpeed = speed;
|
||||||
|
|
||||||
DBGPRINTLN("3");
|
mHostDevice = mSpiPatcher->getDevice();
|
||||||
delay(300);
|
|
||||||
host_device = mSpiPatcher.init();
|
|
||||||
DBGPRINTLN("4");
|
|
||||||
delay(300);
|
|
||||||
|
|
||||||
gpio_reset_pin(mPinMosi);
|
gpio_reset_pin(mPinMosi);
|
||||||
gpio_set_direction(mPinMosi, GPIO_MODE_OUTPUT);
|
gpio_set_direction(mPinMosi, GPIO_MODE_OUTPUT);
|
||||||
|
@ -95,7 +72,7 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle {
|
||||||
.pre_cb = nullptr,
|
.pre_cb = nullptr,
|
||||||
.post_cb = nullptr
|
.post_cb = nullptr
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(spi_bus_add_device(host_device, &devcfg, &spi));
|
ESP_ERROR_CHECK(spi_bus_add_device(mHostDevice, &devcfg, &spi));
|
||||||
|
|
||||||
gpio_reset_pin(mPinEn);
|
gpio_reset_pin(mPinEn);
|
||||||
gpio_set_direction(mPinEn, GPIO_MODE_OUTPUT);
|
gpio_set_direction(mPinEn, GPIO_MODE_OUTPUT);
|
||||||
|
@ -218,11 +195,11 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void request_spi() {
|
inline void request_spi() {
|
||||||
mSpiPatcher.request(this);
|
mSpiPatcher->request(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void release_spi() {
|
inline void release_spi() {
|
||||||
mSpiPatcher.release();
|
mSpiPatcher->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -233,9 +210,9 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle {
|
||||||
gpio_num_t mPinEn = GPIO_NUM_NC;
|
gpio_num_t mPinEn = GPIO_NUM_NC;
|
||||||
int32_t mSpiSpeed = NRF_DEFAULT_SPI_SPEED;
|
int32_t mSpiSpeed = NRF_DEFAULT_SPI_SPEED;
|
||||||
|
|
||||||
spi_host_device_t host_device;
|
spi_host_device_t mHostDevice;
|
||||||
spi_device_handle_t spi;
|
spi_device_handle_t spi;
|
||||||
SpiPatcher mSpiPatcher;
|
SpiPatcher *mSpiPatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__NRF_HAL_H__*/
|
#endif /*__NRF_HAL_H__*/
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef __SPI_PATCHER_H__
|
|
||||||
#define __SPI_PATCHER_H__
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "spiPatcherHandle.h"
|
|
||||||
|
|
||||||
#include <driver/spi_master.h>
|
|
||||||
#include <freertos/semphr.h>
|
|
||||||
|
|
||||||
class SpiPatcher {
|
|
||||||
public:
|
|
||||||
explicit SpiPatcher(spi_host_device_t host_device) :
|
|
||||||
host_device(host_device), initialized(false), cur_handle(nullptr) {
|
|
||||||
// Use binary semaphore instead of mutex for performance reasons
|
|
||||||
mutex = xSemaphoreCreateBinaryStatic(&mutex_buffer);
|
|
||||||
xSemaphoreGive(mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
~SpiPatcher() { vSemaphoreDelete(mutex); }
|
|
||||||
|
|
||||||
spi_host_device_t init() {
|
|
||||||
if (!initialized) {
|
|
||||||
initialized = true;
|
|
||||||
|
|
||||||
spi_bus_config_t buscfg = {
|
|
||||||
.mosi_io_num = -1,
|
|
||||||
.miso_io_num = -1,
|
|
||||||
.sclk_io_num = -1,
|
|
||||||
.quadwp_io_num = -1,
|
|
||||||
.quadhd_io_num = -1,
|
|
||||||
.data4_io_num = -1,
|
|
||||||
.data5_io_num = -1,
|
|
||||||
.data6_io_num = -1,
|
|
||||||
.data7_io_num = -1,
|
|
||||||
.max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE,
|
|
||||||
.flags = 0,
|
|
||||||
.intr_flags = 0
|
|
||||||
};
|
|
||||||
ESP_ERROR_CHECK(spi_bus_initialize(host_device, &buscfg, SPI_DMA_DISABLED));
|
|
||||||
}
|
|
||||||
|
|
||||||
return host_device;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void request(SpiPatcherHandle* handle) {
|
|
||||||
xSemaphoreTake(mutex, portMAX_DELAY);
|
|
||||||
|
|
||||||
if (cur_handle != handle) {
|
|
||||||
if (cur_handle) {
|
|
||||||
cur_handle->unpatch();
|
|
||||||
}
|
|
||||||
cur_handle = handle;
|
|
||||||
if (cur_handle) {
|
|
||||||
cur_handle->patch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void release() {
|
|
||||||
xSemaphoreGive(mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const spi_host_device_t host_device;
|
|
||||||
bool initialized;
|
|
||||||
|
|
||||||
SpiPatcherHandle* cur_handle;
|
|
||||||
|
|
||||||
SemaphoreHandle_t mutex;
|
|
||||||
StaticSemaphore_t mutex_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*__SPI_PATCHER_H__*/
|
|
|
@ -6,7 +6,7 @@
|
||||||
#ifndef __CMT2300A_H__
|
#ifndef __CMT2300A_H__
|
||||||
#define __CMT2300A_H__
|
#define __CMT2300A_H__
|
||||||
|
|
||||||
#include "esp32_3wSpi.h"
|
#include "cmtHal.h"
|
||||||
|
|
||||||
// detailed register infos from AN142_CMT2300AW_Quick_Start_Guide-Rev0.8.pdf
|
// detailed register infos from AN142_CMT2300AW_Quick_Start_Guide-Rev0.8.pdf
|
||||||
|
|
||||||
|
@ -209,19 +209,12 @@ static uint8_t cmtConfig[0x60] PROGMEM {
|
||||||
|
|
||||||
enum {CMT_SUCCESS = 0, CMT_ERR_SWITCH_STATE, CMT_ERR_TX_PENDING, CMT_FIFO_EMPTY, CMT_ERR_RX_IN_FIFO};
|
enum {CMT_SUCCESS = 0, CMT_ERR_SWITCH_STATE, CMT_ERR_TX_PENDING, CMT_FIFO_EMPTY, CMT_ERR_RX_IN_FIFO};
|
||||||
|
|
||||||
template<class SPI>
|
|
||||||
class Cmt2300a {
|
class Cmt2300a {
|
||||||
typedef SPI SpiType;
|
|
||||||
public:
|
public:
|
||||||
Cmt2300a() {}
|
Cmt2300a() {}
|
||||||
|
|
||||||
void setup(uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb) {
|
void setup(uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb) {
|
||||||
mSpi.setup(pinSclk, pinSdio, pinCsb, pinFcsb);
|
mSpi.init(pinSdio, pinSclk, pinCsb, pinFcsb);
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
mSpi.setup();
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +476,7 @@ class Cmt2300a {
|
||||||
return mSpi.readReg(CMT2300A_CUS_MODE_STA) & CMT2300A_MASK_CHIP_MODE_STA;
|
return mSpi.readReg(CMT2300A_CUS_MODE_STA) & CMT2300A_MASK_CHIP_MODE_STA;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpiType mSpi;
|
cmtHal mSpi;
|
||||||
uint8_t mCnt;
|
uint8_t mCnt;
|
||||||
bool mTxPending;
|
bool mTxPending;
|
||||||
bool mInRxMode;
|
bool mInRxMode;
|
||||||
|
|
196
src/hms/cmtHal.h
Normal file
196
src/hms/cmtHal.h
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
||||||
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __CMT_HAL_H__
|
||||||
|
#define __CMT_HAL_H__
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../utils/SpiPatcher.h"
|
||||||
|
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
|
||||||
|
#define CMT_DEFAULT_SPI_SPEED 4000000 // 4 MHz
|
||||||
|
|
||||||
|
class cmtHal : public SpiPatcherHandle {
|
||||||
|
public:
|
||||||
|
cmtHal() {
|
||||||
|
mSpiPatcher = SpiPatcher::getInstance(SPI2_HOST);
|
||||||
|
}
|
||||||
|
|
||||||
|
void patch() override {
|
||||||
|
esp_rom_gpio_connect_out_signal(mPinSdio, spi_periph_signal[mHostDevice].spid_out, false, false);
|
||||||
|
esp_rom_gpio_connect_in_signal(mPinSdio, spi_periph_signal[mHostDevice].spid_in, false);
|
||||||
|
esp_rom_gpio_connect_out_signal(mPinClk, spi_periph_signal[mHostDevice].spiclk_out, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpatch() override {
|
||||||
|
esp_rom_gpio_connect_out_signal(mPinSdio, SIG_GPIO_OUT_IDX, false, false);
|
||||||
|
esp_rom_gpio_connect_in_signal(mPinSdio, GPIO_MATRIX_CONST_ZERO_INPUT, false);
|
||||||
|
esp_rom_gpio_connect_out_signal(mPinClk, SIG_GPIO_OUT_IDX, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(int8_t sdio, int8_t clk, int8_t cs, int8_t fcs, int32_t speed = CMT_DEFAULT_SPI_SPEED) {
|
||||||
|
mPinSdio = static_cast<gpio_num_t>(sdio);
|
||||||
|
mPinClk = static_cast<gpio_num_t>(clk);
|
||||||
|
mPinCs = static_cast<gpio_num_t>(cs);
|
||||||
|
mPinFcs = static_cast<gpio_num_t>(fcs);
|
||||||
|
mSpiSpeed = speed;
|
||||||
|
|
||||||
|
mHostDevice = mSpiPatcher->getDevice();
|
||||||
|
|
||||||
|
gpio_reset_pin(mPinSdio);
|
||||||
|
gpio_set_direction(mPinSdio, GPIO_MODE_INPUT_OUTPUT);
|
||||||
|
gpio_set_level(mPinSdio, 1);
|
||||||
|
|
||||||
|
gpio_reset_pin(mPinClk);
|
||||||
|
gpio_set_direction(mPinClk, GPIO_MODE_OUTPUT);
|
||||||
|
gpio_set_level(mPinClk, 0);
|
||||||
|
|
||||||
|
gpio_reset_pin(mPinCs);
|
||||||
|
spi_device_interface_config_t devcfg_reg = {
|
||||||
|
.command_bits = 1,
|
||||||
|
.address_bits = 7,
|
||||||
|
.dummy_bits = 0,
|
||||||
|
.mode = 0,
|
||||||
|
.duty_cycle_pos = 0,
|
||||||
|
.cs_ena_pretrans = 1,
|
||||||
|
.cs_ena_posttrans = 1,
|
||||||
|
.clock_speed_hz = mSpiSpeed,
|
||||||
|
.input_delay_ns = 0,
|
||||||
|
.spics_io_num = mPinCs,
|
||||||
|
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
||||||
|
.queue_size = 1,
|
||||||
|
.pre_cb = nullptr,
|
||||||
|
.post_cb = nullptr
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_bus_add_device(mHostDevice, &devcfg_reg, &spi_reg));
|
||||||
|
|
||||||
|
gpio_reset_pin(mPinFcs);
|
||||||
|
spi_device_interface_config_t devcfg_fifo = {
|
||||||
|
.command_bits = 0,
|
||||||
|
.address_bits = 0,
|
||||||
|
.dummy_bits = 0,
|
||||||
|
.mode = 0,
|
||||||
|
.duty_cycle_pos = 0,
|
||||||
|
.cs_ena_pretrans = 2,
|
||||||
|
.cs_ena_posttrans = static_cast<uint8_t>(2 * mSpiSpeed / 1000000), // >2 us
|
||||||
|
.clock_speed_hz = mSpiSpeed,
|
||||||
|
.input_delay_ns = 0,
|
||||||
|
.spics_io_num = mPinFcs,
|
||||||
|
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
||||||
|
.queue_size = 1,
|
||||||
|
.pre_cb = nullptr,
|
||||||
|
.post_cb = nullptr
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_bus_add_device(mHostDevice, &devcfg_fifo, &spi_fifo));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t readReg(uint8_t addr) {
|
||||||
|
uint8_t data;
|
||||||
|
|
||||||
|
request_spi();
|
||||||
|
|
||||||
|
spi_transaction_t t = {
|
||||||
|
.flags = 0,
|
||||||
|
.cmd = 1,
|
||||||
|
.addr = addr,
|
||||||
|
.length = 0,
|
||||||
|
.rxlength = 8,
|
||||||
|
.user = NULL,
|
||||||
|
.tx_buffer = NULL,
|
||||||
|
.rx_buffer = &data
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t));
|
||||||
|
|
||||||
|
release_spi();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeReg(uint8_t addr, uint8_t data) {
|
||||||
|
request_spi();
|
||||||
|
|
||||||
|
spi_transaction_t t = {
|
||||||
|
.flags = 0,
|
||||||
|
.cmd = 0,
|
||||||
|
.addr = addr,
|
||||||
|
.length = 8,
|
||||||
|
.rxlength = 0,
|
||||||
|
.user = NULL,
|
||||||
|
.tx_buffer = &data,
|
||||||
|
.rx_buffer = NULL
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t));
|
||||||
|
|
||||||
|
release_spi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void readFifo(uint8_t buf[], uint8_t *len, uint8_t maxlen) {
|
||||||
|
request_spi();
|
||||||
|
|
||||||
|
spi_transaction_t t = {
|
||||||
|
.flags = 0,
|
||||||
|
.cmd = 0,
|
||||||
|
.addr = 0,
|
||||||
|
.length = 0,
|
||||||
|
.rxlength = 8,
|
||||||
|
.user = NULL,
|
||||||
|
.tx_buffer = NULL,
|
||||||
|
.rx_buffer = NULL
|
||||||
|
};
|
||||||
|
for (uint8_t i = 0; i < maxlen; i++) {
|
||||||
|
if(0 == i)
|
||||||
|
t.rx_buffer = len;
|
||||||
|
else
|
||||||
|
t.rx_buffer = buf + i - 1;
|
||||||
|
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t));
|
||||||
|
}
|
||||||
|
|
||||||
|
release_spi();
|
||||||
|
}
|
||||||
|
void writeFifo(const uint8_t buf[], uint16_t len) {
|
||||||
|
request_spi();
|
||||||
|
|
||||||
|
spi_transaction_t t = {
|
||||||
|
.flags = 0,
|
||||||
|
.cmd = 0,
|
||||||
|
.addr = 0,
|
||||||
|
.length = 8,
|
||||||
|
.rxlength = 0,
|
||||||
|
.user = NULL,
|
||||||
|
.tx_buffer = NULL,
|
||||||
|
.rx_buffer = NULL
|
||||||
|
};
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
t.tx_buffer = buf + i;
|
||||||
|
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t));
|
||||||
|
}
|
||||||
|
|
||||||
|
release_spi();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline void request_spi() {
|
||||||
|
mSpiPatcher->request(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void release_spi() {
|
||||||
|
mSpiPatcher->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
gpio_num_t mPinSdio = GPIO_NUM_NC;
|
||||||
|
gpio_num_t mPinClk = GPIO_NUM_NC;
|
||||||
|
gpio_num_t mPinCs = GPIO_NUM_NC;
|
||||||
|
gpio_num_t mPinFcs = GPIO_NUM_NC;
|
||||||
|
int32_t mSpiSpeed = CMT_DEFAULT_SPI_SPEED;
|
||||||
|
|
||||||
|
spi_host_device_t mHostDevice;
|
||||||
|
spi_device_handle_t spi_reg, spi_fifo;
|
||||||
|
SpiPatcher *mSpiPatcher;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*__CMT_HAL_H__*/
|
|
@ -1,183 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef __ESP32_3WSPI_H__
|
|
||||||
#define __ESP32_3WSPI_H__
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
#if defined(ESP32)
|
|
||||||
#include "driver/spi_master.h"
|
|
||||||
#include "esp_rom_gpio.h" // for esp_rom_gpio_connect_out_signal
|
|
||||||
|
|
||||||
#define SPI_CLK 1 * 1000 * 1000 // 1MHz
|
|
||||||
|
|
||||||
#define SPI_PARAM_LOCK() \
|
|
||||||
do { \
|
|
||||||
} while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS)
|
|
||||||
#define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock)
|
|
||||||
|
|
||||||
// for ESP32 this is the so-called HSPI
|
|
||||||
// for ESP32-S2/S3/C3 this nomenclature does not really exist anymore,
|
|
||||||
// it is simply the first externally usable hardware SPI master controller
|
|
||||||
#define SPI_CMT SPI2_HOST
|
|
||||||
|
|
||||||
class esp32_3wSpi {
|
|
||||||
public:
|
|
||||||
esp32_3wSpi() {
|
|
||||||
mInitialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup(uint8_t pinSclk = DEF_CMT_SCLK, uint8_t pinSdio = DEF_CMT_SDIO, uint8_t pinCsb = DEF_CMT_CSB, uint8_t pinFcsb = DEF_CMT_FCSB) {
|
|
||||||
paramLock = xSemaphoreCreateMutex();
|
|
||||||
spi_bus_config_t buscfg = {
|
|
||||||
.mosi_io_num = pinSdio,
|
|
||||||
.miso_io_num = -1, // single wire MOSI/MISO
|
|
||||||
.sclk_io_num = pinSclk,
|
|
||||||
.quadwp_io_num = -1,
|
|
||||||
.quadhd_io_num = -1,
|
|
||||||
.max_transfer_sz = 32,
|
|
||||||
};
|
|
||||||
spi_device_interface_config_t devcfg = {
|
|
||||||
.command_bits = 1,
|
|
||||||
.address_bits = 7,
|
|
||||||
.dummy_bits = 0,
|
|
||||||
.mode = 0,
|
|
||||||
.cs_ena_pretrans = 1,
|
|
||||||
.cs_ena_posttrans = 1,
|
|
||||||
.clock_speed_hz = SPI_CLK,
|
|
||||||
.spics_io_num = pinCsb,
|
|
||||||
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
|
||||||
.queue_size = 1,
|
|
||||||
.pre_cb = NULL,
|
|
||||||
.post_cb = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(spi_bus_initialize(SPI_CMT, &buscfg, SPI_DMA_DISABLED));
|
|
||||||
ESP_ERROR_CHECK(spi_bus_add_device(SPI_CMT, &devcfg, &spi_reg));
|
|
||||||
|
|
||||||
// FiFo
|
|
||||||
spi_device_interface_config_t devcfg2 = {
|
|
||||||
.command_bits = 0,
|
|
||||||
.address_bits = 0,
|
|
||||||
.dummy_bits = 0,
|
|
||||||
.mode = 0,
|
|
||||||
.cs_ena_pretrans = 2,
|
|
||||||
.cs_ena_posttrans = (uint8_t)(1 / (SPI_CLK * 10e6 * 2) + 2), // >2 us
|
|
||||||
.clock_speed_hz = SPI_CLK,
|
|
||||||
.spics_io_num = pinFcsb,
|
|
||||||
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
|
||||||
.queue_size = 1,
|
|
||||||
.pre_cb = NULL,
|
|
||||||
.post_cb = NULL,
|
|
||||||
};
|
|
||||||
ESP_ERROR_CHECK(spi_bus_add_device(SPI_CMT, &devcfg2, &spi_fifo));
|
|
||||||
|
|
||||||
esp_rom_gpio_connect_out_signal(pinSdio, spi_periph_signal[SPI_CMT].spid_out, true, false);
|
|
||||||
delay(100);
|
|
||||||
|
|
||||||
//pinMode(pinGpio3, INPUT);
|
|
||||||
mInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeReg(uint8_t addr, uint8_t reg) {
|
|
||||||
if(!mInitialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint8_t tx_data;
|
|
||||||
tx_data = ~reg;
|
|
||||||
spi_transaction_t t = {
|
|
||||||
.cmd = 1,
|
|
||||||
.addr = (uint64_t)(~addr),
|
|
||||||
.length = 8,
|
|
||||||
.tx_buffer = &tx_data,
|
|
||||||
.rx_buffer = NULL
|
|
||||||
};
|
|
||||||
SPI_PARAM_LOCK();
|
|
||||||
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t));
|
|
||||||
SPI_PARAM_UNLOCK();
|
|
||||||
delayMicroseconds(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t readReg(uint8_t addr) {
|
|
||||||
if(!mInitialized)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uint8_t rx_data;
|
|
||||||
spi_transaction_t t = {
|
|
||||||
.cmd = 0,
|
|
||||||
.addr = (uint64_t)(~addr),
|
|
||||||
.length = 8,
|
|
||||||
.rxlength = 8,
|
|
||||||
.tx_buffer = NULL,
|
|
||||||
.rx_buffer = &rx_data
|
|
||||||
};
|
|
||||||
|
|
||||||
SPI_PARAM_LOCK();
|
|
||||||
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t));
|
|
||||||
SPI_PARAM_UNLOCK();
|
|
||||||
delayMicroseconds(100);
|
|
||||||
return rx_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeFifo(uint8_t buf[], uint8_t len) {
|
|
||||||
if(!mInitialized)
|
|
||||||
return;
|
|
||||||
uint8_t tx_data;
|
|
||||||
|
|
||||||
spi_transaction_t t = {
|
|
||||||
.length = 8,
|
|
||||||
.tx_buffer = &tx_data, // reference to write data
|
|
||||||
.rx_buffer = NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
SPI_PARAM_LOCK();
|
|
||||||
for(uint8_t i = 0; i < len; i++) {
|
|
||||||
tx_data = ~buf[i]; // negate buffer contents
|
|
||||||
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t));
|
|
||||||
delayMicroseconds(4); // > 4 us
|
|
||||||
}
|
|
||||||
SPI_PARAM_UNLOCK();
|
|
||||||
}
|
|
||||||
|
|
||||||
void readFifo(uint8_t buf[], uint8_t *len, uint8_t maxlen) {
|
|
||||||
if(!mInitialized)
|
|
||||||
return;
|
|
||||||
uint8_t rx_data;
|
|
||||||
|
|
||||||
spi_transaction_t t = {
|
|
||||||
.length = 8,
|
|
||||||
.rxlength = 8,
|
|
||||||
.tx_buffer = NULL,
|
|
||||||
.rx_buffer = &rx_data
|
|
||||||
};
|
|
||||||
|
|
||||||
SPI_PARAM_LOCK();
|
|
||||||
for(uint8_t i = 0; i < maxlen; i++) {
|
|
||||||
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t));
|
|
||||||
delayMicroseconds(4); // > 4 us
|
|
||||||
if(0 == i)
|
|
||||||
*len = rx_data;
|
|
||||||
else
|
|
||||||
buf[i-1] = rx_data;
|
|
||||||
}
|
|
||||||
SPI_PARAM_UNLOCK();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
spi_device_handle_t spi_reg, spi_fifo;
|
|
||||||
bool mInitialized;
|
|
||||||
SemaphoreHandle_t paramLock = NULL;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
template<uint8_t CSB_PIN=5, uint8_t FCSB_PIN=4>
|
|
||||||
class esp32_3wSpi {
|
|
||||||
public:
|
|
||||||
esp32_3wSpi() {}
|
|
||||||
void setup() {}
|
|
||||||
void loop() {}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*__ESP32_3WSPI_H__*/
|
|
|
@ -9,10 +9,9 @@
|
||||||
#include "cmt2300a.h"
|
#include "cmt2300a.h"
|
||||||
#include "../hm/radio.h"
|
#include "../hm/radio.h"
|
||||||
|
|
||||||
template<class SPI, uint32_t DTU_SN = 0x81001765>
|
template<uint32_t DTU_SN = 0x81001765>
|
||||||
class CmtRadio : public Radio {
|
class CmtRadio : public Radio {
|
||||||
typedef SPI SpiType;
|
typedef Cmt2300a CmtType;
|
||||||
typedef Cmt2300a<SpiType> CmtType;
|
|
||||||
public:
|
public:
|
||||||
CmtRadio() {
|
CmtRadio() {
|
||||||
mDtuSn = DTU_SN;
|
mDtuSn = DTU_SN;
|
||||||
|
@ -27,13 +26,6 @@ class CmtRadio : public Radio {
|
||||||
mPrintWholeTrace = printWholeTrace;
|
mPrintWholeTrace = printWholeTrace;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(bool *serialDebug, bool *privacyMode, bool genDtuSn = true) {
|
|
||||||
mCmt.setup();
|
|
||||||
reset(genDtuSn);
|
|
||||||
mPrivacyMode = privacyMode;
|
|
||||||
mSerialDebug = serialDebug;
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
mCmt.loop();
|
mCmt.loop();
|
||||||
if((!mIrqRcvd) && (!mRqstGetRx))
|
if((!mIrqRcvd) && (!mRqstGetRx))
|
||||||
|
|
9
src/utils/spiPatcher.cpp
Normal file
9
src/utils/spiPatcher.cpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
||||||
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#include "spiPatcher.h"
|
||||||
|
|
||||||
|
SpiPatcher *SpiPatcher::mInstance = nullptr;
|
84
src/utils/spiPatcher.h
Normal file
84
src/utils/spiPatcher.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
||||||
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __SPI_PATCHER_H__
|
||||||
|
#define __SPI_PATCHER_H__
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "spiPatcherHandle.h"
|
||||||
|
|
||||||
|
#include <driver/spi_master.h>
|
||||||
|
#include <freertos/semphr.h>
|
||||||
|
|
||||||
|
class SpiPatcher {
|
||||||
|
protected:
|
||||||
|
SpiPatcher(spi_host_device_t dev) :
|
||||||
|
mHostDevice(dev), mCurHandle(nullptr) {
|
||||||
|
// Use binary semaphore instead of mutex for performance reasons
|
||||||
|
mutex = xSemaphoreCreateBinaryStatic(&mutex_buffer);
|
||||||
|
xSemaphoreGive(mutex);
|
||||||
|
|
||||||
|
spi_bus_config_t buscfg = {
|
||||||
|
.mosi_io_num = -1,
|
||||||
|
.miso_io_num = -1,
|
||||||
|
.sclk_io_num = -1,
|
||||||
|
.quadwp_io_num = -1,
|
||||||
|
.quadhd_io_num = -1,
|
||||||
|
.data4_io_num = -1,
|
||||||
|
.data5_io_num = -1,
|
||||||
|
.data6_io_num = -1,
|
||||||
|
.data7_io_num = -1,
|
||||||
|
.max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE,
|
||||||
|
.flags = 0,
|
||||||
|
.intr_flags = 0
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_bus_initialize(mHostDevice, &buscfg, SPI_DMA_DISABLED));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
SpiPatcher(SpiPatcher &other) = delete;
|
||||||
|
void operator=(const SpiPatcher &) = delete;
|
||||||
|
|
||||||
|
static SpiPatcher* getInstance(spi_host_device_t dev) {
|
||||||
|
if(nullptr == mInstance)
|
||||||
|
mInstance = new SpiPatcher(dev);
|
||||||
|
return mInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
~SpiPatcher() { vSemaphoreDelete(mutex); }
|
||||||
|
|
||||||
|
spi_host_device_t getDevice() {
|
||||||
|
return mHostDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void request(SpiPatcherHandle* handle) {
|
||||||
|
xSemaphoreTake(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
if (mCurHandle != handle) {
|
||||||
|
if (mCurHandle) {
|
||||||
|
mCurHandle->unpatch();
|
||||||
|
}
|
||||||
|
mCurHandle = handle;
|
||||||
|
if (mCurHandle) {
|
||||||
|
mCurHandle->patch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void release() {
|
||||||
|
xSemaphoreGive(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static SpiPatcher *mInstance;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const spi_host_device_t mHostDevice;
|
||||||
|
SpiPatcherHandle* mCurHandle;
|
||||||
|
SemaphoreHandle_t mutex;
|
||||||
|
StaticSemaphore_t mutex_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*__SPI_PATCHER_H__*/
|
|
@ -47,7 +47,7 @@ class RestApi {
|
||||||
mSys = sys;
|
mSys = sys;
|
||||||
mRadioNrf = (HmRadio<>*)mApp->getRadioObj(true);
|
mRadioNrf = (HmRadio<>*)mApp->getRadioObj(true);
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
mRadioCmt = (CmtRadio<esp32_3wSpi>*)mApp->getRadioObj(false);
|
mRadioCmt = (CmtRadio<>*)mApp->getRadioObj(false);
|
||||||
#endif
|
#endif
|
||||||
mConfig = config;
|
mConfig = config;
|
||||||
mSrv->on("/api", HTTP_GET, std::bind(&RestApi::onApi, this, std::placeholders::_1));
|
mSrv->on("/api", HTTP_GET, std::bind(&RestApi::onApi, this, std::placeholders::_1));
|
||||||
|
@ -771,7 +771,7 @@ class RestApi {
|
||||||
HMSYSTEM *mSys;
|
HMSYSTEM *mSys;
|
||||||
HmRadio<> *mRadioNrf;
|
HmRadio<> *mRadioNrf;
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
CmtRadio<esp32_3wSpi> *mRadioCmt;
|
CmtRadio<> *mRadioCmt;
|
||||||
#endif
|
#endif
|
||||||
AsyncWebServer *mSrv;
|
AsyncWebServer *mSrv;
|
||||||
settings_t *mConfig;
|
settings_t *mConfig;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue