Issues with editing buffer to be sent over SPI/DMA SAML21 (coding mistake?)

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I managed to get DMA working together with SPI by using the ASF quick start guide:

 

https://asf.microchip.com/docs/l...

 

I am able to initialize the buffer that is to be sent to anything in the code itself and it loads very fast on the LCD sceen - however I am running into issues when I am trying to update the buffer as I want to send one row of image data per cycle.

 

Example of code that works just fine, this uploads the color data stored in the buffer as expected. I have some external variables that are declared in a header. The variables are set up in a different file that initializes all the communications between the MCU and different pieces of hardware. The dma_buffer_tx variable is set to the appropriate length in the other file.

extern uint16_t dma_buffer_tx[];
extern volatile bool dma_tx_transfer_done;

for (int row = 0; row<(int)header.imageHeight; row++) {
        /*getNextRow_dma(currAddress, bytesPerRow);
        for(int i=0; i<493; i++){
            if(row%2==0){
                dma_buffer_tx[i]=0x199;
            }
            else{
                dma_buffer_tx[i]=0x177;
            }
        }*/
        TFT_SetCol(0,247);
        TFT_SetPage(row,row);
        TFT_SendCMD(0x2c); //write directly to memory
        spi_select_slave(&lcd_master, &lcd_slave_inst, true);
	    dma_start_transfer_job(&dma_tx);
	    while(!dma_tx_transfer_done){}; //wait
        spi_select_slave(&lcd_master, &lcd_slave_inst, false);

The above code runs fine. I initialized the dma_buffer_tx[] to some arbitrary color codes. It draws it row by row in an instant. Nice.

 

However, when I try to manipulate ANYTHING within the dma_buffer_tx[] - nothing draws anymore. It is as if by accessing the dma_buffer_tx array the whole code breaks down. As you can see in the loop that I have commented out - I tried to put in some arbitrary values for random colors and send them onward through DMA. If I uncomment this loop - nothing draws. I am at a loss. Am I making some basic coding mistake with the external variable? It seems really strange since everything works fine as long as I leave the dma_buffer_tx[] as I initialized it in the code.

uint16_t dma_buffer_tx[DMA_TX_BUF_LENGTH] = {[0 ... 493] = 0x1FA}; //DMA buffer

 

This topic has a solution.

1010001010111101110111

Last Edited: Mon. Aug 9, 2021 - 10:55 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since it works just fine with the whole list filled with 0x1FA, maybe the specific values 0x199 and 0x177 aren't working correctly in the transmission. If you haven't already, you could fill the initial list with one of those values and see if it works.  Besides that, the only other thing in the commented-out section is getNextRow_dma(), so that function might be the source of the problem. Do you know whether the code is actually filling the list?  It might be getting stuck in the loop.

Good luck!

 

Jarrod 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was able to fix it this morning when looking at it with fresh eyes. I did two things, first of all I declared the dma_buffer_tx as a volatile variable. Second, after completing one loop, before getting new values from the flash, I reset the dma_tx_transfer_done to false - that seems to have fixed the issue.

 

Basically, the ASF is a bit buggy and does not reset the complete flag.

1010001010111101110111