Hitachi 63B09E SBC

I recently learned that there is some kind of a new thing started up that is all about Motorola? CPU based single board computers. So I thought I’d post one that I made in uni about 28 years ago. The label on the EPROM is Assist09 so it’s possible that it would boot and allow me to upload code etc if I had a serial cable of the right kind. The board was part of an ultrasonic range finder project I made for uni. I made 3 main boards (all hand wired) along with a sonar head which had yet another board with OpAmps. There was also a power supply box, a keyboard and an LCD. – these days you could do the same thing with an Ardunino Pro Mini, an I2C display and an ebay ultrasound module. The software had a menu system I copied from Supercalc. I wrote most of the software in ‘C’, to do this I found some code to give an early version of GCC the ability to generate 6809 assembler. This ‘OS’ had only the keyboard scanning and interrupt code in assembler. I remember running pmake on the unix server at RMIT when I was compiling the compiler and almost bringing the server to its knees.

The Hitachi 6309 was an enhanced version of the Motorola 6809 Hitachi 6309, and I think I did use some of the extra instructions. I believe there was a 16 to 32 bit multiplication available which I used.

As you can see this was point to point soldered; at that time I had no practical / cost effective way of making a PCB. I am tempted now to do something with this computer, at least to see if it still works, although I have thrown my EPROM programmer and any capability to erase EPROM’s into the tip. I’m sure there are ebay cables, programmers and erasers.. Of course If I can find the actual EPROM with the sonar software, surely I haven’t thrown that away.

Perhaps this is of interest to someone.

Cpu Detail

Cpu Detail

Front of board.

Front of board.

Back of board.

Back of board.

Ruby debugging using Aptana

For a long time I have been unable to use a debugger in an IDE for Ruby. I couldn’t ever get the correct gems installed into Netbeans and had just given up. Today, as a part of setting up my computer after a motherboard transplant, I have found a solution. This might be useful for others so I will post it here.

What I have now is Aptana Studio 3 with Ruby 1.9.3p551; with a working debugger!

I downloaded the following files:
Aptana_Studio_3_Setup_3.6.1
rubyinstaller-1.9.3-p551
DevKit-tdm-32-4.5.2-20111229-1559-sfx

The steps to install (on Windows 7) are:

  1. Run the ruby installer and tick all options.
  2. Run the DevKit application, this will unzip its contents. Choose a permanent target folder for the extracted files.
  3. Open a DOS window and change the folder to wherever the DevKit files were extracted.
  4. In the DevKit folder run ‘ruby dk.rb init’ and then ‘ruby dk.rb install’
  5. Then in the same folder (although it doesn’t matter) run ‘gem install debugger’ and then ‘gem install debugger’
  6. Exit the DOS window
  7. Run the Aptana installer allowing this to install all options.
  8. Check the debugger by doing the following.
    1. Create a Ruby project in Aptana
    2. Once the project is created Add a new file, this must have an explicit ‘.rb’ otherwise the IDE won’t treat it as a ruby source file (you’d think a new file added to a ruby project would be ruby by default).
    3. Add the following code and set a breakpoint on the puts. In the Run menu invoke Debug. The program should stop at the puts (without doing any output). Then press F6 repeatedly to execute the program within the debugger, the breakpoint will get hit once more and then the program will exit.
    a = ["aaa", "bbb"]
    
    a.each do |s|
       puts s
    end
    

    Hope this works for you. Let me know if not.

Debugging the DYPTH01B-SPI

This is a description of the methods I used to get a DYPTH01B-SPI temperature and humidity sensor working with my Arduino Pro Mini. I’d almost given up on the thing many times; it has been a struggle to get any meaningful data out of the device. In the end I discovered what I think is a weird interaction between the example code I had copied and the compiler. This was a red herring that caused me to look down incorrect paths whilst I was debugging.

When I purchased the device I didn’t have a clear idea of what I would use the sensor for; I just liked the idea of measuring some real world data. My intent now is to use a couple of nRF radio transceivers to remotely sample data with the sensor being mounted outside.

I’d had the DYPTH for a while, but hadn’t done anything with it. This neglect was due to a lack of confidence in my ability to get it working, and because I had gotten distracted discovering that cheap ebay robotics motors aren’t precision devices…  (You’ve probably seen the little yellow DC motors on ebay.)

The DYPTH01B is weird because it acts mostly as a master but the slave must tell it to send. The DYPTH01B generates the clock and uses MOSI but the CE must be controlled by the slave which in my case is an Arduino Pro Mini.

I initially tried to use the code I found from here (see the section on Sensor 2).  I managed to get the same poor result that Matthew Little did which is that every now and then valid data appears (although the humidity seems a little high).  Some of the data seems almost random and has an invalid CRC and so is not converted to temperature and humidity. Sometimes a valid CRC is calculated from bad data so then I got weird temperature and humidity values including -ve values.

The following list I shows a selection of this bad data. The lists shows the 4 bytes received from the SPI and then the temperature and humidity calculated from these bytes in the cases where the CRC is correct:

0,81
1,2E
2,20
3,E9

0,1
1,2D 
2,A0
3,BE
T=-9.-9C, H=160%

0,28
1,34
2,80
3,4B

0,1
1,2D
2,A0
3,BE
T=-9.-9C, H=160%0,41

The following is my modified code that produces the above result:

// Written by Nick Gammon
// February 2011
// see http://mushclient.com/spi

// Rework for DYPTH01B_SPI Temperature and Humidity sensor
// using MTH01 Sensor
// D. Richards, Jan 2012
// see http://www.suntekstore.co.uk/product-14001923-DYPTH01B-SPI+Temperature++Humidity+Sensor+Module.html


int ledToggle = -1;
int ledCounter = 0;

#include <LiquidCrystal.h>
/* YourDuino.com Example Software Sketch
 16 character 2 line I2C Display
 Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
 terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address



//Arduino Pin =>  DYPTH01 Function
// SS         =>  LOW
// 11 MOSI    =>  SDAT
// 12 MISO    =>  nc
// 13 CLK     =>  SCK

// 5V         =>  VDD
// GND        =>  VSS
// 7          =>  Reset
// 8          =>  CE

//#include "pins_arduino.h"

byte buf[40];
volatile byte pos;
volatile boolean process_it;
int MTH_temperature;
int MTH_humidity;
#define HCS 8
#define HRT 7
#define FRQ_MON 5
byte clr;

/*
  The following procedure calculates the CRC-8. The result accumulates in the variable CRC.
  Var CRC : Byte;
  Procedure calc_CRC(X: Byte);

  Begin
  CRC := CRC_Table[X xor CRC];
  End;

 Polynomial is x^8 + x^5 + x^4
*/

const unsigned char CRC8table[256] PROGMEM = {

  0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46,
  67, 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109,
  134, 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168,
  197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235,
  61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19,
  126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80,
  187, 138, 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149,
  248, 201, 154, 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214,
  122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84,
  57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23,
  252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210,
  191, 142, 221, 236, 123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145,
  71, 118, 37, 20, 131, 178, 225, 208, 254, 207, 156, 173, 58, 11, 88, 105,
  4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238, 121, 72, 27, 42,
  193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239,
  130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172,
};


void setup (void)
{

   pinMode(HCS, OUTPUT);        // CS output
  digitalWrite(HCS, HIGH);     // CS inactive
  pinMode(HRT, OUTPUT);        // RST output
  digitalWrite(HRT, LOW);     // RST active
  delay(2);
  digitalWrite(HRT, HIGH);     // RST inactive

#ifdef LCD
  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.backlight(); // finish with backlight on

  //-------- Write characters on the display ------------------
  // NOTE: Cursor Position: (CHAR, LINE) start at 0
  lcd.setCursor(0, 0); //Start at character 4 on line 0
  lcd.print("Weather");
#else
  Serial.begin (115200);   // debugging
  Serial.println ("initialising");
#endif
  

 

  delay(1000); // 100ms delay after reset.

  // get ready for an interrupt
  pos = 0;   // buffer empty
  process_it = false;

  //Sample on falling edge
  SPCR |= _BV(CPHA);

  // Clock idle when low set CPOL to 0
  SPCR &= ~_BV(CPOL);


  //  Slave mode
  SPCR &= ~_BV(MSTR);

  // Enables  SPE = 1
  SPCR |= _BV(SPE);

  clr = SPSR;
  clr = SPDR;
  // now turn on interrupts
  SPCR |= _BV(SPIE);



  digitalWrite(HCS, LOW);      // CS active, starts conversion

}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register

  // add to buffer if room
  if (pos < 4)
  {
    buf[pos] = c;
    pos++;
    if (pos >= 4) // when all 4 bytes received
    {
      pos = 0;
      digitalWrite(HCS, HIGH);  // disable further conversions
      process_it = true;      // signal ready to main loop
    }
  }  // end of room available

}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  byte idx;
  byte crc;
  byte byt;
  int i;

  


  if (process_it)
  {
    crc = 0;
    for (i = 0; i < 4; i++)
    {
      byt = buf[i];
      idx  =  byt ^ crc;
      //      idx  =  buf[i] ^ crc;
      crc = CRC8table[idx];
      //      crc = CRC8table[buf[i] ^ crc];
#ifndef LCD
/*
      Serial.print(" n");
      Serial.print(i, HEX);
      Serial.print(" b");
      Serial.print(byt, HEX);
      Serial.print(" c");
      Serial.print(crc, HEX);
      Serial.print(" i");
      Serial.print(idx, HEX);
      Serial.println(">");
*/
#endif
    }
#ifndef LCD
   for (i = 0; i < 4; i++)
   {
     Serial.print(i);
     Serial.print(",");
     Serial.print(buf[i], HEX);
     Serial.println();
   }
#endif
    
    

#ifndef LCD
    //Serial.print(crc, HEX);
    //Serial.print(", ");
    //Serial.println(buf[3], HEX);
#endif

    if (crc == 0 && ((buf[0] & 0xf0) == 0))
    {
      MTH_temperature = ( (256 * buf[0]) + buf[1] ) - 400;
      MTH_humidity = buf[2];
#ifdef LCD
      lcd.setCursor(0, 0); //Start at character 4 on line 0
      lcd.print("T=");
      lcd.print( MTH_temperature / 10);
      lcd.print(".");
      lcd.print( MTH_temperature % 10);
      lcd.print("C");
      lcd.setCursor(0, 1); //Start at character 4 on line 0
      lcd.print("H=");
      lcd.print(MTH_humidity);
      lcd.print("%");
#else

      Serial.print(" T=");
      Serial.print( MTH_temperature / 10);
      Serial.print(".");
      Serial.print( MTH_temperature % 10);

      Serial.print("C, H=");
      Serial.print(MTH_humidity);
      Serial.print("%");

#endif
    }
    else
    {
      // reset chip here
      digitalWrite(HRT, LOW);     // RST active
      delay(2);
      digitalWrite(HRT, HIGH);     // RST inactive
#ifndef LCD
      Serial.print("Reset");
#endif
      delay(100);
    }
    //   Serial.println();

    delay(2000);
  //  pos = 0;                // reset buffer index
    process_it = false;     // preset buffer not ready
    clr = SPSR;
    clr = SPDR;
    digitalWrite(HCS, LOW);    // start conversion

  }  // end of flag set

}  // end of loop

In particular note that I believe the setup of the SPI had some problems (although it’s possible that the SPI defaults to my explicit settings) eg -ve edge clock and clock idle low.

I fiddled around with this a while but almost gave up because there seemed to be too many variables – I didn’t know what was working.  Then the idea came that I should be able to bypass the SPI and read the CLK and MOSI data directly by turning the Arduino into a slow logic analyzer.  I determined that I could make a loop that could execute at about 25khz that was able to read two pins and store the data in an array. My vague understanding of nyquist indicates that this should enable me to sample a clock not more then 1/3 of this frequency which is higher than the 3khz DYPTH clock.  So the following code reads the temperature and humidity by interpreting the binary data from the pins of the DYPTH.

// Written by Nick Gammon
// February 2011
// see http://mushclient.com/spi

// Rework for DYPTH01B_SPI Temperature and Humidity sensor
// using MTH01 Sensor
// D. Richards, Jan 2012
// see http://www.suntekstore.co.uk/product-14001923-DYPTH01B-SPI+Temperature++Humidity+Sensor+Module.html


int ledToggle = -1;
int ledCounter = 0;

#include <LiquidCrystal.h>
/* YourDuino.com Example Software Sketch
 16 character 2 line I2C Display
 Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
 terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//Arduino Pin =>  DYPTH01 Function
// SS         =>  LOW
// 11 MOSI    =>  SDAT
// 12 MISO    =>  nc
// 13 CLK     =>  SCK

// 5V         =>  VDD
// GND        =>  VSS
// 7          =>  Reset
// 8          =>  CE

//#include "pins_arduino.h"

byte buf[40];
volatile byte pos;
volatile boolean process_it;
int MTH_temperature;
int MTH_humidity;
#define HCS 8
#define HRT 7
#define FRQ_MON 5
byte clr;

/*
  The following procedure calculates the CRC-8. The result accumulates in the variable CRC.
  Var CRC : Byte;
  Procedure calc_CRC(X: Byte);

  Begin
  CRC := CRC_Table[X xor CRC];
  End;

 Polynomial is x^8 + x^5 + x^4
*/

const unsigned char CRC8table[256] PROGMEM = {

  0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46,
  67, 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109,
  134, 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168,
  197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235,
  61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19,
  126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80,
  187, 138, 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149,
  248, 201, 154, 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214,
  122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84,
  57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23,
  252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210,
  191, 142, 221, 236, 123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145,
  71, 118, 37, 20, 131, 178, 225, 208, 254, 207, 156, 173, 58, 11, 88, 105,
  4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238, 121, 72, 27, 42,
  193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239,
  130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172,
};

const int MAX_VALUES = 250;
const int TURN_OFF_POINT = 200; //266;
byte pinReading13[MAX_VALUES];
byte pinReading11[MAX_VALUES];
void setup (void)
{

  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.backlight(); // finish with backlight on

  Serial.begin (115200);   // debugging
  Serial.println ("initialising");
  pinMode(11, INPUT);
  pinMode(13, INPUT);
  pinMode(HCS, OUTPUT);
  digitalWrite(HCS, HIGH);
  pinMode(FRQ_MON, OUTPUT);
  return;



}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register

  // add to buffer if room
  if (pos < sizeof buf)
  {
    buf [pos++] = c;

    if (pos >= 4) // when all 4 bytes received
    {
      digitalWrite(HCS, HIGH);  // disable further conversions
      process_it = true;      // signal ready to main loop
    }
  }  // end of room available

}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  byte idx;
  byte crc;
  byte byt;
  int i;
  while (1)
  {
    delay(1000);
    // As soon as HCS goes low we start reading 11 and 13
    digitalWrite(HCS, LOW);
    byte pin13 = 0;
    byte pin11 = 0;
    byte bitPos = 7;
    int x = 0;
    char toggle = -1;
    while (x < MAX_VALUES)
    {
      //  toggle *= -1;
      //  if (toggle == -1)
      //    digitalWrite(FRQ_MON, LOW);
      //  else
      //   digitalWrite(FRQ_MON, HIGH);
      pin13 |=  digitalRead(13) << bitPos;
      pin11 |=  digitalRead(11) << bitPos;

      if (bitPos == 0)
      {
        //  lcd.setCursor(0, 0); //Start at character 4 on line 0
        //  lcd.print(pin11);
        pinReading11[x] = pin11;
        pinReading13[x] = pin13;
        pin11 = 0;
        pin13 = 0;
        bitPos = 7;
        x++;
      }
      else
      {
        bitPos--;
      }

      if (x >= TURN_OFF_POINT)
      {
        digitalWrite(HCS, HIGH);
      }
      // digitalWrite(FRQ_MON,HIGH);

    }
    /*
      Use the digital data to find the temperature.
    */
    int byteCounterForCollectedData = 0;
    int bitCounterForCollectedData = 7;
    int lastClkBit = 0;
    int currentClkBit = 0;
    int byteCounterForConvertedData = 0;
    int bitCounterForConvertedData = 7;
    int dataBit = 0;
    byte dataByte = 0;
    byte dataBytes[4];

    while (byteCounterForCollectedData < MAX_VALUES)
    {
      currentClkBit = 0;
      if ((pinReading13[byteCounterForCollectedData] & (1 << bitCounterForCollectedData)) > 0)
        currentClkBit = 1;
      if ((lastClkBit == 1) && (currentClkBit == 0))  // We have a -ve transition in the input bit stream as sampled from the SPI clock.
      {
        dataBit = 0;
        if ((pinReading11[byteCounterForCollectedData] & 1 << bitCounterForCollectedData) > 0)
        {
          dataBit = 1;
        }

        dataByte |= dataBit << bitCounterForConvertedData;
        bitCounterForConvertedData--;
        if (bitCounterForConvertedData < 0)
        {
          dataBytes[byteCounterForConvertedData] = dataByte;
          dataByte = 0;
          bitCounterForConvertedData = 7;
          byteCounterForConvertedData++;
        }


      }
      lastClkBit = currentClkBit;
   



      bitCounterForCollectedData--;
      if (bitCounterForCollectedData < 0)
      {
        bitCounterForCollectedData = 7;
        byteCounterForCollectedData++;
      }

    }

    int temperature;
    for (int convertedByteCount = 0; convertedByteCount < 4; convertedByteCount++)
    {
      Serial.print(dataBytes[convertedByteCount], HEX);
      Serial.print(",");
     
      
    }
     temperature = (dataBytes[0] * 256 + dataBytes[1]) - 400;
     Serial.print(temperature / 10);
     Serial.print(".");
     Serial.print(temperature % 10);
     Serial.print(" C,");
      Serial.print(dataBytes[2]);
     Serial.print(" %");
     
    Serial.println("");

    /*
      for (int x = 0; x < MAX_VALUES; x++)
      {
        Serial.print(pinReading11[x], HEX);
        Serial.print(",");
        Serial.print(pinReading13[x], HEX);
        Serial.println("");
      }
      while (1)
      {
      }
    */
  }



}  // end of loop

And this seems to work perfectly and the operation of the DYPTH agrees with the specs.  Ie after the CE is made low there is a delay before the device outputs 32 bits of data and if CE is only low for a short period then no more data is sent.   So now I could be confident that at least one thing was working.

So this morning as I was writing this entry I first did a recheck of my pin connections and found that where I had thought I’d connected Arduino SS low I had instead connected MISO low meaning that SS was floating. When I connected SS low I get much more consistent data.  Below is the data, note that I pinched the sensor with my fingers so both the temperature and humidity change, is it measuring my humidity?  In any case  valid data appears from the start (although I am ignoring the CRC).

initialising
2,5C,41,D3,20.4 C,65 %
2,5C,41,D3,20.4 C,65 %
2,5C,41,D3,20.4 C,65 %
2,5E,41,A,20.6 C,65 %
2,5C,41,D3,20.4 C,65 %
2,5D,41,27,20.5 C,65 %
2,5B,41,7D,20.3 C,65 %
2,5C,41,D3,20.4 C,65 %
2,5F,42,AD,20.7 C,66 %
2,63,42,AB,21.1 C,66 %
2,66,43,ED,21.4 C,67 %
2,6B,45,B,21.9 C,69 %
2,70,45,7F,22.4 C,69 %
2,74,46,AF,22.8 C,70 %
2,76,47,47,23.0 C,71 %
2,7B,48,29,23.5 C,72 %
2,7C,49,B6,23.6 C,73 %
2,7D,4A,11,23.7 C,74 %
2,7C,4B,D4,23.6 C,75 %

 

So now I need to find out which of my code changes was the correct fix. First thing is that if I now ignore the CRC (in my modified version of the original code which uses SPI) then the values all seem good. Perhaps CRC is incorrectly generated or calculated on the Arduino side.

What I find is that there seems to be no impact between my setup of the SPI and the original so long as I ignore CRC. The only things I find is that the Arduino SS pin is not specified as connected so I assume that it wasn’t when Matthew Little did his experiments. Leaving the SS pin floating seems to introduce random data. Note that I did try leaving the DYPTH CE line low all the time and this causes no issues. Using the CRC code to do a reset causes data problems since we probably aren’t waiting long enough for the reset to occur.

What I found next during my debugging of the CRC generation was that adding extra code to be used to debug the system caused the CRC to be calculated incorrectly. For example when I added the following code I got a different sequence of CRC problems. Believe it or not. I went back and forward, adding and removing this code and always go similar results. So, something seemed very strange.

      Serial.print(" i:");
      Serial.print(i, HEX);
      Serial.print(" b:");
      Serial.print(byt, HEX);
      Serial.print(" c:");
      Serial.print(crc, HEX);  
      Serial.println(">");

To me this seemed like some form of compiler issue or memory corruption due to bad code. I had already looked at changing the datatypes used in the calculation of the CRC getting differences in the process. I then noticed the PROGMEM keyword on the array of CRC values. This seemed suspicious although at this point I had no idea what it meant but I removed it from the next line:

const unsigned char CRC8table[256] PROGMEM = {
to get:
const unsigned char CRC8table[256] = {

And after I did this the crc calculation works consistently – well I always get zero now indicating no errors and at the slow data speed I wouldn’t expect any errors. After investigating PROGMEM I find that it is supposed to put items into flash but was perhaps being used incorrectly as it relies upon a library that doesn’t seem to be being used and also only works with specific data types.

So, in summary, what I found is that the original code was all ok except for the use of PROGMEM. When PROGMEM was used in the definition of the CRC table the calculation of CRC values using the this definition caused some type of memory corruption. This memory corruption led to random errors being seen in the output.

I think I can now get on and start work on the nRF radio transceivers.

Copying my SATA hard drive

The following two open source tools can be used to copy one SATA drive to another:

Clonezilla

Gparted

Amazing.  Copy an image from one drive to another using clonezilla and then (as you will probably be going from a small to a large drive), using Gparted to expand the partition(s) as you want.

Both these tools should be made into bootable CD Roms and run by booting the computer with each of them in turn. You may need to change the boot order in the bios.