emWin Bus Fault

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
EdHa_4455331
Level 5
Level 5
25 replies posted 25 sign-ins 10 replies posted

I am trying to use an ST7789 interface with emWin and  FreeRTOS on a Cypress POC 6 system. This is my first project using emWin.


My code is crashing out with a bus fault error. After initializing the GUI system, I did a simple GUI_DrawLine( 0,0, 1,1). The code gets to the step shown in the attached FatalStep.png. When I do a "step into" on that step, the code encounters a bus fault - see BusFault.png.

To the best of my knowledge my code goes through the initialization sequence call for in your documentation. So at the moment I have no idea why this code is crashing out. I could probably run down the problem myself if I had the source code, but I don’t, so sthis is causing me some schedule/deadline headaches.

I have already asked about this on the emWin forum, but no one has yet proposed a solutions. So I’m getting a tad desperate.

Can you provide any suggestions to fix this?

Thanks,

Ed H.

0 Likes
1 Solution

I am happy to report that I made it work. Although the comments in various files in emWin v5.46 say that it only supports up to PSOC 5, I have an LCD display working with a PSOC 6 and a ST7789V graphics expander connected via an SPI interface.

But you do have to push several planets into alignment to make it happen. 🙂

View solution in original post

0 Likes
31 Replies
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

Hello,

Please find the code example here which basically interfaces with CY8CKIT-028-TFT Shield which has a display with the same ST7789 driver. So, the driver files will remain the same, you can make use of this in your project.

The code example however isn't using FreeRTOS, so you will need to add it. It's tough to say off the bat what might be resulting in the error without the project. Please attach it so that we can have a closer look.

Please also provide some details of the project you are working on. The kind of display (attach datasheet), the psoc6 device/kit you are using, what the requirements are and we can help you with that

Regards,

Dheeraj

0 Likes
lock attach
Attachments are accessible only for community members.

Good afternoon Dheeraj,

I wasn’t sure whether you wanted me to respond directly to you or the forum, so I decided to start with you first. There is nothing really confidential in the stripped down version that I have attached. So you can put it on the forum if you want to.

Thanks for the suggestion, but the code example you suggested weren’t much help. It doesn’t use FreeRTOS and it uses a parallel interface to the ST8889.

I am working with a CYBLE-416045 BLE module.

The project is attached. The BIG problem is that I have to use an SPI bus to interface to the ST7789. There is not a built-in component in Psoc Creator for the serial version of the interface. So the system will not auto-generate all the interface files that I need.

I did two things: 1) I read the emWin manual and forums to try get a good understanding of everything I needed to do a custom SPI interface, and 2) I used a dummy project to see what Psoc Creator would generate for a parallel interface. I then tried to combine those two inputs into the attached project.

At the moment, the display doesn’t matter. I haven’t even attached it to the CYBLE module yet. But the absence of a display is NOT the problem. The code locks up before it tries to read or write to the display.

Any help or suggestions would be immensely appreciated.

Thanks,

Ed H.

0 Likes
lock attach
Attachments are accessible only for community members.

Ed H,

I'm looking at your project now.  I still don't have a direct clue for you.  I do have a few questions:

Are you using the CY8CPROTO-063-BLE kit as a base for your project?

Have you ever created a FreeRTOS program on a PSoC before?

Was there a version of this project that was working before?

Here's what I've found so far:

Here's what the stack looks like before the crash:

pastedImage_3.png

pastedImage_4.png

xPortStartScheduler in port.c line 367 is where you apparently fall off the rails.

Attached is another project that uses the EINK display and the FreeRTOS.  I retargetted it for the CYBLE-416045-02 module but you will have to reassign the pins as necessary.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
lock attach
Attachments are accessible only for community members.

Are you using the CY8CPROTO-063-BLE kit as a base for your project?

I am using an CYBLE$-416045-EVAL board as the base.

Have you ever created a FreeRTOS program on a PSoC before?

No.

Was there a version of this project that was working before?

