Sending data buffer through serial, some values get shifted

I’m working on a project were I have to send data through serial and I figured out filling a buffer was the best option. So far, I’m puting the values of a lookup table I’m using to output a wave through the DAC and sending those values through serial. The problem is that a few wave periods get sent correctly but then some others get shifted (each value gets multiplied by 256) and then the problem fixes itself. But of course, I need the data to be sent trustfully.

const PROGMEM short sintab[3][512] = ... //lookup tables

int wave = 1;
int i = 0;
int k = 1;


short* buff;

const int buflen = 1048;



void setup(void) {
  buff =  new short(buflen);
  Serial3.begin(57600, SERIAL_8E2);
}

void loop(void) {
    i+= k;
    j++;
    if (i>511){
      i-=512;     
      }
    if (j>buflen){
      byte* bytePointer =(byte*)buff;
      for (int l=0; l<buflen; l++){
        Serial3.write(bytePointer[l]);
        Serial3.flush();
        }
      j = 0;
      delete(buff);
      buff =  new short(buflen);
      }
}

There are the relevant chunks of code. The lookup tables go from 0 to 4095, hence I use short (most significant bit should always be zero). But on the other side, checking with a serial monitor, higher values get received. I tried puting down the baudrate, adding parity and stop bits and allocating memory with the new command (before I was just declaring the buffer as an array). The whole code is attached. Any ideas on how to send the right values and no other is well received.

signal.ino (8.9 KB)

To print a 2 dimension buffer, you can do that:

const uint16_t bufsize = 512;
uint16_t buf[4][bufsize];

void setup() {
  Serial.begin(250000);
  // Fill buf[][]
}

void loop() {

  static uint8_t bufn;
  printArray(buf[bufn]);
  bufn = (bufn + 1) % 4;

}

void printArray(uint16_t x[])
{

  for (int i = 0; i < bufsize; i++) {
    Serial.println (x[i]);
  }
}

For ADC sampling and DAC output, here is an example sketch:

/*******************************************************************************************/
/*                  ADC and DAC in FREE Running Mode and PDC DMA                           */
/*******************************************************************************************/

volatile uint32_t Timestamp, Oldmicros;
volatile boolean Flag, Flag_dac;
volatile uint8_t bufn, bufn_dac;
const uint16_t bufsize = 128;            // size must be a power of 2
const uint8_t bufnumber = 4;             // bufnumber > 2, better be a power of 2
const uint8_t _bufnumber = bufnumber - 1;
uint16_t buf[bufnumber][bufsize];        // bufnumber buffers of bufsize samples,

void setup()
{
  Serial.begin(250000);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(12, OUTPUT);
  adc_setup();
  dac_setup();
  Oldmicros = micros();
}

void loop()
{
  if (Flag) {
    Flag = false;
    Serial.println(Timestamp);
  }
}

/*************  Configure adc_setup function  *******************/
void adc_setup() {

  PMC->PMC_PCER1 |= PMC_PCER1_PID37;                    // ADC power ON

  ADC->ADC_CR = ADC_CR_SWRST;                           // Reset ADC
  ADC->ADC_MR |=  ADC_MR_TRGEN_DIS                      // Free Running Mode selected
                  | ADC_MR_FREERUN
                  | ADC_MR_PRESCAL(1);                  // Or PRESCAL (1) to reduce ADC frequency to 21 MHz

  ADC->ADC_ACR = ADC_ACR_IBCTL(0b01);                   // For frequencies > 500 KHz

  ADC->ADC_IER = ADC_IER_ENDRX;                         // End Of Conversion interrupt enable for channel 7
  NVIC_EnableIRQ(ADC_IRQn);                             // Enable ADC interrupt
  ADC->ADC_CHER = ADC_CHER_CH7;                         // Enable Channel 7 = A0

  /*********  code for PDC/DMA  buffer filling sequence **********/
  ADC->ADC_RPR = (uint32_t)buf[1];                      // DMA buffer - First one will be buf[1]
  ADC->ADC_RCR = bufsize;
  ADC->ADC_RNPR = (uint32_t)buf[2];                     // next DMA buffer
  ADC->ADC_RNCR = bufsize;
  bufn = 2;
  ADC->ADC_PTCR |= ADC_PTCR_RXTEN;                      // Enable PDC Receiver channel request
  ADC->ADC_CR = ADC_CR_START;
}

/*********  Call back function for ADC and DACC PDC/DMA **************/
void ADC_Handler () {

  bufn = (bufn + 1) & _bufnumber;
  ADC->ADC_RNPR = (uint32_t)buf[bufn];
  ADC->ADC_RNCR = bufsize;
  Flag_dac = true;

  bufn_dac = (bufn_dac + 1) & _bufnumber;
  DACC->DACC_TNPR = (uint32_t)buf[bufn_dac];
  DACC->DACC_TNCR = bufsize;

  // For debugging only
  static uint32_t Count;
  if (Count++ == 7812) { //1000000/128 ~7812
    Timestamp = micros() - Oldmicros;
    Oldmicros = micros();
    Flag = true;
    Count = 0;
    PIOB->PIO_ODSR ^= PIO_ODSR_P27;  // Toggle LED_BUILTIN every 1 Hz
  }

}

/*************  Configure adc_setup function  *******************/
void dac_setup ()
{

  PMC->PMC_PCER1 = PMC_PCER1_PID38;                   // DACC power ON

  DACC->DACC_CR = DACC_CR_SWRST ;                     // Reset DACC
  DACC->DACC_MR = DACC_MR_TRGEN_DIS                   // Free Running Mode selected
                  | DACC_MR_USER_SEL_CHANNEL1         // select channel 1
                  | DACC_MR_REFRESH (1)
                  | DACC_MR_STARTUP_8
                  | DACC_MR_MAXS;

  DACC->DACC_ACR = DACC_ACR_IBCTLCH0(0b10)
                   | DACC_ACR_IBCTLCH1(0b10)
                   | DACC_ACR_IBCTLDACCORE(0b01);

  DACC->DACC_IER = DACC_IER_ENDTX;
  NVIC_EnableIRQ(DACC_IRQn);                          // Enable DACC interrupt
  DACC->DACC_CHER = DACC_CHER_CH1;                    // enable channel 1 = DAC1

  /*************   configure PDC/DMA  for DAC *******************/
  DACC->DACC_TPR  = (uint32_t)buf[0];                 // DMA buffer
  DACC->DACC_TCR  = bufsize;
  DACC->DACC_TNPR = (uint32_t)buf[1];                 // next DMA buffer
  DACC->DACC_TNCR =  bufsize;
  bufn_dac = 1;
  DACC->DACC_PTCR = DACC_PTCR_TXTEN;                  // Enable PDC Transmit channel request

}

void DACC_Handler() {

  if (Flag_dac) {

    Flag_dac = false;

    static uint32_t Count;
    if (Count++ == 7812) { //1000000/128 ~7812
      Count = 0;
      PIOD->PIO_ODSR ^= PIO_ODSR_P8;  // Toggle pin 12 every 1 Hz
    }
  }

}