hideakitai / ESP32DMASPI

SPI library for ESP32 which use DMA buffer to send/receive transactions
MIT License
170 stars 36 forks source link

Cannot use Slave mode with esp_camera #7

Closed openedhardware closed 3 years ago

openedhardware commented 3 years ago

I'd like to take a photo and send to the SPI master, but SPI slave library doesn't work with esp_camera module together.

Each module individually works fine. I can send any data to SPI master without esp_camera module enabled and also can take a photo without slave module enabled.. But problem occurs when I enable both at the same time.

Here is my code:

#include "esp_camera.h"
#include "esp_system.h"
#include <Arduino.h>
#include "soc/soc.h"                // Disable brownour problems
#include "soc/rtc_cntl_reg.h"       // Disable brownour problems
#define CAMERA_MODEL_AI_THINKER     // Has PSRAM
#include "camera_pins.h"
#include <ESP32DMASPISlave.h>

#define PIN_FLASH         4

camera_fb_t * fb = NULL;
ESP32DMASPI::Slave slave;

static const uint32_t BUFFER_SIZE = 8192;
uint8_t* spi_slave_tx_buf;
uint8_t* spi_slave_rx_buf;
unsigned long cnt = 0;

void setup() {

  delay(3000);
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);    // Turn-off the 'browout detector'

  pinMode(PIN_FLASH, OUTPUT);
  digitalWrite(PIN_FLASH, LOW);

  Serial.begin(115200);
  Serial.setDebugOutput(true);

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;

  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality for larger pre-allocated frame buffer.
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x\n", err);
    return;
  }
  Serial.println(F("Initialized Camera"));

  sensor_t * s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1);         // flip it back
    s->set_brightness(s, 1);    // up the brightness just a bit
    s->set_saturation(s, -2);   // lower the saturation
  }
  s->set_framesize(s, FRAMESIZE_QVGA);    // drop down frame size for higher initial frame rate
  Serial.println(F("Adjusted Camera Settings"));

  // to use DMA buffer, use these methods to allocate buffer
  spi_slave_tx_buf = slave.allocDMABuffer(BUFFER_SIZE);
  spi_slave_rx_buf = slave.allocDMABuffer(BUFFER_SIZE);
  memset(spi_slave_tx_buf, 0, BUFFER_SIZE);
  memset(spi_slave_rx_buf, 0, BUFFER_SIZE);

  slave.setDataMode(SPI_MODE0);
  slave.setMaxTransferSize(BUFFER_SIZE);
  slave.setDMAChannel(2); // 1 or 2 only
  slave.setQueueSize(1); // transaction queue size

  // begin() after setting
  // HSPI = CS: 15, CLK: 14, MOSI: 13, MISO: 12
  slave.begin(); // default SPI is HSPI

  digitalWrite(PIN_FLASH, HIGH);
  Serial.println(F("Taking a picture..."));    // Take a picture with the camera
  fb = esp_camera_fb_get();
  if (fb) {
    Serial.printf("Took a picture, %dx%d, %dbytes\n", fb->width, fb->height, fb->len);
  } else {
    Serial.println("Camera capture failed");          
  }
  digitalWrite(PIN_FLASH, LOW);
  esp_camera_fb_return(fb);

}

void loop() {
}

I tried to decrease the BUFFER_SIZE, but no luck:

--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time--- More details at http://bit.ly/pio-monitor-filters
--- Miniterm on COM3  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
Initialized Camera
Adjusted Camera Settings
Taking a picture...
[E][camera.c:1483] esp_camera_fb_get(): Failed to get the frame on time!
Camera capture failed

Please help! :)

hideakitai commented 3 years ago

There may be some configuration (pin, DMA channel, etc.) conflicts between the camera and SPI. Please check if there are any duplicate pin assignments or DMA settings for the camera.

openedhardware commented 3 years ago

Yes, seems esp_camera uses the DMA bus 1 and 2.

Is there any way to use your awesome library without using DMA?

Thanks!

hideakitai commented 3 years ago

No, this library is optimized to use DMA. Would you please use the standard SPI library instead?

openedhardware commented 3 years ago

Yes, I tried following libraries, but no luck.. :/

https://github.com/martinberlin/esp32-spi-slave https://github.com/iPAS/esp32-slave-spi

hideakitai commented 3 years ago

You can use the SPI library of esp32-arduino.

https://github.com/espressif/arduino-esp32/tree/master/libraries/SPI

openedhardware commented 3 years ago

I'd like to use the ESP32-CAM module in SPI slave mode, not master.. Thanks!

hideakitai commented 3 years ago

Ah, ok. If you can test it, I will try to make it. Are you interested in it?

openedhardware commented 3 years ago

Yeah, absolutely!

Just sent an email, please check.

Thanks!

hideakitai commented 3 years ago

I've tried to make it. Please check it out! https://github.com/hideakitai/ESP32SPISlave

hideakitai commented 3 years ago

Closing this issue because https://github.com/hideakitai/ESP32SPISlave can solve this.

beniroquai commented 4 months ago

Thanks for sharing the information! I'm working on a similar idea. @openedhardware did you get it to work in the end? Did you publish the source somewhere? Or is it simply the code above with the ESP32SPISlave library?