hideakitai / ESP32DMASPI

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

SINUS_TABLE #52

Closed AntonioRiccelli77 closed 4 months ago

AntonioRiccelli77 commented 4 months ago

I'm continuing the tests on the MAX542 DAC but I can't get a functional result with DMA. In summary. I have to send from an ESP32 Master a table of at least 32 16-bit values sent as MSB + LSB pairs (MSB FIRST) in the fastest possible way because I am interested in reaching 300Khz output to the DAC, however this does not happen with the standard method I can't get above 8Khz. Here is the code:

this is a sinus.h ``

define TABLE_SIZE 32

uint16_t sinus[TABLE_SIZE]={

0x8000, 0x98f8, 0xb0fb, 0xc71c, 0xda82, 0xea6d, 0xf641, 0xfd89, 0xffff, 0xfd89, 0xf641, 0xea6d, 0xda82, 0xc71c, 0xb0fb, 0x98f8, 0x8000, 0x6707, 0x4f04, 0x38e3, 0x257d, 0x1592, 0x9be, 0x276, 0x00, 0x276, 0x9be, 0x1592, 0x257d, 0x38e3, 0x4f04, 0x6707

};

``

this is a MAX542.h `

include

include "helper.h"

include "sinus.h"

ESP32DMASPI::Master master;

static constexpr size_t BUFFER_SIZE = TABLE_SIZE2; // should be multiple of 4 static constexpr size_t QUEUE_SIZE = 1; uint8_t dma_tx_buf; uint8_t *dma_rx_buf;

SPIClass *hspi = NULL;

const int slaveSelectPin = 15;

void initMAX542() {

// to use DMA buffer, use these methods to allocate buffer
dma_tx_buf = master.allocDMABuffer(BUFFER_SIZE);
//dma_rx_buf = master.allocDMABuffer(BUFFER_SIZE);
master.setDataMode(SPI_MODE0);           // default: SPI_MODE0
master.setFrequency(10000000);            // default: 8MHz (too fast for bread board...)
master.setMaxTransferSize(BUFFER_SIZE);  // default: 4092 bytes
master.setQueueSize(QUEUE_SIZE);         // default: 1

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

for(size_t i=0;i< TABLE_SIZE; i++){

    dma_tx_buf[i]=highByte(sinus[i]);

    dma_tx_buf[i+1]=lowByte(sinus[i]);

    Serial.print(dma_tx_buf[i]);

}

delay(2000);

Serial.println("start spi master");

}

void setMAX542(){

 // start and wait to complete one BIG transaction (same data will be received from slave)
 const size_t received_bytes = master.transfer(dma_tx_buf, NULL, BUFFER_SIZE);

} `

this is a main.cpp ` void setup{

initMAX542();

}

void loop() {

setMAX542();

} `

hideakitai commented 4 months ago

Could you format your codes correctly?

AntonioRiccelli77 commented 4 months ago

code.zip

hideakitai commented 4 months ago

I cannot use my computer for a while, so I would like you to make it easier to view from my cell phone...

AntonioRiccelli77 commented 4 months ago

main.cpp https://pastebin.com/embed_js/E3c38sfF sinus.h https://pastebin.com/embed_js/RhKs16GE MAX542.h https://pastebin.com/embed_js/Fcccc9MP

Please copy and paste link in browser but the redirections in git doesn't work apparently...

AntonioRiccelli77 commented 4 months ago

SPI

Cattura2

SPI DMA

Cattura
AntonioRiccelli77 commented 4 months ago

if it worked, I would also like to know how to introduce a delay of a few microseconds between one transaction and the next so as not to exceed the slave's ability to receive data not very quickly

hideakitai commented 4 months ago

I can't see the link when I open it in my browser…

hideakitai commented 4 months ago

Also, what is your problem? It also works with DMA but requires more speed? Or DMA SPI doesn't work at all?

AntonioRiccelli77 commented 4 months ago

Also, what is your problem? It also works with DMA but requires more speed? Or DMA SPI doesn't work at all?

DMA SPI doesn't work at all. In oscilloscope screen shot see the problem. The output of DAC is absent in this method. DMA is too fast ? If yes, how to introduce a delay beetween transactions?

hideakitai commented 4 months ago

Please refer https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks

AntonioRiccelli77 commented 4 months ago

#include <Arduino.h>
#include "MAX542.h"
#include <ESP32DMASPIMaster.h>
#include "helper.h"

#define TABLE_SIZE 32

uint16_t sinus[TABLE_SIZE]={

0x8000, 0x98f8, 0xb0fb, 0xc71c, 0xda82, 0xea6d, 0xf641, 0xfd89,
0xffff, 0xfd89, 0xf641, 0xea6d, 0xda82, 0xc71c, 0xb0fb, 0x98f8,
0x8000, 0x6707, 0x4f04, 0x38e3, 0x257d, 0x1592, 0x9be, 0x276,
0x00, 0x276, 0x9be, 0x1592, 0x257d, 0x38e3, 0x4f04, 0x6707

};

ESP32DMASPI::Master master;

static constexpr size_t BUFFER_SIZE = TABLE_SIZE*2; // should be multiple of 4
static constexpr size_t QUEUE_SIZE = 1;
uint8_t *dma_tx_buf;
uint8_t *dma_rx_buf;

//SPIClass *hspi = NULL;

const int slaveSelectPin = 15;

