cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f103c8cb HAL library with SPI over DMA

Rafal Pospieski
Associate
Posted on May 28, 2017 at 20:40

Hi!

I`m trying to send data from memory to SPI using DMA for LCD TFT purposes. To speed up the drawing I would like to send the same half-word x times (fill the rectange with the same color for example). At this point I`m able to send correcty the data to defined SPI port from particular memory adress (without memory incrase since I would like to send the same data over and over again) . The issue is that the DMA  command only allows me to send 8bit data and I need to use 16 bits (half-word).

The question - is there any possibility to send half-word (without memory increase by DMA) to SPI  (instead of 8bits only)?

LCD_WriteReg(0x0020, 0 );//set x coordinate do TFT

LCD_WriteReg(0x0021, 0 );

//set z coordinate do TFT

SendIndex(0x0022);//send data

SendDataStart();

color=color+1250;

uint16_t i;

for (i=0;i<30;i++)

{

HAL_SPI_Transmit_DMA(&hspi1, (uint8_t*)&color, 1024*5);            //<===== Eight bits only, I need 16 bits

while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

}

SendDataEnd();

0690X000006079OQAQ.png

best regards

Rafal

#stm32f103c8cb-hal-library-with-spi-over-dma
3 REPLIES 3
ChrisH
Associate III
Posted on May 29, 2017 at 01:35

I belive that you need to reconfigure SPI for DataSize of 16bits, obviusly set DMA to transmit halfword for both peripheral and mem. Then you can simply call HAL_SPI_Transmit_DMA with a pointer to 16bit variable. You might get some compiler errors either ignore or cast the uint8_t*. Any should work anyway. 

Rafal Pospieski
Associate
Posted on May 30, 2017 at 22:53

ChrisH,

Thank You so much for sugesstion, that would work if I would not need to send 24 bits as general commands. I`m communicating with LCD thru R61505W TFT contoller. that kind communication requires in general command of 24 bits as below:

0690X00000607CDQAY.png

so if I change the 8 bits to 16 bits that makes instead of sending 3 bytes (- refering to above picture ) two halfwords (which does not corespond to above diagram)

byte1 (Device ID code+RS+RW)

byte2 (MSB 8 bits)

byte3 (LSB 8 bits)

total 24 bits as required above

If I switch to 16 bits I would have to send

halfword1 (16 bits)

halfword2 (16 bits)

(32 bits in total -does not match 24 bits)

so in general as example instead of sending command as example

0x70 (device ID Code+RS+RW 8 bits)

0x34 (MSB 8 bits)

0x65 (LSB 8 bits)

after switching to 16 bits I woud have to send command as

0x0070 

(device ID Code+RS+RW BUT THAT WOULD BE 16 bits -wrong)

0x3465 (MSB+LSB 16 bits)

and that would not match the timming graph above.

So, maybe I would have to stick with 8 bits and at some point will have to switch to 16 bits where in need to transfer thru DMA?

How can I switch from 8 to 16bits in runtime?

I hope I dont have to reconfigure thru ''Init'' statement as below? Is there any other way?

hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_16BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;

hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;

hspi1.Init.NSS = SPI_NSS_SOFT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 10;

if (HAL_SPI_Init(&hspi1) != HAL_OK)

{

Error_Handler();

}

best regards

Rafal

Posted on May 30, 2017 at 23:54

Assuming you want to keep using HAL you need t DeInit 

peripheral change datasize and init again. More or less:

HAL_SPI_DeInit(&hspi1);

hspi1.Init.DataSize = SPI_DATASIZE_16BIT;

HAL_SPI_Init(&hspi1);

obviously reconfigure dma DMA if you have to.