The SAML10E16A: A Cortex-M23 MCU

SAML10E16A and a Segger J-Link EDU debug probe

This is my first Cortex M23 MCU. It is made by Atmel/Microchip which may lead to I/O synchronization oddness later but time will tell. Initial attempts to get this working with an ST-Link clone were not successful however the J-Link Edu works great.

SVD data was obtained from Atmel over at http://packs.download.atmel.com/

When you extract the SAML10E zip file you will come across this file: ATSAML10E16A.svd. This can be used to produce a header file with I/O structures using the utility svdconv.exe (available from Keil’s MDK installation). This is done as follows:

SVDConv.exe ATSAML10E16A.svd –generate=header

On my Linux system I added “wine” and the full path in front of that – you may not have to do this on your own system.

This produces a header file although not without some errors. The biggest problem seems to be in the area of the RTC. A little bit of manual editing fixed the “show-stopping” error in the generated header file. More investigation needed here however as other problems may lurk. Anyway, the header file was good enough to get a basic blinky program off the ground.

Blinky sources can be found over here https://github.com/fduignan/atmel/. I expect to add more in the near future.

Dublin Maker 2020+ badge.

Dublin Maker didn’t happen this year because of Covid-19. I had been working on a badge (unofficial) but then parked the project for a while. Recently I resurrected it and have begun building badges. Software is not complete yet and the documentation needs to be developed but the picture above shows an almost complete badge without the display fitted (it overlays the MCU in the middle of the badge). Just about all of the background hardware driver code is done.

The 2019 badge took a hardwired wired approach to multi-player gaming. While this worked, it was a little unreliable mainly due to low quality 3.5mm stereo sockets and cables. This badge uses an NRF24L01 radio module instead and it appears to work quite well. Also it is actually a little cheaper than the wired version. Other differences include a change to the MCU which features more pins and double the flash memory (32kB!!). The most notable change however is probably the use of a PCB. This was designed in KiCad and fabricated by PCBWay – a process that was surprisingly cheap, quick and easy.

Lets hope Dublin Maker 2021 takes place.

Using the HD107S RGB Led with a BBC Microbit

The HD107S is a low cost RGB LED unit which features an SPI interface. I paid just over €9 for 50 of them. They are quite easy to program using a microcontroller platform such as the BBC Microbit. The short program below was written on MBed and downloaded to the Microbit. It causes the LED to cycle through a range of colours.

#include "mbed.h"

SPI spi(P0_21, P0_22, P0_23); // mosi, miso, sclk
void getRainbow(unsigned &Red, unsigned &Green, unsigned &Blue);

int main() {

    unsigned Red,Green,Blue;
    Red = Green = Blue = 0;    
    char tx_buffer[16];
    char rx_buffer[16];
    spi.format(8, 3);
    spi.frequency(1000000);
    tx_buffer[0]=0; // header
    tx_buffer[1]=0; // header
    tx_buffer[2]=0; // header
    tx_buffer[3]=0; // header
    tx_buffer[4]=0xe0 + 0x1f; // max brightness (1f = brightness figure - lower to suit)
    while(1) {
        getRainbow(Red,Green,Blue);
        tx_buffer[5]=Blue; // blue
        tx_buffer[6]=Green; // green
        tx_buffer[7]=Red; // red        
        spi.write(tx_buffer, 8, rx_buffer, 0);              
        wait(0.01);
        
        
    }
}
void getRainbow(unsigned &Red, unsigned &Green, unsigned &Blue)
{   // Cycle through the colours of the rainbow (non-uniform brightness however)
    // Inspired by : http://academe.co.uk/2012/04/arduino-cycling-through-colours-of-the-rainbow/    
    static int State = 0;
    switch (State)
    {
        case 0:{
            Green++;
            if (Green == 255)
                State = 1;
            break;
        }
        case 1:{
            Red++;
            if (Red == 255)
                State = 2;
            break;
        }
        case 2:{
            Blue++;
            if (Blue == 255)
                State = 3;          
            break;
        }
        case 3:{
            Green--;
            if (Green == 0)
                State = 4;
            break;
        }
        case 4:{
            Red--;
            if (Red == 0)
                State = 5;
            break;
        }
        case 5:{
            Blue --;
            if (Blue == 0)
                State = 0;
            break;
        }       
    }    
}

A bluetooth low energy UV sensor

This is my first project that involves the NRF52832 BLE MCU. The NRF52832 takes the analog signal from an ML8511 UV sensor and makes it available over a BLE service. Connections are pretty straightforward: the ML8511 output is connected to P0_28 of the NRF52832. An LED is connected to P0_25. That’s all there is to it apart from power (3.3V) and ground. The BLE value output is an integer value that represents UV intensity in mW/cm^2.

