For a successul write opertaion, i have to send 3 * 32bit frames. but the ESP32 takes quite a long time between each SPI frame.
Between the first two frames its 5ms and for the last frame it takes 10ms.
Here is my code:
Code: Untitled.cpp Select all
/* SPI Slave example, sender (uses SPI master driver)
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "lwip/igmp.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "soc/rtc_periph.h"
#include "driver/spi_master.h"
#include "esp_log.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
#include "esp_intr_alloc.h"
#define SENDER_HOST SPI2_HOST
static const char *TAG = "Energy meter";
#define GPIO_MOSI 7
#define GPIO_MISO 2
#define GPIO_SCLK 6
#define GPIO_CS 10
spi_device_handle_t Devicehandle;
spi_transaction_t init_spi(void)
{
spi_bus_config_t buscfg={
.mosi_io_num=GPIO_MOSI,
.miso_io_num=GPIO_MISO,
.sclk_io_num=GPIO_SCLK,
.quadwp_io_num=-1,
.quadhd_io_num=-1,
};
spi_device_interface_config_t devcfg={
.command_bits=0,
.address_bits=0,
.dummy_bits=0,
.input_delay_ns=0,
.clock_speed_hz=2000000,
.duty_cycle_pos=128,//50% duty cycle
.mode=3,
.spics_io_num=GPIO_CS,
.cs_ena_posttrans=0,
.queue_size=7
};
esp_err_t ret = -1;
spi_transaction_t trasactionHandle;
memset(&trasactionHandle, 0, sizeof(trasactionHandle));
ret=spi_bus_initialize(SENDER_HOST, &buscfg, SPI_DMA_CH_AUTO);
assert(ret==ESP_OK);
ret=spi_bus_add_device(SENDER_HOST, &devcfg, &Devicehandle);
assert(ret==ESP_OK);
return trasactionHandle;
}
uint sendSPIdata(uint8_t cmd, uint8_t data_h, uint8_t data_l, uint8_t chcksum, spi_transaction_t trasactionHandle){
ESP_LOGI(TAG, "Sending data to SPI bus");
int n=0;
esp_err_t ret = -1;
trasactionHandle.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
trasactionHandle.length = 32;
trasactionHandle.tx_data[0] = cmd;
trasactionHandle.tx_data[1] = data_h;
trasactionHandle.tx_data[2] = data_l;
trasactionHandle.tx_data[3] = chcksum;
ret=spi_device_transmit(Devicehandle, &trasactionHandle);
ESP_LOGI(TAG,"Sent: %d with return %d\n", trasactionHandle.tx_data[0],ret);
n++;
return ret;
}
uint spiWriteCmdData(unsigned char cmd0, uint dat, spi_transaction_t handle){
unsigned char cksum, cmdb;
uint send_dat = dat;
cmdb = (0x3f&cmd0) | 0x80;
cksum = ~((dat&0x00ff) + (dat>>8) + cmdb);
return sendSPIdata(cmdb,send_dat>>8,send_dat&0x00ff,cksum, handle);
}
void spiWRflash(uint addr, uint dat_h, uint dat_l, spi_transaction_t ha){
//printf("dat_l is %04X, dat_h is %04X address is %04X \n", dat_l,dat_h,addr);
spiWriteCmdData(0x08,dat_l, ha);
spiWriteCmdData(0x0A,dat_h,ha);
spiWriteCmdData(0x0c,addr,ha);
}
uint8_t iWriteRegister(uint data, uint16_t regAddress, spi_transaction_t h){
int ret = 0;
//printf("Writing %04X to %04X\n", data, regAddress);
spiWRflash(regAddress, (data>>16), data&0xffff, h);
return ret;
}
unsigned long readEMregister(unsigned int addr,spi_transaction_t han)
{
unsigned int dat_l, dat_h;
//printf("Reading register %04X \n", addr);
spiWriteCmdData(0x10, addr,han);
dat_l = spiWriteCmdData(0x12, addr,han);
dat_h = spiWriteCmdData(0x14, addr,han);
return (uint32_t)dat_h << 16 | (uint32_t)dat_l;
}
void vSetGPIOlevel(gpio_num_t number, int level)
{
esp_err_t iRetL = ESP_FAIL;
gpio_reset_pin(number);
iRetL = gpio_set_direction(number, GPIO_MODE_OUTPUT);
if (iRetL != ESP_OK){
ESP_LOGW(TAG, "Cannot set GPIO direction, V9203 mode might be set incorrectly");
}
iRetL = gpio_set_level(number, level);
if (iRetL != ESP_OK){
ESP_LOGW(TAG, "Cannot set GPIO level, V9203 mode might be set incorrectly");
}
ESP_LOGI(TAG, "GPIO %i is set to %i",number, level);
}
void app_main(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "Starting up!");
//vSetGPIOlevel(GPIO_NUM_18,1);
//vSetGPIOlevel(GPIO_NUM_19,1);
spi_transaction_t spitHandler = init_spi();
while(1){
sleep(1);
ret = iWriteRegister(0xDEADBEEF, 0xc001,spitHandler );
//break;
ESP_LOGI(TAG, "Program end!");
}
assert(ret==ESP_OK);
}