Author Topic: STM32 + SPI only work one cycle  (Read 5266 times)

0 Members and 1 Guest are viewing this topic.

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
STM32 + SPI only work one cycle
« on: August 02, 2019, 08:49:26 am »
Hi,

I am working with a STM32L053C microcontroller and i want use an e-paper display. Actually i am using STM32cubeIDE and HAL.

I have a problem with the display and the microcontroller. If i run the example display example code, all works fine. The problems start when i tried to put together all parts of my hardware. All works fine but the e-paper not. At the first cycle the e-paper works well but only works one time. Next cycles the e-paper not work as expected. Only show the last instructions that it was sent last cycle.

Between cycles i have tried to disconnect the e-paper and connect again, but this not works.

I  saw with the osciloscope that the SPI commnications not work as the first time.

I think the SPI comunicatión don´t work well after the first cycle.

I tried to DeInit() the SPI after the first cycle and Init() the SPI on each cycle but not work.

How can i restart the SPI port? Is it possible restart the SPI as whent the microcontroller start the first time?

Could anyone said me some suggestions to resolve the problem?

Thanks,
Regards.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 + SPI only work one cycle
« Reply #1 on: August 02, 2019, 10:47:30 am »
You can reset the SPI perihperal, but that won't fix your problem.
SPI can't get stuck in state. It is either busy transmitting/receiving a word, or waiting for a word. It has a busy flag for this.

But a poorly written driver can get out of sync with the display.
Because it didn't wait for the display to process a command for example. The LCD will just ignore the next command, and you're out of sync.
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #2 on: August 02, 2019, 11:08:44 am »
Hi,

Thanks for your response.

I get the SPI state just before the init and always i get state_ready. In all cycles but not work the display:

Code: [Select]
if (EPD_Init(&epd, lut_full_update) != 0) {
  //printf("e-Paper init failed\n");
  HAL_UART_Transmit(&hlpuart1, "e-Paper init failed\r\n", strlen("e-Paper init failed\r\n"), 100);
}

uint8_t spi_estado = HAL_SPI_GetState(&hspi1);
memset(uartBuf, '\0', sizeof(uartBuf));
sprintf(uartBuf, "SPI estado: 0x%08X | %d\r\n", spi_estado, spi_estado);
HAL_UART_Transmit(&hlpuart1, uartBuf, strlen(uartBuf), 100);

In each cycle i power on and off the display.

One time i have added next line into the e-paper library:

Code: [Select]
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
and the spi send function looks like:

Code: [Select]
void EpdSpiTransferCallback(unsigned char data) {
  HAL_GPIO_WritePin((GPIO_TypeDef*)pins[CS_PIN].port, pins[CS_PIN].pin, GPIO_PIN_RESET);
  HAL_SPI_Transmit(&hspi1, &data, 1, 1000);
  while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
  HAL_GPIO_WritePin((GPIO_TypeDef*)pins[CS_PIN].port, pins[CS_PIN].pin, GPIO_PIN_SET);
}

I am using this e-paper stm32 library:
https://github.com/soonuse/epd-library-stm32/tree/master/1.54inch_e-paper/stm32

If the SPI not work well, why the e-paper work onle the first cycle? Next while cycle not work and if i use the stop mode, when the microcontroller wake-up the e-paper not work.

Thanks for your time,
Regards.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 + SPI only work one cycle
« Reply #3 on: August 02, 2019, 01:07:03 pm »
This is probably just a bad driver, or improper use of the driver. The driver expects the display to be in a certain state, which it isn't due to a previous command not being performed or being sent while busy.

You can check with a logic analyzer if the SPI still sends stuff, which I'm sure it does.

Verify if the display also has a busy bit, check this when waiting for it to do it's thing.

Also verify that you're not going to a sleep mode that loses register and ram contents that you do not expect to lose.
« Last Edit: August 02, 2019, 01:08:45 pm by Jeroen3 »
 

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 6337
  • Country: ca
  • Non-expert
Re: STM32 + SPI only work one cycle
« Reply #4 on: August 02, 2019, 10:13:53 pm »
Are you using a debugger (stlink) to see if you code is getting stuck somewhere or doing anything unexpected?

Performing an SPI transfer *in* the SPI transfer complete callback doesn't seem right to me (I think thats what it is). Try updating every 500ms or something instead.
edit: ignore its not the complete callback

https://github.com/soonuse/gdep015oc1_1.54inch_e-paper/blob/master/stm32/BSP/epdif.c
« Last Edit: August 06, 2019, 10:12:02 pm by thm_w »
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #5 on: August 04, 2019, 06:57:21 pm »
Are you using a debugger (stlink) to see if you code is getting stuck somewhere or doing anything unexpected?

Performing an SPI transfer *in* the SPI transfer complete callback doesn't seem right to me (I think thats what it is). Try updating every 500ms or something instead.

