When all you have is a hammer…….

Last weekend I attended a retro-computing fair at the Centre of Computing History in Cambridge.  This was my first visit to this popuar museum and I was impressed by the range of exhibits that they had on show.

35 years ago – Cambridge was buzzing with computer activity – and it was home to at least two of the prominent home computer companies in the early 1980s – Acorn and Sinclair.  Machines of this era were on prominent display throughout the museum.

I got my first computer around this same time – a ZX81 which I built up from a kit – following a price reduction – in the Spring of 1983, the ZX81 was very much being superseded by more sophisticated hardware such as the Spectrum, the BBC Micro and a plethora of other 8-bit machines.  It cost me £39.99, at a time when £40 was a week’s wage in a summer job, to a sixth former.  I still have it – or most of it, a surviving keepsake, when many other bits of more sophisticated electronic hardware have long since been junked.

When all you have is a Z80 – everything needs to be solved with Z80 code……….

The early 1980s machines were relatively unsophisticated and we learned how to get the most out of them with clever coding and a bit of ingenuity.   Slowly the IBM PC and it’s clones became the dominant machine in the office, and computing changed forever.

In the early 1990s, my job involved designing pcbs using ORCAD.  For Autumn 1990 to Spring 1991, I pushed tracks around the screen using a ‘286 machine clocked at 25 or 33MHz.  I don’t remember the job being particularly arduous or slow – but then we barely had Windows – and the PCs would really only run a single application at a time. There was no Internet, no distractions and no social media interrupting your thought processes every 20 seconds.

Now we are surrounded by microcontrollers of all sizes, and electronic hardware has never been cheaper – our daily lives revolve around staring into LCD screens – both big and small – we have become addicted to checking our phones and our social media apps – in the hope that something interesting is happening elsewhere.

But I digress….. I’m here to write about a revolution in open source hardware.

Last year, Alan Wood and I, designed an FPGA dev board around the Lattice ICE40 device.  This was our first venture into open source FPGA hardware – very much triggered by Clifford Wolf’s open source FPGA toolchain “Project IceStorm”.

We put together the combination of a low cost ARM microcontroller and an easily programmable FPGA.  We wanted to create a platform that was interesting from a hardware perspective  and one that could readily be expanded. And so “BlackIce” was created.

Returning to the retro-computing fair,  I was fortunate enough to be able to demonstrate some retro machines, created by community member David Banks running on our BlackIce hardware.

The following designs are now available from David’s github repository:

  1. Acorn Atom (6502)
    https://github.com/hoglet67/Ice40Atom3
  2. BBC Micro Model B (6502) with BBC BASIC
    https://github.com/hoglet67/Ice40Beeb2
  3. Jupiter ACE (Z80A with FORTH)
    https://github.com/hoglet67/Ice40JupiterAce1
  4. CP/M Platform – Z80A with either serial terminal connection or colour VGA /PS/2 Keyboard
    https://github.com/hoglet67/Ice40CPMZ802

David has included binary files for each of these designs that need to be programmed into the STM32L433 using DFU-UTIL. These binary files contain the ROM data and make the design file “sticky” – i.e. resident in the STM32 flash – so on power on the FPGA boots to whichever retro computer you have chosen.

