PScript – part 1 – Core language

The first programming language I learned back in 80’s was BASIC. BASIC was never considered a professional language, but the more modern Visual Basic was and is still in heavy usage as both programming language and scripting language. Python have taken over for a lot of scripting and is making it’s way into heavier applications these days, but Python requires a lot of Flash to be running.

My own plans for PLAIN is stalling a bit due to it’s complexity, but I often wondered how much would it take to create a scaled down scripting language that can be used embedded. I recall 8052AH having PBASIC as far back as 1979 and for those who don’t know it BASIC was for years the language that ran on most computers in the world. Computers used in washing machines and coffee tractors etc.

The rationale of this is easy to see in Arduino’s wire lib. It is popular because it is easy to blink a led and many applications only need a few sensors and digital outputs.

So, how difficult is it to create an embedded scripting language that look like a scaled down version of PLAIN? To be honest – not much.

PLAIN is great, but it is still a language that needs to be compiled and downloaded. What I would like is a small interpreter that I can integrate into a CLI/Shell and write commands on the spot. I can do that with Python, but it is a large package + I am not a big fan of Python.

I want to use C++ and I target a minimum of 64Kb Flash and 20Kb SRAM. This fits the low end STM32 and maybe I can tune it down to faciliate smaller MCU’s, but that is for later.

I want a simple, classic interpreter that execute as we parse to minimize system requirements.

Lets work on the language:

Data Types

bool boolean
bit bit field
int8 8 bit signed integer
int16 16 bit signed integer
int32 32 bit signed integer
uint8 8 it unsigned integer
uint16 16 bit unsigned integer
uint32 32 bit unsigned integer
string tekst string
real32 32 bit float
record packed variable collection that can be declared on a selected address

Core Language

declare uint8 varA = <init expression>
assign varA = 3 + 4 * 5
func func MyFunc(uint32 pA…) : uint32

end

for for x = 1 to 10 step 1

end

while while <expression>

end

if if < expression >

elseif < expression>

else

end

Shell commands

Save save < name>
Load load < name>
Run Run

Build-in functions

print, println print functions. Will output text to a build-in console IO, usually an UART or similar.

This is a very minimalistic approach, but we can add context later as we need them. I will in addition link up the system library from PLAIN and enable add-on content from the platform package.

My own usage is as a CLI/Shell language and I want capabilities like auto-start of shell scripts etc.

Most of my modules have USB that is excellent as a high speed serial port, so a user install a simple console app and plug in a module and voila – he/she can operate or program that module directly.

Arduino NANO BLE 33 Sense

Arduino recently launched a new version of NANO with a powerfully 32-bit ARM M4 core, 64Mhz speed, 1Mb Flash and 256 Mb SRAM. And this is just the beginning.

It’s MCU is nRF52840 that also contains a BLE Radio and SW stack. It has all the features you expect from a modern M4, but it is more on this board than just the MCU w/BLE.

Located on the Sense version NANO 33 you will find five different components:

  • LSM9DS1 with  3D accelerometer, 3D gyroscope and 3D magnetometer.
  • MP34DT05-A with microphone.
  • APDS-9960 with Digital Proximity, Ambient light, RGB and Gesture Sensor.
  • LPS22HB with Altimeter and Barometer.
  • HTS221 with Humidity and Temperature.

The board is a bit expensive – 27.- EUR + P&P + another 35.- EUR in customs to Norway. I probably paid ca 80.- EUR for my sample, so I will not be buying more.

Device Bus – Part 5 Signals

This illustration show the 6 signals currenty used for “Device Bus”. The 3 first are a standard SPI in Half Duplex mode. That means that one device is Half Duplex Master driving the clock and sending on MOSI, while the others send/receive on MISO. The extra signals are designed to assist in deciding whom becomes Network Master and to avoid collisions on the bus.

RPION was initially designed for RPI to pull this high, but we can as well call it “MASTER REQUEST”. All devices will silence the bus, stop sending and any current Master will switch to Device mode waiting for someone to re-start the clock.

MSTRON is pulled high by the master, meaning that if we have no master this will be low.

BUSON is pulled high by any device sending and pulled back low afterwards.

All pins are active high and will have a weak pull down. All devices should configure these as input pins until it is time to change. This way we will have no conflict if several devices try pulling high at the same time.

Once a device is started it will check if MSTRON is active – if it is it will wait. If it is not it will wait a random time and pull MSTRON active. We wait yet another random time and pull BUSON active as we transmit our ID. At this point we are the Master, but we also have damper resistors on SPI in case we still have a collision.

Starting an existing network is easy as all devices have stored their previous state – only the Master will attempt a Master start up while the other devices wait an extended time.

And yes we could have done all this is SW with SPI only, but I did not like the collisions I had – that said – this is only an experiment.

 

Device Bus – Part 4 Ethernet Board

I decided to change XPortHub2 due to parts of the layout – I need to use SPI 1 for “Device Bus” due to speed on F405, but the paths was crossed with Ethernet SPI and USB, meaning I had high frequency signals close without any isolation. I decided to re-route that part and add the same Device Bus signals designed for the test board. It is hard to see the difference, but it’s a huge difference between 1.0 and 1.1 as this is.

I really would like to make this a 4 layer design, but a 2 layer PCB cost 5.- USD and a 4 layer 45.- USD, so it’s a lot of difference. I will go ahead with this + the Device Bus test board.

The SPI on this is supported by extra signals RPION, BUSON and MASTERON the save way as on the Test board, but I am only using SPI0 on RPI and operating directly from F405.

Device Bus – Part 3 Test board

I needed a board to test the new Device Bus/Watchdog so I stripped a XPortHub2 and added the logic that can be seen in the top right corner. It occupies almost 1/4 of the board so it does require some space. I need to work on that to find an optimal layout/solution.

I am considering adding this to XPortHub2, but I will need to re-route the entire board and move up to 4 layers for that. On this Test board above I can still get away with this being 2 layers so a test round cost me 15.- USD and components. I also decided on adding 2 more pins (Spare1 and Spare2) to RPI bus – just in case.

The one thing I don’t like is the size of the STM32G070KB – it is the large version of LQFP32 and the same size as a LQFP48. It occupy some space, but I think that will be ok as I reorganize the boards. Lets order the boards so we can move on into SW.

Device Bus – Part 2 Schematics

This is the schematics for Device-Bus, current sensor and power switch. I have a stripped down XPortHub that I might use for testing – removing W5500 leaves plenty of space without digging into 2nd side and 4 layer design. I simply would like to make some boards, put them in a stack and test for now.

The challenge with using SPI’s in Half Duplex mode is that I need someone to be Master – to drive the TDM loop. This is a challenge as I start up without anyone assigned this task. I did consider several aproaches and decided on giving Raspberry PI a separate RPION pin it can pull high. RPI starts later than the others, and pulling RPION high will silence the bus – all devices moves to Device mode and wait for RPI to take over. This was the easy one.

The more complicated scheme is if RPI has not started or is not plugged in. At this point we will have several boards fighting over control. So I added a second BUSON pin which tells everyone someone is running the bus. I might use more pins here, but as a device starts it can wait a random time, if no-one switch on BUSON it can do so, wait a random time and if no-one start the clock it can do so. At this point we have used 2 x random number delays – it will take some bad luck for two devices to believe they have the bus, and even more to start the clock at the same time. To be sure we broadcast our uniue ID.

STM33G070 don’t have an unique ID and it don’t have a random number generator, but STM32F405 does so we use that one. The delays I talk about should be 1-100ms, meaning the entire start-up conflict should be settled in max 200ms if we have chaos – at normal start we have flags indicating what roles the devices have.

If we by some strange luck still have two Devices trying to control the bus we will just get garbage as we try to communicate. Each bus have resistors to avoid full short-cuts and we have current sensors that will detect pin short-cuts as well. So all we do is to drop the bus and start over again. Assuming we are master and lose communication we use the same scheme. It also means that if we unplug boards or shut them down someone else will take over the bus – it should work.

Once synched we need to figure out whom is on the bus so we can set up the TDM sequences – this time we have two of them. With two SPI-buses it would be tempting to run two schemes and accept that two different Devices control each their bus. This will however never work with Raspberry PI involved since the Broadcom SPI’s are more limited in the sence they only support SPI Half-Duplex Master.

My remaining challenge now is how do we detect that we are alone on the bus? Lets revert the question – the solution becomes more obvious as we ask for a list of confirmed Node’s we can talk to!

As for the schematics U12 feed 3.3V to U3 and U4 that is the MCU and EEPROM. U9 is an INA193 current sensor. The proposed 0.25 Ohm resistor will at 500mA produce 2.5V to the ADC and at 10mA 50mV to the ADC. I have to test shunt and gain later for a consolidated scheme – I am more interested in currents below 100mA than above, so lets see. I am a bit concerned that low currents will only be noise.

U13 is the power switch. On U12 we bind EN to 5V so that it is always on, but on U13 we connect EN to PA0 on U3 (G070). It has a pull-down so we are unable to switch power on before U3 does the job. This way we switch on G070 that switch on F405 (or not).

U3 is STM32G070KB. Part of the new M0+ series from ST and high spech at low cost. I was considering using a Flash page for data, but decided to add a low cost I2C EEPROM with 32Kb (258Kbit). This can store configuration for F405 as well solving another function I want on all boards. U4 is a TSSOP8 package and the I2C interface is 1Mbits/sec. EEPROM is slower to read/write than FRAM, but I am not sure I care. I can also add a CRC and write two pages etc to avoid havoc if we shut down during writes.

The UART connected on PA10/PA9 is capable of 6Mbits/sec and as we will be crossing TX/RX directly we will be using full duplex. We also have 7 DMA’s so we use 6 on SPI1, SPI2 and UART and still have 1 left for MEM to MEM. We also have 32Kb to use as buffers. I need to use interrups for EEPROM and bit banging for the ADC, but we have sufficient juice as this is a 64Mhz MCU.

Just a footnote that STM32G030KB is half the cost, only have 8Kb SRAM and 2 UARTS, but it’s UARTS are 8Mbps/sec. I2c’s and SPI’s are the same speed. I am having that in mind if we can downscale later. The entire BOM is below 3.- USD. It will take a while to order PCB’s and parts, but I am looking forward to this experiment.