Yes, i have used a stlink and i have checked if the code do some wrong. I am a begginer but i think that the code "working as expected" (i am not 100% sure).

First while loop, i send some text and one QR code to show in the e-paper. I do some tasks with the e-paper without problems. First cycle (first while loop), all work as expected. Next whiles loop (using and not using the stop mode as low power mode), the e-paper only show the last screen sent in the last loop. When i send something to the e-paper, the display show the last screen sent in last loop. Next commands sent to the e-paper, the display don´t show anything, next command show the last screen sent in the first loop. The rest of the code work as expected.

I don´t understood what do you want say here: Performing an SPI transfer *in* the SPI transfer complete callback doesn't seem right to me (I think thats what it is). Try updating every 500ms or something instead.

This is probably just a bad driver, or improper use of the driver. The driver expects the display to be in a certain state, which it isn't due to a previous command not being performed or being sent while busy.

You can check with a logic analyzer if the SPI still sends stuff, which I'm sure it does.

Verify if the display also has a busy bit, check this when waiting for it to do it's thing.

Also verify that you're not going to a sleep mode that loses register and ram contents that you do not expect to lose.

I have not a logic analyzer :( I need buy one.

If the SPI had a conflict, why i dont get the problems in the first loop?

When the microcontroller wake-up, i do the init of SPI, but only work well at the first loop. I have tried with the stop mode and without the stop mode, but don´t work.

The e-paper only have a 3 SPI pins (MOSI, CLK, CS) and other pins as reset, busy, vcc, gnd... Between loops i turn off the VCC e-paper, so the hardware should be how the first cycle.

I am not sure about the library works well because if i disconnect the e-paper i dont get the init error.

How i could reset the microcontroller SPI interface? (if this is possible). This is not a good solution but could be a temporary solution.

Thanks,
Regards.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9888
  • Country: us
Re: STM32 + SPI only work one cycle
« Reply #6 on: August 04, 2019, 08:17:13 pm »
I haven't played with STM32 SPI so feel free to ignore all of this:

SPI packets are framed by CS'  First, CS goes low, some data is transferred (the length in bytes is determined by the slave) and, AFTER the last byte is actually transferred and the SPI gadget changes state to Ready (or sends a completion interrupt), then CS is changed to high.

The problem with most code is that it doesn't wait for the last byte to transfer before raising CS' and from then on, things go sideways.  Perhaps the last byte of the previous transaction is now the first byte of the current transaction.

I'm not going to go through the HAL code, that stuff is too grim to contemplate.  I swear these libraries are created by doctors specializing in Carpel Tunnel surgery caused by the excessive typing.  Never use 5 characters when an entire sentence will suffice!

It appears that the code above actually waits for Ready but unless I read the datasheet and reviewed the library code, I would be wondering.  Of course a logic analyzer is a great help and I actually bought the 4 channel Rigol DS1054Z scope for the specific purpose of decoding SPI transactions.  Yes, it also does a lot of other really neat things!
« Last Edit: August 04, 2019, 08:20:18 pm by rstofer »
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #7 on: August 04, 2019, 08:48:37 pm »
I haven't played with STM32 SPI so feel free to ignore all of this:

SPI packets are framed by CS'  First, CS goes low, some data is transferred (the length in bytes is determined by the slave) and, AFTER the last byte is actually transferred and the SPI gadget changes state to Ready (or sends a completion interrupt), then CS is changed to high.

The problem with most code is that it doesn't wait for the last byte to transfer before raising CS' and from then on, things go sideways.  Perhaps the last byte of the previous transaction is now the first byte of the current transaction.

I'm not going to go through the HAL code, that stuff is too grim to contemplate.  I swear these libraries are created by doctors specializing in Carpel Tunnel surgery caused by the excessive typing.  Never use 5 characters when an entire sentence will suffice!

It appears that the code above actually waits for Ready but unless I read the datasheet and reviewed the library code, I would be wondering.  Of course a logic analyzer is a great help and I actually bought the 4 channel Rigol DS1054Z scope for the specific purpose of decoding SPI transactions.  Yes, it also does a lot of other really neat things!

My oscilloscope is the DS1054Z. I don´t remember that it has an analyzer.

One thing, if i turn off the e-paper VCC, the display should be initialized?

Thanks,
Regards.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 + SPI only work one cycle
« Reply #8 on: August 04, 2019, 08:57:30 pm »
If you turn off Vcc from the display then you must also tell the library is should initialize the display again.

Anyway, resetting SPI is easy. See RCC->APB2RSTR bit SPI1RST (bit 12), chapter 7.3.10 of the reference manual.

The DS1054Z does have SPI protocol decoding as an option. This forum has topics about how to enable those protocol decoding options if it isn't enabled already.

The e-paper only have a 3 SPI pins (MOSI, CLK, CS) and other pins as reset, busy, vcc, gnd... Between loops i turn off the VCC e-paper, so the hardware should be how the first cycle.
Does the library know about this busy signal? Did you implement this correctly?
« Last Edit: August 04, 2019, 09:00:37 pm by Jeroen3 »
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #9 on: August 04, 2019, 09:54:13 pm »
If you turn off Vcc from the display then you must also tell the library is should initialize the display again.

Anyway, resetting SPI is easy. See RCC->APB2RSTR bit SPI1RST (bit 12), chapter 7.3.10 of the reference manual.

The DS1054Z does have SPI protocol decoding as an option. This forum has topics about how to enable those protocol decoding options if it isn't enabled already.

The e-paper only have a 3 SPI pins (MOSI, CLK, CS) and other pins as reset, busy, vcc, gnd... Between loops i turn off the VCC e-paper, so the hardware should be how the first cycle.
Does the library know about this busy signal? Did you implement this correctly?

I am not the writer of library, so i am not sure if the library works well. I think that the library use the busy signal. This is the library that i am using: https://github.com/soonuse/epd-library-stm32/tree/master/1.54inch_e-paper/stm32

I initialize the library always. I will go to check my oscilloscope to debug the SPI protocol and check the SPI reset too.

Thanks,
Regards.
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #10 on: August 05, 2019, 08:14:13 am »
Hi,

I test the SPI reset but dont works. I have added this lines (MX_SPI1_Init() is used in each loop before i use the e-paper):

RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST; //reset SPI1
RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST; //reset SPI1

MX_SPI1_Init();

I have checked the library to be sure about if the CS, BUSY and RST pins are been used, and the library use the pins.

I will go to check the oscilloscope to see the logics.

I am using too an ADC, TIM2, UART2, LPUART1 and RTC. Could be any interference between interfaces?

Thanks,
Regards.
« Last Edit: August 05, 2019, 08:16:16 am by grafi »
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 + SPI only work one cycle
« Reply #11 on: August 05, 2019, 08:18:22 am »
I test the SPI reset but dont works. I have added this lines (MX_SPI1_Init() is used in each loop before i use the e-paper):
Did you also reset the library?

I am using too an ADC, TIM2, UART2, LPUART1 and RTC. Could be any interference between interfaces?
No. There is only one chip I know of that had a failure like this. And it was bad. They didn't even release the batch, they all got marked engineering sample.
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #12 on: August 05, 2019, 08:26:49 am »
Yes.. i do this:

Code: [Select]
RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST; //reset SPI1
RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST; //reset SPI1

MX_SPI1_Init();

HAL_Delay(1000);

if (EPD_Init(&epd, lut_full_update) != 0) {  
  HAL_UART_Transmit(&hlpuart1, "e-Paper init failed\r\n", strlen("e-Paper init failed\r\n"), 100);
}

Is it correct? or i need add this line:

Code: [Select]
EPD epd;
Just before of:

Code: [Select]
if (EPD_Init(&epd, lut_full_update) != 0) {  
  HAL_UART_Transmit(&hlpuart1, "e-Paper init failed\r\n", strlen("e-Paper init failed\r\n"), 100);
}

Maybe i am wrong, how can i reset the library?

Thanks,
Regards.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 + SPI only work one cycle
« Reply #13 on: August 05, 2019, 09:35:26 am »
Looks like EPD_Init will do what you want. But resetting everything everytime you want to update the display is not how it is supposed to work.

Go read the source code of the library. It's not that big. You'll figure it out.
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #14 on: August 05, 2019, 12:52:03 pm »
I think that i found the problem. Maybe the SPI wasn´t the problem. I am programming this line inside the e-paper function:

Code: [Select]
unsigned char* frame_buffer = (unsigned char*)malloc(EPD_WIDTH * EPD_HEIGHT / 8);
and the only option is program this line in the main(). If i write this line in other place, the e-paper only works well in first loop.

I don´t know why this happend. Could anyone tell me?

Thanks all your time.
Regards,
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 + SPI only work one cycle
« Reply #15 on: August 05, 2019, 02:25:48 pm »
Malloc uses heap, do you have heap enabled and assigned?
Does Malloc return a usable pointer and not NULL?
Do you even need to use malloc, could you point to a static allocated aligned array of size (EPD_WIDTH * EPD_HEIGHT / 8 ).
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14429
  • Country: fr
Re: STM32 + SPI only work one cycle
« Reply #16 on: August 05, 2019, 02:28:01 pm »
Ouch.
* Does the MCU even have enough RAM for this malloc?
* Is malloc called only once or repeatedly without ever freeing memory?
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #17 on: August 05, 2019, 02:38:24 pm »
Ouch.
* Does the MCU even have enough RAM for this malloc?
* Is malloc called only once or repeatedly without ever freeing memory?

My program use 65% of the RAM. When i compile the code, i don´t get any warning about space.

If i don´t write in main(), the malloc is called one in each loop.

Malloc uses heap, do you have heap enabled and assigned?
Does Malloc return a usable pointer and not NULL?
Do you even need to use malloc, could you point to a static allocated aligned array of size (EPD_WIDTH * EPD_HEIGHT / 8 ).

It is my first time that i use malloc. I have not enogh knowledge about this. I need learn more about it.

Thanks,
Regards.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14429
  • Country: fr
Re: STM32 + SPI only work one cycle
« Reply #18 on: August 05, 2019, 03:04:03 pm »
My program use 65% of the RAM. When i compile the code, i don´t get any warning about space.

Indicated RAM usage at compile time can't take dynamic allocations into account AFAIK. So infer that you only have 35% RAM left for your malloc().

If i don´t write in main(), the malloc is called one in each loop.

You can't just keep allocating more memory without freeing some first. If you keep calling malloc in a loop without calling a corresponding free(), you'll be running out of memory in no time. That's called a memory leak.

Just declare and use a static array instead.
malloc should be used very cautiously in embedded code, doesn't seem to be justified here, and in any case, you should definitely learn how to use it before considering using it. Stick to static arrays for now.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9888
  • Country: us
Re: STM32 + SPI only work one cycle
« Reply #19 on: August 05, 2019, 03:54:21 pm »

My program use 65% of the RAM. When i compile the code, i don´t get any warning about space.

If i don´t write in main(), the malloc is called one in each loop.

It is my first time that i use malloc. I have not enogh knowledge about this. I need learn more about it.

Thanks,
Regards.

All you need to learn is to NEVER use dynamic allocation in embedded processors with limited RAM.  My rule is to never use it at all!

The GCC string functions use the heap therefore sprintf() and, by extension, printf() use the heap.  In most cases, the programmer has to implement sbrk() (the allocator) and if you see sbrk() in the linker map, the heap is likely being used.  For many libraries, sbrk() and some file functions are contained in syscalls.c.  Get rid of it!

Static allocation is the way to go because the data either fits in the memory or it doesn't but that is known at link time.  With the stack growing down and the heap growing up, they sometimes collide.

There are some lightweight versions of printf() that don't use the heap.  I grab up my K&R "The C Programming Language" book and copy the various string functions into my own library.  I don't get as far as printf() but I do have the basic functions and conversions like itoa() and atoi() so I'm pretty much set for debugging output.

I avoid the heap at every opportunity!
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 + SPI only work one cycle
« Reply #20 on: August 05, 2019, 07:10:39 pm »
When applied correctly dynamic memory can serve great purpose. Let's not lose ourselves in a discussion about the morality of dynamic memory on embedded systems.

I think we've now pointed Grafi in the correct direction for a while.

Try
Code: [Select]
unsigned char frame_buffer[(EPD_WIDTH * EPD_HEIGHT / 8)];
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #21 on: August 05, 2019, 07:27:02 pm »
Hi,

Sorry i can reply before. I have check the option of static buffer (as Jeroen3 say) but i have not enogh RAM memory. The buffer needs 5000 bytes if i am not wrong. The microcontroller has 8kb o RAM and i comment some debug messages. Now i have 4.48kb of free memmory. If i use the malloc option, i can complile. The code works as expected for now. I will be watching the code for the next hours.

Next time i will need to work with more RAM.

Thanks for the comments, they are very usefull to the next steps.
Regards,
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 + SPI only work one cycle
« Reply #22 on: August 06, 2019, 06:47:09 am »
Malloc is also unable to allocate enough memory. The last bit of screen will be outside the SRAM. This may or may not create a fault.
And then it makes sense it only works once, because the chip will be in the hardfault handler when it writes to the non-existing memory.

Or worse, malloc does allocate memory, completely overwriting the other parts of your application.
 

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: STM32 + SPI only work one cycle
« Reply #23 on: August 06, 2019, 07:17:16 pm »
That's absolutely wrong with using malloc/free in embedded systems, if one knows what they are doing and is careful with what they are doing.
// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 

Offline grafiTopic starter

  • Contributor
  • Posts: 23
  • Country: es
Re: STM32 + SPI only work one cycle
« Reply #24 on: August 08, 2019, 07:08:27 am »
Malloc is also unable to allocate enough memory. The last bit of screen will be outside the SRAM. This may or may not create a fault.
And then it makes sense it only works once, because the chip will be in the hardfault handler when it writes to the non-existing memory.

Or worse, malloc does allocate memory, completely overwriting the other parts of your application.

For now, all works well. I am not using all screen.

Thanks all for your time.
Regards,
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf