Monday, 7 May 2018

Front Panel Components for Logisim

Over the last decade, low-cost programmable microcontrollers (e.g. Arduino) and small embedded systems (e.g. Raspberry Pi) have popularised electronics as a hobby. I think a big contributing factor is that, as components have become more integrated, designs that once would have required complex circuitry have become programs that you can just download onto a chip. While still something of a niche, programmable logic takes this even further. Circuits themselves are designed in a form of code, not unlike writing software, and downloaded into hardware wholesale.

I used to work for Altera, one of the big manufactures of Field Programmable Gate Arrays (before it got swallowed up by Intel). I've spent a lot of time working with programming logic and all this technology is undoubtedly great, but I will admit to feeling a little bit jaded about writing VHDL. As a hobbyist, some of the appeal of hardware is that it's "hard". Real, physical, and tangible. When it comes to fun, downloading stuff onto a programmable chip doesn't quite do it for me.

My personal hero is this respect is Bill Buzbee for creating the Magic-1. A computer constructed out of 74 series logic chips. As in, even the processor is constructed out of discrete logic wired together. What's even more impressive is that he re-targeted the lcc C compiler to the custom instruction set of his creation, and then ported Minix to run on it. On a good day, you can even browse a web site hosted on the machine itself. I have to admit, to me the thought of electrical impulses making their way from pin to pin in response to my HTTP requests is more marvellous to imagine than the same thing at the microscopic scale of a contemporary microprocessor.

Anyway, the above is all just background to my desire to walk in Bill's (and every other member of the Home-brew CPU Web-ring's) footsteps. I've been working on designing a somewhat more modest system in the open-source logic simulator Logisim. Rather than a fully internet connected Unix machine, I'm aiming for something more akin to an oversized Gameboy. One of the key peripherals is a 16 by 16 element RGB LED matrix, but Logisim's built-in Dot Matrix component isn't quite sophisticated enough for this.

Fortunately, Logisim allows you to extend it with new components written in Java. I've created a new component library called Logisim Front Panel to contain any additional components I need for my simulation. At the moment, this just consists of a RGB Matrix component, but I plan to at least add an RGB 7 Segment display with similar capabilities. You can download a pre-compiled JAR file here.

RGB Matrix Example 1
The above animated GIF shows the RGB Matrix in action. A counter is used to cycle through the lines while adjusting the bit-pattern at the colour inputs. A property of the human visual system called flicker fusion means that although, in real hardware, only one line is illuminated at the time, we perceive a complete image which accumulates the light received over time.

It takes 256 simulation ticks for the counter to cycle through completely and this is set as the value for the Fusion Window attribute on the RGB Matrix component. You can see the image being built up over the first cycle and it remains stable thereafter. As there are 8 lines, a given pixel can only be active for at most one 8th of that. Hence, the Maximum Duty attribute is set to 32 ticks. The variation in colour across the matrix is created by different pixels being illuminated between 1 and 32 ticks in a window.

The circuit is available in the examples directory of the distribution. More details about the actual machine to come in a future instalment.

Tuesday, 3 April 2018

HsQML released: Cabal Armageddon

For some years now, HsQML* has been accumulating an increasingly complex pile of Template Haskell in its Setup script in order to accommodate all the API changes since Cabal 1.14. It couldn't last forever and indeed Cabal 2.0 has finally delivered a blow to what must have at least been a contender for the title of "world's most arcane Setup.hs". Not a fatal blow mind you, but let's say that it's less complicated than it used to be.

Last September, I very quietly released version of HsQML which, among
other things, used the new setup-depends feature to try and stem the tide and force building the Setup script against Cabal 1.24. However, the even newer release made last week finally adopts the Cabal 2.0 API and does away with Template Haskell. Hurray!

There are a number of other minor fixes in these two releases, mostly adjusting for newer versions of Haskell tools and libraries.

* For the uninitiated, HsQML is a Haskell binding to the Qt Quick user interface toolkit.

release- - 2018.03.28

 * Fixed building with Semigroup/Monoid changes in base 4.11 (GHC 8.4.1).
 * Fixed crash if setDebugLogLevel called before other functions.
 * Fixed GHCi cbits library install location.
 * Changed Setup script to use Cabal 2 API only.
 * Relaxed Cabal constraint on 'QuickCheck'.

release- - 2017.09.08

 * Added facility for setting Qt application flags.
 * Fixed building GHCi objects with Cabal 1.24.
 * Relaxed Cabal constraint on 'QuickCheck' and fixed test suite.
 * Relaxed Cabal constraint on 'directory'.

Friday, 22 July 2016

HsQML released: From Zürich

Last night I arrived in Zürich for ZuriHac 2016 and, in the brief space between finding my way from the airport and falling asleep, released HsQML You can download the latest release of this Haskell binding to the Qt Quick GUI framework from Hackage as usual.

This is purely a bug-fix release, fixing building with newer versions of Cabal (1.24, GHC 8) and Qt (5.7+). It also resolves some difficulties with building the library on MacOS and I've revised the MacOS install documentation with more information.

In other news, I've decommissioned the old Trac bug-tracker as I accidentally broke it some time ago during a server upgrade and failed to notice. I take this as a bad sign for its effectiveness, so please just e-mail me with any issues instead. I enjoy hearing from people trying to use the library and I always try to reply with assistance as quickly as possible, so don't be shy.

release- - 2016.07.21

  * Added support for Cabal 1.24 API.
  * Fixed linking shared builds against MacOS frameworks (needs Cabal 1.24+).
  * Fixed building with Qt 5.7.

Friday, 26 February 2016

HsQML released: Belated Automatic List Models

A couple of days ago I released HsQML, the long-awaited and much overdue next release of my GUI binding to the Qt Quick framework. You can download the latest release from Hackage as usual.

The major new addition in this release is the AutoListModel component, which you can import in your QML scripts from the HsQML.Model 1.0 namespace. This provides a way of creating QAbstractItemModels based on lists of items. This feature is some way off full support for creating custom models, but still a significant improvement over binding marshalled arrays to QML views directly. Namely, when the updating a list via the AutoListModel, it can generate item add, remove, and change events based on the differences between the old and new arrays. An direct array binding, on the other hand, would cause the entire model to be reset so that views lose their state, cannot animate changes, etc.

This is demonstrated by the hsqml-model1 sample program included in the latest release of the hsqml-demo-samples package and pictured below. Try running it and see how the view of blue squares at bottom animates when you change the model.

Basic reference documentation for the AutoListModel is included in the Hackage documentation. The topic demands some more exposition, and will be the topic of further blog posts with some more exciting sample programs in the works.

release- - 2016.02.24 * Added AutoListModel component. * Added functions for joining and killing engines. * Added functions to manipulate Qt's command-line arguments. * Added exception handler to callbacks. * Relaxed Cabal dependency constraint on 'filepath', 'tagged',
'transformers', and 'QuickCheck'. * Changed runEngineLoop to pass through command line arguments by
default. * Fixed class at same address as deleted class causing inaccessible
objects. * Fixed memory corruption bug prior to Qt 5.2 with workaround. * Fixed building with Fedora-style moc executable names (non-qtselect). * Fixed building GHCi objects with GHC 7.10. * Fixed missing strong reference on engine context objects. * Fixed missing include breaking compilation with Qt 5.0. * Fixed switch compiler warnings. * Fixed imports to support older GHCs.

Wednesday, 17 June 2015

Fast and Slow Sticky Notes in Haskell and Qt

Last year I gave a talk for the London Haskell User Group on building a Sticky Notes application using Haskell, Qt, and the HsQML binding between them. The video has been out for a while now and made the rounds elsewhere, but I've thus far neglected to post it on my own blog! Slides are here. See below for an update on the example program and an answer to the most commonly asked question after the fact.

Fast and Slow? An update!

For the sakes of simplicity, the original version of the sticky notes program shown in the talk uses an SQLite database to serve the view directly with no in-memory model or caching. This is at least the cause of some sluggishness and at worst pathological performance depending on your machine.

As alluded to in the talk, there is a better albeit more complicated way. This involves moving the slow database accesses onto a separate thread and keeping a fast in-memory model to support the user interface. Changes made by user are now queued up and then flushed to disk asynchronously.