Code was developed using the mbed online compiler. This particular BLE board was bought from AliExpress for around €6. It is not available as a “platform” on mbed however the Delta DFBM-NQ620 seems to be compatible so I used that. Interesting to note that at this point in time the Serial interface class for the NRF52832 is in a known broken state.

Code is available over here on mbed.

Controlling a PL9823 LED over Bluetooth LE

I received an ESP32-Camera board from Aliexpress recently but unfortunately it’s camera was broken (the supplier is sending a free replacement). Not wanting to waste the otherwise good ESP32 I decided to see if it could be used to control the brightness and colour of an LED such as the PL9823. These LED’s are controlled using a serial data string which is documented elsewhere in this blog (https://ioprog.com/2016/04/09/stm32f042-driving-a-ws2812b-using-spi/ and https://ioprog.com/2018/11/08/stm32l031-controlling-a-pl9823-led-using-spi/)

It turned out to be pretty straightforward.

The ESP32 board was connected to the PC over a USB-Serial converter. Two buttons were added to control boot mode and the PL9823’s Data In pin was connected to IO2. The code to control all of this was developed in the Arduino environment (based off an example) and is as follows:

#include <SPI.h>

/*
 *  Controlling a PL9823 LED over bluetooth on an ESP32
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp
    Ported to Arduino ESP32 by Evandro Copercini
*/

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#define SERVICE_UUID        "22389e17-7cee-41ce-8aa0-28a4482f7020"
#define CHARACTERISTIC_UUID "a575e1bf-e15f-4534-a80c-1837348360ad"

void writePL9823(uint32_t Colour)
{
    // each colour bit should map to 4 SPI bits.
    // Format of Colour (bytes) 00RRGGBB
    uint8_t SPI_Output[12];
    int SrcIndex = 0;
    int DestIndex = 0;
    for (DestIndex = 0; DestIndex < 12; DestIndex++)
    {
        if (Colour & (1 << 23))
        {
            SPI_Output[DestIndex] = 0xe0;
        }
        else
        {
            SPI_Output[DestIndex] = 0x80;
        }
        Colour = Colour << 1;
        if (Colour & (1 << 23))
        {
            SPI_Output[DestIndex] |= 0xe;
        }
        else
        {
            SPI_Output[DestIndex] |= 0x8;
        }
        Colour = Colour << 1;
    }    
    SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); 
    SPI.transfer(SPI_Output, 12);
    delay(10);
    SPI.endTransaction();
}

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
    
      if (value.length() > 0) {
        // Write debug messages out to serial port
        Serial.println("*********");
        Serial.print("New value: ");
        for (int i = 0; i < value.length(); i++)
          Serial.print(value[i]);

        Serial.println();
        Serial.println("*********");
        // update the PL9823 LED
        uint32_t intvalue;
        intvalue = strtoul(pCharacteristic->getValue().c_str(),NULL,16);
        writePL9823(intvalue);
      }
    }
};

void setup() {
  
  SPI.begin(1,4,2,3); // (int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
  Serial.begin(115200);  
  Serial.println("Connect to the device over BLE and change the colour of the LED");

  BLEDevice::init("BLE_PL9823");
  BLEServer *pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());

  pCharacteristic->setValue("ffffff");
  
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();

  // Write the initial value out to the PL9823
  uint32_t intvalue;
  intvalue = strtoul(pCharacteristic->getValue().c_str(),NULL,16); 
  writePL9823(intvalue);
}
void loop() {
  // put your main code here, to run repeatedly:
  
  delay(1000);
}

Using an Andoid app like BLE Scanner, it is possible to control the the LED by sending a hex string such as ff0000 for maximum red; 00ff00 for max green and 0000ff for max blue. These colours can be mixed to form arbitrary colours and brightness.

NRF51822 with an accelerometer and an Oled display

The CJMCU-8223 is a small breakout board featuring an NRF51822 and an LIS3DH accelerometer. It is shown above attached to an SSD1306 Oled display. Programs are loaded on to it using an ST-Link debugger clone.

There are many different ways to program this chip but I decided to develop code for it using the online compiler at mbed.org. This environment allows you write and compile code within your browser. Compiled programs are dropped in to your downloads directory in the form of “hex” files. These downloads can then be written to your target MCU using your preferred debugger. The advantage of this approach is that you don’t have to set up a toolchain on your PC and, you can avail of lots of ready made libraries and example code.

This particular example provides two Gatt services over BLE. An LEDService allows a connected bluetooth device to control the blue LED on the breadboard. An accelerometer service allows the connected device read the accelerometer values (scaled up by a factor of 1000 to avoid floating point printing). The code for this example can be found via this link over at mbed.org.

When you compile this code, the hex file delivered to your PC needs to be uploaded to the NRF51822. This is done as follows:

In one command window (terminal) start openocd as shown here:

Leaving that window running, open a new one and run telnet entering the commands shown below.

