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:
- /* 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);
- }