SPA100 interfacing (part 2) - to blinky and beyond..

SPA100 interfacing (part 2) - to blinky and beyond..

Several SPA100 customers have had issues 'getting to blinky' (in this case, getting a packet of data out of the SPA100) with their own software - In most cases this has been down to the way their outgoing packet has been setup and the way the outgoing checksum has been calculated.

Protocol (lifted straight from our internal document EPP1.08) - E&OE!

---------------------------------

PC>INSTRUMENT (mid level protocol structure/packets)

A packet of data consists of 8 bytes (& there attendant start/stop bits). There is to be no space between the stop bit of one byte and the start bit of the next.

Write (single location only)

START

Bit 0

Bit 1

Bit 2

Bit 3

Bit 4

Bit 5

Bit 6

Bit 7

STOP

0

A8

A9

A10

A11

A12

A13

A14

1

1

0

A0

A1

A2

A3

A4

A5

A6

A7

1

0

D24

D25

D26

D27

D28

D29

D30

D31

1

0

D16

D17

D18

D19

D20

D21

D22

D23

1

0

D8

D9

D10

D11

D12

D13

D14

D15

1

0

D0

D1

D2

D3

D4

D5

D6

D7

1

0

CS8

CS9

CS10

CS11

CS12

CS13

CS14

CS15

1

0

CS0

CS1

CS2

CS3

CS4

CS5

CS6

CS7

1

A14-A0 (“ADDRESS, 15 bits): the start address of the data to be written or read
D31-D0 (“DATA”, 32 bits): this is either just the data.
CS15-CS0 (“CHECKSUM”, 16 bits): created by adding the three pairs of 16bits and 0x5555.

Read (single location only)

START

Bit 0

Bit 1

Bit 2

Bit 3

Bit 4

Bit 5

Bit 6

Bit 7

STOP

0

A8

A9

A10

A11

A12

A13

A14

0

1

0

A0

A1

A2

A3

A4

A5

A6

A7

1

0

D24

D25

D26

D27

D28

D29

D30

D31

1

0

D16

D17

D18

D19

D20

D21

D22

D23

1

0

D8

D9

D10

D11

D12

D13

D14

D15

1

0

D0

D1

D2

D3

D4

D5

D6

D7

1

0

CS8

CS9

CS10

CS11

CS12

CS13

CS14

CS15

1

0

CS0

CS1

CS2

CS3

CS4

CS5

CS6

CS7

1

A14-A0 (“ADDRESS, 15 bits): the start address of the data to be written or read
D31-D0 (“DATA”, 32 bits): this is either just the data.
CS15-CS0 (“CHECKSUM”, 16 bits): created by adding the three pairs of 16bits and 0x5555.

DATA TYPE

115.2 kbps, 8N1, using a CH340C.

SPA (PC>INSTRUMENT)

An 8 byte packet of data is sent from the PC up to the instrument. This is formatted thus:

Address

R/W?

Name

Units

Values

0x0000

W

Status

-

-

0x0001

W

Main Control Register

b0-12=unused

b12=disable STATUS LED (0=LED enabled, 1=LED disabled)

b13=reset CAL sync marker data (0=no reset, 1=reset)

b14=erase all calibration FLASH (0x001E must be 0xAA55)

b15=write data back to calibration FLASH

b16=transmit enable (0=suppress TX, 1=allow TX)

b17-31=unused

Arbitrary

32bits

0x0002

W

Timebase (@100KHz) e.g. 50000=2Hz, 10000=10Hz

Arbitrary

16bits unsigned

0x0003

W

Input Relay Range (0,1,2,3)

Arbitrary

32bits unsigned

0x0004

W

PGA Gain (e.g. 1,2,4,8)

Arbitrary

16bits unsigned

0x0005

W

Resolution (e.g.16, 18)

Arbitrary

16bits unsigned

0x0006

W

Zero/Short Input Relay (0=off, 1=on/short)

Arbitrary