I actually have developed a large amount of real time code that works quite well and uses a UART port for the console output. But I have never been able to get a call to emWin to work. I stripped all that out of the version that I sent to you.

Here's what the stack looks like before the crash:

Hmmm.. you didn’t seem to reproduce my results. My before/after call stacks showed that the system crashed out in the WM_ActivateClipRect() function.

(see attached).

Thanks,

Ed H.

0 Likes

Ed,

It's possible that your code might go a little further than mine.  This might be because you can communicate (at least in part) to the display.  I have no display therefore there is no feedback to provide the code.

Can you put a scope on the SPI lines and verify in part that the Display is receiving and possibly responding to SPI commands?

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

I repeat: I do NOT have a display yet. I put breakpoints where the code SHOULD try to communicate with the display. The code never gets there. Therefore, the problem most likely has NOTHING to do with communications with the display.

0 Likes

Ed,

I've ordered a ST7789. I hope to get it in about a week.

I actually have developed a large amount of real time code that works quite well and uses a UART port for the console output.

Did this code run under FreeRTOS?

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Did this code run under FreeRTOS?

Yes.

0 Likes

Ed,

I haven't given up on you or your issue.

I've done some deep debugging and found the following.  Here is a hierarchical breakdown where the "Bus Fault" occurs.

  • Gui_Drawline  ...
    • WM_Init_IVSearch  ...
      • WM_ActivateClipRect ...
        • 0x100868EA ldmia    r0!, {r1, r2}

Within WM_ActivateClipRect there is a call to an assembly "ldmia r0!, {r1, r2}".  Executing this line causes the Bus Fault.

Obvious Reason:  ldmia command loads registers r1 then r2 with the 32-bit contents found at the address pointed to by r0.

Since r0 = 0x09 (r1 = 0x80242c8 r2 = 0x01)  There is no accessible memory at address 0x09.  This causes a Bus Fault.

What ever is loading r0 at this point is not initialized properly.  I'm still in the process to find the reason but without knowing what WM_ActivateClipRect function arguments are, it is a bit difficult.  (Seeger did not include the source code but they did include the address labels in their object code.)

Here's a pic of the code and registers and memory @ address 0x09 just before the Bus Fault.

pastedImage_10.png

More Info:

r0 is getting set to 0x09 in the branch to GUI_ALLOC_LOCKH.  (I assume this is GUI allocate a Lock on the Heap)

In GUI_ALLOC_LOCKH it branches to GUI_ALLOC_h2p (I assume this is GUI allocate heap to pointer).

GUI_ALLOC_h2p is where the return back in r0 - 0x09.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Ed,

Even after changing the heap type to other types I still have the same problem.

One thing I noticed.  The version of emWin (V5.46) you're using is specified for the PSoC3 and PSoC5.  The PSoC6 middleware version is V5.48.   Is it that this release of emWin not valid for the PSoC6?

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

The version v5.46 version of emWin that I am using arrived as part of the PSoc Creator 4.3 package. I haven’t been able to find a place in the Cypress website where I can switch to a particular version of emWin. Can you please give me a link to where I can download v5.48?

Thanks,

Ed H.

0 Likes

Ed,

To my understanding, V5.48 is only available when it is built as a ModusToolbox project.  In ModusToolbox 2.1, there is no UDB support.

Len

PS:  I'm still trying to find out why it's not working under V5.46.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Ed,

I may have some additional info.

Cypress has an example of a PSoC6 driving a ST7789.  The example project is called: CE223726_EmWin_TFT_Display_ST7789.

I recommend you take a look at it.  It does use emWin V5.46.

There are some differences to your project.  The example doesn't use FreeRTOS (no OS) and the ST7789 is a parallel interface instead of  serial.  These differences may be minor.

