Labels

Thursday, 10 February 2022

TinaLinux on Nezha

 Generally I am happy with Debian as the OS on a microprocessor.  I am most familiar with it since it is installed on RPi and I use it regularly.

Allwinner have developed TinaLinux for thei embedded systems.  It is based on OpenWrt which was initially targetted as a Linux implementation for routers.  TinaLinux compressed images are upto 100MB in size compared with about 1GB for a Debian image including GUI.

Some Sipeed D1-Nezha boards apparenly had TinaLinux in flash memory when they were delivered but mine didn't and I wanted to find out more.  There wasn't a Tina image available for the Nezha, although there is one for the LicheeRV, and I successfully booted the LicheeRV Tina SD card on Nezha.

Allwinner provide an SDK for creating Tina builds - you can specify in great detail which Linux features and comands you want to include and use the Linux "make" command to compile the software and build the image.  Images can be burned to SD card or copied to Nand flash memory.  When you boot from an image you can test that the features and commands work as expected.

Setup SDK

There are various pre-requisites and requirements for the environment hosting Tina SDK.  In particular, you are advised to to use an old (v14 from 2014) version of Ubuntu.  Luckily a Virtualbox VM is available from Allwinner which has been setup with appropriate software.  I downloaded it (1.6GB) and started it up in the VirtualBox environment.  The VM supports shared folders and has a network connection so I am easily able to transfer files to / from the VM and download software from the internet.

The next step is to download the Tina SDK from Allwinner.  A user registration is required together with a public key from the recipient machine to obtain access to the download.  I created keys with  ssh-keygen on my Ubuntu VM and uploaded the public key to the Allwinner site.  Following their instructions I used the repo command to download the SDK from github.  The download took well over two hours and resulted in 11GB of software in the tina-d1-open folder.

Build an Image

Rather than doing any configuration I decided to build an image based on the configuration provided.  It took some time to compile everything, but after 8 hours I saw a message saying the build was successful.  I was then able to pack the image, copy it to Windows and use PhoenixCard to burn it to SD card.  Amazingly the SD card booted into linux (the first part of the boot is shown below) and I was able to sign on to TinaLinux on the serial console and have a look around.


Test the system


The first problem I had was that the filesystem has no spare space, and in fact it is read-only - which is appropriate for a nand flash load but doesnt help me.
It took me a while to work out where the system partition table is defined within the Tina SDK but once I had made it somewhat bigger and rebuilt the system I had some space available.  Of course the make utility only recompiles changes and the rebuild was complete in 10 minutes.  I couldn't find a place in the SDK to make the root filesystem read-write so I remounted the disk at first startup.

Now that we have a system we can configure I tried to get a network.  The ifconfig and udhcpc utility will start up ethernet but wifi would't work for me.  With ethernet working I rebuilt the system to include sshd-server and after booting I was able to start sshd and ssh into the system from a remote terminal.

For the moment I don't want to do too much configuration.  I contented myself with adding a small web server (uhttpd) and fdisk providing the ability to modify partitions.

Each time the system is rebuilt any tailoring is lost.  Luckily my Nezha has a USB stick plugged in and it is useable from Tina so I created a script on the stick which I can run on boot.  This mounts rootfs read-write, starts sshd and permits root to have ssh access locally.

In conclusion I am very pleased that I have been able to build a TinaLinux system and test it on the Nezha.






Saturday, 29 January 2022

Sipeed LicheeRV Panel

Intro

The Sipeed LicheeRV 86 Panel is a very exciting product.  It is based on the same LicheeRV D1 board and dock but it includes a 4" touch screen and ethernet connection.  At $72 it is somewhat more expensive than the basic boards but it is much closer to being a self-contained working system.  It works on 5V USB or 12V supply.  The panel comes with a case which protects the board which is attached to its rear side.  In fact it could easily provide the basis for a home automation control.  It is only about the size of a light switch and could easily be wall mounted near a door way to activate room functions.  The only extra needed is a 12V power supply (similar to the one used by low voltage LEDs).


There is plenty of documentation available on the Sipeed BBS and the linux-sunxi community web-site has started to add descriptions.

Installation - Tina


I first installed the Tina WAFT (WebAssembly Framework for Things) image using good instructions which Sipeed provided, translated to English with Google Translate.  A USB cable connected to the USB-C UART port at one end and the PC at the other to provide power and a serial console.  The system boots in about 5 seconds into Maix Linux.  Tina / MaixLinux is a very small IoT (Internet of Things) linux which uses Busybox to provide basic command line tools. The image is only 115MB in size so it is great for small systems. I quickly tried looking at using WAFT but the demo didn't seem to work.  In addition, the panel screen didn't work initially (rapid scrolling of the image) so I moved on Debian.



Installation - Debian


The debain image is somewhat larger.  Initially I chose LicheeRV_Debian_86_480p.7z. It was easy enough to download from mega.nz although it was 1.1G compressed and expands into a 4GB image.
As usual I used PhoenixCard software to burn the image and inserted in the SD card on the back of the panel.  The system boots up without many errors and you can sign on via the serial console (putty) as sipeed or root.

The Panel has an ethernet connection using a rather unusual connector onto the back of the panel which is shown below.  The cable provided has an RJ45 and a barrel connector on one end and circuit board connectors for ethernet (on the left) and power (on the right).  If you want you can use the 12V power connector instead of using USB power input.  With the ethernet connected we can easily signin to the system using ssdh