void initMAX542() {

    /*
    hspi = new SPIClass(HSPI);
    pinMode(slaveSelectPin, OUTPUT);

    hspi->begin(14, 12, 13, slaveSelectPin);
    */

    // to use DMA buffer, use these methods to allocate buffer
    dma_tx_buf = master.allocDMABuffer(BUFFER_SIZE);
    //dma_rx_buf = master.allocDMABuffer(BUFFER_SIZE);
    master.setDataMode(SPI_MODE0);           // default: SPI_MODE0
    master.setFrequency(10000000);            // default: 8MHz (too fast for bread board...)
    master.setMaxTransferSize(BUFFER_SIZE);  // default: 4092 bytes
    master.setQueueSize(QUEUE_SIZE);         // default: 1

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

    for(size_t i=0;i< TABLE_SIZE; i++){

        dma_tx_buf[i]=highByte(sinus[i]);

        dma_tx_buf[i+1]=lowByte(sinus[i]);

        Serial.print(dma_tx_buf[i]);
        // copy received data to tx buffer for next transfer
        //memcpy(sinus, dma_tx_buf, BUFFER_SIZE);

    }

    delay(2000);

    Serial.println("start spi master");

}

/*
void setMAX542(char msb, char lsb) {

  hspi->beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));

  digitalWrite(slaveSelectPin, 0); // Start of transmission: set chip select LOW

  hspi->transfer(msb);

  hspi->transfer(lsb);

  digitalWrite(slaveSelectPin, 1); // Start of transmission: set chip select LOW

  hspi->endTransaction();

}
*/

void setMAX542(){

    // initialize tx/rx buffers
    //initializeBuffers(dma_tx_buf, dma_rx_buf, BUFFER_SIZE);

    // start and wait to complete one BIG transaction (same data will be received from slave)

    master.transfer(dma_tx_buf, NULL, BUFFER_SIZE);

   /*
   for(size_t i=0;i< TABLE_SIZE; i++){

        hspi->beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));

        digitalWrite(slaveSelectPin, 0); // Start of transmission: set chip select LOW

        hspi->transfer(dma_tx_buf[i]);

        hspi->transfer(dma_tx_buf[i+1]);

        digitalWrite(slaveSelectPin, 1); // Start of transmission: set chip select LOW

        hspi->endTransaction();

        //Serial.print(dma_tx_buf[i]);

    }
    */

}

 void setup() {

  Serial.begin(115200);

  initMAX542();

 }

void loop() {

   setMAX542();

}
hideakitai commented 4 months ago

As I said before, is MAX542 designed to receive sinus in one transaction? In case of normal SPI, it seems to send it every 2 bytes.

AntonioRiccelli77 commented 4 months ago

MAX542 can be accept 2 byte for translation MSB+LSB for 16bit Revolution and not over. This Is problem for DMA ?

Il Sab 16 Mar 2024, 22:10 Hideaki Tai @.***> ha scritto:

As I said before, is MAX542 designed to receive sinus in one transaction? In case of normal SPI, it seems to send it every 2 bytes.

— Reply to this email directly, view it on GitHub https://github.com/hideakitai/ESP32DMASPI/issues/52#issuecomment-2002133820, or unsubscribe https://github.com/notifications/unsubscribe-auth/APCFLXTX3WPKBH7SNPHDSZDYYSYMNAVCNFSM6AAAAABEZGS7PCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMBSGEZTGOBSGA . You are receiving this because you authored the thread.Message ID: @.***>

hideakitai commented 4 months ago

This library sends a lot of bytes in one transaction. So, if MAX542 does not accept more than 16 bits in one transaction, you should use standard SPI.

AntonioRiccelli77 commented 4 months ago

Is possibile modify library for this device and Speed up the standard SPI ? If you capable can pay for your help...

Il Sab 16 Mar 2024, 22:43 Hideaki Tai @.***> ha scritto:

This library sends a lot of bytes in one transaction. So, if MAX542 does not accept more than 16 bits in one transaction, you should use standard SPI.

— Reply to this email directly, view it on GitHub https://github.com/hideakitai/ESP32DMASPI/issues/52#issuecomment-2002146416, or unsubscribe https://github.com/notifications/unsubscribe-auth/APCFLXQTKQLRGIDDUPFK2WLYYS4GPAVCNFSM6AAAAABEZGS7PCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMBSGE2DMNBRGY . You are receiving this because you authored the thread.Message ID: @.***>

hideakitai commented 4 months ago

In general, if you want to increase the speed with normal SPI, you need to increase the clock speed and speed up the CS operation (do not use Arduino's digitalWrite but use native GPIO operation).

hideakitai commented 4 months ago

You can find many articles to speed up digitalWrite

hideakitai commented 4 months ago

If you really need my help, I can of course create a library (or sketch) using the ESP32 SPI API as a job. In that case, please send me an email.

AntonioRiccelli77 commented 4 months ago

OK, I'll send you the specifications as soon as possible and give me a financial quote for your fee for writing a custom library

Ty so much

Il Sab 16 Mar 2024, 23:18 Hideaki Tai @.***> ha scritto:

If you really need my help, I can of course create a library (or sketch) using the ESP32 SPI API as a job. In that case, please send me an email.

— Reply to this email directly, view it on GitHub https://github.com/hideakitai/ESP32DMASPI/issues/52#issuecomment-2002158129, or unsubscribe https://github.com/notifications/unsubscribe-auth/APCFLXUBZPVF4BYSRJNOEODYYTAKBAVCNFSM6AAAAABEZGS7PCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMBSGE2TQMJSHE . You are receiving this because you authored the thread.Message ID: @.***>