In examining the example code to yours I noticed the following:

  • The example only calls GUI_Init(). GUI_X_Config() and LCD_X_Config() are never directly called.  I suspect they are called indirectly through GUI_Init().  This might explain why running GUI_Drawline() eventually crashes because something wasn't setup properly.
  • When I replaced your GUI_X_Config() and LCD_X_Config() calls with GUI_Init() it crashes in GUI_Init().  However debug tracing where it crashes I found your _InitController() function in LCDConf.c has an assert(false) which causes the crash.  In the example, _InitController() actually has code in it.   I believe the app designer is required to place meaningful code here to initialize the LCD controller. 
    When I removed MasterSpi_Start() from DisplayManagerTask() and placed it in _InitController() and ran the code, GUI_Drawline() gets continually executed in the for(;;) loop in the DisplayManagerTask().  NO CRASHES!!!

Consider the following changes recommended above.  Besides moving MasterSpi_Start() into _InitController(), you may have to add some LCD SPI commands to initialize the ST7789.  This should be done in this routine.

Additionally reconsider whether DisplayDriverTask() is actually needed.  It appears redundant.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

I followed your recommendation and have gotten past the crash issue.  I think I have now all the puzzles pieces in place except for one.

A little history: I got off track with GUI_Init() because but emWin was crashing out when I first started trying to use it. While trying to debug that, I started trying to replace it with the sequence of functions it called (GUI_X_Config and LCD_X_Config) in order to be able to trap the crash. It turned out that if you include both FreeRTOS and emWin in the Peripheral Driver Library, the "as delivered" version of GUI_Init() has a bug (so to speak). To use emWin with FreeRTOS, a call to the function GUI_X_InitiOS() has to  be added to GUI_X_INIT  to create a mutex used by emWin (and you have to enable mutexs in FreeRTOS). Once I had figured out, I just kept going and didn't revert back to just using GUI_Init().

Now, the last aggravation is this v5.46/v5.48 issue. The fact that PSOC Creator 4.3 does not support emWin development on a PSoC 6 system came as a complete surprise to me. Can you please provide me with a link that I must have missed early on that tells me that?

My company really likes the both PSoC 6 and the Creator IDE and now has several on-going projects using both,  but mine is the only one with an LCD (and so needs emWin). My management is not happy with the prospect of having to develop projects under two different IDEs (Creator and Modus Toolbox). And of course, since I am the messenger, I get the blame. So, is there any way possible to get emWin v5.48 merged over into Creator 4.3, or am I absolutely forced to move to Modus Toolbox for now?

Thanks again,

Ed H.

Ed,

Thanks for the info about the potential bug in GUI_Init().

From what I can tell,  emWin is supported on the PSoC6 however at this time only V5.46 is the release that is available in Creator.

I don't know if Seeger has plans to support later releases in Creator.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

I am happy to report that I made it work. Although the comments in various files in emWin v5.46 say that it only supports up to PSOC 5, I have an LCD display working with a PSOC 6 and a ST7789V graphics expander connected via an SPI interface.

But you do have to push several planets into alignment to make it happen. 🙂

0 Likes

Ed,

I'm happy to hear you've got it working.

You travails with the emWin have inspired me to try my hand at it.

I've taken the CE223726_EmWin_TFT_Display_ST7789 project I mentioned earlier for a parallel interface and have converted it to a 4-wire SPI interface.  I've got the emWin conversing with the SPI pushing commands to the ST7789.  The output looks correct.

I'm waiting for the LCD display I ordered to come in.  It should have been here 3 days ago.

I hope I can call on you if I have some questions.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

If you have the SPI outputs correct, you are most of the way there.

The only other tricky part is doing whatever needs to be done for the ST7789 initialization in _InitController(). If you can’t find an example initialization sequence for your LCD, I will be happy to share the one I used.

One more possible pitfall: emWin sometimes uses WriteM8_A1 to send a full row of pixels at a time (as with GUI_CLEAR()). I found that the ST7789 controller seemed to needed a short pause between being delivered each row through sequential calls to WriteM8_A1. You may need to include delay like at the end of WriteM8_A1 if you seem to be getting incomplete display updates.

Glad to hear that you were able to get it resolved. We have a lot of examples using the parallel interface but none with serial. It would be great if you could share your project with the community to help other community users wanting to interface using SPI.