16bits unsigned

0x0007

W

PWM output level (0-65535)

Arbitrary

16bits unsigned

0x0008

W

 

Arbitrary

16bits unsigned

0x0009

W

 

Arbitrary

16bits unsigned

0x000A

W

 

Arbitrary

16bits unsigned

0x000B

W

 

Arbitrary

16bits unsigned

0x000C

W

 

Arbitrary

16bits unsigned

0x000D

W

 

Arbitrary

16bits unsigned

0x000E

W

 

Arbitrary

16bits unsigned

0x000F

W

 

Arbitrary

16bits unsigned

0x0010

W

 

Arbitrary

16bits unsigned

0x0011

W

 

Arbitrary

16bits unsigned

0x0012

W

 

Arbitrary

16bits unsigned

0x0013

W

 

Arbitrary

16bits unsigned

0x0014

W

 

Arbitrary

16bits unsigned

0x0015

W

 

Arbitrary

16bits unsigned

0x0016

W

 

Arbitrary

16bits unsigned

0x0017

W

 

Arbitrary

16bits unsigned

0x0018

W

 

Arbitrary

16bits unsigned

0x0019

W

 

Arbitrary

16bits unsigned

0x001A

W

 

Arbitrary

16bits unsigned

0x001B

W

 

Arbitrary

16bits unsigned

0x001C

W

 

Arbitrary

16bits unsigned

0x001D

W

 

Arbitrary

16bits unsigned

0x001E

W

Calibration FLASH ADDRESS (CAL FLASH location to write)

Arbitrary

16bits unsigned

0x001F

W

Calibration FLASH DATA (for writing to CAL FLASH)

Arbitrary

32bits unsigned


SPA (INSTRUMENT>PC)

An 16 byte packet of data is sent from the INSTRUMENT to the PC. This is formatted thus:

Data returned:
2 bytes – STATUS (only 2 bits used, 14 bits reserved for future use)
2 bytes - USB voltage (12 bits) / Calibration Data (16 bits)
3 bytes - 1x 24bit current value of ADC’s
8 bytes – reserved for future use
1 byte - Checksum!
Total of 16 bytes.

Byte

Function

0

Device Status (MSB)

1

Device Status (LSB)

2

USB voltage (MSB) / Calibration Data (MSB)

3

USB voltage (LSB) / Calibration Data (LSB)

4

Reserved for future use

5

Reserved for future use

6

ADC raw current (MSB, b23-b16)

7

ADC raw current (CSB, b15-b8)

8

ADC raw current (LSB, b7-b0)

9

Reserved for future use

10

Reserved for future use

11

Reserved for future use

12

Reserved for future use

13

Reserved for future use

14

Reserved for future use

15

Checksum

 
Device Status
bits 0 to 11=unused
bit 12=USB/CAL status (0=USB voltage, 1=calibration DATA)
bit 13=CAL data start packet marker (0=no marker, 1=initial byte)
bits 14,15=unused

Notes
USB voltage is not implemented on the SPA100
ADC raw current is a signed value

Calibration data
When b13 of the status packet =1 signals the 0th word (word is 2 bytes) of the calibration data.
Word 0= DAC value at +40V source output
Word 1= DAC value at -40V source output
Word 2,3= unused
Word 4,5= Range 1+ ADC raw value (32 bit signed), known as “adcpos
Word 6,7= Range 1- ADC raw value (32 bit signed), known as “adcneg
Word 8-11= Range 1+ Calibration current value (64 bit float [double]), known as “ipos
Word 12-15= Range 1- Calibration current value (64 bit float [double]), known as “ineg
….
Word 88,89= Range 8+ ADC raw value (32 bit signed [long])
Word 90,91= Range 8- ADC raw value (32 bit signed [long])
Word 92-95= Range 8+ Calibration current value (64 bit float [double])
Word 96-99= Range 8- Calibration current value (64 bit float [double])