When the system was booted up the 4 inch screen showed a signon screen scrolling vertically and was unuseable.  I tried all the different images, both Tina and Debian but the screen problem remained.  Eventually I tried over-writing the "fex" partition on the SD card (partition 1) with the fex file for a 720p display.  On booting the system works perfectly.  So the problem was that the downloaded images were for a 480p screen, which is the one which is described in the advert.  However I have a 720p screen which needs a different fex file.  I reported this on the LicheeRV/Nezha Telegram thread and a note will be added to the linux-sunxi community webpage to explain this.
I plugged a screen and keyboard into the HOST USB port and I was then able to signin to Debian.  The screen is 720p x 720p so although it is very small it is very detailed and if you look closely enough it is quite useable.  As a first test I ran HTOP to display system usage.
I wanted to display an image and there weren't any I could find on the system.  I needed to install wget using the apt package manager and could then download an image from my website and display it on the panel.  It looks very clear.

Initially I couldn't get the wireless interface to work on either Debian or Tina.  Once I realised that I am using the 8723ds wireless chip (not the xr829) I retrieved the correct images and wifi networking works fine.

I now have available a lovely RISC-V panel with ethernet / wifi with a small high quality screen. 





  





Thursday, 27 January 2022

Sipeed LicheeRV Dock

 A couple of weeks after I saw the Sipeed LicheeRV advertised and bought one, the LicheeRV Dock became available.  A docking station for the LicheeRV costs about £4.  I ordered a LicheeRV + Dock on 29th December and it was delivered 13th January.  The docking station provides a HDMI connection, a USB port, 40 pin connector and wifi (Realtek 8723DS), so there are many more things you can do with it.

 


Its specification is very similar to the Nezha which came out 6 months ago but it is about 1/3 the price.  This was expected, the Nezha gave people an early look at RISC-V.  The LicheeRV is more of a product.

Documentation for the LicheeRV is now available on the sipeed BBS and it is quite extensive.  Although it is initially in Chinese,  Google Translate does a perfectly acceptable job translating it into English for me.



There are also a number of images available to make installation easier.  Firstly I tried the Debian image and, once I had plugged a screen in on the HDMI port and a keyboard/mouse on the USB port I was ready to go.


It was easy to boot into Debian and use the GUI.  Once I worked out the wifi is RTL8723DS and chosen the right image I could configure the wifi and SSH into the system easily enough.

Similarly Tina is easy to setup.  I downloaded and burned the image for tina hdmi 8723 and booted up.  I was then able to configure wifi details and connect to the network.

The screen is used as a monitor rather than a terminal I think.  When booting it show a 480x480 screen shot in chinese with a date 2021.12.8.  I can display a color bar test but the frame viewer doesn't work for me (yet?).


So for about £20 I have a working RV system with network, HDMI and a choice of Operating Systems.




Tuesday, 25 January 2022

LFS : Linux from Scratch

 Why

Linux installation is straightforward.  For an RPi you just download an image in Windows, burn it on to an SD card, insert the card in RPi with screen, keyboard attached and turn the power on.  Adding network capability is similarly easy, in Raspbian you specify the package name to the apt command and the necessary steps are completed to install dependencies and the requested software.

From other activities I know that setting up partitions and choosing a kernel are also important.  Building a kernel is a matter of ensuring you have all the necessary files and running one long compile job.

The missing part of the picture is the ability to set up all the basic software in files and folders so that the system works.  It turns out that, as expected, there is a lot of work involved.  Thanks to the LFS (Linux from Scratch) project and the PiLFS ( RPi LFS) guide I have been able to successfully build my own minimal system, sign on, add packages etc.    

It is a challenging objective and the LFS team have done an amazing job in making each of the 100 or so tasks understandable so that you can create the Linux system you want.  Even with this  I would have struggled to build my own system.  PiLFS provides a guide to how to implement LFS on a Pi system together with a host configuration containing working build software and two large scripts to automate many of the tasks.  I feel that LFS is awesome and I'm grateful to PiLFS for making it practical to build with my patchy Linux knowledge.

Host System

You need a set of software running on the host system to be able to build linux, the list includes kernel, c compiler, make and various utilities:

bash  binutils  bison  bzip2  coreutils  diffutils  findutils  gawk  GCC  glibc  grep  gzip  Linux-kernel
m4  make  patch  perl  python  sed  tar  texinfo  xz

This isn't a long list bearing in mind the scale of the work we are undertaking.  I use a RPi4 as my host system.  PiLFS provide a RPi image so we can be sure we start with the correct pre-requisites.  We boot RPi with the image and we can start building. 

The first task is to make a new partition as a target for the software which is built.  Following PiLFS suggestion create a new partition (20GB) on the SD card.  All the software will be installed in the root file system; on completion we boot software from the new partition.

Download software and create LFS user

A number of tarballs are downloaded containing sources for software to be installed on our new system.  They are installed in the /sources folder on the new system.  There are also some patch files which will need to be applied.  Software is downloaded from the linux from scratch website which ensures that packages are all at compatible levels.

A userid LFS is setup to carry out compilation tasks for the new system.  Good practice says that root should only be used when necessary, LFS is able to carry out most of the work.

Create Toolchain and utility tools

The first thing we need to do as user lfs is build a toolchain for the new system.  Binutils is created first, it provides a linker and assembler.  Next we compile GCC onto the new system - of course we are using GCC on the host system to do the compilation.  Our task is made easier because both our host and target systems are RPis so GCC is going to work.  A proper cross-compiler would be (even) more challenging.

The remaining toolchain software we need is linux-headers, glibc and libstdc (for c++).  These five builds are quite complex and PiLFS provides a script which automates the process for us.

The script also compiles utilities which will be required on the new system m4, ncurses, bash, coreutils, diffutil, file, findutils, gawk, grep gzip, make, patch, sed, tar, xz. 

Entering Chroot

The chroot command allows us to use the new filesystem we have created with the existing kernel. The chroot environment doesn't have access to the host software.  Before entering chroot we have to setup the virtual filesystem that the kernel uses to manage / communicate with software running in the environment. 

Within chroot, as root user, we create some essential files (/etc/hosts. pwsswd, group) and compile some more tools (gettext, bison, perl, python, texinfo, util-linux).

Building new system software

We are finally ready to do the proper build of all the software on the new system.  There are 73 steps to carry out and PiLFS has simplified the process by putting all the builds into a script for us.
Many hours later the build is finished.

Finale

One of the last tasks is to setup a filesystem table (/etc/fstab) for the target system.  It looks very similar to the host except that the root partition is changed to the one we have just been building.

In our simplified environment we are going to use the same kernel as before - there is no particular advantage in building a new one and we can do it as a separate exercise whenever.  In addition we have been working for many hours to get this far and I want to see if it works... 


it does :):):)

Amazingly we have our own working linux system.  Anything that works has been done by us and anything that doesn't is yet to be installed.  It is very satisfying.  Thanks to the LFS project I know (or can find out by checking the doc) what all the components are, how they are built and what they do.  In particular LFS has an excellent summary of the relevant configuration options used to create the software.

Next Steps

There are a few extras we need to add for a basic working system:
openssh - needed to login from a terminal session, in particular to be able to copy / paste commands.
wget - needed to download packages to extend our system
ntp - RPi has no clock so we need to obtain the time at each system startup.

We can also install other software installs facilitated by LFS or attempt our own installations from github etc.

In conclusion this is a wonderful exercise to help me understand what I am using on a Linux system.







Sunday, 16 January 2022

Sipeed LicheeRV

 Back in June 2021, I was fortunate enough to spot that the Sipeed Nezha RISC-V development SBC was on sale.  It is the first Linux RISC-V SBC system for less than $100 and marks the beginning of a new era in home / hobbyist computers.  It is based on the Raspberry Pi form factor and runs Debian Linux.  I have greatly enjoyed getting to know it and particularly using it to write some simple RISC-V assembly programs which I can compile directly using the GCC compiler.

On 24th November I saw on the Sipeed twitter feed that the Lichee RV is for sale.  It uses the same processor as the Nezha but has very few peripherals on board and no GPIO pins.  An SPI connector is used for an LCD screen and there is an SD card holder.  Instead it has an m2 connector which can connect to external devices such as Ethernet, wifi, bluetooth.  It costs $13 as opposed to the Nezha $99 crowdfunder price and doesn't have a limit on the number available.

 I purchased the version with a screen (total $17) on Ali Express and waited in anticipation for it to be delivered.  It arrived in the UK on 4th December and was delivered 16th December so I was one of the first to receive them outside China, certainly an early arrival in Europe.

Initially I wasn't sure what to do with it, my Nezha SD card didn't seem to do anything.  On 24th December O-GL in France and Daniel Maslowski in Germany on Telegram provided me with the information needed.  There is an international download folder on mega.nz and a  set of tutorials on the sipeed forum.


On 4th January I was  lucky enough to look a the Mega.nz site and see that a zip file for an Ubuntu 20.04 build including the LCD had just been uploaded.  It was slightly more complicated to download than the usual images, I had to locate files manually in the correct part of the SD card.  However this meant that the download was 167MB instead of 1.07GB so it was worth the extra work.  Initially the build did nothing but on 5th January someone on Telegram posted a correction to the instructions and the result was that I could get a working Ubuntu Linux with tiny LCD console.


Of course there wasn't a lot I could do with just a screen but I was quickly able to solder on the four pins in the bottom left corner of the board so that I could connect an FTDI cable, allowing me to sign on to a serial console session.
So I now have a working Linux system on a tiny 6cm x 4cm board - a bit similar to the RPi Zero.

I was also able to download Debian and Tina images and create SD cards.  The Sipeed tutorial provides console commands to switch the on board LED on/off using GPIO commands and Iwas able to check that this works.  The basic board doesn't have any networking capability so I had to await my LicheeRV dock before progressing much further.







Saturday, 15 January 2022

Christmas Lights Improvements last year

 For the past few years I have set up music controlled colourful Xmas lights using Lightshow Pi software (LSPi) running on a Raspberry Pi RPi.  LSPi software hasn't changed in the past three years but it still works and support is still available from enthusiastic users, particularly SoftwareArtist.  I started my updates for Xmas early in December 2021 which helped me produce something useful in time for Xmas day.

Last year I ran the music (MPD) and LSPi on the same server.  My RPi server used for this application had a disastrous SD card failure during the year so I needed to reinstall software on my shiny new RPi4 application server (PI41) this December.  Luckily LSPi configuration was backed up and my notes on installation was up to date.  Currently the MPD music player is active on my web server (PI40) along with the web pages to select and play music.  

LSPi Installation is well documented on reddit.  I followed  the instructions, which have been updated for RPi4.  I encountered one error in building "rpi-audio-levels" which the helpful SoftwareArtist on reddit provided a solution for.  Once I updated RPi firmware, LSPi installation worked fine and I was able to test that LSPi on PI40 was controlling GPIO output properly.

The LSPi configuration required for my setup is quite simple.  Music is streamed in from MPD on PI40 and RGB output provided on three GPIO pins.  The sample LSPi configuration file has detailed explanatory comments for all the options but my cutdown file only requires a few.
The most important command is "stream_command_string" which causes LSPi to listen to the music being played on PI40 by MPD.  Clearly MPD needs to be setup with a streaming output on port 8000 to achieve this in mpd.conf






I found by trial and error the pin_modes, pwm_range and attenuate_pct settings to give a pleasing range of colours on the output.  We need to set preshow_configuration to null to avoid a few seconds delay before the lightshow starts.  I was grateful that this solution avoids the syncing problems I have previously experienced with the lights being a secnd or two behind the music.  The current solution is quite impressive, RPi is calculating Fast Fourier Transforms (FFTs) in real time to determine music frequencies and using these to calculate pwm duty cycles.

The second improvement I made this year was to "finalise" my MOSFET setup.  I use MOSFETs to increase the RPI GPIO voltage to 12V and provide the current that MOSFETs need to drive the 5050 LED strip. Previously a breadboard solution provided this facility.  My track record in transferring working breadboard configurations to perfboard has been abysmal so although the circuit is quite straightforward I was very careful to draw out a design, check it, cut wires to length and find the necessary components before I started.  I colour-coded the RGB wires and on completion made sure the wires were tidy then put labels on the connections.  





I am rather proud of the results, it works a treat and I will probably keep the lights setup all year round.

Tuesday, 26 October 2021

Nezha : Using syscalls for IO

 It was back in July I first posted about my Nezha RISC-V SBC.  At the time I was pleased to have a solid, reliable Debian build and excited with the ability to write native RV assembly programs and run them  at the command line without the usual inconvenience of cross-compilation and loading.

I purchased Anthony Reis' (AR) beginners guide to RV assembly which provides a gentle learning curve for me.  It starts with a chapter on machine language which is interesting as it describes the format of some types of instructions ().  I am hoping not to do too much low level debugging but this info provides an insight into the RV design, in which instructions are standardised to facilitate their implementation on a variety of hardware platforms.

One of the problems with an instructional RV book is that people have a range of environments in which they write programs.  Many would use a QEMU RV VM, some would have a smaller RV machine to load executables onto and a lucky few like me have an RV linux SBCfor native compilation. As AR starts on the assembly language tutorials he provides his own program which functions as an RV-32 assembler and simulation environment.  This provides input output to the screen using his own bespoke functions.  For example two instructions sin and sout are provided to input / output a string to / from a program.  A lot of assembly programming deals with peripherals so this isn't very helpful (although it is the correct approach for a general purpose tutorial / textbook).

The first thing I need to do is to work out how to implement the same functionality in my linux / gcc environment so that I don't need to use AR's assembler / io functions.  Previously I was able to use Stephen Smith's hello world example which uses a linux system call (ecall) to output a string.  Instead of using ecall it is possible to to the call statement, so that you can use the C function name rather than a numeric syscall number.  RV registers a0, a1, a2, ... registers are used for the parameters.  I was very pleased with my first attempt, shown below, which calls printf to display a string containing an integer parameter.  I needed to link it with a linker option "-no-pie" to include the necessary library modules for terminal output.


Once we have this mechanism it is easy to provide simple macros with the same name and parameter as those used in Anthony Reis book.  Now my first program example, which adds two numbers together looks just like the one in the book.





Sunday, 17 October 2021

DIY Frequency Counter

 

I am concerned with my 6502 reliability now that I have increased the clock speed to 1MHz and I want the ability to slow the clock down (again).  I could revert to my arduino Nano clock but this is quite a bit slower.  Instead I decided to use a decade counter so that I can slow the clock by a factor of 10, 100, 1000 etc.  Chips are ridiculously chep and I can easily add one next to the clock on the breadboard.
It occurred to me that I need to measure my clock speed to be sure the counter is having the expected effect.  It would also be very useful to check the nano clock generated frequenct if I am using it.

Ebay shows some cheap kits alongside expensive "professional" equipment.  I only need a rough idea so a kit is perfect.  It comprises TTH (through the hole) components, 5 x seven segment displays for output and a PIC16 microcontroller for measurement.

The only instruction provided is a link to a youtube video.  It turns out to be very helpful.  Kev, the guy who provides it, makes a board whilst talking, it takes about 5 minutes.  It is reassuring and charming that he is quite amateurish.  There are a couple of important points he makes, firstly how to solder the extra capacitor to improve low frequency measurement and secondly a reference / link to operating instructions he has found.

The board is very nice to solder with well-spaced components and generous solder pads.  I built it and it works.  It accurately tested a 20MHz oscillator as having a frequency 20.064 MHz.  Next I measured the clock speed on my W65C02SXB board, which I understood was running at 8MHz.  The measurement was 1.8MHz, looking at the clock chip on the board I noticed that this is correct - so the tester has already proved itself useful.

In conclusion, I am very pleased with this circuit, it is always nice to solder useful things.  I am now ready to face my next 6502 test.








W65C02SXB : WDC to the rescue

 

I am a little nervous about my 6502 system.  I moved beyound the "use wires to connect hardware on breadboard" stage so time ago and I am more intereseted in software development now.  In fact I am aiming to run C and BASIC programs on my system next.  Underneath the hardware is working but subject to the vagaries of bad connections or deficiencies in programming due to my incomplete understanding.  The recent increase in clock speed (or some undiscovered unknown issue) has led to the system becoming frustrating to work with and almost unuseable.

Whilst considering buying a circuit board to formalise my hardware (for example from dbuchwald) I came across a development board from WDC  which perfectly matches my requirement. It was released in 2014, apparently as an educational board and is still available. WDC have been the main player keeping 6502 hardware ecosystem alive for many years now so a board from them is likely to be good.

The W65C02SXB  has a 65C02, ROM, RAM, VIA and ACIA just like mine.  Obviously it has the advantage that all connections are in place and should be reliable.
The clock runs at 8MHz s the board should be significantly faster than my existing breadboard version.
The second enhancement is that all necessary pins, including data bus address bus and 65C02 control pins are available on headers so are easily accessible for attaching devices / peripherals.

I ordered one immediately from Mouser in the UK and it was delivered by Fedex five days later after an epic journey from Grand Prairie, Texas.



There is a getting started project provided by WDC which demonstrates how to assemble (WDC02AS), link (WDCLN) and run a program to flash the onboard X LEDs.  The program is loaded and run using the debugger (WDCDB) which shows you the assembler source, memory variables / registers and allows you to single step or run through a program.  This is magnificent and provides a whole new world, hopefully making it much easier to develop code.

A second project  providing very detailed instructions is available from Instructables to flash an external LED attached to a VIA pin.  The executable image is loaded via TIDE (Terbium IDE) into memory and can then be run using the debugger.

These WDC tools make software development a very different experience from my DIY environment and hopefully speed up the process.  All I need to do is attach appropriate hardware to the board connectors and start development.  It looks like WDC and instructables hoped for other projects to be based on the board but I haven't seen many, there are a few references on 6502.org which I can follow up.

Monday, 20 September 2021

6502 : Xmodem Fights Back



 Previous I have been pleased to be able to (1) download a file to RAM and (2) use xmodem to transfer a program and then run it. I was very pleased with both results and felt that I had cracked xmodem.  The good feeling didn't last long.

Download speed

I wanted to get started on testing my C programs and they use the terminal working at 19.2k baud whereas my download testing has been conducted at 9600 baud.   The C program displayed some garbled characters when the speed was reduced to 9.6k and in general my programs work at 19.2k so I need to standardise my transfers on 19.2k.

Increase clock speed

Unfortunately, when I changed to 19.2k my xmodem downloads appeared to complete but would not run as they were losing characters.  My thoughts turned to flow control or increasing the clock speed.  RTS/CTS flow control didn't seem to work last time I tried it and I don't really need my Nano slow testing capability so adding the 1MHz clock chip is the way to go.  

Changing over to the clock chip simply requires connecting 5V, GND and the clock output to 6502.  After doing this nothing was displayed on the terminal screen with a simple program which outputs a message.  I find I need to put a 255 cycle delay loop between each character output to the terminal.  I tried RTS/CTS flow control but it made no difference.

A short while later I discovered, on the 6502 site forum that the 65C51 has a design error which means that flow control doesn't work


 The easiest workaround is the method I chose; to insert a delay.

Spurious Interrupts

With the transmission speed fixed, I returned to testing xmodem downloads.  Unfortunately matters became worse.  The 6502 appeared to randomly restart itself during or after downloads.  I guessed that the system was getting interrupts, causing it to jump to the reset vector.  So far I have only covered Ben's interrupt tutorials and haven't set anything up.  The 6502 has an NMI pin (connected to 5V) and an IRQ pin connected to the 6522 VIA CA1 pin.    I set up small code snippets which displayed a message on the terminal when one of the interrupts occurred and configured the NMI and IRQ vectors accordingly.

As expected the IRQ vector was used each time a spurious interrupt occurred.  This happened even when the IRQ pin was held high.  The 6502 provides a BRK instruction (opcode $00) which also causes an interrupt to the IRQ vector.  When an interrupt occurs, the interrupt return address and process status register byte are written to the stack.  Initially my code to test BRK would not return to continue the program when an RTI (return from interrupt) instruction was encountered.  I found in an article that compilers need to treat BRK as a 2 byte opcode to jump back to the correct address but they only reserve 1 byte ($00) which means the program returns to the wrong address.  I corrected this by adding NOP after BRK and RTI then works fine.


I spent some time writing interrupt code which saves the type of interrupt, return address and interrupt count to page zero variables so that I can print out interrupt details.  A separate subroutine can print this information out to the LCD on request.   For debugging spurious interrupts we only need capture a single interrupt so the interrupt processor has an option to print details within the interrupt and not return to the program.

With the capability to determine spurious interrupt details in place we are now more prepared to continue debugging xmodem.




Monday, 30 August 2021

6502 : Xmodem

 My 6502 system is working well but I still find the program upload process irritating.  I am probably being a diva about this as the old school method to remove, program, replace the EEPROM chip was very painful.   My programs are quite small but it takes time to compile them, transfer them to an Arduino sketch then run the sketch to copy the program to EEPROM.  For a 1KB program, which is quite large for my assembler programs but reasonable for C it can take a minute to process.

I have been thinking of trying to implement XMODEM for a while, it seems sensible to use the serial port session which will allow a transfer at 19200 baud, taking a few seconds for program download into RAM (not EEPROM).  6502.org provides a copy of Daryl Rictor's xmodem code so a couple of weeks ago I tried it out.  The code is intended for a 65C02 + ACIA 6551, the same as mine, and it is only a couple of hundred lines long so I thought I have a good chance of success.  I was a little nieve but that is the best way to start a long journey.

It was easy to download the program and tweak it to compile/load successfully.  However, on starting Xmodem nothing happened.  Not knowing the code or the protocol or having a tool to look at serial port traffic meant that debugging and experimentation were unsuccessful.

I found the modem protocol is quite simple so I wrote a C program under Windows WSL to download a test packet meaning that at least I had reasonable input.  I still couldn't get the example code working so I wrote my own version called xm.  After a while this worked fine, I could compile a program, start xm running and run my serial program to send the machine code. I excluded most of the modem error checking, particularly block number and CRC checks as we are transmitting at quite slow speeds down a 15cm cable.  The only downside is that I have to exit Putty to start the serial program downloading as they share the COM port; on completion I have to restart Putty.  This can be accomplished by means of a batch file loop but still it doesn't seem right.

In an effort to streamline this process I considered writing my own terminal emulator, from which I could easily start the transfer program.  Again I chose C under WSL as my development environment.  Configuring and using serial ports with C isn't terribly easy, some low level commands are required to setup the UART; as usual a good tutorial made this easy.  After that READ and WRITE statements can be used to fill/send buffers through the port.  Under Linux and WSL there isn't a function kbhit() to tell you if the user has pressed a key so I had to implement that myself based on Morgan Mcguire.  Although I could easily capture and display information from the 6502 and deal with keyboard input properly I couldn't get the two to work together seamlessly and I didn't complete this attempt.

On a whim I googled to see whether there are any software only (free) packages which can monitor the serial port.  It turns out there are a few, and Serial Port Monitor seemed a good choice.  The free version is old and not Windows 10 friendly so I used a demo of the paid version.  It is a shame it costs $100 so it is't something I would buy for a one-off problem.  The software is clever enough (using admin privilege) to share the serial port with Putty and after a few minutes learning I could see the serial port traffic.

Using Serial Port Monitor I could see that xmodem was sending a good packet to the 6502 but it was being NAKed by the 6502 and repeatedly resent.  My debugging focussed again on the sample code but I still couldn't get it working.  In particular, not all bytes were read in the ACIA port properly.  I tried all sorts of things to make it work, including slowing the transmission to 9600 or 4800, swapping my Arduino Nano controllable clock for the 1Mhz chip,  using RTS / CTS flow control with extra wires on the USBTTL connection, putting delays on the 6502 send characters which were being garbled.

Eventually I decided to write my own 6502 program, jmodem.  With my new understanding of modem and the structure of the sample code it was a simple job to write my own using subroutines I have previously written.  The only new feature is to read characters until no more come.  Xmodem sends a 128 byte buffer with 3 header characters, terminated by two CRC bytes.      It then stops and waits for ACK or NAK.  If any characters are lost there will be less than 133 characters in total.  Once I had this subroutine working with Putty terminal input remaining coding was easy.  The program initially accepted just one block, checked the number of bytes and transferred it to a fixed memory address.  It was then easy to loop round until an EOT byte was received.


Success is sweet.  I can now load programs into RAM quickly when I want to without exiting Putty using a standard technique.  Completed programs or subroutines can still be saved in ROM using the Arduino Mega but we no longer need it for normal development or system usage.





Thursday, 19 August 2021

Printing reports from Google in Landscape

I have a simple but very useful mariadb/mysql database for my art slideshow app and I use the excellent utility HeidiSQL to maintain it.  Mariadb doesn't have reporting capabilities which is a problem for me as I occasionally need to print lists of pictures.  It is, of course, possible to create and display queries and I can save these to a linux file.  However they need some formatting and importing them to Word, setting up the layout, checking it looks ok is a pain.  Exporting csv data and reading into Excel is a comon way of processing records, but I am not keen on writing Excel macros to do this.  I am sure there are lots of reporting packages I could use but that would be overkill.

I do have the capability to output a selection of records to a browser thanks to Tania Rascia's excellent tutorial.  I use the web query to update descriptions in the database associated with pictures so I thought it would be worthwhile to see whether I am able to print reports.  Usually printing from a web browser provides what you want but is messy due to screen formats being inappropriate but I thought some tailoring would be possible.

In fact it turns out to be a simple and effective solution.  Clearly we want to use CSS to reformat our web page for printing.  Using the @media CSS rule you can specify separate definitions for screen and print.  My first experiment was to display screen text as blue and printed text as green.
To test output just choose print in the browser and you see the print version of the report in print preview


After that we can write print specific CSS to ensure the report is in landscape mode and that instructions and unnecessary screen text are hidden.  I can also set up a print button on my screen.


A very satisfying solution to my problem.






Wednesday, 11 August 2021

Windows 10 Pro

Why

One of the good things about using RPis is that we can SSH into them remotely so it is easy to use multiple systems for different purposes with a single screen (or two) and keyboard.

I am planning to purchase a new PC but I am not looking forward to it  because of all the tasks involved in switching over from the old one.  It would be much simpler and satisfying to run old and new in parallel.  I could set up the new PC and transfer over important and frequently used applications and data.  There are lots of apps, data, configurations on the old one which I probably don't need and I could leave them in place initially.

Unfortunately running two Windows PCs with separate screens and keyboards is a pain.  They take up a lot of space and aren't convenient to use.  I could use KVM style screen / keyboard switch but good ones are expensive and I find them messy.

I could use TeamViewer, splash top  or VNC to access the old PC from the new one.  In the past I have found them a bit clunky but that is probably my lack of familiarity.  However I decided to try Microsoft Windows Remote Desktop which I would hope is well integrated.

How

To use RDP I need my existing Win10 PC to be running Win10 Pro.  Win10 Pro doesn't have many useful features but RDP and bit locker disk encryption are good.  

Buying direct from Microsoft is quite expensive but a quick Google showed me that there are plenty of third-party suppliers who can provide a product key for about £20.  These sites can be dodgy so I picked one called unitysoft, which has an office address and support available.  On purchase I received a product key and some straightforward instructions.

All you really have to do is change the product key in Settings > System >  About.
The computer then spends a couple of minutes reconfiguring existing software so you have Windows 10 Pro.  You can check this in Settings > System > About 😀😊😊

To access the PC remotely just download the Microsoft Remote Desktop app onto Macbook, iPad etc and connect to the system with your current userid and password.  If you are logged on locally you will be logged off.

So

This is wonderful, just what I always wanted.  I can install my new PC, transfer over what I want to it and leave the old box in the corner connected to network but without screen / keyboard.  If there is something I need over the next few months (and there will be) I can turn on the old PC and sort it out.

In the example below you see my lovely Macbook M1 with a Windows Remote Desktop.  Normally I would run it as a full screen, but this shows the Apple background and apps as well as the Windows desktop.  At the moment I am debugging a 6502 program with my board attached to the PC using a COM port.  I can sit in comfort with no cables or hardware attached attached to my Macbook and happily use Windows functions. Bliss.



Monday, 9 August 2021

6502: Download programs to RAM

 My current mechanism for loading programs onto 6502 is to use the Arduino Mega to download machine code to ROM.  Although this is a vast improvement on using an Eeprom programmer it is quite slow, particularly for C programs which tend to be larger.

It would be preferable to use the 6502 serial interface to download a compiled program to RAM where it cn be executed.  This is analagous to loading a program from disk into memory and running it.  I still expect to save completed programs and subroutines in ROM, but this scheme should make the development cycle easier.

Both Extraputty and TeraTerm provide xmodem transfers.  Daryl Rictor has provided a sample xmodem implementation for 6502 so I have the basic ingredients available to me.

My objective is to take a machine code / hex program from the PC, transmit via USB serial port to the ACIA 6551 then read it in to RAM where it can be executed.

Initial tests did not go well. I dont have the ability to log the character string that Extraputty / xmodem is sending or an understanding of the protocol or much idea of how the receive program works.  The trial and error method is somewhat doomed.

The xmodem protocol is intended to be simple to implement, a major factor in its long term popularity. 

 
Data is downloaded in 128-byte packets.
Each packet has a 3 byte header: <soh=0x01> <block number> <inverted block number>
There is also a 2 byte trailer containing a CRC code.
This makes a total of 133 bytes

The receiver sends a character 'C' to the sender to start transmission.
Sender responds with a packet (133 bytes) which the receiver acknowledges with <ACK>.
The receiver carries out block number and CRC checks, if they fail the receiver sends <NAK> instead of <ACK> and the sender retransmits.
This is repeated until all packets are sent, at which point the sender sends <EOT=0x04>

To simplify testing I wrote a C program on my PC which sens a single xmodem format packet to the 6502.  I was pleased to find that Windows/WSL allows me to use a PC COMnn port as /dev/ttySnn providing the program has sudo privileges.  It is a bit fiddly to configure the settings but straightforward if you have a good tutorial .  The completed program looks more complicated than it is. 

Unfortunately, even with a known test program I couldn't make xmodem work. My 6551 works fine but my system or ExtraPutty may be incompatible in some way with Daryl's xmodem example.

I then decided to write my own xmodem receiver.  I simply have to read in some data packets, in a known format, into RAM using my existing subroutine library and I have Daryl's example for hints and guidance.  As we are using a short local connection I can skip the error checking - if an error occurs I would just reload the program.

This approach is much more successful.  I can take an executable program, created using cc65 on the PC and transfer it to 6502 RAM.  After checking using the monitor that my first program was transferred successfully to RAM address $1000 I tried to run it but (of course!) it failed.  The program had originally been compiled to run at $8000.  Once I changed the .org statement to rectify this it ran fine.  I would include an  image but the test program just displays a '#' character and allows character input.

This is an excellent result.  Although there are currently a number of rough edges to smooth over we have a working solution.  It allows us to reduce reliance on the Arduino Mega and the expectation is that it will accelerate downloads and speed up my development cycle (which involves frequent program changes).

Wednesday, 21 July 2021

Nezha : creating an image

Debian 0.3 Image

I received a working Debian Image with my Nezha, which is great but its only provenance was that it came with the board and was built on 1st June, just before the boards were shipped.  On 10th June Wu Caesar, the main man, provided an "official" release Debian 0.3 which was built on 3rd June.

I struggled to burn it to an SD card as it wasn't in a standard image format.  The Telegram forum was vital to resolve this.  The readme.txt said that you need a utility "PhoenixSuit"  used by Allwinner to burn the image.  However, try as I might, I couldn't get PhoenixSuit 3.1.0 to work.  A Telegram post on 1st July provided a link to RVboards downloads; the RVboards SBC is identical to the Nezha.  The download site contained PhoenixCard 4.2.5 which is a much newer version of the image burning software.  I successfully burned Debian 0.3 images to both 64GB and 16GB SDcards.  After using PhoenixCard you can't reformat SD cards using Windows but it may be possible to fix with the PhoenixCard "restore" option.

The image has networking configured and boots into an LXDE GUI on the HDMI port.  Although slower than other Linux SBCs it was great to see it is a proper product.  GCC is ready for use so we are off to a great start.  In the following minor setup tasks I was most pleased that configuration activities were totally normal.

Debian 0.3 configuration

I want to run the system headless, so I set up a static address.  Systemd networking is used so there was a slightly different procedure, setting up a file /etc/systemd/network/lan0.network containing the static address details.  Once the static address is in place I can use SSH access and copy over an ssh-id file for autologin.

At first I wasn't sure if / how the console is configured as we dont have a boot config.txt file.  The board comes with a USBTTL cable and I found details for connections in the advert for the rvboard on AliExpress!  Once the serial cable is connected and started at 19200 baud we see the console startup which has much useful detail in it.

I could now change the run level using systemctl from graphical.target to multi-user.target.  Startup and shutdown are now significantly faster.

Debian 0.5 image

On 2nd July Pierce Andjelkovic kindly provided a Debian 0.5 image on Telegram.  Again I had a tortuous trial and error experience installing it. The instructions are in Chinese but Google translate does a great job in decoding the chinese character sequences.

The image is copied to an SD card using dd then adjusted using gdisk to delete the 6th and last partition.  I struggled to get gdisk to delete the partition on my 16GB disk and eventually found I could do it using my Nezha board, running Debian 0.3.  I also found that simply burning the image to a 32GB SD card is a lot easier, it doesn't need the partition to be deleted.

The same configuration tasks were completed for static IP (although I needed to edit the traditional /etc/network/interfaces) and runlevel.

Debian 0.5 software

I could use apt-get to upgrade software successfully and installed lighttpd as a simple webserver without difficulty.  This is great, we can assume that the usual debian functions work normally.

I wanted to use a samba client to access shares on other systems but cifs is apparently not included so I could not mount devices on other systems.  However I could install samba and configure local shares so that other systems can copy files on/off.

Having GCC native compilation available is wonderful so I quickly tested the hello world C program.  More importantly and exciting is that I can do native compilation of risc-v assembly programs.  Not knowing what risc-v instructions are or how to program isn't a problem.  With Google as my friend I was able to successfully compile and run a risc-v hello world program, amazing 😁

To learn assembly I purchased a book RISC-V Assembly Language by Anthony Dos Reis which was mentioned on Telegram forum.  It appears to provive a nice simple introduction so I am looking forward to it.

Wednesday, 23 June 2021

Nezha : RISC-V Linux SBC

The title of this post contains ample details to excite (me).  The "open source" architecture RISC-V is well on its way into the mainstream.  To be of general interest it needs to run Linux and a price point of $99 is well below previous development boards.

I ordered one as soon as I saw the indiegogo crowd funding page on 21st May.  Crowd funding was complete by 26th May, boards were shipped about 8th June and mine arrived yesterday.

Nehza has a similar form factor to a Raspberry PI and similar connectivity for HDMI, power, Ethernet, Wifi, Bluetooth, USB and Audio.  In a direct comparison RPI4 is faster, with more capabilities but that isn't the point.  Here we are running RISC-V not ARM.  Personally I feel this is an important moment in the evolution of systems.


I connected up the board, inserted the SD card provided and booted it up.  It started a Debian desktop and allowed me to signon.  Once ethernet was connected, I could happily SSH into the system.  This is perfectly what I hoped for.  I have a new (but familiar) world to explore.

Friday, 18 June 2021

6502 : CC65 and C Programming

Until now I have used VASM to assemble my 6502 programs and it has done the job well.  I have noticed that there are a few 6502 C compilers and I recall from my bare metal programming that you (only!) need a stack, a library and some initialisation code for a C environment.  There appears to be a WDC compiler which isn't well used and CC65 which is popular and practical.  As a first step I will move from using VASM assembly to CA65, which is a part of the CC65 program suite.

CA65

As CC65 is available as a debian package and I use Windows 10 for my 6502 development environment I installed it under WSL (Windows Subsystem for Linux).  I can now take assembler source programs, which are written in Notepad++ and copy the to directories I use for WSL.  Assembly with CA65 starts with running ca65 at the command line with a few options specified.  In particular we have to specify --type as "none"; CA65 is happy to assemble for various microcomputers (C64, Apple ][, etc) but my home brew system has no extra requirements.  The output listing shows that it creates the same output byte for byte as VASM.  The output file is formatted for linking modules and libraries so although I have nothing to link in I also need to run the linker LD65.  So I replace my vasm command with:
    ca65 -l map -t none testbed.s    and
    ld65 -o testbed.exe -t none testbed.o
Now I can process and load the program via the Arduino Mega as previously.

CC65

Creating a C environment is somewhat more challenging.  Luckily Dirk Grappendorf has set this up for his 6502 which is very similar to mine and has been kind enough to create a github repo containing the code.  I downloaded the repo and set about making my own minimal code base.  My target is a "hello, world" program which outputs a screen message.


There are very few files in the solution:

cc65.lib is the most significant, it is the library of C functions needed for stdio and stdlib.

firmware.cfg defines the different areas of memory in the computer, ROM, RAM layout is specified so the compiler can do the hard work in placing files.

startup.s is the initialisation code which sets up the stack, initialises memory and calls main().

zeropage.s provides the layout for variables in the zero page.

acia.s contains the serial programs init, getc, gets, putc, puts which we will use for screen output.

interrupt.s contains skeleton interrupt processing code (which I am not yet using)

io.inc65 defines a long list of constants for ACIA, VIA and other devices.

Once I edited firmware.cfg for my memory configuration, io.inc65 for my acia addresses and acia.s for my serial port config (19200 baud) I could compile and link the program with a single command:
   cl65 -C firmware.cfg -m firmware.map -o main.exe main.c acia.s zeropage.s startup.s  interrupt.s cc65.lib

This created a 32KB file which can be burned into my ROM.  In fact I use my Arduino Mega to write ROM so I don't want the entire 32KB file.  My program is less than 1KB in size.  I amended firmware.cfg to "pretend" I only had 2KB ROM, which created a much more manageable file.  Amazingly, thanks mainly to Dirk, my C environment works and without too much trouble I can read and write the screen, here is the first test program. 😊😊😊😊😊


C lib

So far we haven't used any C library functions, our example uses Dirks acia_init,acia_getc, and acia_putc for IO.  In fact I can remove include statments for <stdio.h> and <stdlib.h> without issue.  Of course C programs without library functions are not particularly useful, we really want to have them available to us.  I tried adding the abs() function from stdlib.h and it worked fine.  I also successfully tested strcpy() from <string.h>.  

<stdio.h> is more difficult to test; I haven't "linked" my I/O routines into C streams yet and my hardware/software doesn't have interrupts setup so I wouldn't expect I/O to work.  I did hope that I could use the sprintf() function to format output for me and wrote a test program but it didn't work.  I will look into the problem in more detail when I consider cc65.lib.  In fact cc65.lib was provided by Dirk I need to look at how he created it or derived it from cc65 provided libraries.

My mechanism for loading programs into ROM  using an Arduino Mega sketch is wonderful, it is automated and requires no removal/insertion of chips.  Using C and library functions necessarily means that our programs are increasing in size - programs may be 4KB or even more!  The Arduino environment only has 8KB for variables so I had to use the PROGMEM mechanism which directs the compiler to store nominated constants in ROM only.  A 4KB program takes over a minute to load which is not bad really but I will need to look at speeding up the sketch.

SIM65

CC65 also contains a simulator SIM65, which you can use to test your C programs. It is easiest to use with programs containing standard C library functions (printf etc).  You can add in assembly language subroutines from C.

Of course, without the real hardware, low level "driver" functions don't have much meaning but you can "simulate" them.  For example my "term_puts" assembly routine could be replace by one which calls printf.
In fact most or all emulators have this problem, they can't exactly replicate my hardware.  If I aim to design my hardware / software to be similar to Apple ][, BBC Micro, C64 etc I could use their full emulators to test programs but even then my hardware will be quite different from the original product.

I am not sure if I will use this but it is another great tool to have available.