And just to clarify, emWin v5.46 is fully supported by PSoC6. It is just that the library for PSoC3/4/5 was distributed as a standalone package and for PSoC6 it is part of the PDL library.

The initialization sequence for the ST7789 controller should mostly be the same as the code example, changes might be if there is a command to set the interface as serial (3-wire, 4-wire) or parallel (RGB, 8080 etc.).

And yes, I agree that interfacing serially with EmWin is harder than parallel because there is no component we provide like GraphicsLCDCtrl component to do this automatically. It needs some effort on the user side. Thank you for your feedback and interest in Cypress products. I will pass this feedback on to the internal team for the evaluation.

Regards,

Dheeraj

0 Likes

Ed,

I was planning on using the initialization sequence in the example.  If you want to share yours maybe it's better.

Thank you about the warning of possiblly needing the delay with the WriteM8_A1 command.  I'll keep my eye out for it and trap for it.

I notice the ST7789 in the 3 and 4-wire SPI interfaces use a "dummy clock cycle" just before reading the data on the commands that are retrieving data from the display.   I was planning on performing 16 bit read(s) and left shifting the data through the dummy bit from the dummy clock.

Lastly,  the ST7789 SPI graphic display I ordered (which I still haven't received) is the DM-TFT13-377 from a company DisplayModule.

What SPI ST7789 Display did you end up using?

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

First, WRT the dummy clock cycle on reads: I don’t think emWin ever reads anything back from the display, so I don’t (yet) have any experience in that department. I may have to add a read back later to the power-on-self-test to be sure the display seems to be at least conversant with the MCU.

Another source of confusion – I am using a 240X320 display mounted in a landscape orientation. In the actual LCD hardware, the X-axis is the short dimension (as if the display was in a portrait orientation). BUT… the auto-generated defaults for some options in emWin flip the orientation so that all the calls to emWin functions act like the X dimension is along the long dimension (landscape orientation) – which is actually what I want. But the initialization of the ST7789 controller doesn’t know about the flip – so the columns and rows (x and y) seem flipped when you are talking directly to ST7789 controller (like during the initialization sequence) as opposed to when you talk to it indirectly through emWin functions.

The init sequence shown here is probably about as bare bones as you can get. I mimicked the delays from various other examples I saw on the web. I really couldn’t find anything in the controller’s documentation to support them.

// LCD Reset control line high (inactive)

Cy_GPIO_Write(LcdResetN_0_PORT, LcdResetN_0_NUM , 1);

vTaskDelay(2);

// LCD Reset control line low (active).

Cy_GPIO_Write(LcdResetN_0_PORT, LcdResetN_0_NUM , 0);

vTaskDelay(10);

// LCD Reset control line high (inactive)

Cy_GPIO_Write(LcdResetN_0_PORT, LcdResetN_0_NUM , 1);

vTaskDelay(150);

WriteCommand(ST7789_SLPOUT); // Sleep out

WriteCommand(ST7789_COLMOD);

// 65K RGB interface (5-6-5), 16 bit/pixel.

WriteData(0x55);

vTaskDelay(10);

WriteCommand(ST7789_MADCTL);

WriteData(0x08);

// Column address set

WriteCommand(ST7789_CASET);

WriteData(0x00);

WriteData(0x00);

WriteData(0x00);

WriteData(240);

// Row address set

WriteCommand(ST7789_RASET);

WriteData(0x00);

WriteData(0x00);

WriteData(320>>8);

WriteData(320&0xFF);

WriteCommand(ST7789_INVON);

vTaskDelay(10);

WriteCommand(ST7789_NORON);

vTaskDelay(10);

WriteCommand(ST7789_DISPON);

vTaskDelay(10);

Ed,

Thanks.  When I finally get my display, I'll give your initialization sequence a try with the exception:

  // Row address set

  WriteCommand(ST7789_RASET);

  WriteData(0x00);

  WriteData(0x00);

  WriteData(240>>8);

  WriteData(240&0xFF);

Since my display is a 240x240.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Ed,

I FINALLY got my SPI interface (4-wire) ST7789 display.

I tried both your initialization and the initialization that came with the example project.  No luck.

I checked the SPI comm.  It's format is correct.

At this point, I'm trying to validate that the HW sent to me is in operational order.

What's the simplest I can do to provide it?

I took your "WriteCommand(ST7789_INVON);" command and sent "WriteCommand(ST7789_INVOFF);" instead.  Still no change.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Well, flipping from INVON to INVOFF should have flipped the screen from all black to all white. So this should have been a pretty good quick and easy test.

So that raises the first question: How does you display manage the back light and is it on? The backlight is often handled through separate control pins. Since my particular implementation has its back-light is hard wired to “always on”, there is no mention of setting up the backlight in my initialization sequence.

I ASSUME that you are also trying to run under FreeRTOS. If you are not, you have to do some calls to GUI_Exec() yourself (although the INVON/INVOFF shouldn’t have needed that).

I assume your display also has a chip enable control signal. You said the SPI format was correct. Did you also check the chip enable line was being driven correctly during an SPI exchange?

Did you also implement the D/Cx control line? This control line is needed in addition to the SPI lines. Did you also check this line when you were monitoring the SPI lines?

The display usually has some hardware pins that configure the interface to be either 8 bit parallel, 16 bit parallel, or SPI. Are those pins configured correctly?

If all of the above checks out, then any simple command should work. For example:

GUI_DispString( “Zombies are coming!”); // “Hello world” is SO boring. ☺

And if none of that fixes it, then you are now living the life of an embedded programmer.

Hope one of these suggestions helps.

Ed h>

0 Likes

Ed,

Thanks for taking an interest in helping me out.

So that raises the first question: How does you display manage the back light and is it on? The backlight is often handled through separate control pins. Since my particular implementation has its back-light is hard wired to “always on”, there is no mention of setting up the backlight in my initialization sequence.

Although I do have a control pin attached to the backlight, I left it always ON.  I can see the backlight is ON.  It's quite apparent.

I ASSUME that you are also trying to run under FreeRTOS. If you are not, you have to do some calls to GUI_Exec() yourself (although the INVON/INVOFF shouldn’t have needed that).

Actually I'm trying to run the "CE223726_EmWin_TFT_Display_ST7789" project almost "as-is" (with substitutions of a SPI interface instead of the parallel).  This project is NOT FreeRTOS.  I'll look into the GUI_Exec() call.   However, I am getting to the _InitController() routine where the calls to init the Display controller are getting executed.

I assume your display also has a chip enable control signal. You said the SPI format was correct. Did you also check the chip enable line was being driven correctly during an SPI exchange?

I'm controlling the SPI_CS manually to create a proper active low pulse for the entire SPI command and data sequence.  Now here's where the "bone of contention" may be.   The SPI display I'm using (DM-TFT13-377) chose not to support the SPI_CS line to the board.  In their implementation they are tying the SPI_CS line to GND.   According to Arduino posts using this display, they appear to have gotten it operational.  My understanding is that the ST7789 IC is also using the D/Cx line (which is supported on my design) to determine if the SPI_MOSI data is a command or data.  If it is a command, then this is the "equivalent" of a SPI_CS going active low prior to the command.

If my other experiments fail, I will take the Backlight control signal and wire it to the SPI_CS and leave the Backlight on permanently.

Did you also implement the D/Cx control line? This control line is needed in addition to the SPI lines. Did you also check this line when you were monitoring the SPI lines?

Yes.  I set this line manually in my code.  According to the ST7789 4-wire timing spec, this line is checked by the ST7789 before the LSb is transferred.  I set the D/Cx bit to the correct bit for the entire 8 bits of the command or data.

The display usually has some hardware pins that configure the interface to be either 8 bit parallel, 16 bit parallel, or SPI. Are those pins configured correctly?

These pins on the ST7789 are not accessible to the user.  I have to assume that there are hard-set to 4-wire SPI by the manufacturer of the display board.  Otherwise I'm SooL.

I'll try the GUI_DispString() but I'm not giving much hope since the neither INVON or INVOFF make a difference in the display.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Ø According to Arduino posts using this display, they appear to have gotten it operational. My understanding is that the ST7789 IC is also using the D/Cx line (which is supported on my design) to determine if the SPI_MOSI data is a command or data. If it is a command, then this is the "equivalent" of a SPI_CS going active low prior to the command.

Hmm… that doesn’t sound exactly right. To the best of my understanding, the D/Cx line has nothing to with the CS function. The purpose of the CS function is to allow multiple peripherals to share the SPI bus. If a particular chip’s CS line is not low, then that chip assumes the MCU is talking to a different peripheral and ignores the exchange. Now, if your LCD has CS tied to GND, that’s ok. It just means it can’t share the SPI bus with any other peripheral ICs.

The D/Cx line is sort on an extra auxiliary input signal. If it is low when the LCD receives bytes over the SPI channel (and the CS is low) then the graphics controller will interpret those bytes as “command” bytes (usually targeting control registers). If D/Cx line is high when the LCD receives bytes over the SPI channel (and the CS is low) then the graphics controller will interpret those bytes as “data” bytes (and they are usually pixel data for a row on the LCD).

0 Likes

Ed,

You are correct that the SPI_CS is commonly used for signalling to different SPI devices on the same SPI bus which one is currently being communicated.  In my case, there is only one SPI device on the bus.

On other SPI devices that I've interfaced, the SPI_CS is also used to qualify the beginning of a SPI sequence where the first byte is the command/addressing sequence and the following bytes are the data.  In these instances, the inactive High to active Low of SPI_CS resets the SPI device internal state machine to wait for the addressing/command byte since there is no equivalent to the D/Cx pin.

In the ST7789 IC interface the D/Cx pin serves a similar means of resyncing to the addressing/command phase.

When I viewed a few YouTube tutorial videos using this same DM-TFT13-377 display, there was NO mention of modifying the display PCB to connect the SPI_CS signal to the Arduino.  link: TFT 240x240 ST7789 SPI with Arduino - ICStation - YouTube

I have an Arduino and I could following one of the tutorials to see if I can get the display working.  If I can, I can monitor how the Arduino is communicating with the display to see what I might be missing.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Ed,

Update:

I have the display.  It's non-operational on my PSoC.

I used the Arduino and examples available.  It is non-operational on the Arduino too.  At this point, I'm assuming I have received a defective display.

What display are you using?

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Not totally sure since the hardware guys ordered it and just handed it to me. And it doesn’t seem to have a model number on it. But it is an Adafruit 2.0” 320X240 TFT module.

0 Likes

Ed,

Thanks.  I'll look it up on the Adafruit site.

Len

My guess is that you might have this display with a microSD slot.

pastedImage_0.png

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Ed H,

I get the same issue in the same location in the code as you.  This could be because I don't have your display.

In your Display tasks you are initializing the GUI_X_Config and LCD_X_Config code.  Once for each Task.

I don't know if this is a good or bad thing to initialize the HW twice.  I disabled one of the tasks and saw no improvement.

It's possible that the HW is not being initialized properly.  For me I don't have the HW, this might be why I crash at GUI_DrawLine( 0,0, 1,1).

Since you need to communicate to the display by SPI you might what to test if the SPI is operating by adding some SPI unit test code to push data out (MOSI) of the SPI port and see that data is coming in (MISO).  You might have a HW wiring issue.

The issue you are seeing is that the GUI_DrawLine() is provided by Seeger in the emWin library as object code ONLY.  That's why you cannot easily debug the issue.  The source code for this function is not provided. That's why the stack output shows <signal handler called()> as function and "??????" as the file.

If you're really in the mood for a deep-dive, you can jump into the GUI_DrawLine() function in assembly code.

Hopefully Seeger who created emWin can be of more help.

I'd check with them if they have example code that might be close to the interface of your display.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes