MSB2 Firmware: Difference between revisions
Karl Koscher (talk | contribs) |
mNo edit summary |
||
(18 intermediate revisions by one other user not shown) | |||
Line 10: | Line 10: | ||
** Communicates with any embedded platform | ** Communicates with any embedded platform | ||
** Communicates with any desktop/laptop/handheld/cell phone with a available uart port | ** Communicates with any desktop/laptop/handheld/cell phone with a available uart port | ||
== Current Firmware Images == | |||
{| class="wikitable" | |||
!style="width:300px"| Sensor Board !! style="width:100px" | Download Link | |||
|- | |||
| MSB2 - Hardware Version 2 (BT + SD built in) | |||
|| [{{SERVER}}/files/imote2/firmware/HW3_MSB_flow_control_force_power_led.hex MSB2] | |||
|- | |||
| LSB | |||
|| [{{SERVER}}/files/imote2/firmware/LSB_firmware_V1_0_and_bootloader.hex LSB] | |||
|} | |||
A more detailed set of firmware images for the MSB are available from: [http://www.cs.washington.edu/homes/supersat/MSB/ http://www.cs.washington.edu/homes/supersat/MSB/] and for the LSB at [http://ubicomp.cs.washington.edu/firmware/LSB/ http://ubicomp.cs.washington.edu/firmware/LSB/]. In addition the firmware source may be downloaded from assab.cs.washington.edu and built using a pre-configured build environment located at <tt>/projects/ubicomp/uwar/software/MSB Firmware Windows XP Professional 2.vmwarevm</tt> | |||
Line 59: | Line 72: | ||
All MSB firmware responses will be sent back as packets that begin with 2 characters '#' followed by '|', then an identifier byte describing what the packet is and how it should be interpreted. | All MSB firmware responses will be sent back as packets that begin with 2 characters '#' followed by '|', then an identifier byte describing what the packet is and how it should be interpreted. | ||
{| class="wikitable" style="text-align:center" | {| class="wikitable" style="text-align:center" | ||
!colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 | !colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | ... !! colspan="2" style="width:70px" | Byte N | ||
|- | |- | ||
|style="width:35px"| '#' || 0x23 || style="width:35px"| '|' || 0x7C || colspan="2" style="background:#ABCDEF;"| ID | |style="width:35px"| '#' || 0x23 || style="width:35px"| '|' || 0x7C || colspan="2" style="background:#ABCDEF;"| ID || colspan="2" style="background:#ABCDEF;"| Payload || colspan="2" style="background:#ABCDEF;"| Checksum | ||
|} | |||
The checksum is calculated by adding up all bytes 2 through N - 1, and taking the lower 8 bits of the result. | |||
==== Packet IDs ==== | |||
{| class="wikitable" style="text-align:center" | |||
!style="width:70px" | ID !! style="width:140px" | Type | |||
|- | |||
| 0x00 || [[#Sensor_Packets|Sensor Packet]] | |||
|- | |||
| 0x01 || [[#Sensor_Packets|Sensor Packet]] | |||
|- | |||
| 0x02 || RTC Packet | |||
|- | |||
| 0x04 || [[#Error_Packets|Error Packet]] | |||
|- | |||
| 0x08 || [[#Microphone_Data_Packet|Microphone Packet]] | |||
|- | |||
| 0x10 || [[#Individual_and_Tricolor_LED_command_format|LEDs Packet]] | |||
|- | |||
| 0x20 || [[#Calibration_Information_Packet|Calibration Information Packet]] | |||
|- | |||
| 0x40 || [[#Schedule_Format|Schedule Packet]] | |||
|- | |||
| 0x80 || [[#Power_Packets|Power Packet]] | |||
|} | |} | ||
</ul> | </ul> | ||
Line 121: | Line 158: | ||
<ul> | <ul> | ||
This command alters the sensor sampling schedule. May only be executed in the WAIT state.<br /><br /> | This command alters the sensor sampling schedule. May only be executed in the WAIT state.<br /><br /> | ||
'''Host sends:''' '!alter' | '''Host sends:''' '!alter' SCHED_DATA | ||
{| class="wikitable" style="text-align:center" | {| class="wikitable" style="text-align:center" | ||
!colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width:70px" | Byte 5 | !colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width:70px" | Byte 5 | ||
!! style="width: | !! style="width:140px" | Byte 6 - 23 | ||
|- | |- | ||
| | |style="width:35px"| '!' || 0x21 || style="width:35px"| 'a' || 0x61 ||rowspan="2" style="width:35px"| 'l' || 0x6c || style="width:35px"| 't' || 0x74 || style="width:35px"| 'e' || 0x65 || style="width:35px"| 'r' || 0x72 || colspan="2" style="width:70px" | [[#Schedule_Format|Schedule Data]] | ||
| | |||
|} | |} | ||
==== Data Returned ==== | ==== Data Returned ==== | ||
Line 214: | Line 227: | ||
!colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width:140px" | Byte 5 | !colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width:140px" | Byte 5 | ||
|- | |- | ||
|style="width:35px"| '!' || 0x21 || style="width:35px"| 'g' || 0x67 ||style="width:35px"| 'a' || 0x61 ||style="width:35px"| 'i' || 0x69 ||style="width:35px"| 'n' || 0x6e || colspan="2" style="background:#ABCDEF;" | Gain | |style="width:35px"| '!' || 0x21 || style="width:35px"| 'g' || 0x67 ||style="width:35px"| 'a' || 0x61 ||style="width:35px"| 'i' || 0x69 ||style="width:35px"| 'n' || 0x6e || colspan="2" style="background:#ABCDEF;" | Gain (0x00 to 0xFF) | ||
|} | |} | ||
<b>Note: Since '!' is a reserved character, a gain value of 0x21 cannot be set with this command.</b> | |||
</ul> | </ul> | ||
Line 223: | Line 237: | ||
'''Host sends:''' '!write' | '''Host sends:''' '!write' | ||
{| class="wikitable" style="text-align:center" | {| class="wikitable" style="text-align:center" | ||
!colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width: | !colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width:70px" | Byte 5 | ||
|- | |- | ||
|style="width:35px"| '!' || 0x21 || style="width:35px"| 'w' || 0x77 ||style="width:35px"| 'r' || 0x72 ||style="width:35px"| 'i' || 0x69 ||style="width:35px"| 't' || 0x74 || style="width:35px"| 'e' || 0x65 | |style="width:35px"| '!' || 0x21 || style="width:35px"| 'w' || 0x77 ||style="width:35px"| 'r' || 0x72 ||style="width:35px"| 'i' || 0x69 ||style="width:35px"| 't' || 0x74 || style="width:35px"| 'e' || 0x65 | ||
|} | |||
</ul> | |||
=== Clock Command === | |||
<ul> | |||
This writes sets the first seven bytes of the RTC registers. May only be executed in the WAIT state. More information on the RTC's registers is available in [http://us.st.com/stonline/products/literature/ds/10396.pdf this datasheet].<br /><br /> | |||
'''Host sends:''' '!clock' | |||
{| class="wikitable" style="text-align:center" | |||
!colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width:70px" | Byte 5 !! colspan="2" style="width:70px" | Byte 6 !! colspan="2" style="width:70px" | Byte 7 !! colspan="2" style="width:70px" | Byte 8 !! colspan="2" style="width:70px" | Byte 9 !! colspan="2" style="width:70px" | Byte 10 !! colspan="2" style="width:70px" | Byte 11 !! colspan="2" style="width:70px" | Byte 12 | |||
|- | |||
|style="width:35px"| '!' || 0x21 || style="width:35px"| 'c' || 0x63 ||style="width:35px"| 'l' || 0x6c ||style="width:35px"| 'o' || 0x6f ||style="width:35px"| 'c' || 0x63 || style="width:35px"| 'k' || 0x6b || colspan="2" style="background:#ABCDEF;" | RTC Reg 0 || colspan="2" style="background:#ABCDEF;" | RTC Reg 1 || colspan="2" style="background:#ABCDEF;" | RTC Reg 2 || colspan="2" style="background:#ABCDEF;" | RTC Reg 3 || colspan="2" style="background:#ABCDEF;" | RTC Reg 4 || colspan="2" style="background:#ABCDEF;" | RTC Reg 5 || colspan="2" style="background:#ABCDEF;" | RTC Reg 6 | |||
|} | |||
</ul> | |||
=== RTCal Command === | |||
<ul> | |||
This writes sets the RTC's calibration register. May only be executed in the WAIT state. More information on the RTC's registers is available in [http://us.st.com/stonline/products/literature/ds/10396.pdf this datasheet].<br /><br /> | |||
'''Host sends:''' '!rtcal' | |||
{| class="wikitable" style="text-align:center" | |||
!colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width:70px" | Byte 5 !! colspan="2" style="width:70px" | Byte 6 | |||
|- | |||
|style="width:35px"| '!' || 0x21 || style="width:35px"| 'r' || 0x72 ||style="width:35px"| 't' || 0x74 ||style="width:35px"| 'c' || 0x63 ||style="width:35px"| 'a' || 0x61 || style="width:35px"| 'l' || 0x6c || colspan="2" style="background:#ABCDEF;" | RTC Reg 7 | |||
|} | |||
</ul> | |||
=== Flash Command === | |||
<ul> | |||
This command transfers execution to the bootloader, which may be used to program and verify the rest of the firmware. May only be executed in the WAIT state. <b>Use this command with caution!</b> If the MSB is not configured to boot into the booatloader, and you corrupt the main firmware, you may no longer be able to use the MSB without [[Sensor_Board_Programming#Programming_the_Atmega128L_Firmware | reprogramming it with special hardware]].<br /><br /> | |||
'''Host sends:''' '!flash' | |||
{| class="wikitable" style="text-align:center" | |||
!colspan="2" style="width:70px" | Byte 0 !! colspan="2" style="width:70px" | Byte 1 !! colspan="2" style="width:70px" | Byte 2 !! colspan="2" style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 !! colspan="2" style="width:70px" | Byte 5 | |||
|- | |||
|style="width:35px"| '!' || 0x21 || style="width:35px"| 'f' || 0x66 ||style="width:35px"| 'l' || 0x6c ||style="width:35px"| 'a' || 0x61 ||style="width:35px"| 's' || 0x73 || style="width:35px"| 'h' || 0x68 | |||
|} | |} | ||
</ul> | </ul> | ||
== Data Format == | == Data Format == | ||
=== Schedule Format === | |||
<ul> | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 0 | |||
!! style="width:70px" | Byte 1 !! style="width:70px" | Byte 2 !! style="width:70px" | Byte 3 !! style="width:70px" | Byte 4 | |||
!! style="width:70px" | Byte 5 !! style="width:70px" | Byte 6 !! style="width:70px" | Byte 7 !! style="width:70px" | Byte 8 !! style="width:70px" | Byte 9 | |||
|- | |||
| colspan="2" style="width:70px" | Interrupts Per 10 Secs|| colspan="2" style="width:70px" | Mic Hz || colspan="2" style="width:70px" | Accelerometer Hz * 10 || colspan="2" style="width:70px" | Ambient Light Hz * 10 || colspan="2" style="width:70px" | Barometer Hz * 10 | |||
|- | |||
| Low-order || High-order || Low-Order || High-Order || Low-Order || High-Order || Low-Order || High-Order || Low-Order || High-Order | |||
|} | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 10 !! style="width:70px" | Byte 11 !! style="width:70px" | Byte 12 !! style="width:70px" | Byte 13 !! style="width:70px" | Byte 14 !! style="width:70px" | Byte 15 !! style="width:70px" | Byte 16 !! style="width:70px" | Byte 17 | |||
|- | |||
| colspan="2" style="width:70px" | Compass Hz * 10 || colspan="2" style="width:70px" | DALS Hz * 10 || colspan="2" style="width:70px" | Humidity Hz * 10 || rowspan="2" style="width:35px" | Power Control || rowspan="2" style="width:35px" | Mic Gain | |||
|- | |||
| Low-order || High-order || Low-Order || High-Order || Low-Order || High-Order | |||
|} | |||
==== Power Control Bits ==== | |||
Certain sensors can be powered down in between samples. To enable this, set the appropriate bits in the power control byte. Note that due to the amount of time required to power up and down the sensors, the maximum sampling rate will be decreased for these sensors. | |||
{| class="wikitable" style="text-align:center" | |||
!style="width:70px" | Bit 7 !! style="width:70px" | Bit 6 !! style="width:70px" | Bit 5 !! style="width:70px" | Bit 4 !! style="width:70px" | Bit 3 !! style="width:70px" | Bit 2 !! style="width:70px" | Bit 1 !! style="width:70px" | Bit 0 | |||
|- | |||
| 0 || 0 || 0 || 0 || 0 || style="background:#ABCDEF;"| Accel || style="background:#ABCDEF;"| Compass || style="background:#ABCDEF;"| DALS | |||
|} | |||
==== Microphone Gain ==== | |||
This byte ranges from 0 to 255. 0 represents minimal gain, while 255 represents maximal gain. The gain may also be adjusted during sampling with the !gain command. | |||
</ul> | |||
=== Microphone Data Packet === | === Microphone Data Packet === | ||
<ul> | <ul> | ||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 0 !! style="width:70px" | Byte 1 !! style="width:70px" | Byte 2 !! style="width:70px" | Byte 3 !! colspan="2" style="width:70px" | Byte 4 ... N | |||
|- | |||
| rowspan="2" style="width:70px" | Number of Samples || rowspan="2" style="width:70px" | Time Counter || colspan="2" style="width:70px" | Interrupt Counter || colspan="2" style="width:70px" | Samples | |||
|- | |||
| Low-order || High-order || Low-Order || High-Order | |||
|} | |||
Samples are all 16-bit unsigned integers, in little-endian order. | |||
</ul> | |||
=== Error Packets === | |||
<ul> | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 0 | |||
|- | |||
| style="width:70px" | Error Code | |||
|} | |||
==== Error Codes ==== | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Error Code || style="width:210px" | Description | |||
|- | |||
| 'F' || Incorrect Firmware for hardware | |||
|- | |||
| 'I' || Timeslice overrun | |||
|- | |||
| 'B' || Microphone buffer overflow | |||
|- | |||
| 'S' || Sensor readings buffer overflow | |||
|- | |||
| 'M' || Microphone buffer overflow | |||
|} | |||
</ul> | |||
=== Calibration Information Packet === | |||
<ul> | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 0 | |||
!! style="width:70px" | Byte 1 !! style="width:70px" | Byte 2 !! style="width:70px" | Byte 3 !! style="width:70px" | Byte 4 | |||
!! style="width:70px" | Byte 5 !! style="width:70px" | Byte 6 !! style="width:70px" | Byte 7 !! style="width:70px" | Byte 8 !! style="width:70px" | Byte 9 | |||
|- | |||
| colspan="2" style="width:140px" | Board Serial Number || rowspan="2" style="width:70px" | Hardware Version || rowspan="2" style="width:70px" | Major Software Version || colspan="2" style="width:70px" | Minor Software Version || colspan="2" style="width:70px" | Barometer Calibration Word 1 || colspan="2" style="width:70px" | Barometer Calibration Word 2 | |||
|- | |||
| Low-order || High-order || Low-Order || High-Order || Low-Order || High-Order || Low-Order || High-Order | |||
|} | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 10 | |||
!! style="width:70px" | Byte 11 !! style="width:70px" | Byte 12 !! style="width:70px" | Byte 13 !! style="width:70px" | Byte 14 !! style="width:70px" | Byte 15 | |||
|- | |||
| colspan="2" style="width:70px" | Barometer Calibration Word 3 || colspan="2" style="width:70px" | Barometer Calibration Word 4 || rowspan="2" style="width:70px" | Mic Gain || rowspan="2" style="width:70px" | Accelerometer Range | |||
|- | |||
| Low-order || High-order || Low-Order || High-Order | |||
|} | |||
==== Hardware Version Codes ==== | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Error Code || style="width:210px" | Description | |||
|- | |||
| 0x00 || MSB for iMote1 | |||
|- | |||
| 0x01 || MSB for iMote2 | |||
|- | |||
| 0x02 || MSB2 for iMote2 | |||
|- | |||
| 0x03 || MSB2 Rev C for iMote2 | |||
|- | |||
| 0x10 || LSB | |||
|} | |||
</ul> | |||
=== Sensor Packets === | |||
<ul> | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 0 | |||
!! style="width:70px" | Byte 1 !! style="width:70px" | Byte 2 !! style="width:70px" | Byte 3 !! style="width:70px" | Byte 4 | |||
!! style="width:70px" | Byte 5 !! style="width:70px" | Byte 6 !! style="width:70px" | Byte 7 !! style="width:70px" | Byte 8 !! style="width:70px" | Byte 9 | |||
|- | |||
| rowspan="2" style="width:70px" | Sensors Bit Mask || rowspan="2" style="width:70px" | Time Counter || colspan="2" style="width:140px" | Interrupt Counter || colspan="2" style="width:140px" | Accelerometer X Axis || colspan="2" style="width:140px" | Accelerometer Y Axis || colspan="2" style="width:140px" | Accelerometer Z Axis | |||
|- | |||
| Low-order || High-order || Low-Order || High-Order || Low-Order || High-Order || Low-Order || High-Order | |||
|} | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 10 | |||
!! style="width:70px" | Byte 11 !! style="width:70px" | Byte 12 !! style="width:70px" | Byte 13 !! style="width:70px" | Byte 14 | |||
!! style="width:70px" | Byte 15 !! style="width:70px" | Byte 16 !! style="width:70px" | Byte 17 !! style="width:70px" | Byte 18 !! style="width:70px" | Byte 19 | |||
|- | |||
| rowspan="2" style="width:70px" | Ambient Light Sensor Gain || colspan="2" style="width:140px" | Ambient Light Sensor Reading || colspan="2" style="width:140px" | Barometer Temperature || colspan="2" style="width:140px" | Barometer Pressure || colspan="2" style="width:140px" | Compass || rowspan="2" style="width:70px" | DALS Visible Light | |||
|- | |||
| Low-order || High-order || Low-Order || High-Order || Low-Order || High-Order || Low-Order || High-Order | |||
|} | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Byte 20 | |||
!! style="width:70px" | Byte 21 !! style="width:70px" | Byte 22 !! style="width:70px" | Byte 23 !! style="width:70px" | Byte 24 | |||
|- | |||
| rowspan="2" style="width:70px" | DALS Infrared Light || colspan="2" style="width:140px" | Humidity Temperature || colspan="2" style="width:140px" | Humidity | |||
|- | |||
| Low-order || High-order || Low-Order || High-Order | |||
|} | |||
==== Sensor Bit Mask ==== | |||
{| class="wikitable" style="text-align:center" | |||
! style="width:70px" | Error Code || style="width:210px" | Description | |||
|- | |||
| 0x01 || Accelerometer | |||
|- | |||
| 0x02 || DALS Visible Light | |||
|- | |||
| 0x04 || DALS Infrared Light | |||
|- | |||
| 0x08 || Compass | |||
|- | |||
| 0x10 || Barometer Pressure | |||
|- | |||
| 0x20 || Barometer Temperature | |||
|- | |||
| 0x40 || Humidity | |||
|- | |||
| 0x80 || Humidity Temperature | |||
|} | |||
When the least-significant bit of the [[#Packet_format_.28from_the_MSB_Firmware.29|Packet ID]] is set, the ambient light data is also available. <b>Only the bytes for the sensors present in the sensor bit mask are sent.</b> For example, if there's only an accelerometer and DALS Visible light reading, only bytes 0-9 and 19 will be sent. All sensor readings are directly taken from the sensors. Consult each sensor's datasheet for interpretation. | |||
</ul> | </ul> | ||
== Bootloader == | |||
The bootloader can be used to program and verify the main firmware of the MSB. To enter the bootloader, send the [[#Flash_command|flash command]]. The bootloader communicates at 115200/8/N/1. Software flow control is supported. | |||
=== Hex files === | |||
The bootloader can accept Intel HEX files directly. When sent a HEX file, the bootloader reprograms the main firmware. When sending | |||
hex files, you should wait 70 ms after sending a line on a new 256-byte boundary. For example, here's a proper sequence to send to the MSB: | |||
<pre> | |||
:100FE00041443531363242524D2020203130306B71 | |||
:100FF000203235362D506F736974696F6E204469E5 | |||
:10100000676974616C20506F74202020202020209C | |||
(Wait 70 ms) | |||
:10101000202020205350490A002020202020204C4E | |||
</pre> | |||
This delay ensures that the MSB has enough time to write the previous 256-byte block to the flash. | |||
=== Other commands === | |||
* !b -- Boot main firmware | |||
* !d<start address><end address> -- Dumps the main firmware memory, from the start address to the end address, in Intel HEX format. The adddresses are sent as hexidecimal strings. For example: !d0000C87F | |||
* !w<seconds before booting, byte><verbosity, byte> -- Write new bootloader configuration to the EEPROM. If the verbosity byte is non-zero, the bootloader version is printed on boot. | |||
* !v -- Returns the bootloader version string. |
Latest revision as of 18:47, 30 June 2008
Overview
The MSB2 and LSB both use the same firmware core with custom modifications to support the sensors and other subsystems specific to each platform. The goals of the firmware are:
- Encapsulate all low level functions in easily accessible commands
- Hides all startup/initialization routines
- Provide a variable sampling schedule (with some constraints) that automatically handles powering off unused sensors
- Provide commands for accessing calibration and other sensor metadata
- Sample and send data via a hi-speed binary uart interface
- Communicates with any embedded platform
- Communicates with any desktop/laptop/handheld/cell phone with a available uart port
Current Firmware Images
Sensor Board | Download Link |
---|---|
MSB2 - Hardware Version 2 (BT + SD built in) | MSB2 |
LSB | LSB |
A more detailed set of firmware images for the MSB are available from: http://www.cs.washington.edu/homes/supersat/MSB/ and for the LSB at http://ubicomp.cs.washington.edu/firmware/LSB/. In addition the firmware source may be downloaded from assab.cs.washington.edu and built using a pre-configured build environment located at /projects/ubicomp/uwar/software/MSB Firmware Windows XP Professional 2.vmwarevm
State Diagram
The system has two main states, the default wait state and the running state. The other states are used for setting up various components of the system. Once everything is working; however, the user simply enters the running state and begins recording data. In addition to the command states shown here available here several other commands are available (depending upon the hardware) which can be used to manipulate various parts of the system.
Communication protocol
Communication with the MSB Firmware takes place over the first uart on the ATmega, at 921,600 baud, with an option of having flow control. You must only send one byte per timer interrupt! For example, if your INTERRUPT_COUNT is set to 5120 (512 Hz), you must wait at least 1/512th of a second between bytes.
Commands
-
Commands are six-character sequences where '!' (hex 0x21) indicates the start of a command. The parser is reset by a '!', so if you make a mistake when sending a command, simply resend the command starting with a '!'. Some commands include their arguments as part of their five command bytes.
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | Command |
Note: '!' is a reserved character and may not be used as an argument for any command that includes its arguments in the command bytes.
LED Commands
-
LED commands are special one-byte commands that turns the LEDs on and off. Two LED command formats exist: one to adjust the individual LEDs, and one to adjust both the individual LEDs and the tri-color LED. In both formats, a 0 bit for an LED turns it on, and a 1 bit turns it off.
Individual LED command format
Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | Red | Green | Blue | 1 |
Individual and Tricolor LED command format
Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|
1 | Tri-color Blue | Tri-color Green | Tri-color Red | Red | Green | Blue | 1 |
Packet format (from the MSB Firmware)
-
All MSB firmware responses will be sent back as packets that begin with 2 characters '#' followed by '|', then an identifier byte describing what the packet is and how it should be interpreted.
Byte 0 | Byte 1 | Byte 2 | ... | Byte N | |||||
---|---|---|---|---|---|---|---|---|---|
'#' | 0x23 | '|' | 0x7C | ID | Payload | Checksum |
The checksum is calculated by adding up all bytes 2 through N - 1, and taking the lower 8 bits of the result.
Packet IDs
ID | Type |
---|---|
0x00 | Sensor Packet |
0x01 | Sensor Packet |
0x02 | RTC Packet |
0x04 | Error Packet |
0x08 | Microphone Packet |
0x10 | LEDs Packet |
0x20 | Calibration Information Packet |
0x40 | Schedule Packet |
0x80 | Power Packet |
Example Communication Sequence
-
Here's an example of what a host computer would send to query the state of the LED and what it would receive from the MSB:
Host sends: '!query' + 0x10 [query command + 0x10 to indicate a LED query]
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'q' | 0x71 | 'u' | 0x75 | 'e' | 0x65 | 'r' | 0x72 | 'y' | 0x79 | 0x10 |
MSB Firmware responds with: ['#|' start header + 0x10 to indicate a LED packet and 0x00 the current state of the LEDs
Byte 0 | Byte 1 | Byte 2 | Byte 3 | ||||
---|---|---|---|---|---|---|---|
'#' | 0x23 | '|' | 0x7C | 0x10 | 0 | 0x00 |
Available Commands
Start Command
-
This command begins sampling of the sensors and outputting the readings. May only be executed in the WAIT state.
Host sends: '!start'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 's' | 0x73 | 't' | 0x74 | 'a' | 0x61 | 'r' | 0x72 | 't' | 0x74 |
Cease Command
-
This command stops sampling of the sensors. May only be executed in the RUNNING state.
Host sends: '!cease'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'c' | 0x63 | 'e' | 0x65 | 'a' | 0x61 | 's' | 0x73 | 'e' | 0x65 |
Reset Command
-
This command reinitializes the sensor board. May only be executed in the WAIT state.
Host sends: '!reset'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'r' | 0x72 | 'e' | 0x65 | 's' | 0x73 | 'e' | 0x65 | 't' | 0x74 |
Alter Schedule Command
-
This command alters the sensor sampling schedule. May only be executed in the WAIT state.
Host sends: '!alter' SCHED_DATA
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 - 23 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'a' | 0x61 | 'l' | 0x6c | 't' | 0x74 | 'e' | 0x65 | 'r' | 0x72 | Schedule Data |
Data Returned
The MSB will verify that it can meet the desired schedule, and if not, will adjust it accordingly. In either case, the effective schedule will be returned over the serial port in the same format, except with "!alter" replaced with the MSB response bytes, with ID = 0x40.
Query Command
-
This command returns various information about the state of the MSB. May only be executed in the WAIT state.
Host sends: '!query' QUERY_ID
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'q' | 0x71 | 'u' | 0x75 | 'e' | 0x65 | 'r' | 0x72 | 'y' | 0x79 | Query ID |
Query Types
ID | Type |
---|---|
0x40 | Current Schedule |
0x20 | Calibration Information |
0x10 | LEDs State |
0x02 | RTC Registers |
USB Enable Command
-
This command enables or disables the USB/Digital Compass power. May be executed in either the RUNNING or WAIT states.
Host sends: '!usb-0' or '!usb-1'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'u' | 0x75 | 's' | 0x73 | 'b' | 0x62 | '-' | 0x2d | USB status ('0' or '1') |
GPS Enable Command
-
This command sets the state of the GPS Enable signal (Atmel_PA7). May be executed in either the RUNNING or WAIT states.
Host sends: '!gps-0' or '!gps-1'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'g' | 0x67 | 'p' | 0x70 | 's' | 0x73 | '-' | 0x2d | GPS enable ('0' or '1') |
Gain Command
-
This command temporarily adjusts the gain while the sensors are being sampled. May only be executed in the RUNNING state.
Host sends: '!gain' GAIN_VALUE
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'g' | 0x67 | 'a' | 0x61 | 'i' | 0x69 | 'n' | 0x6e | Gain (0x00 to 0xFF) |
Note: Since '!' is a reserved character, a gain value of 0x21 cannot be set with this command.
Write Command
-
This writes the current schedule to the EEPROM to be used as the default schedule. May only be executed in the WAIT state.
Host sends: '!write'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'w' | 0x77 | 'r' | 0x72 | 'i' | 0x69 | 't' | 0x74 | 'e' | 0x65 |
Clock Command
-
This writes sets the first seven bytes of the RTC registers. May only be executed in the WAIT state. More information on the RTC's registers is available in this datasheet.
Host sends: '!clock'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 | Byte 9 | Byte 10 | Byte 11 | Byte 12 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'c' | 0x63 | 'l' | 0x6c | 'o' | 0x6f | 'c' | 0x63 | 'k' | 0x6b | RTC Reg 0 | RTC Reg 1 | RTC Reg 2 | RTC Reg 3 | RTC Reg 4 | RTC Reg 5 | RTC Reg 6 |
RTCal Command
-
This writes sets the RTC's calibration register. May only be executed in the WAIT state. More information on the RTC's registers is available in this datasheet.
Host sends: '!rtcal'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'r' | 0x72 | 't' | 0x74 | 'c' | 0x63 | 'a' | 0x61 | 'l' | 0x6c | RTC Reg 7 |
Flash Command
-
This command transfers execution to the bootloader, which may be used to program and verify the rest of the firmware. May only be executed in the WAIT state. Use this command with caution! If the MSB is not configured to boot into the booatloader, and you corrupt the main firmware, you may no longer be able to use the MSB without reprogramming it with special hardware.
Host sends: '!flash'
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
'!' | 0x21 | 'f' | 0x66 | 'l' | 0x6c | 'a' | 0x61 | 's' | 0x73 | 'h' | 0x68 |
Data Format
Schedule Format
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 | Byte 9 |
---|---|---|---|---|---|---|---|---|---|
Interrupts Per 10 Secs | Mic Hz | Accelerometer Hz * 10 | Ambient Light Hz * 10 | Barometer Hz * 10 | |||||
Low-order | High-order | Low-Order | High-Order | Low-Order | High-Order | Low-Order | High-Order | Low-Order | High-Order |
Byte 10 | Byte 11 | Byte 12 | Byte 13 | Byte 14 | Byte 15 | Byte 16 | Byte 17 |
---|---|---|---|---|---|---|---|
Compass Hz * 10 | DALS Hz * 10 | Humidity Hz * 10 | Power Control | Mic Gain | |||
Low-order | High-order | Low-Order | High-Order | Low-Order | High-Order |
Power Control Bits
Certain sensors can be powered down in between samples. To enable this, set the appropriate bits in the power control byte. Note that due to the amount of time required to power up and down the sensors, the maximum sampling rate will be decreased for these sensors.
Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | Accel | Compass | DALS |
Microphone Gain
This byte ranges from 0 to 255. 0 represents minimal gain, while 255 represents maximal gain. The gain may also be adjusted during sampling with the !gain command.
Microphone Data Packet
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 ... N | |
---|---|---|---|---|---|
Number of Samples | Time Counter | Interrupt Counter | Samples | ||
Low-order | High-order | Low-Order | High-Order |
Samples are all 16-bit unsigned integers, in little-endian order.
Error Packets
Byte 0 |
---|
Error Code |
Error Codes
Error Code | Description |
---|---|
'F' | Incorrect Firmware for hardware |
'I' | Timeslice overrun |
'B' | Microphone buffer overflow |
'S' | Sensor readings buffer overflow |
'M' | Microphone buffer overflow |
Calibration Information Packet
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 | Byte 9 |
---|---|---|---|---|---|---|---|---|---|
Board Serial Number | Hardware Version | Major Software Version | Minor Software Version | Barometer Calibration Word 1 | Barometer Calibration Word 2 | ||||
Low-order | High-order | Low-Order | High-Order | Low-Order | High-Order | Low-Order | High-Order |
Byte 10 | Byte 11 | Byte 12 | Byte 13 | Byte 14 | Byte 15 |
---|---|---|---|---|---|
Barometer Calibration Word 3 | Barometer Calibration Word 4 | Mic Gain | Accelerometer Range | ||
Low-order | High-order | Low-Order | High-Order |
Hardware Version Codes
Error Code | Description |
---|---|
0x00 | MSB for iMote1 |
0x01 | MSB for iMote2 |
0x02 | MSB2 for iMote2 |
0x03 | MSB2 Rev C for iMote2 |
0x10 | LSB |
Sensor Packets
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 | Byte 9 |
---|---|---|---|---|---|---|---|---|---|
Sensors Bit Mask | Time Counter | Interrupt Counter | Accelerometer X Axis | Accelerometer Y Axis | Accelerometer Z Axis | ||||
Low-order | High-order | Low-Order | High-Order | Low-Order | High-Order | Low-Order | High-Order |
Byte 10 | Byte 11 | Byte 12 | Byte 13 | Byte 14 | Byte 15 | Byte 16 | Byte 17 | Byte 18 | Byte 19 |
---|---|---|---|---|---|---|---|---|---|
Ambient Light Sensor Gain | Ambient Light Sensor Reading | Barometer Temperature | Barometer Pressure | Compass | DALS Visible Light | ||||
Low-order | High-order | Low-Order | High-Order | Low-Order | High-Order | Low-Order | High-Order |
Byte 20 | Byte 21 | Byte 22 | Byte 23 | Byte 24 |
---|---|---|---|---|
DALS Infrared Light | Humidity Temperature | Humidity | ||
Low-order | High-order | Low-Order | High-Order |
Sensor Bit Mask
Error Code | Description |
---|---|
0x01 | Accelerometer |
0x02 | DALS Visible Light |
0x04 | DALS Infrared Light |
0x08 | Compass |
0x10 | Barometer Pressure |
0x20 | Barometer Temperature |
0x40 | Humidity |
0x80 | Humidity Temperature |
When the least-significant bit of the Packet ID is set, the ambient light data is also available. Only the bytes for the sensors present in the sensor bit mask are sent. For example, if there's only an accelerometer and DALS Visible light reading, only bytes 0-9 and 19 will be sent. All sensor readings are directly taken from the sensors. Consult each sensor's datasheet for interpretation.
Bootloader
The bootloader can be used to program and verify the main firmware of the MSB. To enter the bootloader, send the flash command. The bootloader communicates at 115200/8/N/1. Software flow control is supported.
Hex files
The bootloader can accept Intel HEX files directly. When sent a HEX file, the bootloader reprograms the main firmware. When sending hex files, you should wait 70 ms after sending a line on a new 256-byte boundary. For example, here's a proper sequence to send to the MSB:
:100FE00041443531363242524D2020203130306B71 :100FF000203235362D506F736974696F6E204469E5 :10100000676974616C20506F74202020202020209C (Wait 70 ms) :10101000202020205350490A002020202020204C4E
This delay ensures that the MSB has enough time to write the previous 256-byte block to the flash.
Other commands
- !b -- Boot main firmware
- !d<start address><end address> -- Dumps the main firmware memory, from the start address to the end address, in Intel HEX format. The adddresses are sent as hexidecimal strings. For example: !d0000C87F
- !w<seconds before booting, byte><verbosity, byte> -- Write new bootloader configuration to the EEPROM. If the verbosity byte is non-zero, the bootloader version is printed on boot.
- !v -- Returns the bootloader version string.