Early morning planning!
Whenever dealing with applications that will be depending on high performance it is wise to check out bottlenecks asap. This apply to all risk scenarios based on assumptions, simply check them out first because they might force your next step. I have three checkpoints coming up:
(1) Speed of SPI with a Hat involved. I am fairly confident on this due to the nature of SPI.
(2) Sampling speed on STM32 and 5LP. I am actually expecting 5LP to be capable of sampling GPIO at a very high frequency, but I might be wrong. Dealing with programmable logic I was hoping for far more than 10Msps, but reading the datasheet I get an impression that this might be a wrong assumption. SPI on a STM32F405 is 42Mhz and GPIO 84Mhz, ADC 2.4Mhz etc. I fail to see similar numbers on the 5LP. I know I am comparing a Cortex M3 with a much faster M4, but I expect a lot of performance from Programmable Logic. The reason for this is because I am hoping I can use the logic to buffer as I sample using the logic’s clock speed like I would have done on a FPGA. But, I realise that I might be in error on this!
(3) Speed of graphics. Raspberry PI is fully capable of full screen animations at 50fps using the GPU’s, but we need to verify that the graphics library we use will support this. I know I can do 50fps on Raspberry PI with GPU’s, but can I do so with the graphics quality I want?
I did a GPIO Hat earlier and due to the pin compatibility on STM32 I can just replace the M3 with a STM32F405 and use this to sample GPIO pins. This will act as a low cost Logic Analyzer. My expectation is that I can sample in a Close Assembly loop, apply smart filter and trigger Logic and use DMA to transfer buffers to Raspberry PI. The sampling speed will depend on MCU speed. 10Mhz means I need a maximum of 16 instructions per sample on a 168Mhz RISC. I know I am on deep water on this, but we will see. I am also curious as to what sampling speed I can achieve with a M3 only. It will be funny to test this regardless.
Doing the same on 5LP is also very easy due to the breadboard friendly dev kit at 10.- USD. Time to do some testing.
Cypress released a Cortex M3 MCU some time ago that caught my interest. I ordered two devkits costing 10.- USD each and all in all their concept actually impresses me. Cypress have for years released MCU’s that are referred to as “PSoC” (Programmable System on Chip). The difference is that a 5LP includes a ARM MCU, but very little I/O by default as this will have to be coded in Verilog logic. Basically it is a merge of a MCU and a programmable digital- and analogue- sub-system.
What caught my attention was their free IDE containing a C compiler and a EDA to program logic in block diagram form. This just had to be tested and I am always impressed by something as complex as this being made so easy. I am also pleased to see that all required tools are free so I will advice to pick up a kit and start hacking!
Comparing 5LP with STM32F105 (as an example) is like comparing apples and bananas. The STM32 comes with a pre-defined list of I/O and if you only need standard I/O it will be far more cost optional. But, the issue with 5LP is that it can do so much more than standard I/O.
The included plug&play blocks also comes with C libraries, but testing a simple UART I must admit that the C library did not impress me. Cypress (the Company) did however impress me because as I communicated my thoughts back to Cypress I was contacted by several people in their organization to discuss my opinions. Obviously the company care a lot about their products and customers.
I have three applications in mind for 5LP:
- An advanced GPIO Hat with programmable Logic.
- An Oscilloscope.
- A Logic Analyzer.
I must however admit that while I am fairly comfortable with STM32 this MCU is so complex that it put my skill-set at a test. I need a far better understanding of it’s capabilities before I start any project with this one.
One of my interests for some time have been how to create a MSO (Mixed Signal Oscilloscope). I have several scopes, but I lack a Logic Analyzer on any of them.
My first thought was to bit-bang the GPIO of Raspberry PI directly, but as I looked into this I realized that I would not get much speed out of it. The issue is that Linux can’t really sit around bit-banging as it got other tasks as well. To actually do this you would be better of without the OS running.
They have created a 14 channel, 100Mhz Logic Analyzer on Beaglebone Black, but that makes heavy usage of the 2 embedded PRU’s. It would make sense if we could use one core to bit-bang, but I am not sure how to do that without replacing Linux itself.
One channel is typically 2kb of display data for a frame on a 1920×1024 screen. To be ideal we need a minimum of 25 frames per second (fps) and preferable 50 fps. That is ca 50-100Kb per second eight channels. Or more exactly 200Kb/s for 16 channels which again is ca 1.6Mbps and well within what we can expect from the SPI if we use a Hat.
A STM32 F4 can sample rather fast. Clocking at 180Mhz it should be able to do intelligent sampling of 16 channels up to 10M samples per second if the write the code correctly. This will obviously include some logic to trigger a sample run and upload it. As uploading is done by SPI from a DMA it don’t lake MCU time and we just need to fill a buffer and send it. This Application will need to be tight.
10Mhz will be good, but the hard fact is that most of my needs are covered with 1Mhz. The additional win here is that we get to program the analyzer logic so we can add recognition of things like CAN, SPI, I2C, UART etc. I am considering two MCU’s for this job:
STM32F405 ticks at 180Mhz and is a M4. Cypress 5LP is a ARM M3 ticking at 80Mhz, but it contains programmable logic that might significantly increase the sampling frequency if used correctly.
The drawing above illustrate the different components used to achieve a complete application with HMI. We have briefly discussed the internals of the Hat (left) consisting of hardware interfaces or communication drivers, a IO configuration and the SPI driver communicating with Raspberry PI.
RPI have the master SPI driver and two new components that are part of it’s easyIPC server. One is a Data Repository. Basically a database over available features and data associated with it. This database will be in memory.
API Server allows easyIPC to be connected to multiple clients either on the same Raspberry PI or from a different computer. This connect your HMI application to easyIPC as if it was a database of information.
HMI framework is basically the GUI used to visualize real-time data and add user Interfaces.
This is a very brief drawing sop we will consolidate it as we finish it.
Just moved a MicroSD card from a Raspberry PI 3 over to Zero and it just works. The only challenge I have is cables for keyboard/mouse + I use a HDMI adapter cable that is a bit unstable.
Nice to know because the easiest way to develope for the Zero is probably just to use Raspberry PI 2/3.
Wow, I actually got a Zero in my hands.
I have been holding back production of new Hat’s because I wanted to check with zero drilling holes. I am not sure where I got my dimensions from, but I was actually 1 mm off.
Dealing with embedded solutions you also need to deal with HMI. A majority of HMI will always be on displays so having the Raspberry PI as base is quite nice. It is very capable of supporting our GUI needs, but how do we program it?
A friend of mine uses Python with various libraries. I will do a Python demo, but I have something else in mind. I wrote an entry about the Nextion HMI solutions from www.iteadstudio.com earlier. They use a STM32 and a TFD combined with a designer. You create a HMI with objects that later can be communicated with using a serial port. I bought one of them for testing and I am quite impressed over the concept thought I will add that their solution have a few fallbacks.
I will always argue that source code must exist in human editable form. A HMI graphical design is no exception as it is source code with scripting logic embedded. I would have used XML for this purpose. The concept is not new as it has been used in various embedded solutions for years. The most common is PABX telephones with displays.
The issue with HMI is that using more advanced solutions like Qt or similar actually require a bit of knowledge. Most embedded developers or makers focus their knowledge differently and writing an advanced GUI application is often outside their comfort zone. They are simply not willing to spend the time required to master things like Qt. But, even if you master these skills you will find that solutions like Nextion take away a lot of hours if you can accepts the limitations.
I would like to put the GPU’s on Raspberry PI to some usage, but having looked into OpenGL I must admit that this is not an easy task. Using Qt makes it easier, but using Qt itself on Raspberry PI is a bit of an issue even if you forget the skillset issue most will have. Just for the record it actually exist other solutions than Qt as well.
What I would like to do is to create an advanced HMI solution for Raspberry PI using the concepts described above. You simply outline your HMI in XML that is loaded into an application that communicate with easyIPC. The Application + Your XML becomes Your HMI. Embedding this into a stand-alone executable is doable. The graphical designer part is the easy one in my case since I have made numerous flow-chart alike tools in the past. My only remaining puzle is to select a graphical library for C/C++ on Debian to build this in.
It’s some years ago I wrote my first XML parser. The story was that I was doing a communication interface and discovered that the interface sent XML messages. In two days I wrapped up a small XML parser as a library and got the task done.The technique I used was a classic recursive descent parser.
The parser I will introduce here uses a very different technique that is much, much faster and smaller. This is a state engine parser. I was a bit bored a few years back and decided to test out the idea of a parser technique where you consider xml as a state engine with characters as events. Using a lookup table to categorize characters the technique ended up in a very fast parser in less than 300 lines of C++ code. This is closer to a SAX parser than a DOM parser and will parse a file or a communication stream byte for byte. The combination of low footprint and close to no RAM usage enable the parser for small MCU’s like Arduino.
The interface is callback functions with parser content. The parser will parse XML with a speed comparable to strlen(), but you need to parse the content. To help you get OnBeginGroup, OnParameter, OnEndGroup etc. We will be using this parser a lot due to the usability of XML.
Alf & Vegard’s RISC processor was created while they where students at NTH in Trondheim, Norway back in 1996. It has since become one of the most popular MCU’s worldwide. It’s foremost competition was Microchip’s PIC series, so it’s ironic that it’s now Microchip that own Atmel (and AVR). Even more ironic that while Atmel ruled we received rumours from the team that Atmel was in the process of ditching their 8 bits. Now we see new 8 bit AVR’s hitting the marked again.
Happy 20 year anniversary!
Modern CAN uses two formats referred to as CAN 2.0A and CAN 2.0B. These again can use at least two wired solutions. The one we discuss here is the high speed version using twisted pairs. Two newer relatives to CAN that require either a logic circuit or MCU with special port support are CAN FD and FlexRay.
CAN eXtended uses CAN 2.0B that often is called “extended frame”. CAN 2.0A uses a 11 bit arbitration field as ID, while CAN B add’s another 18 bits to this. CAN eXtended uses these 29 bits as follows:
- – 2 bit priority
- – 1 bit message direction
- – 8 bit device id
- – 10 bit stream id
- – 7 bit sequence number
- – 1 bit message continue indicator
As CAN only can carry 8 bytes on a single message we need to use several CAN messages for some of the larger easyIPC messages. To do so we take advantage of the 1 bit continue indicator. If cont = 0 we know this is a new message with a Message ID in the first byte of the payload. If we need to use several CAN messages as an envelope we add a envelope header and an envelope tail:
PID is 16 bit parameter ID. PID=0 is Envelope head, PID=1 is Envelope Tail. Envelope Head contain a 8 bit parameter indicating number of messages that at minimum is 2 and maximum 255. The first message will have cont flag =0, the rest will have cont flag =1 to indicate that this is not a message head.
Envelope Tail contain a 16 bit Envelope CRC which is the CRC for the total message payload.