Once you have done this, type reset into the telnet session and the board should start running.

You can interact with the board using BLE Scanner on your phone or maybe work with node.js or python to develop a PC based application.

If you need to do some debugging, it is possible to export the program from the mbed environment into a format that is compatible with a number of toolchains (including gcc/gdb). I have tried this and it works pretty well although you may need to disable interrupts on the MCU while doing this as the debugger can get confused if there is bluetooth activity during the debug session.

Breadboard games 2020

With the Covid-19 pandemic ongoing it is not likely there will be any further Breadboard Games events this year. There was a small event in early March in Kevin St. public library with children from Singe Street primary school. On that day the attendees built a board very similar to the one we used in
St. Audoen’s school in 2017.

So what about the rest of the year? Well, a couple of events happened this year that made me think of a particular game: the passing of John Horton Conway and the pandemic so the game is of course “The game of life”. Lots has been written about this game and I will not repeat that here, instead I will focus on how this can be implemented using a low cost microcontroller (MCU), screen and breadboard. There will likely not be “event” based on this game but maybe a reader will be inspired to try it out for themselves.

game_of_life_breadboard

The schematic
game_of_life_schematic

This circuits makes use of components I had lying left over from other breadboard games projects. The MCU is the 30 cent (approx) STM32F030F4P6. This display is a 176×220 TFT board with a parallel interface. The databus runs between PA0-PA7 on the STM32 and DB0-DB7 on the display (it is not shown completely as it would have cluttered the schematic).
The specifications of the MCU are pretty meagre: 16kB of Flash, 4kB of RAM, 48MHz clock speed. All pins have been used to control the display.

The game
Conway’s game of life is all about automata (cells) that live or die depending upon what surrounds them. Cells can die of loneliness (less that 2 neighbours), starvation (more than 3 neighbours) and they can come to life if they are bordered by exactly 3 neighbours. These rules are applied repeatedly to the cells in the landscape. I’ve chosen to do this in two passes. The first pass decides what the state of each cell will be during the next time around based on current state. The second pass switches from the old state to the new state. This of course requires memory (RAM) and this MCU only has 4kB. The display has 176×220 = 38720 pixels. The game allocates one pixel per cell so without some sort of compression there is no way this MCU can store this amount of data. To further add to the storage burden I’ve decided to go with a coloured version of GoL called Quad-Life. Each pixel can be one of 4 colours or black. Where can this be stored?

Stealing memory from the Display
The RM68130 display has enough on-board RAM to store 18bits for each of the 176×220 pixels. All of this does not have to be used for controlling the display however. If the display is switched to 8 colour mode then only 3 of those 18 bits is required per pixel (1 for red, 1 for blue and 1 for green). The remaining 15 bits can be used to hold whatever you like without impacting on what you see on screen. At least that was the theory…. I’ve been using various small displays like this for a while and up until now have had little success reading data back from them. The SPI versions are particularly tricky; some don’t even have read-back functionality. Happily the RM68130 does allow you read back from it’s graphics memory but there’s a catch: the bits you write do not come back to you in the same order. Now I’m willing to accept I may have made a mistake here but I found it VERY confusing reading data back from the display. After many hours I figured out enough to store 1 byte of my choosing alongside each pixel. This means the MCU just got an additional 38720 bytes of RAM – plenty for storing the future states of each cell. By the way there are other displays that should work like this. I’ve tried the ST7775 and the ILI9225 (both parallel interfaces) and they both worked fine

Additional game details

GoL has to start somewhere. You need some way of supplying initial states for the cells (pixels). As you can see above there are no more pins available for user input (PA13 and PA14 are used for debugging). One further feature of the display is that also functions as a resistive touch screen. The user now simply draws the initial state using a stylus (or finger).

The GoL landscape is not meant to run in to a hard border so when a cell goes beyond an edge it “wraps” around to the other side.

Gameplay
The video below shows the game “in action”. It is not particularly fast and manages about 1 update per second. Consider it a slightly interactive desk ornament 🙂

The code
Code is as usual available over here on Github. There has be no attempt to optimize the performance of this code in any way. It is shown in what is hopefully the easiest to understand mode.

The STM32G030

The STM32G030 is similar in many ways to the STM32F030. It has approximately the same peripherals and is available for a similar price (in western countries). There are some significant differences however:
The ‘G030 however uses a Cortex M0+ (instead of the M0 in the F030),
The ‘G030 has a maximum clock speed of 64MHz (48MHz for the F030),
The model I chose STM32G030K8T6 has twice the Flash (64KB) and twice the RAM (8KB) that the ‘F030 has.
stm32g030_display
Full size image
I’ve put together a number of examples over on github that might help someone get started. These include a simple blinky, serial comms, serial comms with an ADC, systick interrupts and finally driving an ST7789 LCD display.