Device Bus – Part 1

I was in the middle of planning a 8 pin bit-bang bus as my attention was drawn to STM32G070KB that cost 0.7 USD, comes in a LQFP32 package and contains: 2 x 1Mbps I2C, 2 x 32Mbps SPI, 4 x 6Mbps USARTS, 128Kb Flash, 32KbSRAM, running at 64Mhz and 7 DMA channels. Looking at the RPI pinout (above) this becomes very interesting.

So – what if I drop my bit-bang plans and use the two SPI’s for data transfer on the bus while I use a 6Mbps USART for communication with STM32 – basically dropping SPI between F405 and RPI bus? A 6Mbps full duplex UART backed by 2 x 32Mbps SPI’s is a lot of bandwidth.

Funny how things evolve – I started this by wanting to add an on/off switch to my boards – and we still have that as well – I also have several ADC’s and GPIO pins available on G070 so I have options in solving the tricky start up scheme. But, I need to draw sequence diagrams for the various situations to convince myself I have solved this.

I plan to use a I2C for a EEPROM storage. FRAM would be better, but it also cost more – lets see. A 32 Kb EEPROM also provide config storage space for F405 – so its far from wasted.

Moving on – I have space on top to add these components. My main concern is interference between the two MCU’s so this will force me up to 4 layers and components on both sides. I need ground planes between the MCU’s unless I manage to mount them on same side – but it is getting crowdy on some boards. SWD can be connected on RPI bus so we can program Device Bus. I am starting to like this concept 🙂

 

STM32 Flash Usage

STM32L011F4 only have 16Kb Flash, and as I generate the code I need from STM32CubeIDE it compiles to 11,37Kb on Debug, leaving only 4,63Kb Free for the application. Looking at the map I see several nasty C functions n the drivers. The GCC compiler is decently good and greedy on bytes, but that don’t help if the drivers use up the little Flash that is.

ST is great at Hardware, but their Software is not that great. It makes their small MCU’s non-usable if the driver uses all the Flash for itself.

My first idea was to use L011 as watchdog, but looking at Flash, SRAM and prices I decided to go for STM32G070KB that comes in a 32 pin package with 128Kb Flash, 32Kb SRAM and running at 64Mhz. This is a new M0+ series and I like the size and the price – buying from Farnell this time.

Watchdog/D-Bus

This is the block diagram for XPortHub2 with an added Watchdog/D-bus. My objective here is that I want to add some features to the board and decided to do an experiment adding an external Watchdog/D-Bus by using a smaller STM32 in support.

  • SPX3819 can be switched on/off enabling me to power a board on/off.
  • Adding a current sensor I also have an external watchdog in place.
  • I can use the Raspberry PI Backbone bus to drive a 8 bit SPI alike design to communicate with the rest of the stack.
  • I can communicate with STM32F405 using an UART.

The principle of a Half-Duplex SPI is simple as you run one clock and read/write data at the clock speed. Using 8 pins means I get 8x the speed of a single-line SPI and can achieve a high data throughput using a lower frequency. I want to test this on my new XPortHub2 and it only require a few, small components added. I probably have to re-route the entire board, but I think this will be worth it.

A Half Duplex SPI at 42Mbs per sec is ca 5Mb per sec – which is very fast. To compete with that I would need to bit-bang in 5Mhz speed. I don’t think that is possible, but 1Mhz should be realistic. Mhz here is Mb since we transfer 8 bits per clock. It is a lot of pins for an experiment, but I need a way for the Watchdog to commnunicate on it’s fun – so lets do this.

Adding a 2nd MCU at top using the bottom layer is doable, but it raises a chalenge – I will either need a breakoutboard for this or move to a 4 layer PCB to avoid interefence. I like the idea of a piggypack board for now – it is a less intrucive change on XPortHub – which by itself is going to require a change later regardless – I don’t expect to make a board as complex as XportHub and get it all right the first time.

XPortHub2 w/Ethernet

3D model of XPortHub2. This contains an 10/100Mbps Ethernet with a standard RJ45 socket that replace TF Card, I2C and SPI on XPortHub1.

  • New style SWD port.
  • Raspberry PI Backbone with SPI and CAN.
  • RTC with Battery holder on back.
  • 8 x user leds.
  • 2 x CAN ports. CAN1 is connected on Raspberry PI Connector so that CAN connect as you stack board together. Just like SPI.
  • 2 x RS485 ports.
  • 2 x RS232 ports.
  • 1 x USB port.
  • 1 x 10/100Mpbs Ethernet port.
  • 1 x TTL UART.
  • SPI Flash.

I fancied having a STM32 based board with Ethernet thought I already have an ESP32 based one. This board is attractive as a stand-alone adapter board as well.

Starting now we will also offer boards for sale. This is only limited number of prototype boards that can be purchased through www.basicpi.com.

This last image show the back of the board where you can see the CR1220 battery holder. One big upgrade is that KiCad show the ground plane correctly and even detect icelands. This groundplane worked out nicely.