Problem using DMA to transfer arrays of 264 bytes via SPI MCU MKW01Z128

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem using DMA to transfer arrays of 264 bytes via SPI MCU MKW01Z128

610 Views
joseplluismoral
Contributor II

Hi!

 

- Im programming the DMA to transfer a bunch of bytes (264 bytes) from memory to SPI and from SPI to memory

- The intended use is to test the  Read and Write the at45db081 flash memory pages

 

To perform a Write Page I use the following code structure:

1-. Send the 4 bytes command via SPI without using the DMA (for code simplicity)

2-. Programming the DMA0 and DMAMUX0 to read from memory array and transfer the contents to the SPI

3-. Launch the DMA0 request4-. Once the transfer has been finished, (the DMA0_BCR counter reaches 0) the DMA0 interrupt occurs and there is performed a reset of the DMA0 channel and clearing of the interrupt byte.

 

To perform a Read Page I use the following code structure:

1-. Send the 8 bytes command via SPI without using the DMA (for code simplicity)

2-. Programming the DMA0 and DMAMUX0 to perform 264 dummy writes to the SPI

3-. Programming the DMA1 and DMAMUX1 to perform the read from SPI data to a array

4-. Launch the DMA0 and DMA1 request

5-. Once the transfer has been finished (the DMA1_BCR counter reaches 0) the DMA1 interrupt occurs and there is performed a reset of the DMA0 channel and clearing of the interrupt byte

 

The two Functions performs without any problem separately, meaning (in the first debug sesion I only call the Write, and then, i close the session, and open a second one call only the Read)

(The bytes written and read are valid and they are loaded correctly from and to the array), (I have checked the waveforms on the oscope)

 

The problem arises when I call the two of them from the main (First the Write and then the Read, using a handler to wait until the interrupt of the write has ocurred and then, the read is called, again using a handler to wait for the interrupt indicating the DMA1 has finished the read)

 

I don't know why separately, the two operations perfom well, and when I use them and call them one before the other in main,  furthermore using a handler to not start the following transfer until the first has come to an end, in that case, the data read in the array is all 0.

 

I post the code project for the completion off the issue, I hope anyone can bring come light on that

 

I use:

- Kinetis design studio 3.0

- GDB PEMicro interface debugging

- PEMIcro multilink for debugging/programming

 

Many thanks!

Original Attachment has been moved to: kw01_bootloader_dma_mincode.rar

0 Kudos
2 Replies

470 Views
mjbcswitzerland
Specialist V

Josep

The AT45DB081D requires typially 2ms to complete a page prgramming operation (max. 4ms).

If you do a write and a read without waiting for the programming to complete the chip will be busy and return no data since it doesn't allow reading in this state.

You need to poll its status register (after a write or erase) until its "rdy/busy" bit informs that it is ready to be read again.

Regards

Mark

0 Kudos

470 Views
joseplluismoral
Contributor II

Dear Mark

In the main.c I wait for the memory page write completion checking the status byte of the memory, so I think this step is done correctly.

I solved the problem changing the way the Write DMA transfer is performed;

1-. Send the 4 bytes command via SPI without using the DMA (for code simplicity)

2-. Programming the DMA0 and DMAMUX0 to read from memory array and transfer the contents to the SPI

3-. programming a transfer of 263 bytes (264-1) and SAR0 as the second position of the array &array[1] instead of &array[0]

4-.read the SPI_S status register and launching the first byte transfer manually.

3-. Launch the DMA0 request

4-. Once the transfer has been finished, (the DMA0_BCR counter reaches 0) the DMA0 interrupt occurs and there is performed a reset of the DMA0 channel and clearing of the interrupt byte.

This way, the Read memory page using DMA reads the correct data weritten onto memory.

I post the code used, maybe someone could find it useful

Thanks for your answer Mark

0 Kudos