For each of these designs you will need a Digilent VGA pmod (£8.99 from Farnellhttp://uk.farnell.com/digilent/410-345/pmod-board-video-graphics-array/dp/27681896)

atom3

Connecting VGA and PS/2 Keyboard using standard Digilent pmods

This plugs into Pmods 7/8 and 9/10.

You will also need a PS/2 keyboard – which requires a trivial adaptor (4 resistors) plugged into Pmod 11/12 or can be bought from Digilent here:

http://www.mouser.co.uk/ProductDetail/Digilent/410-094/?qs=sGAEpiMZZMsF1ODjcwEocGEoetGlDts14V4qfo%2fFYIE%3d3

You will see from the datasheet for the PS/2 connector – that it is a very simple circuit.

Below is our display at the Centre for Computing History – with the BlackIce board hosting a BBC B running a sphere demo in BBC basic.BBC_retro_sphere

 

 

 

 

 

 

 

Advertisements
Posted in Uncategorized | Leave a comment

Arduino meets open FPGA

sdr

BlackIce Open FPGA – Includes an 80MHz “Arduino”

Arduino is the Marmite of embedded programming – you either love it or hate it.

Regardless of how you feel about it – Arduino in the last 12 years probably has introduced more people to embedded programming of microcontrollers than any other organisation. What started with the humble AVR ATmega8 in 2005 has grown to include a multitude of different microcontrollers. and devices.

Initially the Arduino IDE handled only Atmel AVR microcontrollers – but with the addition of the Arduino Due board, it has opened up to include ARM devices – including parts by Atmel and ST Microelectronics.  To allow this to work the GCC toolchain for ARM has been integrated into the Arduino IDE along with the necessary “board files” and hooks to the various programmer devices.

In late August I noted that the STM32L4 parts had been brought into the fold – by way of the “Butterfly” boards which use the STM32L433.  This is the same microcontroller that we use on the current generation of myStrom BlackIce FPGA boards – and to have this part readily programmable from within the Arduino ecosystem will open up a whole new set of possibilities for the BlackIce board.

The STM32L433 brief specification:

64 pin low power ARM M4 Cortex microcontroller
256Kbytes of flash memory, 64Kbytes of SRAM
80MHz clock
USB 2.0 Full speed interface
11 timers
Capacitive touch interface
12 bit 5 MSPs ADC
2 x 12 bit DACs
SPI and Quad SPI
I2C

The full datasheet

Whilst my initial efforts in late August allowed me to program the STM32L433 from within the Arduino IDE using the “Butterfly” board file, it was going to take further work to create a custom board file for our BlackIce pcb.

Following on from the Hebden Bridge “Wuthering Bytes” festival in early September, our programmer friend Richard Miller has now created the necessary board file and Arduino platform support for BlackIce – and so all of the peripheral features and GPIO are now accessible via Arduino library functions.

Instructions for configuring the Arduino IDE and more details of the accessible GPIO signals are included on Richard’s Github repository.

This framework includes the DFU-UTIL program – which allows you to bootload the STM32 from within the Arduino IDE. Here are a few helpful hints:

  1. First remove the programming jumper from pins 14 and 16 of the Pi connector
  2. Plug the USB cable into the centre microUSB connector
  3. Always press the reset switch before you recompile and program.
  4. Replace the jumper if you want the code to be permanent
  5. If you want to access the UART – use “Serial1.xxx” in any functions that use the Serial code.

It was not long before I had Blink running, so I decided to load my old favourite – SIMPL. This is a small interactive toolkit that allows you to exercise the hardware via a series of serial commands. You can read about it and find the code on my Github repository .

All appeared to work and soon I had the STM32L433 executing my interactive code.

Finally, as the STM32 is cocked at 80MHz – which is 5 times faster than the standard Arduino, plus it is a 32 bit processor rather than an 8-bit device, out of curiosity, I decided to run the standard dhrystone benchmark test to see how it compares to the regular 16MHz Arduino.

The results were interesting, clearly showing that the 32 bit ARM architecture scores over the 8-bit AVR:

Arduino Uno

Microseconds for one run through Dhrystone: 78.67
Dhrystones per Second: 12711.22
VAX MIPS rating = 7.23

BlackIce:

Microseconds for one run through Dhrystone: 8.94
Dhrystones per Second: 111854.70
VAX MIPS rating = 63.66

So on the Dhrystone benchmark – BlackIce is about 8.8 times faster than the regular Arduino R3.

Arduino GPIO Headers

One of the features of BlackIce is that most of the spare GPIO signals from the STM32L433 microcontroller have been brought to Arduino-style female headers.  These allow connection to the analogue ADC, PWM, UART, SPI and I2C lines.  All apart from the six ADC inputs are 5V tolerant. For simple extensions to the BlackIce board – Arduino style shields may be fitted – but preferable if they are of the 3V3 type to avoid 5V reaching the FPGA pins and potentially causing damage.

Serial Terminal connection

BlackIce has a UART to USB converter IC which appears as a CH340 COM port.  It is available on the micro USB connector closest to the bottom left corner of the pcb.  This may be utilised from within Arduino provided that it is referenced as “Serial1”

STM32 – FPGA Interface

The STM32L433 shares a total of 20 signal lines with the ICE40 FPGA.  Some are used to provide the FPGA configuration interface (for FPGA programming) but may be re-used at runtime.

The signals are arranged into the following groups.

SPI Interface:    MOSI, MISO, SCLK, SS

Quad SPI Interface:  QD0,  QD1, QD2, QD3, QCS and QCK

GPIO Interface:    Dig 16, Dig 17,  Dig 18, Dig 19 (Slide switches)  B1, B2 (Buttons)

UART Interface:   TX , RX

Misc Controls:      RESET, DONE

All of these with the exception of RESET and DONE appear on the FPGA as GPIO and may be repurposed as required.

Posted in Uncategorized | Leave a comment

Splitting the Atom

It’s not everyday that you meet someone with the talent and tenacity of Dave Banks (@hoglet67 on Twitter).  In less than three days, Dave ported his FPGA based Acorn Atom from Xilinx and VHDL across to Lattice ICE40 and verilog. The result is a fully functioning Acorn Atom – running on our latest open source FPGA board, BlackIce.

The Atom was a forerunner of the Acorn Electron and the BBC Micro. It used a 6502 microprocessor an provided a chunky colour display – which was virtually unknown back in 1980 when the Atom first appeared.

On Friday, Dave emailed me to say that he was going to begin to port his Atom design to the BlackIce board – and was looking at the VGA implementation using the recreated Motorola 6847 graphics controller as used in the Atom. However, the 6847 module was written in VHDL and would have to be ported to verilog first – so that it could take advantage of the open source “IceStorm” FPGA toolcain.

Then without warning, on Saturday evening the following two images appeared:

custom_vga

With the help of a few carefully chosen resistors and a hacked VGA cable, Dave had fashioned a VGA output – driving the resistor arrays direct from the FPGA pins. The result was the characteristic Atom “pre-boot” screen – when the video RAM is full of random data.

atom_1

Within a couple of hours, Dave had achieved the boot screen, connected a PS/2 keyboard and written “Hello World” in Acorn BASIC.

To any casual observer – all of this happened within the short space of Saturday afternoon.

atom_hello_word

BlackIce_PS2

By late Saturday night – and a few tweets on my part – interest was gaining rapidly – and eagerly awaiting part 2 of Dave’s installments.

atom_sch

Dave put up an original Atom schematic – to illustrate the extent of the digital logic that had been implemented within the ICE40 FPGA – and by Sunday evening we faced some Alien Invaders – a port of the famous “Galaxians” game:

galaxians_1s

 

galaxians_2

It was now Sunday evening and Dave mentioned that he had work out a way to get ROM data into the large external SRAM (256K words) that is closely coupled to the FPGA.  This involved some neat coding tricks – and taking advantage of the flexibility of the BlackIce loading mechanism.

Dave’s progress was soon appreciated by the “stardot” forum – a group devoted  to Acorn retro computers – and very soon, a fellow forum member, Ed Brindley, had implemented a similar Atom – using the BlackIce board and some Digilent pmods  – for the VGA and keyboard.

atom3

atom4

This all looks like excellent progress – but Dave was like a dog with a bone – he had to solve the issue of using the microSD socket on the underside of the BlackIce board to allow a full repertoire of Atom software to be loaded via SD card.

This latest triumph appeared on Tuesday morning – just 3 days after commencing this mammoth project.

Dave’s write-up of this project appears on the myStorm forum with full technical details – which you may find here

Atom7

Atom6

Atom5

Thanks to Dave for his tireless work in making this happen in such a short space of time.

BackIce will be featuring at @WutheringBytes in Hebden Bridge between September 1st and 10th.

Throughout the week we have talks, workshop sessions and general FPGA geekery goodness.

If you’d like to obtain a BlackIce open source FPGA board – please follow this link – or contact me at ken dot boak at gmail dot com

Ken.

Posted in Uncategorized | Leave a comment

A Minimum Interactive Language Toolkit

In previous posts I began to describe a minimum interactive language toolkit which could work standalone in virtually any small microcontroller. Here are the following prerequisites I stated in the previous post:

  1.  Interactive – commands may be typed at the keyboard for immediate execution
  2.  Commands can be combined into programs then compiled for later execution
  3.  Extensible – from a small kernel of commands, a whole application can be built
  4.  No external tools required other than a serial terminal – all tools run on chip.

This may appear to be a huge break from conventional wisdom, as virtually all embedded microcontroller development is done in high level C – compiled using a package of tools hosted on a more powerful machine – such as laptop.

Microcontrollers have evolved to have a fairly large proportion of their memory as flash-ROM, and modest quantities of  RAM – so it’s not unusual to find a micro with 32K bytes of flash but only 2k bytes of RAM. Whilst this partition of memory resources is not ideal for interactive languages (more RAM would be nice) – it’s enough to get started.

In the early days of microprocessors – it was commonplace to have a “Monitor” program – which consisted of a few simple commands to allow hexadecimal opcodes to be entered directly into memory and then executed from a given address. Some of these monitor programs also allowed a hex-dump to be sent to a terminal, to examine the contents of memory, plus primitive editing commands.

Typically the monitor would take a few hundred bytes of ROM, but it provided the absolute basics of being able to write machine code. Assemblers seldom existed, given the meager resources of the early home computers, and so a lot of coding was done by hand assembly – using pencil and paper – or by copying hexadecimal listings out of magazines.

What I am proposing here is a program that offers the same low level support as a monitor, but rather than programming in raw Hex or machine language, the User has access to a small instruction set of highly mnemonic commands.  These are executed out of memory by a  generic virtual machine, hosted on the MSP430 microcontroller.

This can be coded in about 562 bytes of assembly language, of which 128 bytes are a 64 entry look-up table. The MSP430 generally dos not have a good code density with an average of around 2.95 bytes being required for each instruction.

The mechanics of this virtual machine are as follows:

  1. Take in a string of serial characters and place in a buffer until the newline character is detected.
  2. Parse through the characters one at a time creating a jump address into a look-up table based on the ascii value of the character.
  3. Numerical character strings are handled by the number routine, forming them into a 16-bit integer which is placed on the stack.
  4. All other characters cause program flow to jump to a table-selected address from where code is executed. Numerical parameters may be used from the stack.
  5. Where appropriate putchar is used to provide serial output of numbers and strings
  6. Jump back to the parser in (1).

The prototype has been coded up in MSP430 assembly language – and is available at the following github repository.

A More Efficient Instruction Set?

Most MSP430 instructions are two bytes,  but moving byte or word constants into registers, byte comparisons and byte subtractions require a further two bytes to hold the constant.  Calls also require the second pair of bytes to hold the call address.

As much of the interpreter is based on the testing and handling of characters and the manipulation of ascii values – it would appear prudent to have a class of instruction that could efficiently handle 8-bit values.  This could be done by allowing an 8-bit immediate value to be coded into the instruction, with a 4-bit field for the source/destination register and a 4 bit instruction.

This becomes a balancing act between a processor that can efficiently handle 16-bit maths operations via registers and still efficiently handle 8-bit immediates. It becomes quite a challenge to shoe-horn this into a 16-bit instruction wordlength, but it’s no different to the challenge that the 8-bit ISA designers had when the immediate was the byte following the opcode.

Last year I reviewed the 8080/Z80 common instruction set based on how they were decoded – and I produced the following image.  Whilst the 8080 and Z80 were 8-bit micros, they did have a small capability to handle 16-bit numbers by way of their register pairs plus a very few 16-bit instructions.  perhaps there could be some inspiration from the 8080 instruction set – for a processor that could handle 8-bit immediates and short jumps – whilst being predominantly a 16-bit machine.

z80_octal_3

When expressed in octal – and a bit of colour added  – it’s clear to see how the instructions were grouped with the most significant 2 bits defining the class, the next 3 bits defining the operation, and the bottom 3 bits defining the operand(s). It’s a clever bit of encoding – that ensured that almost all of the 256 opcodes did something useful.

If we take the top two bits to define the instruction Group – a very rough description is as follow – where only Group 01 and 10 are entirely regular and defined by the bit fields. Groups 00 and 11 need further decoding to derive their classification.

00  xxx   yyy     – INC, DEC, double ADD, relative jumps etc

01  DST   SRC     – regular source to destination register moves

10  ALU  SRC    – register-accumulator ALU operations ADD ADC SUB SBC AND XOR OR CMP

11  FLG  JMP    – conditional CALL, RET, JMP operations

With Groups 00 and 11 being a bit of a mash-up — it might be possible to re-hash them into something a bit more logical.

A Hybrid CPU.  – Neither Fish- Nor Fowl

The 8080 was based on a modest set of 8 registers that could be combined to form 16-bit pairs  bc, de, hl.  Limited arithmetic was permitted within these pairs – in that they could be added to hl as an accumulator, incremented or decremented.  They could be loaded with immediate 16-bit constants and could be used as indirect pointers for load and store operations to memory.  The hl pair had special preference in that it was used as a memory pointer and any of the other registers could load or deposit through (hl). Push and Pop operations were done on the register pairs.

With 8 registers we have the possibility of creating a small stack – and with a rich, orthogonal set of register to register moves (Group 01), there is little or no requirement to have the usual stack manipulation instructions.  Group 10 instructions allow any register to have math or logical operations done using the accumulator as the destination.  So in theory if the register file were considered to be a pseudo-stack – any of the members could interact with the accumulator – or top of stack.

A machine capable of executing Group 01 and 10 instructions would be fairly versatile – so lets keep these in place.  That leaves manipulating Groups 00 and 11 to provide the other necessary instructions.

 

 

 

 

 

Posted in Uncategorized | Leave a comment

Minimal Computing – some more thoughts

This post is concerned with minimal computing – a subject that is close to my heart. I write this on the day that my Employers have suffered a major ransom-ware cyber attack on their servers and IT systems, bringing the companies activities to a virtual standstill.  To me this proves the fragility of the technology that we entrust for our day to day lives. There has to be a better, much simpler way……..

In the 1960s, the world of computing was evolving quickly as many new machines came on the market.  For code developers at that time, this presented a problem in that every new machine had a different assembly language, and this, and other quirks of the machine had to be mastered before efficient coding could be done.

High level languages such as Fortran, Algol and Cobol first appeared in the late 1950s, and whilst these eliminated the need for the developer to handle the machine language directly, the languages brought their own problems and abstracted control of the machine from the programmer.

The young developers of that age wanted something better, and both Ken Thompson of Bell Labs and C fame, and Charles H. Moore – inventor of Forth,  came up with their own solutions – to create a comfortable programming environment where they could code efficiently.

Thompson was part of the team including Brian Kernighan and Dennis Richie, working a Bell Labs who brought us the C programming language and the UNIX operating system – which is the basis of Linux and the foundation layer of almost all open source software.

Moore decided that he preferred a language that was closer to the “metal”,  and interactive in nature – so as to avoid the edit, compile, debug cycle – typical of a compiled language such as C.  Moore also believed that the target processor should be able to host it’s own toolchain – and not rely on external resources from a more powerful machine. Key to this was the dual capabilities of Forth – summarised (from Wikipedia) “Forth features both interactive execution of commands  and the ability to compile sequences of commands for later execution.” It is also extensible, in that it has the means for the programmer to create new commands.

Inspired by Chuck Moore’s Forth, and the minimum instruction set computing (MISC) ICs that he subsequently developed, I decided to get to the heart of minimum interactive computing and devise a computing environment that could be applied to the smallest, resource limited microcontrollers and offer the four main features of Forth that I felt were most important

  1.  Interactive – commands may be typed at the keyboard for immediate execution
  2.  Commands can be combined into programs then compiled for later execution
  3.  Extensible – from a small kernel of commands a whole application can be built
  4.  No external tools required other than a serial terminal

These I believe are the minimum requirements for computing – an interactive computing environment that can accessed with nothing more than a serial terminal.

Now some versions of Forth can be very comprehensive and run to about 16Kbytes, though most are between 4K and 6K.  My quest was for a much-reduced “Forth-Like” environment, that was so small, that it could almost become part of the bootloader, and be always present at start-up.  My initial experimentation was with Arduino – as it was so widely available,  but I then progressed to ARM and MSP430 – because of their larger wordsizes.  I settled on the MSP430 as my “model processor”  – because of it’s 16-bit wordsize (ideal for Forth) and the fact that it had a very “clean, orthogonal” instruction set, with a rich set of registers. I found coding in MSP430 assembly language relatively straightforward and thus I use it to test out new ideas.

As a bare minimum, the interactive environment needs to be able to do the following:

  1. Read consecutive serial characters from a UART and place them into an input buffer.
  2. Identify numerical strings from this buffer and convert them into integers to store in RAM.
  3. Use non-numerical characters as the index for a jump table, allowing the processor to branch to blocks of code on the basis of the ascii value of the character.
  4. Execute code at the jump address, then return to fetch the next character from the input buffer.

These actions are best performed by an inner interpreter  running within a loop, which co-ordinates the actions and ensures that the characters from the buffer are interpreted in sequence until the buffer end is reached with a newline character. This is all that is required to form the basis of an interactive character interpreter framework – and in MSP430 assembly language may be achieved in about 300bytes – including the initialisation of peripherals (UART, GPIO etc) and the get_char and put_char UART routines.

The other main aspect of a Forth-like language is that ability to store sequences of commands from the input buffer to memory,  and “compile” them, so that they are available to be run later.

Forth uses the process of giving these sequences a name or “word” and uses a process called the “colon definition” to commit the sequences to memory in an orderly arrangement – such that they may be retrieved and executed later.  Forth uses a dictionary structure to do this which it scans to find the word just typed.  Whilst convenient, this offered more sophistication than I needed so I adopted a much more basic approach.

In order to keep this process extremely simple, I decided that  naming a sequence would just really mean allocating a known character to it, such that it can be executed upon receipt of that character.  Then finding a fixed address to store the sequence could also be based on the value of that character, so that it may be located by a jump table.

So with this simple approach, for example  we can type a sequence  100L   The number decode routine will put 100 (decimal) onto the stack and then jump to the code that is addressed by decoding ascii L. This might be for example a routine that sends a number to a parallel 8-bit port which has LEDs attached.  The routine picks up the value of 100 from the stack and lights the LEDs to give a binary representation of 100.

This was how the programming toolkit started – just the means to decode a single integer number and use it within a given routine to perform some I/O action.

It was decided that capital letters would be used for the user routines, allowing a full 26 different actions, initially passing a single numerical parameter to the routine via the stack.  This was deemed a little limited, so a mechanism was derived to put more parameters onto the stack – so that arithmetical operations could be done.

Forth uses whitespace to separate words, but I thought that the space character could be used to separate sequences of numbers and place them on the stack one after another:

14 29    put 14 on the stack then put 29 on the stack

We can then introduce code that provides the basic maths operators + – * /

14 29+     Adds 14 and 29 leaving 43 on the top of the stack

14 29-     Subtracts 14 from 29 leaving 15 on the top of the stack

Following on from the above example we can then add in the “L”   LEDS command

14 29+L      Illuminates the LEDs with binary pattern for 43

14 29-L       Illuminates the LEDs with binary pattern for 15

So the fledgling language began – a means to perform a series of operations expressed as a string of serial characters. As the language evolved, the following conventions emerged:

Language primitives:   All ascii symbols and punctuation marks ! ” % ^ & *  ( ) _ +  etc

Built in functions:          Lower case characters a to z

User “Words”:                  Upper Case characters A to Z

Assembly Language Implememtation

Tiny-Forths had been explored before – notably on the AVR, a register rich 8 -bit processor but these resulted in about a 2K bytes implementation. My aim was to reduce the core of the language to less than 1024 bytes.

In the winter and spring of 2017, I decided to code up the language in MSP430 assembly language.  This served two purposes, I got to learn a little MSP430 assembly language, and it illustrated what sort of resources were required of a processor in order to implement a compact version of this language.

The MSP430 was chosen because it was a 16 bit processor – and it had a very orthogonal instruction set and a rich set of 16 registers. To me, it represented a blank canvas on which to paint the essence of the language.

The MSP430 code was quite compact with the kernel of the language fitting into some 300 bytes and a full implementation in under 900 bytes.

In the next part I will take the ideas around a self contained 1K byte interactive language toolkit further.

 

 

 

 

 

 

 

 

 

 

 

Posted in Uncategorized | 1 Comment

Minimal CPUs – “One Page Computing”

As I continue to explore the boundaries between computing hardware, firmware and software as part of an effort to reduce the perceived complexity to something that I can understand, the idea arose for a computing platform with an artificially imposed simplicity.

Hackaday has run competitions for the best code application written in fewer that 1024 bytes of code, so this led me to think about what sort of computing machine could be constructed in fewer than 1024, 2-input NAND gates. Memory would not be counted.

It was whilst pondering this when I received a comment to a past blog post from “BigEd” – who is a participant and moderator in the anyCPU forum

As a result of his comment,  I visited the anyCPU forum, and this showed that hardware constrained cpus were nothing new.

anyCPU is a spin-off from 6502.org to address the interests of those actively developing new cpu designs using FPGAs.  Several of these cpus were designed  with influences from the 6502, using the 6502 as a benchmark for the performance of the new designs. This has led to some interesting challenges within the forum – such as to create an 8-bit design with similar or better performance to the 6502, and the “One Page Computing” challenge  – which deserves special mention.

“One Page Computing”

The “OPC” project is to create a fully functioning, useful cpu, who’s design can be captured in just 1 page of verilog code – where a page is defined as 66 lines of 132 characters – or the old green and white, fan-fold, tractor feed line-printer paper.

This artificial design constraint,  puts some interesting challenges on the design – and in remarkable short time – has led to an interesting evolution of cpu designs – that meet this criteria. With each generation of the design, the instruction set has improved, as has the performance.

The OPC challenge was conceived in mid-April and in barely 4 months the OPC design has gone through 6 major iterations as outlined in this github project   This shows that FPGAs can be used to quickly prototype new cpu designs with minimum of expenditure.

The clever folks on the OPC Project now have written an assembler, and there is a C compiler currently being adapted to cater for the OPC6 instruction set.  Another enthusiast is porting PLASMA, a high level bytecoded language to the OPC6.

OPC6 was design constrained by the need for it’s verilog description to fit onto 1 page of printer paper – but this has shown that quite sophisticated cpus can be designed from very little resources.

“BigEd” has done a quick port of the OPC6 onto a Lattice ICE40 – merely to look at the resources used:

After packing: 
IOs 57 / 206 
GBs 0 / 8 
GB_IOs 0 / 8 
LCs 598 / 7680 
DFF 106 
CARRY 64 
CARRY, DFF 0 
DFF PASS 57 
CARRY PASS 3 
BRAMs 2 / 32 
WARMBOOTs 0 / 1 
PLLs 0 / 2 

After placement: 
PIOs 33 / 206 
PLBs 108 / 960 
BRAMs 2 / 32

The after placement figures show that the logic has used about 1/8th of the programmable logic blocks (PLBs) and one sixteenth of the available Block RAM, on the 8k Lattice Ice40.

For comparison – a soft core 6502 uses the following:

After placement: 
PIOs 27 / 206 
PLBs 144 / 960 
BRAMs 0 / 32

With low cost FPGA boards now available, for as little as £40,  supported by an open-source tool chain, there has never been a better time to get started with “One Page Computing”.

The OPC6 is the latest cpu to evolve from the OPC experiment.

It has 16 registers and provides a fairly comprehensive instruction set allowing register to register operations, not dissimilar to the MSP430, but lacking in several of the addressing modes. The conditional predicate bits allow the instruction to be conditionally executed according to the status of the ALU flag bits.

The OPC6 Instruction set is as follows   (See https://revaldinho.github.io/opc/ for full size):

opc6_instruction_set_1

 

 

 

 

Posted in Uncategorized | 4 Comments

Getting started with myStorm BlackIce

dav

 

Getting Started with myStorm BlackIce

Introduction

myStorm BlackIce is a unique combination of low power FPGA and ARM microcontroller designed and manufactured specifically to bring affordable FPGA open source  hardware and software to Hobbyists, Makers and Students.

Working in conjunction with Clifford Wolf’s innovative open source FPGA development toolchain, known as “Project IceStorm”  it allows new digital designs to be written in verilog, synthesised and programmed into the FPGA.

The features found on BlackIce offer the user access to the widest variety of devices and expansion interfaces including PMODs, microSD, SRAM, LEDs switches and buttons.

External circuits connect via the PMOD connectors – and these are available from a variety of sources or for the experienced hobbyist some of these expansion devices may be created at home – using readily available hardware.

Few FPGA development boards feature a powerful 32-bit ARM microcontroller on board , such as the STM32L433 – but it was found at the development stage of the myStorm project that including a microcontroller greatly widened the scope for experimentation, and provided a powerful, versatile, support chip to the FPGA.

The STM32 provides the programming interface for the FPGA, so that it may be programmed over USB using little more than a serial terminal program.

For Windows Users  – TeraTerm is Recommended.

For MAC OS X  Users   – CoolTerm

For Linux Users –  see notes below

Alternatively the FPGA may be programmed via a Raspberry Pi – particularly useful if the Raspberry Pi is being used to host the FPGA development toolchain.

 

Project Icestorm

Project IceStorm was written by Clifford Wolf with contributions from others – and it is used to program a range of FPGAs entirely using open source software.  It is a viable alternative to the proprietary toolchains provided by FPGA vendors which often consume tens of gigabytes on the hard drive. Project IceStorm is tiny by comparison.

Project IceStorm aims at reverse engineering and documenting the bitstream format of Lattice iCE40 FPGAs and providing simple tools for analyzing and creating bitstream files. The IceStorm flow (YosysArachne-pnr, and IceStorm) is a fully open source Verilog-to-Bitstream flow for iCE40 FPGAs.

The focus of the project is on the iCE40 LP/HX 1K/4K/8K chips.   BlackIce uses the iCE40HX4K-TQ144 part

The typical workflow involved in creating a working FPGA design

  1.  Create your design using the verilog hardware description language using a text editor.
  2.  Submit the verilog file (eg design.v) to the YoSys Logic Synthesiser
  3. Invoke the Arachne Place and Route to act on the YoSys output file
  4. Use the IceStorm toolchain  (icepack, icebox, iceprog, icetime, chip databases) to create the bitstream file
  5. Program the Bitstream file into the FPGA

Whilst this set of operations may seem quite complex – it can be automated either from the command line,  or by using the APIO IDE – which is a cross-platform IDE tailored to the requirements of FPGA design projects.

 

The STM32L433 Microcontroller

On the left hand side of the BlackIce pcb is the 64 pin microcontroller which acts as the support device for the FPGA – primarily handling the programming function.

The STM32L433 has 256K of flash memory and 64K of SRAM clocked at a maximum of 80MHz.  It is a powerful microcontroller in its own right – similar in capability to an Arduino Due.

20 of its GPIO lines are brought out to Arduino style headers for maximum flexibility and access to analogue and digital interfaces.

When not being used for programming, the microcontroller can be used for the User’s own application firmware – in a choice of languages including C/C++, Forth or JavaScript (Espruino https://www.espruino.com/) and MicroPython (http://micropython.org/)

The STM32 may be programmed with Arduino (1.8.3 or later) or using the mbed online compiler.  Forth enthusiasts can use Mecrisp Ice V0.9 – which has been specifically tailored to support the STM32 and the ICE40 FPGA.

The STM32 is used to buffer the bitstream file – that is the binary format file that is used to program the FPGA with its logical design.  This bitstream file is created using an open source toolchain called Project IceStorm.

Why a Microcontroller?

The STM32L433 microcontroller is a powerful 32-bit ARM Cortex M4 device clocked at 80MHz and offering 100DMIPS. It is however one of the ultra-low power series – so perfectly complements the iCE40 – which is also a low power part.

Every FPGA needs some supporting hardware to allow the Bitstream file to be programmed into it’s internal RAM – and this is very often done by an FTDI device – the FT2232.  However this FT2232 is an expensive part, costing about $4.50, and it still needs a $0.30 Flash memory to hold the bitfile.  Once the FT2232 has programmed the Flash chip, it can then serve as a UART to USB interface for the FPGA.

When we designed myStorm, we decided that the cost of the FTDI device was prohibitive – and we could get a lot more value from the board by spending that part of the budget on a high spec microcontroller – and using that to provide the FPGA programming function.   When not actually in programming mode – it can be used to host the User’s application – which can be written in a variety of languages.  The result is that you get a general purpose microcontroller development board, with access to 20 lines of digital and analogue I/O – capable of working with some of the currently most popular microcontroller environments.

The microcontroller adds support and versatility to the FPGA, and for some designs the combination of FPGA and ARM will give rise to some unique projects.

The mcu and the FPGA are connected via a Quad SPI bus – capable of running at 60MHz – or 240Mbit/s.

The mcu provides analogue peripherals including a multi-channel 5MSPs 12bit ADC and two 12-bit DAC channels

BlackIce offers features not found in other comparably priced FPGA boards

More PMODS – a total of 6 double and 2 single PMODS   = 56 GPIO lines appear on PMODS including differential LVDS lines

For compatibility – further GPIOs have been routed to an Olimex expansion board header

STM32 ARM Cortex co-processor acts as a complete support system for the FPGA – offering a convenient means of programming the FPGA

The STM32 mcu adds 20off  5V tolerant analogue and digital I/O routed to Arduino style headers – including  6 analogue to digital converter inputs and 2 DAC outputs with 12 bit resolution

STM32  can be used as a slave set of standard peripherals to the outside world – including timers, ADC DAC, SPI, I2C and USB

It can be programmed using STM32Duino, mBed Nucleo, MeCrisp Forth.

BlackIce includes a 256Kx16 SRAM closely coupled to the FPGA

microSD card socket on underside of pcb – which may be accessed either by the FPGA or ARM mcu

Using APIO to manage the ToolChain and Development Process

The APIO package is a plug-in for the open source Atom Editor environment. It was written specifically to manage projects involving the Project Icestorm toolchain and Lattice ICE40 FPGAs.

Project Icestorm consists of several stages which are conveniently managed by the APIO IDE which is a derivative of PlatformIO – specifically tailored to meet the needs of the Project  IceStorm toolchain.  APIO runs as a module within the Atom Editor Environment.

The advantage of using an IDE such as APIO, is that it works across all platforms, and provides a convenient way of managing the toolchain and the various modules (files) that make up the design project.

The design is coded in verilog, and it’s then just a case of building the project.

This invokes the YoSys “Logic Synthesiser” and the Arachne “Place and Route” tools. It then takes the p&r file and converts it into a binary “Bitfile”  which is used to program the FPGA.

On BlackIce, an STM32L433 ARM  M4 Cortex microcontroller is used to manage the programming of the ICE40 FPGA.

The STM32 device runs an application firmware called “Iceboot”  – and this allows the binary bitstream file to be loaded via the STM32 and then into the FPGA.

This is done via the native USB device port on the STM32 microcontroller using a terminal program such as Teraterm, using it’s “Send File” option from the File menu tab. Ensure that the Binary option is checked on the file selection dialogue box. FPGA loading takes only about 2 or 3 seconds.

 

Programming the STM32

In our application the STM32 runs the programming firmware “Iceboot”. However it can be programmed to permanently retain the FPGA bitstream image – so that this is automatically loaded on power-up. This may be useful for demonstration purposes where you want the FPGA image to be non-volatile.

Additionally, the STM32 may be programmed with application firmware, provided that this does not interfere with the FPGA loading mechanism.

20 lines of GPIO, including six ADC channels are brought out to Arduino-style expansion connectors, and these are available for User experimentation.

The STM32 is readily programmed using mbed – as it can be made to look like a Nucleo device – using a ST-Link to program it.  Later versions of the Arduino IDE now support the M4 Cortex microcontroller – so this may also be used.

Alternatively it can be put into DFU  (Device Firmware Upgrade) mode by removing the jumper link connected across the 7th and 8th pin of the right hand row of header pins. Reflashing the firmware using DFU is an advanced topic, and is covered in the Appendix.

Arduino Headers

These headers allow access to many of the interfaces on the microcontroller including ADC inputs,  DAC outputs, SPI, I2C and UART interfaces and timer inputs and outputs.  They also access the four  “slide switch” inputs that connect to both FPGA and ARM.

The headers run east-west across the centre of the board, and break out many of the ARM microcontroller GPIO signal to a set of connectors that are compatible with Arduino shields.  Note that whist these GPIO lines are 5V tolerant – the rest of the board is 3V3 only – so extreme care should be exercised when working with mixed supply rail designs.

Shields

The Arduino Shield headers can be used to access up to 20 digital lines and 6 analogue lines.

50mm x 50mm square pcbs may be conveniently mounted  – or an extended shield 60mm x 50mm will pick up all  14 LVDS pairs from the Olimex connector.  Care should be taken however because the FPGA lines are not 5V tolerant.

Switches

There are to user push button switches which connect to both the microcontroller and the FPGA. These are useful for when a logic design requires momentary intervention.

They are connected to pins  PC8 and PC9 of the microcontroller and pins 63 and 64 of the FPGA.

In addition to the push switches on the left, there are four DIP slide switches arranged in two banks of two. These also connect to both the mcu and the FPGA and are also exposed to the outside world via pins on the “Digital 3” connector of the Arduino Headers.  They are useful for setting up a mode of operation or connecting to external stimuli.

To the right of the mode switches is a Reset Button which provides a momentary active low reset signal to the microcontroller.  This is independent of the high going reset signal that the microcontroller sends to the FPGA at the time of programming.

 

System connector – sometimes called the “Pi Header”

This is a 2 x13 male header on the left hand edge of the pcb which carries certain signals that allow the FPGA to be programmed from an external device such as a Raspberry Pi. It has a mix of programming pins, control pins and power.

The UART RX and TX signal  lines from the FPGA also appear on pins – compatible with the position of the corresponding UART pins on the Raspberry Pi expansion header. Full details of these signals are in the appendix.

Programming Jumper Link.

This is a 2.54mm jumper link which normally bridges across pins 14 and 16 of the system connector.  When removed, it forces the microcontroller into DFU boot mode (Device Firmware Upgrade), which allows it to be programmed with new system firmware. Occasionally there may be a firmware upgrade posted in the myStorm repository to provide new features.

The microcontroller may additionally be programmed using a low cost “ST Link”  – a small system programming device – which may be sourced cheaply from ebay. This plugs into the programming pins of the system header.

For normal operation, the jumper link must remain across pins 14 and 16.

PMODS

These are an industry standard interface connector originally devised by Digilent – a major manufacturer of FPGA development boards.

They come in 6 pin or 12 pin (2 rows of 6 pin) right angled female headers, organised on a specific pitch spacing between connectors.

The connect directly to the FPGA GPIO pins and also carry 3V3 and 0V power.   Small external circuit boards, carrying a variety of expansion circuitry or devices may be plugged directly into these headers – picking up 4 I/O pins for a single PMOD, and 8 I/O pins on a double PMOD.

On BlackIce there are two single PMOD connectors and 6 double PMOD connectors.   The double PMODs on the right hand edge of the pcb carry the fast LVDS (low voltage differential signalling) pairs of signals – and these may be used for driving the most demanding of high speed hardware.

A total of 56 GPIO lines  (including 14 pairs of LVDS lines) are brought out via the PMOD connectors.

There are a whole range of third party PMODs available from a variety of suppliers – such as ADCs, 7 segment displays, audio codecs etc, etc.  See here for further information plus a selection of what is available:  http://store.digilentinc.com/pmod-modules/

The small size of PMOD circuit boards makes them a convenient size for home construction – taking advantage of low cost pcb manufacturing services.

Olimex Expansion Connector

This is a 2 x 17  2.54mm connector that accesses 28 of the FPGA GPIO signals and is compatible with the range of expansion modules supplied by Olimex.   These low cost  modules include ADC, DAC, VGA & PS/2, and buffered digital I/O.

To take advantage of this – a 2 x 17 pin male header should be fitted in this position, or a 2×17 right angled box header fitted from the underside of the board.  More details in the appendix.

MicroSD Card

On the rear of the pcb is a microSD card socket which may be accessed from the FPGA or the microcontroller.

SRAM

Also on the rear of the pcb is a 256Kx16 fast (10nS) asynchronous SRAM – directly connected and closely coupled to the FPGA. This can be used in FPGA designs where additional external storage is required.

Other Features

BlackIce is provides with a 100MHz oscillator module from which internal clock signals for the FPGA may be derived via the internal PLL (phase locked loop) module.

Multiplexer

A small 2 way multiplexer chip allows selection between external programming of the FPGA from the system connector, or onboard programming from the ARM device.  When onboard programming is selected it routes the output of the FPGA signals P52, P53,P54 and P55 to the SPI bus of the microcontroller, whilst ordinarily these are used for driving the LEDs.

https://www.olimex.com/Products/FPGA/iCE40/

User LEDs

There are four coloured LEDs available to the user Blue, Green, Amber and Red.  These can be used to indicate certain status within the FPGA, or to create for example a traffic light display.

An additional STATUS LED is connected to port PC13 of the microcontroller – and can be used for user purposes if the user is developing code for the microcontroller using Arduino, mbed or similar.

A further red LED indicates that the FPGA programming has been DONE.

The power white LED shows when 5V power is connected.

Powering the Unit

The board may be powered from either microUSB socket or from the 5V power and 0V ground pins on the 2x13way connector.

There are two microUSB connectors:

sdr

sdr

This one closest to the ARM chip, just below the 2×13 pin system connector is the direct USB connection to the STM32 microcontroller – and is used primarily for sending the programming bitfile to the mcu.

The lower of the two microUSB sockets connects to a USB-UART converter IC, and is used to communicate serially with the FPGA – assuming that your logic design contains a suitable UART module. It may also be used to convey serial data from the ARM mictocontroller, and on first power-up or following a reset it sends the message showing the firmware revision.  The firmware running on STM32 connects to this com port at 115,200 baud.

Sending a Bitstream file to the BlackIce Board

There are two USB sockets:

  1. Programming Port

The one closer to the middle of the board is connected to the USB interface on the microcontroller – and if you plug into this one  – it will appear as a virtual com port, capable of running at more than 1 Mbit/second.

This is the one that is primarily used to transfer the large bitstream file from the laptop, through the microcontroller and into the FPGA – very quickly – in a couple of seconds.

After you have sent the bitstream file and it is correctly loaded – the message should then say

Config done

 Waiting for UART or USB serial

 

2. UART Port

The microUSB port nearer the corner of the board is connected via a CH340 USB converter to the UART lines of both the microcontroller and the FPGA.

This port is normally used for getting serial input/output from the FPGA  – provided that your logic design included a suitable UART connected to the correct pins.

However, at start-up or following a reset of the STM32 it is used to send a start-up message. Following this message, the STM32 switches it’s Tx line to a high impedance input – allowing the FPGA UART access to the com port adaptor.

If you plug into the lower port – set up a 115,200 baud terminal and press the  reset button (top right) you should get this message on the terminal screen

Mystorm Version 0.3
Setup Done

Note that the version is now 0.3 –  you may previously have been using version 0.2

DFU Programming.

This is an alternative programming method that uses “Device Firmware Upgrade” – which is a factory built in bootloader within the STM32 microcontroller.   DFU is used for 2 specific purposes:

  1. To put new firmware onto the STM32
  2. To load an image of the FPGA design into the flash memory – so it loads this on power-up.

Putting new firmware on the STM32 is covered in Appendix 1.

The other thing to note is that you must keep the jumper link fitted across pins 14 and 16 of the “system” connector.    This is only removed when you want to update the firmware that runs on the microcontroller.

Availability

The myStorm BlackIce boards are now available in production quantities – and priced as follows:

For Customers in UK £40 + £2 postage
For Customers in EU 45 Euros + 4 Euros shipping
For Customers in US $52.50 + $7.00 shipping

For world wide customers – please contact me and ask about shipping costs.

You can PayPal me at ken dot boak at gmail dot com to place an order or discuss volume discounts.

 

Appendix 1.

How to Update the STM32 Firmware using DFU Mode

BlackIce uses an STM32L433 ARM M4 Cortex microcontroller to act as the FPGA  programming and support chip. It allows the upload of the bitstream binary file using the native USB port of the STM32.  This is done using the microUSB connector closest to the ARM processor and using a terminal emulator program such as Teraterm or CoolTerm.
Occasionally the support firmware “IceBoot” will need to be updated – and this is done using the dfu mode – or Device Firmware Upgrade mode of the STM32.  This is a factory installed bootloader which allows the firmwate on the STM32 to be upgraded via USB.
In order to invoke DFU mode – the shorting link fitted between pins 14 and 16 of the “Pi Header” needs to be removed.  This allows a pin to be released from being held low and this forces the STM32 into dfu mode.
Once in dfu mode, it is possible to use the STMicroelectronics Dfuse application (for Windows) or the dfu-util program with Linux to load the new firmware into the STM32.
If you are using the Windows application, the firmware has to be first converted into “dfu format” and this is done with another application called “DFU File Manager” which is bundled with the STM software tools. This can be used to convert a binary or HEX format file into the required dfu format, before using the dfuse programmer application.
How to update the Firmware – for Linux Users

 

For Linux users this process is a little easier as this file conversion is handled automatically by the dfu-util.  Here’s Matthew Venn’s description of how to do this
Here’s how on Linux (works for Ubuntu 14).

Unplug blue jumper on pin7&8.

Plug USB cable into socket closest to ARM chip.

Use lsusb to find the device:

  lsusb
  Bus 001 Device 026: ID 0483:df11 STMicroelectronics STM Device in DFU Mode

Use dfu-util (sudo apt-get install dfu-util) to list DFUs:

  sudo dfu-util -d 0483:df11 -l
  dfu-util 0.5

  (C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.
  (C) 2010-2011 Tormod Volden (DfuSe support)
  This program is Free Software and has ABSOLUTELY NO WARRANTY

  dfu-util does currently only support DFU version 1.0

  Filter on vendor = 0x0483 product = 0xdf11
  Found Runtime: [05ac:828f] devnum=0, cfg=1, intf=3, alt=0, name="UNDEFINED"
  Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash  /0x08000000/0128*0002Kg"
  Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=1, name="@Option Bytes  /0x1FFF7800/01*040 e"
  Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=2, name="@OTP Memory /0x1FFF7000/01*0001Ke"
  Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=3, name="@Device Feature/0xFFFF0000/01*004 e"

We want the internal flash (alt=0), so now with the iceboot.dfu:

  sudo dfu-util -d 0483:df11 -D ~/Downloads/iceboot.dfu --alt 0
  dfu-util 0.5

  (C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.
  (C) 2010-2011 Tormod Volden (DfuSe support)
  This program is Free Software and has ABSOLUTELY NO WARRANTY

  dfu-util does currently only support DFU version 1.0

  Filter on vendor = 0x0483 product = 0xdf11
  Opening DFU USB device... ID 0483:df11
  Run-time device DFU version 011a
  Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash  /0x08000000/0128*0002Kg"
  Claiming USB DFU Interface...
  Setting Alternate Setting #0 ...
  Determining device status: state = dfuIDLE, status = 0
  dfuIDLE, continuing
  DFU mode device DFU version 011a
  Device returned transfer size 2048
  Dfu suffix version 11a
  Warning: File product ID 0000 does not match device df11
  DfuSe interface name: "Internal Flash  "
  file contains 1 DFU images
  parsing DFU image 1
  image for alternate setting 0, (1 elements, total size = 22744)
  parsing element 1, address = 0x08000000, size = 22736
  done parsing DfuSe file

Then unplug usb, put jumper back, plug into other USB socket and check dmesg:

  [108129.748055] ch341 1-1.2.3.4.3:1.0: ch341-uart converter detected
  [108129.749285] usb 1-1.2.3.4.3: ch341-uart converter now attached to ttyUSB0

Check serial output:

  miniterm /dev/ttyUSB0 115200
  --- Miniterm on /dev/ttyUSB0  115200,8,N,1 ---
  --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---

Press reset button:

  Mystorm version 0.2
  Setup done
  Waiting for UART

Now you should be able to flash your mystorm like this:

cat chip.bin > /dev/ttyUSB0

(takes about 10 seconds).

 

Appendix 2.

 

STM32 GPIO Pin Out

Pin Port Primary  Analogue Other 
DIG0 PC4 USART3TX ADC_IN14
DIG1 PC5 USART3RX ADC_IN15
DIG2 PB1 ADC_IN9
DIG3 PB10 USART3_TX
DIG4 PB11 USART3_RX
DIG5 PA5 ADC_IN5
DIG6 PA8 TIM1_CH1
DIG7 PC6 TIM3_CH1
DIG8 PC7 TIM3_CH2
DIG9 PA4 ADC_IN4
DIG10 PB12 SPI2_NSS
DIG11 PB15 SPI2_MOSI
DIG12 PB14 SPI2_MISO
DIG13 PB13 SPI2_SCK
DIG14 PB9 I2C1_SDA
DIG15 PB8 I2C1_SCL
DIG16 PD2 GPIO SW1
DIG17 PC10 USART3/4 TX SW2
DIG18 PC11 USART3/4 RX SW3
DIG19 PC12 USART3/4_CK SW4
A0 PC0 ADC_IN10
A1 PC1 ADC_IN11
A2 PC2 SPI2_MISO ADC_IN12
A3 PC3 SPI2_MOSI ADC_IN13
A4 PA0 USART4_TX ADC_IN0
A5 PA1 USART4_RX ADC_IN1
Posted in Uncategorized | Leave a comment