Scale and Offset for each range is calculated in EPIC/SPA software using the ADC raw value and calibration values.
Scale= (ipos - ineg) / (adcpos - adcneg)
Offset= ineg – (adcneg * Scale)

So to calculate the actual current (for a given range):
Current= (ADC * Scale) + Offset
---------------------------------

Below are some examples of messages you can send to the SPA100, you should use them to compare against the output from your own code:

LED OFF ("80 01 00 01 10 00 E5 57") is built with:
80 01 (address 0001h)
00 01 (bits 31-16) - bit 16 set, transmission enabled
10 00 (bit 15-0) - bit 12 set (LED suppress, i.e. inverted)
E5 57 (checksum)

LED ON ("80 01 00 01 00 00 D5 57") is built with:
80 01 (address 0001h)
00 01 (bits 31-16) - bit 16 set, transmission enabled
00 00 (bit 15-0) - bit 12 clear (LED normal)
D5 57 (checksum)

SET TIMEBASE TO 10000 (10Hz), ("80 02 00 01 27 10 FC 68")
80 02 (address 0002h)
00 01 (bits 31-16) - bit 16 set, transmission enabled
27 10 (bit 15-0) - 10,000 (10Hz)
FC 68 (checksum)


Note: As described in the protocol, the checksum is the 16 bit addition of the "address", "data31-16", "data15-0", "0x5555" words.  If you are doing the calculation using 32 bit maths, probably wise to AND the final checksum result with 0x0000FFFF to mask off any carry forward in values in bits 16 & 17 of the result.  Essentially:

Checksum = (Word1 + Word2 + Word3 + 0x5555) & 0xFFFF

If you don't want to write code that will slowly download and then reassemble the calibration data (it's fairly tedious).  Then you can use the function built into the SPA PC software (v25.001 onwards) to translate the calibration file into more human readable values.

This function is found in SPA25.002 menu - UTILITIES>DEVELOPMENT ONLY>TRANSLATE CALIBRATION FILE.

An example of the translated output is shown below:

"
translated from: C:\Program Files\Electron Plus\SPA\SPA_cal.txt
DAC+40V: 5956
DAC-40V: 367
unused: 0
unused: 0
ADC Range1+: -8144915
ADC Range1-: 8212096
Calibrated Current for Range1+:  0.002007760000000 A,   2.008 mA,   2007.760 uA,   2007760.000 nA,   2007760000.000 pA
Calibrated Current for Range1-: -0.002007090000000 A,  -2.007 mA,  -2007.090 uA,  -2007090.000 nA,  -2007090000.000 pA
ADC Range2+: -6248922
ADC Range2-: 6312186
Calibrated Current for Range2+:  0.000200642050000 A,   0.201 mA,   200.642 uA,   200642.050 nA,   200642050.000 pA
Calibrated Current for Range2-: -0.000200642050000 A,  -0.201 mA,  -200.642 uA,  -200642.050 nA,  -200642050.000 pA
ADC Range3+: -8126029
ADC Range3-: 8133363
Calibrated Current for Range3+:  0.000020015000000 A,   0.020 mA,   20.015 uA,   20015.000 nA,   20015000.000 pA
Calibrated Current for Range3-: -0.000020016000000 A,  -0.020 mA,  -20.016 uA,  -20016.000 nA,  -20016000.000 pA
ADC Range4+: -6236378
ADC Range4-: 6298176
Calibrated Current for Range4+:  0.000002000400000 A,   0.002 mA,   2.000 uA,   2000.400 nA,   2000400.000 pA
Calibrated Current for Range4-: -0.000002000400000 A,  -0.002 mA,  -2.000 uA,  -2000.400 nA,  -2000400.000 pA
ADC Range5+: -7999750
ADC Range5-: 8083571
Calibrated Current for Range5+:  0.000000199739950 A,   0.000 mA,   0.200 uA,   199.740 nA,   199739.950 pA
Calibrated Current for Range5-: -0.000000200340070 A,  -0.000 mA,  -0.200 uA,  -200.340 nA,  -200340.070 pA
ADC Range6+: -6155968
ADC Range6-: 6211360
Calibrated Current for Range6+:  0.000000019957120 A,   0.000 mA,   0.020 uA,   19.957 nA,   19957.120 pA
Calibrated Current for Range6-: -0.000000019958110 A,  -0.000 mA,  -0.020 uA,  -19.958 nA,  -19958.110 pA
ADC Range7+: -8095859
ADC Range7-: 8108947
Calibrated Current for Range7+:  0.000000001994610 A,   0.000 mA,   0.002 uA,   1.995 nA,   1994.610 pA
Calibrated Current for Range7-: -0.000000001994610 A,  -0.000 mA,  -0.002 uA,  -1.995 nA,  -1994.610 pA
ADC Range8+: -6193651
ADC Range8-: 6305562
Calibrated Current for Range8+:  0.000000000199162 A,   0.000 mA,   0.000 uA,   0.199 nA,   199.162 pA
Calibrated Current for Range8-: -0.000000000199661 A,  -0.000 mA,  -0.000 uA,  -0.200 nA,  -199.661 pA
"

For the purpose's of generating "Scale" and "Offset" values for each range (see earlier in this post):

"ipos" would be ADC RangeX+
"ineg" would be ADC RangeX-
"adcpos" would be Calibrated Current for RangeX+
"adcneg" would be Calibrated Current for RangeX-

Each range has it's own calibration coefficients, i.e. replace the X with 1,2,3,etc.. Be sure to use SI units, i.e. -199.661pA would be -0.000000000199661 or -1.99661E-10. We use SI units and double precession floating point math in all our PC software.

The 8 ranges are achieved using 4 relay settings and 2 gain settings in the ADC, the two speeds (2H/10Hz) have different sample resolutions.  Here is an excerpt of the SPA25.002 code base that defines those settings:

-----------------------------------
 ; set the samplerate
  Select SPA_SampleRate
    Case 2    : ALL_register($02)=50000 : ALL_register($05)=18 ; SPA_SampleDepth
    Case 10   : ALL_register($02)=10000 : ALL_register($05)=16 ; SPA_SampleDepth
    Case 100  : ALL_register($02)=1000  : ALL_register($05)=16 ; SPA_SampleDepth  
    Default   : ALL_register($02)=50000 : ALL_register($05)=18 ; SPA_SampleDepth
  EndSelect  
    
  ; set the input relay ($03) and the PGA ($04) for the correct range
  Select SPA_InputRange
    Case 1  : ALL_register($03)=0 : ALL_register($04)=1 ; 1mA
    Case 2  : ALL_register($03)=0 : ALL_register($04)=8 ; 100uA
    Case 3  : ALL_register($03)=1 : ALL_register($04)=1 ; 10uA
    Case 4  : ALL_register($03)=1 : ALL_register($04)=8 ; 1uA
    Case 5  : ALL_register($03)=2 : ALL_register($04)=1 ; 100nA
    Case 6  : ALL_register($03)=2 : ALL_register($04)=8 ; 10nA
    Case 7  : ALL_register($03)=3 : ALL_register($04)=1 ; 1nA
    Case 8  : ALL_register($03)=3 : ALL_register($04)=8 ; 100pA
    Default : ALL_register($03)=3 : ALL_register($04)=1 ; 1nA - default, incase value is not set, this is safe.
  EndSelect  

-----------------------------------

Recalibrating an SPA100 is best done through SPA PC software. For that reason I won't describe the process of erasing the calibration coefficients and uploading new ones.

One final note, if you choose to use the incoming checksum, it is calculated using 8 bit (byte) addition of the preceding 15 bytes.  We use this in our software to spot error'd communications and initiate a resynchronisation of the comms, it's very rare and somewhat of a hangover from my history of designing large RS485 networks of things back in the nineties.

-Ben

Back to blog