I've now released an updated version ( of the hsqml-demo-notes package which includes a new faster version of the program illustrating exactly this technique. This hsqml-notes executable is now built using the new code and, for reference, the original code is built into the hsqml-notes-slow executable.

The fast variant uses three MVars to communicate between the UI and database threads. An MVar is kind of synchronisation primitive offered by Haskell akin to a box which may either contain a data value or be empty. Operations on MVars take out or put in values to the box and will block if the MVar is not in the appropriate state to accept or produce a value. Hence, a variety of different constructs such as locks and semaphores can built out of MVars.

The first MVar in the new notes code, modelVar, contains a Map from note IDs to the data associated with each note. This is the in-memory model. It includes all the fields held in the database table plus an additional field which indicates whether there are any pending changes which need flushing to the database (whether the record is "dirty"). The MVar semantics here act as a lock to prevent more than one thread trying to manipulate the model at the same time.

A second MVar, cmdVar, is used as a shallow channel for the UI thread to signal the database thread when there is work to do. The database thread normally waits blocked on this MVar until a new command value is placed in it, at which point it takes out and acts upon it. The first command given to the database thread when the program starts is to populate the model with the data stored on disk. Thereafter, whenever a user makes a change to the model, the dirty bit is set on the altered record and a command issued to the database thread to write those dirty records to the database.

Finally, the third possible type of command causes the database thread to close the SQLite file and cleanly exit. In that case, the third MVar, finVar, is used as a semaphore to signal back to the UI thread once it has shut down cleanly. This is necessary because the Haskell runtime will normally exit once the main thread has finished, and the MVar provides something for it block on so that the database thread has time to finish cleaning up first.

What is the FactoryPool actually for?

QML objects require a relatively explicit degree of handling by Haskell standards because the idea that data values can have distinct identities to one another even if they are otherwise equal is somewhat at odds with Haskell's embrace of referential transparency. This sense of identity is important to the semantics of QML and can't be swept under the rug too easily. Crucially, using signals to pass events from Haskell to QML requires that both the Haskell and QML code are holding on to exactly the same object.

One way to accomplish this is to carefully keep track of the QML objects you create in your own code. The factory-pool is an attempt to provide a convenience layer atop object creation which saves the programmer from having to do this. It is essentially an interning table which enforces the invariant that there is no more than one QML object for each distinct value (according to the Ord type-class) of the Haskell type used to back it. If you query the pool twice with two equal values then it will give you the same object back both times. Importantly, it uses weak references so that objects which are no longer in use are cleared from the intern table and it doesn't grow in size indefinitely.

One of the difficulties people have had with understanding the factory-pool from the notes example is that it's not generally necessary to make it work. Aside from the initial loading of the database, all the activity is driven from the front-end and so displaying a single view isn't strictly reliant on the signals firing correctly. If you replace the code to retrieve an object from the pool with a plain object instantiation, the default QML front-end for the demo would still work the same, albeit more wastefully.

To see the pool doing something useful, try the "notes-dual" front-end (by specifying it on the command line), which I've come to think of as the most interesting of the demos. It displays two front-ends simultaneously backed by the same data model. Changes in one are immediately reflected in the other. This works because when each front-end retrieves the list of notes they both obtains the same ObjRef from the pool for each Note as each other. Hence, when a change is made in one front-end, and a change signal is fired, both the front-ends receive it and remain in sync.

Without the pool, the onus would be on the application code to keep track of the objects in some other fashion. For example, if each read of the notes property created a new set of objects every time it was accessed then many more objects would need to have signals fired on them in order to ensure that every piece of active QML had received notice of the event. Each front-end would still be backed by the same data, methods and properties would still have access to the same set of Note values, but their objects would be distinct from the perspective of signalling and, unless special care was taken, the front-ends wouldn't update correctly.

Tuesday, 20 January 2015

HsQML released: Control those Contexts

Happy New Year! Another year and another new release of HsQML is out, the Haskell binding to the Qt Quick framework that's kind to your skin. As usual, it's available for download from Hackage and immediate use adding a graphical user-interface to your favourite Haskell program.

The major new feature in this release is the addition of the OpenGLContextControl QML item to the HsQML.Canvas module. Previously, the OpenGL canvas support introduced in left programs at the mercy of Qt to configure the context on their behalf and there was no way to influence this process. That was a problem if you want to use the latest OpenGL features because they require you to obtain a newfangled Core profile context whereas Qt appears to default to the Compatibility profile (or just plain OpenGL 2.x if that's all you have).

To use it, simply place an OpenGLContextControl item in your QML document inside the window you want to control and set the properties to the desired values. For example, the following snippet of code would request the system provide it with a context supporting at least the OpenGL 4.1 Core profile:

import HsQML.Canvas 1.0

OpenGLContextControl {
    majorVersion: 4;
    minorVersion: 1;
    contextType: OpenGLContextControl.OpenGL;
    contextProfile: OpenGLContextControl.CoreProfile;

The supported properties are all detailed in the Haddock documentation for the Canvas module. There's also a more sophisticated example in the corresponding new release of the hsqml-demo-samples package. This example, hsqml-opengl2, displays the current context settings and allows you to experiment with requesting different values.

This graphics chip-set has seen better days.

Also new in this release, i) the defSignalNamedParams function allows you to give names to your signal parameters and ii) the EngineConfig record has been extended to allow setting additional search paths for QML modules and native plugins..

The first point is an interesting one because, harking back, my old blog post on the Connections item, doesn't actually demonstrate passing parameters to the signal handler and that's because you couldn't ordinarily. You could connect a function to the signal manually using the connect() method in QML code and access arguments positionally that way, or written the handler to index into the arguments array for it's parameters if you were willing to stoop that low. Now, you can give the parameters names and they will automatically be available in the handler's scope.

Finally, the Template Haskell shims inside Setup.hs have been extended to support the latest version of the Cabal API shipping with version 1.22. The Template-free SetupNoTH.hs remains supporting 1.18 ≤ n < 1.22 will continue to do so at least until Debian upgrades their Cabal package. Setup.hs will now try to set QT_SELECT if you're running a recent enough version of GHC to support setting environment variables and this can prevent some problems with qtchooser(1).

release- - 2015.01.20

  * Added support for Cabal 1.22 API.

  * Added facility for controlling the OpenGL context.
  * Added defSignal variant with ability to set parameter names.
  * Added option for setting the module and plugin search paths.
  * Changed Setup script to set QT_SELECT (base >= 4.7).
  * Fixed crash resizing canvas in Inline mode.
  * Fixed leaking stable pointers when objects are collected.
  * Fixed Canvas delegate marshaller to fail on invalid values.
  * Fixed discrepancy between kinds of type conversion.

Thursday, 4 December 2014

HsQML released: London Edition

Last week I gave a talk to the London Haskell User Group on my GUI library HsQML. The slides are available now and a video of the talk will be posted on the group's YouTube channel in due course (I'll post again when that happens).

The most distinctive, some might say contentious, thing about HsQML compared to other Haskell GUI libraries is the split between implementing the back-end logic of an application in Haskell and describing its user interface using the QML domain specific language. This tends to frighten people off and I was at pains to stress that while QML does have inbuilt scripting capabilities, we can build real applications with just a thin layer of QML over our Haskell code.

The talk walking through the implementation of a new sample "sticky notes" application. Here, the Haskell back-end takes care of persisting the user's data in an SQLite database and exposes a data model to QML. Several alternate QML front-ends then show how the same data model can be skinned with different user interfaces.

One of the sticky notes application's front-ends uses Qt Quick Controls for a native look and feel, shown here on three platforms.

Belatedly also, I'm announcing version of HsQML which debuted on Hackage at the week-end. This minor release fixes a couple of bugs. Most notably, that fact that HsQML was leaking the QApplication object and this caused programs to occasionally crash on exit under Linux. HsQML now ships an OnExitHook() which should shutdown the Qt framework when the GHC RTS does, or alternatively you can call the new shutdownQt function to do it manually.

release- - 2014.11.29

  * Added function to shutdown the Qt framework.
  * Fixed intermittent crash on exit under Linux.
  * Fixed reanimated objects being passed to QML as undefined.
  * Fixed typo in the names of implicit property signals.