Project HOME

Pebbles/Autohan CD/DVD Player.

Part of An Embedded Platform for Pushlogic and Tuple Space Computing


The Pebbles project has made a CD/DVD player where the internal state variables are implemented with tuplecore, the Embedded Tuple Core. The player can play audio tracks via the back panel RCA connectors or as streaming media over the network. The internal application software is implemented using Pushlogic.

The player was made using the control panel and power supplies from a commercial CD/DVD player, with the processor card being replaced with our own Molly card.

CD PLayer Software Structure

The software is logically partitioned into separate components, each of which separately registers as a field in the "$#parts" tuple.

The components are:

  • The display
  • The keypad
  • The network interface
  • The hosting service (Tuplecore + Pushlogic + Tinyweb)
  • The CD/DVD player canned application
  • The compact disc mechanism

Each of these components stores a tuple as a field in the parts tuple and refreshes the tuple sufficiently frequently that it is not garbage collected.

The keypad device driver presents a single tuple with primary key "$#parts#keypad" that has a field for each physical key. The key names are stop, play, pause, ffwd, rewind, trkfwd, trkbk and so on. The value of each field is 1 while that key is held down and zero otherwise. It is assumed that other code will not write to these fields rather than storing them under the protection of an $RO sub-tuple.

The keypad on one of the CD players also has a number of LED indicators. There are indicators for play and pause and so on. The device driver clears these on initialsation and when the stop key is pressed, but no further local control of them is implemented. Instead, fields called stopled and playled are provided in the tuple that allow an application to operate the LEDs.

The display device on both CD players has four pairs of two digit BCD numbers that can also be blanked. These are labelled as track, index, minute and second. Each of these may be written by storing to the relevant field in the tuple that represents the display, such as "$#parts#display#track" using a character string containing zero, one or two digits. The Tuple Core makes an upcall to the display device driver when any field has an event (i.e. is changed) so that the physical display can be updated. The physical displays are VF tubes with a local RAM cum register file with a bit per segment. The displays also contain a number of other fields that differ from one display to the other. These too can be controlled by writing a 1 or 0 to their fields. One display has a set of 16 track indicators. In our approach, each track indicator consumes 20 or so bytes of RAM to store its associated field - perhaps a considerable overhead compared with hand-coded assembler/C programming ?

The Network Interface network interface tuple is stored in the "$#parts#network" field and is also augmented with a field to describe its audio capabilities.

The Hosting Serviceis a described with a Tuple that states that the only form of foreign application that can be hosted is Pushlogic programs of up to a specific size. (Details still being developed).

The CD canned applicationis a described with a Tuple called "canned" whose filed "code" contains the complete Pushlogic stored in the ROM. This application is loaded into the Pushlogic interpreter when power is applied and provides both the normal operation of the CD player and any enhanced features provided for interaction with other devices over the network.

The CD/DVD mechanismis a represented with a Tuple called "works". This has two main fields: command (cmd) and status (stat). Command can be set to play, open, pause and stop. Two fields contain locations in absolute time, packed BCD, hour, minute, second and frame. Of these, the seek field may be written to cause a seek whereas the current field may be read to find the last value recovered from the pickup subcode. The volume table of contents of the current disk is stored in the sub-tuple under the field toc. It consists of a fields whose tag names are successive integers and whose values are absolute start times in the same format as the seek and current fields.

Streaming audio over the network is established by setting the "works#sink" field to the URI of another device, but this field is not updated by the canned application: instead, the assumption is that network activity will be initiated by remote network apps.

A tuple called "platform" reflects meta-info, such as the processor architecture, memory usage, IP and MAC addresses and bundle names.

Canned Application

A basic application to make the CD player operate is completely straightforward: it must simply update the mechanism command field in response to keypad operations and update the display in response to changes in the current field of the mechanism. This application also allows remote control of the device over the network, provided it does not control the mechanism when no button is being pressed and it ignores or is happy to tolerate external direct manipulation of the mechanism tuple.


def bundle PioneerDvd()
    // The keypad field ranges over three values:stop, play, pause, but reverts to "" 
    // when nothing is being held down.
    // The field cmd can be changed under the feet of this script by other 
    // apps running elsewhere
    // If keypad were a sensitive parent, then the pushback when some othe app
    //  changes the field would perhap updated the leds
    // using this script.
  input devices#keypad#now : { Stop : Play Pause Eject Tfwd Trwd};
  output works#cmd : {stop : play pause resume eject};
  output devices#keypad#playled : {0 : 1};
  output devices#keypad#pauseled : {0 : 1};
  output devices#keypad#stopled : {0 : 1};
  input parts#mech#stat#track : {0..99};
  input parts#mech#stat#sec : {0..59};
  input parts#mech#stat#min : {0..99};
  input parts#mech#stat#idx : {0..99};
  output parts#disp#track : {0..99};
  output parts#disp#sec : {0..59};
  output parts#disp#min : {0..99};
  output parts#disp#idx : {0..99};

Basic Application

The following Pushlogic sequence implements the main transport controls

  with devices#keypad
     if (#now == stop) 
      { #(playled, pauseled, stopled)  := (0,0,1);
        works#cmd  := stop;
      else if (#now == play)    
      { #(playled, pauseled, stopled)  := (1,0,0);
        works#cmd  := play;
      else if (#now == pause)    
      { // This bit is not idempotent - expect a compile time warning!
          if (works#cmd == play) 
          { #(playled, pauseled, stopled)  := (1,1,0);
             works#cmd  := pause;
          { #(playled, pauseled, stopled)  := (1,0,0);
             works#cmd  := play;

This code copies the song position from the mechanism to the display.

    with $#parts#mech#stat
      $#parts#disp#track  := #track;
      $#parts#disp#min  := #min;
      $#parts#disp#sec  := #sec;
      $#parts#disp#idx  := #idx;

Owing to the execution semantics of pushlogic, to get a continuous, efficient, real-time update of the display from the mechanism no guard or sensitivity needs be specified in this source code.

Trackup and down are more interesting because, as all scripts need to be idempotent (multi-runnable), a differentiator is needed to detect the start of each new keypress:

  if (local#keypad_old != devices#keypad#now) 
	   if (devices#keypad#now == Tfwd) 
	    parts#mech#stat# track := parts#mech#stat# track + 1;
	    // If this is end of disk, then a pushback will undo this assign
	   else if (devices#keypad#now == Trwd)
		parts#mech#stat# track := parts#mech#stat# track - 1;
		// If this is end of disk, then a pushback will undo this assign
	local#keypad_old := devices#keypad#now;

More interesting application

To make the application a bit more interesting, and to take into account that we have a pair of heterogeneous CD players, we extend the application so that it is possible to display and control one CD player from the other. The application that controls one CD player from the other can be run equally well on either CD player or on a separate execution platform.

The final, complete Pushlogic code is to be inserted here. Under construction.

Hardware Implementation

Prototype top view, showing internal Molly card.

Project HOME