Amulet Communication Protocol

Amulet uses an ASCII communication protocol between the Amulet LCD module and your embedded device (external processor). The external processor must be capable of RS-232 serial communications. Amulet master messages are initiated either by timer events or by user input from the touch panel. Amulet master messages are derived from compiled Amulet widgets stored in the data flash on the Amulet Controller Board. (See Widgets Document for more information.)
See Appendix A for a sample implementation of the Amulet protocol on an external processor.

For more detail on the Amulet communication protocol, click on the following topics:


Serial Port Pinouts

Physical interface Serial cable connections (standard RS-232):

SIGNAL

DB9
FEMALE

DB9
MALE

DESCRIPTION
DOUT

Pin 2

Pin 2

Amulet output
(your processors input)
DIN

Pin 3

Pin 3

Amulet input
(your processors output)
GND

Pin 5

Pin 5

Signal Ground
Jumpered

Pin 4

Pin 6

 
Jumpered

Pin 7

Pin8

 


Communication Format

Communications between the Amulet LCD module and an external processor are asynchronous serial transmissions, with the following format:

The default baud rate is 115,200 bps. Other baud rates are set by using a META tag in the <HEAD> section of the HTML page by using the Amulet META attribute Baud.Project= xxxxx or Baud.Page=xxxxx, where xxxxxx is either 9600, 19200, 57600, or 115200.

Baud.Project should be used if the baud rate is going to be the same on all pages of the project. If using the Baud.Project META attribute, you only need to include that Amulet META on the home page.

Example:


Communication Modifications

The default communication time-out period is 200ms. Other time-out periods are set by using a META tag in the <HEAD> section of the HTML page. Valid range is 0.02-2.55 seconds, in .01 increments. See timeout documentation in HTMLSupport. For example, to set the time-out rate at 20ms, use:

        <META NAME="Amulet" Content="TimeOut.Page=0.02">


The default interbyte delay is dependent upon the activity on the display. Unless there is a large and fast animated .gif, the interbyte delay will usually be around 120us. If a longer interbyte delay is required, a 2-3ms delay can be added by using a META tag in the <HEAD> section of the HTML page. Example:

        <META NAME="Amulet" Content="UARTDelay.Project">


By default, the protocol does not provide for a termination character, except when sending strings. The Amulet can be forced to null terminate every single response by using a META tag in the <HEAD> section of the HTML page. With this META attribute, all messages sent from the Amulet will be followed by a 0x00. This can be handy in the receive section of your serial protocol code if you don't have time to analyze each byte received as it is coming in. Example:

        <META NAME="Amulet" Content="NullTerminate.Project">


If you are using a BASIC Stamp product, you should use the BASICStamp META tag attribute. You should also use 9600 baud. The BASICStamp attribute essentially sets both the UARTDelay and NullTerminate flags. The interbyte delay will be between 2-3ms and all messages from the Amulet will be null terminated. When using the SERIN command, use the following special string formatter SERIN 16, 84, [STR ByteArray \L {\E}]  Where ByteArray is the name of an internal byte array in the BASIC Stamp, L is the size of the byte array, and E is the termination character. In the Amulet case, E would be 0. Make sure you do not put quotes around 0, otherwise the BASIC Stamp will be looking for a termination character of '0' or 0x30. Please see your BASIC Stamp documentation for full details regarding the SERIN command. Example of the BASICStamp META tag attribute:

        <META NAME="Amulet" Content="BASICStamp.Project">


When the Amulet receives a "Set" or "Draw" command, by default, it responds back with the corresponding response byte followed by an echo of all the bytes sent to the Amulet. To cut back on unnecessary bytes, the SlaveAckRsp META tag attribute can be used. Instead of sending an echo of the entire message, it will only respond with an ACK (0xF0). If no response is desired, the SlaveNoRsp attribute can be used. Examples:

        <META NAME="Amulet" Content="SlaveAckRsp.Project">

        <META NAME="Amulet" Content="SlaveNoRsp.Project">

(See HTMLSupport document for more information.)


Amulet Protocol Overview

The Amulet system has two different ways of interfacing with an external processor. One method has the Amulet LCD module as the master and the external processor as the slave. The other method has the external processor as the master and the Amulet as the slave. Both methods can be run concurrently on the same HTML page.

To set the Amulet as the master, the HTML page to be compiled needs to have href commands that start with Amulet:UART. The Amulet will send out the href command at an interval based upon the updateRate specified in the HTML page. The Amulet expects a response from the external processor within 200ms, by default.

The Amulet does not need to be configured to be a slave. If the external processor chooses to be the master, it can send a valid Amulet message to the Amulet at any time or on any page and the Amulet will become the slave for that message. If the Amulet has any further master messages, it will once again become the master until the external processor chooses to be the master.

When the Amulet is the slave, the external processor can read and write to "virtual dual-port" RAM which resides on the Amulet side. The Amulet has 256 byte variables, 256 word variables, 199 19-character string variables and a 6 byte deep RPC buffer. Amulet Widgets can have href commands that start with Amulet:InternalRAM to access these "virtual dual-port" RAM variables.

The command characters are the same, regardless of who is the master or who is the slave. This means that a "Get byte variable" command sent to the Amulet looks exactly like a "Get byte variable" command sent to the external processor.

Amulet as Master

The Amulet communication protocol is half-duplex. The Amulet LCD module(master) can send ten different types of messages to the external processor (slave):

If the message is valid, the slave should either return the requested data (if a "Get" request) or confirm the message (if an "Invoke" or "Set" command). If the message is not valid, the slave should respond with an acknowledge (0xF0) to have the Amulet move to the next request, or the slave can respond with a negative acknowledgement (NAK) (0xF1) to have the Amulet resend the last message.

Table 1 defines thirteen messages that can be sent between the master and the slave, not counting the graphic primitive messages. The valid range of variables and Remote Procedure Calls is 0-0xFF. The valid range for byte variable values returned from the slave (in response to the "Get Byte variable" request) is also 0-0xFF. The valid range for word variable values returned from the slave (in response to the "Get Word variable" request) is 0-0xFFFF. String and label variable values returned from the slave (in response to the "Get String variable" request) can have a maximum of 252 ASCII (0x20-0x7E) characters plus a null termination character (0x00).

Since this is an ASCII protocol, two bytes must be sent out for every byte of data to be transmitted. All messages will start with a command character followed by the ASCII representation of all data. For example, if the HTML file being compiled has a view widget with an href of Amulet:UART.byte(0x1A).value(), which will send out the "Get Byte Variable #0x1A" request, the message to be transmitted would consist of three bytes. The first byte is the command byte for "Get Byte Variable" 0xD0. The second byte is 0x31, which is the ASCII representation of the high nibble"1". The third and final byte is 0x41, which is the ASCII representation of the low nibble "A".

NOTE: The slave must respond to every valid Amulet command, even if it's only an acknowledge (0xF0). When commands are not responded to, a time-out will occur after 200ms, by default, and that message will be repeated until either a response is received or after a total of eleven attempts. After eleven attempts, all UART variables are reset in an attempt to resync with the slave processor.

Message
Byte 1
Byte 2
Byte 3
Byte 4
Byte 5
Byte 6
Byte 7 .......... Byte N
Amulet Get Byte Variable
0xD0
Variable
Hi Nibble
Variable
Lo Nibble
None
None
None
None
None
Server Response
0xE0
Variable
Hi Nibble
Variable
Lo Nibble
Value
Hi Nibble
Value
Lo Nibble
None
None
None

Amulet Get Word Variable
0xD1
Variable
Hi Nibble
Variable
Lo Nibble
None
None
None
None
None
Server Response

0xE1


Variable
Hi Nibble

Variable
Lo Nibble
|-----MS Byte-----|
Value Hi        Value Hi
Hi Nibble        Lo Nibble
|-----LS Byte-----|
Value Lo        Value Lo
Hi Nibble        Lo Nibble

None


Amulet Get String Variable
0xD2
Variable
Hi Nibble
Variable
Lo Nibble
None
None
None
None
None
Server Response
0xE2
Variable
Hi Nibble
Variable
Lo Nibble
ASCII
char
ASCII
char
ASCII
char
ASCII ............ 0x00
char                     


Amulet Get Label Variable
0xD3
Variable
Hi Nibble
Variable
Lo Nibble
None
None
None
None
None
Server Response
0xE3
Variable
Hi Nibble
Variable
Lo Nibble
ASCII
char
ASCII
char
ASCII
char
ASCII ............ 0x00
char                     


Amulet Get Remote Procedure Calls (RPC)
0xD4**
RPC flag
Hi Nibble
RPC flag
Lo Nibble
None
None
None
None
None
Server Response
0xE4
RPC flag
Hi Nibble
RPC flag
Lo Nibble
RPC #1
Hi Nibble
RPC #1
Lo Nibble
RPC #2
Hi Nibble
RPC #2 ............ 0x00
Lo Nibble                     


Amulet Set Byte Variable
0xD5
Variable
Hi Nibble
Variable
Lo Nibble
Value
Hi Nibble
Value
Lo Nibble
None
None
None
Server Response
0xE5
Variable
Hi Nibble
Variable
Lo Nibble
Value
Hi Nibble
Value
Lo Nibble
None
None
None

Amulet Set Word Variable

0xD6


Variable
Hi Nibble

Variable
Lo Nibble
|-----MS Byte-----|
Value Hi        Value Hi
Hi Nibble        Lo Nibble
|-----LS Byte-----|
Value Lo        Value Lo
Hi Nibble        Lo Nibble

None

Server Response

0xE6


Variable
Hi Nibble

Variable
Lo Nibble
|-----MS Byte-----|
Value Hi        Value Hi
Hi Nibble        Lo Nibble
|-----LS Byte-----|
Value Lo        Value Lo
Hi Nibble        Lo Nibble

None


Amulet Set String Variable
0xD7
Variable
Hi Nibble
Variable
Lo Nibble
ASCII
char
ASCII
char
ASCII
char
ASCII .......... 0x00
char                    

Server Response
0xE7
Variable
Hi Nibble
Variable
Lo Nibble
ASCII
char
ASCII
char
ASCII
char
ASCII .......... 0x00
char                    


Amulet Invoke Remote Procedure Call (RPC)
0xD8
RPC
Hi Nibble
RPC
Lo Nibble
None
None
None
None
None
Server Response
0xE8
RPC
Hi Nibble
RPC
Lo Nibble
None
None
None
None
None

Amulet Get Byte
Variable Array
0xDD
Variable
Hi Nibble
Variable
Lo Nibble
None
None
None
None
None
Server Response
0xED
Variable
Hi Nibble
Variable
Lo Nibble
Value
Hi Nibble
Value .............. 0x00
Lo Nibble                       

None
None

Amulet Get Word
Variable Array
0xDE
Variable
Hi Nibble
Variable
Lo Nibble
None
None
None
None
None
Server Response

0xEE


Variable
Hi Nibble

Variable
Lo Nibble
|-----MS Byte-----|
Value Hi        Value Hi
Hi Nibble        Lo Nibble
|-----LS Byte-----|                       
Value Lo        Value Lo   .......   0x00
Hi Nibble        Lo Nibble                     

Amulet Set Byte
Variable Array
0xDF**
Variable
Hi Nibble
Variable
Lo Nibble
Value
Hi Nibble
Value .............. 0x00
Lo Nibble                       

None
None
Server Response
0xEF
Variable
Hi Nibble
Variable
Lo Nibble
Array Cnt
Hi Nibble
Array Cnt
Lo Nibble
None
None
None

Amulet Set Word
Variable Array

0xF2**


Variable
Hi Nibble

Variable
Lo Nibble
|-----MS Byte-----|
Value Hi        Value Hi
Hi Nibble        Lo Nibble
|-----LS Byte-----|                       
Value Lo        Value Lo   .......   0x00
Hi Nibble        Lo Nibble                     
Server Response

0xF3

Variable
Hi Nibble
Variable
Lo Nibble
Array Cnt
Hi Nibble
Array Cnt
Lo Nibble
None
None
None
** Denotes command is only applicable when Amulet is set as Slave.                                                                                                                   

Table 1. Thirteen types of messages can be sent between the master and the slave, not counting the graphic primitives.

Synchronization--The master initiates all communications by sending a message to the slave. All valid messages from the Amulet to the external processor start with one of eight command bytes: [0xD0],[0xD1],[0xD2],[0xD3],[0xD5],[0xD6],[0xD7] or [0xD8] -- these are considered the Master Start Of Message (MSOM) characters. NOTE: These eight MSOM bytes ALWAYS signify the start of a message and they are not allowed in the body of any message. The only valid characters in the body of a message are: ASCII 0-9 (0x31-0x39), and A-F (0x41-0x46), except in the body of the "Get string" response, where all ASCII characters from ' ' -' ~' (0x20-0x7E) are valid, as well as the line feed character (0x0A)(See Widgets for more line feed info). If the slave receives any character other than those specified, the message should be considered errant, and the slave should start over hunting for a new MSOM character.

All slave responses must start with the counterpart of the MSOM character that began the message that is being responded to. The valid Slave Start Of Message (SSOM) bytes are: [0xE0],[0xE1],[0xE2],[0xE3],[0xE5],[0xE6],[0xE7] or [0xE8]. The body of the response message starts with a byte for byte echo of the command message. The echo is then followed by any optional response data (in ASCII format).

Upon receiving the last byte of a valid message from the master, the slave then has, by default, 200ms to respond to the message before the master times out. After 200ms, if there is no response, the master will continue to repeat the message until a response is received. After 10 unsuccessful attempts, the Amulet will flush its transmit buffer and reset all UART variables.

Other time out durations are set by using a META tag in the <HEAD> section of the HTML page. Example:

(See HTMLSupport document for more information.)

NOTE: The external processor slave must respond to every valid Amulet master command. It is okay to respond with a single byte of acknowledgement (0xF0) without transmitting data, but all Amulet commands should be responded to. When commands are not responded to, a time-out will occur, and that message will be repeated 10 more times before flushing the transmit buffer and resetting all UART variables.


Amulet as Slave

The Amulet communication protocol is half-duplex, meaning the slave should not respond until the master is done sending its message. The external processor (master) can send fourteen different types of messages to the Amulet LCD module (slave). The external processor can read from and write to all the Amulet Internal RAM variables. The external processor can also send graphic primitives (line, rectangle, filled rectangle and pixel) to the Amulet. The external processor can also force the Amulet to jump to a specific page.

If the message is valid, the Amulet LCD module slave will either return the requested data (if a "Get" request) or confirm the message (if a "Draw" or "Set" command). Use slaveAckRsp or slaveNoRsp META attributes to configure the Amulet to respond back to "Draw" or "Set" commands with either an ACK (0xF0) or no response at all. If the message is not a valid Amulet message, the Amulet will not respond.

The protocol is the same regardless of who is the master. So if an external processor is requesting the value of a byte variable on the Amulet (which would be an Internal RAM byte variable), the command opcode would be the same as if the Amulet was requesting the value of a byte variable that resides on the external processor.

RPC buffer

If a setup where the Amulet is always the slave is needed or desired, then up to six RPCs can be buffered in the Amulet's Internal RAM. The external processor can request the contents of the RPC buffer by sending a "Get Internal RAM RPC buffer" request (0xD4), followed by the RPC buffer flag byte (which is ASCII-ized like all data within the Amulet protocol). The RPC buffer flag byte options are 0x00:send all RPCs from buffer, then flush. 0xFF:flush RPC buffer.

When the Amulet is the master and an RPC is invoked, the Amulet will immediately send out the RPC command. If the Amulet is setup to use the Internal RAM RPC buffer instead, then the Amulet will send the RPC to an RPC buffer. The RPC buffer can only be read by an external processor by sending a "Get Internal RAM RPC buffer" request (0xD4). The Amulet will respond with all the RPCs (up to six) stored in the RPC buffer, and then a null termination character, to signify the end of the buffer. After sending out the contents of the RPC buffer, the Amulet will flush the buffer.


Dual Master Collisions

In a dual-master system, it is possible that both masters will choose to send a message out at the same time. Anytime the Amulet sees an incoming master message coming from the external processor, it stops sending any message it is currently sending and waits until the incoming message is fully received. The Amulet will then respond to the master message. The Amulet will then try to resend its master message it was attempting to send before receiving the incoming master message from the external processor.

The one exception to this rule is if using the META tag attribute BASICStamp or the combination of the UARTDelay and NullTerminate attributes. In either of those cases, the Amulet will turn off its receive ability when starting to send a master message. The receive is re-enabled after sending the null termination character. This is to compensate for the fact that the BASICStamp has a loopback on its Rx and Tx lines.


Software handshaking using a modified XON/XOFF protocol

In a system where the Amulet is the slave, it is possible to send a number of master messages in a row without waiting for a response from the Amulet. This becomes an important point when there are a large number of messages that need to be sent to the Amulet in a short period of time. If the Amulet is set to respond to every master message, like it will by default, or if you have setup the Amulet to respond with an ACK by using the Meta attribute SlaveAckRsp, only the last sent message will be responded to. So, if you send over 30 master messages packed together as a single stream of bytes, only one response message or ACK will be returned from the Amulet.

One of the problems of this technique is that the Amulet has a 256-byte receive buffer which can be filled to capacity if too many bytes are sent to the Amulet. The receive buffer is not circular, so when the Amulet is done parsing an incoming message, as long as there are no more bytes left in the receive buffer, the buffer counter is reset and the next message can be up to 256-bytes in length. Using the example above, if the master sends another 30 master messages before the Amulet is finished parsing the first batch of 30 master messages, the buffer counter will not get a chance to reset, thus filling up the buffer since 60 master messages, which on average are 5-bytes each, will not fit in a 256-byte receive buffer. If the buffer ever gets filled up, any further bytes that are sent will not be saved. Obviously, that is not acceptable in most applications.

To counter this problem, we've created a modified form of the XON/XOFF software handshaking protocol. In order to use the Amulet XON/XOFF protocol, you should probably use the Meta attribute SlaveNoRsp so that the Amulet will not respond to any master messages that do not require a response. Whenever the Amulet receives an XOFF command (0x13) it will respond with an XON command (0x11). So, to safely use the software handshaking, you should send a number of messages which will be less than 256 bytes in length, then terminate the stream of bytes with an XOFF command. Do not send any further commands until the Amulet has responded with the XON command. At that point, you can be assured that all the previous commands have been acted upon and the receive buffer is completely empty, thus allowing for another large string of bytes, up to 256.

This raises the question, why not just use SlaveAckRsp and wait for the ACK. In a perfect world, that would work perfectly fine. Unfortunately, when talking about serial communications, it is folly to believe that everything will be perfect. If there is a slight delay in between messages, it is possible for the Amulet to sneak an ACK out before the entire master stream of bytes is completely done. This could result in the master seeing the ACK, and depending on how/when the code decides to look at the incoming messages, incorrectly assuming that the ACK was in response to the last individual message of the stream. This could result in the master starting to send another large stream of bytes. That might or might not be a problem. If the Amulet was able to finish parsing the final message of the stream, then the receive buffer counters will be reset and the next stream will fit in the receive buffer, assuming the stream is less than 256 bytes. But, there could be a race condition where the Amulet doesn't quite finish parsing the final message of the stream before the master starts sending the new stream. This could result in entire streams being lost. Once again, that is not acceptable in most applications.

Therefore, if you are sending large streams to the Amulet, it is highly suggested that you use the SlaveNoRsp Meta attribute and also send an XOFF command at the conclusion of your stream. Do not send your next stream until the Amulet returns an XON command. This will close any race condition windows.


Note About Sending Master Messages Between Amulet Page Changes

When the Amulet changes from one page to another, all UART buffers are flushed, so if you are in the middle of sending the Amulet a Master Message while it is changing pages, it is possible that the Amulet will not fully receive your message. Another thing to keep in mind is that when first loading a page, the transmission of messages is halted until the page is fully rendered. The Amulet is capable of buffering incoming messages, but it will not process or respond to any incoming messages until the page is fully rendered. It can take up to 500ms for some complex pages to be fully rendered, so if you were to send a Master Message at the beginning of a page change, the Amulet might not respond back for up to 500ms later. If the Amulet does respond, it will have performed the request, albeit maybe not exactly when you thought it should.

With the above in mind, if your processor pounds Master Messages out at a rapid rate, you might want to have all your pages start out by sending an RPC, set byte or byteOut command that lets your processor know when it is okay to start transmitting again. You could also have an RPC, set byte or byteOut command go out prior to leaving any page, so your processor will know when to halt transmissions as well.


Graphic Primitives

See Graphic Primitives for more information regarding the use of graphic primitives.

Table 2 defines the four types of messages regarding graphic primitives that can be sent between an external processor and the Amulet. If a graphics primitive is sent that does not fit within the bounds of the given LCD (i.e. a delta x of 380 pixels on a 320 x 240 LCD) the Amulet will not draw the graphic primitive.

Message

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Byte 8

Byte 9

"Draw" Line Primitive

0xD9

Pnt 1 X 
Hi Byte
Hi Nibble

Pnt 1 X 
Hi Byte
Lo Nibble

Pnt 1 X 
Lo Byte
Hi Nibble

Pnt 1 X 
Lo Byte
Lo Nibble

Pnt 1 Y 
Hi Byte
Hi Nibble

Pnt 1 Y 
Hi Byte
Lo Nibble

Pnt 1 Y 
Lo Byte
Hi Nibble

Pnt 1 Y 
Lo Byte
Lo Nibble

Byte 10

Byte 11

Byte 12

Byte 13

Byte 14

Byte 15

Byte 16

Byte 17

Byte 18

Byte 19

Pnt 2 X 
Hi Byte
Hi Nibble

Pnt 2 X 
Hi Byte
Lo Nibble

Pnt 2 X 
Lo Byte
Hi Nibble

Pnt 2 X 
Lo Byte
Lo Nibble

Pnt 2 Y 
Hi Byte
Hi Nibble

Pnt 2 Y 
Hi Byte
Lo Nibble

Pnt 2 Y 
Lo Byte
Hi Nibble

Pnt 2 Y 
Lo Byte
Lo Nibble

Line Pattern

Line Weight


Message

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Byte 8

Byte 9

Amulet Response

0xE9

Pnt 1 X 
Hi Byte
Hi Nibble

Pnt 1 X 
Hi Byte
Lo Nibble

Pnt 1 X 
Lo Byte
Hi Nibble

Pnt 1 X 
Lo Byte
Lo Nibble

Pnt 1 Y 
Hi Byte
Hi Nibble

Pnt 1 Y 
Hi Byte
Lo Nibble

Pnt 1 Y 
Lo Byte
Hi Nibble

Pnt 1 Y 
Lo Byte
Lo Nibble

Byte 10

Byte 11

Byte 12

Byte 13

Byte 14

Byte 15

Byte 16

Byte 17

Byte 18

Byte 19

Pnt 2 X 
Hi Byte
Hi Nibble

Pnt 2 X 
Hi Byte
Lo Nibble

Pnt 2 X 
Lo Byte
Hi Nibble

Pnt 2 X 
Lo Byte
Lo Nibble

Pnt 2 Y 
Hi Byte
Hi Nibble

Pnt 2 Y 
Hi Byte
Lo Nibble

Pnt 2 Y 
Lo Byte
Hi Nibble

Pnt 2 Y 
Lo Byte
Lo Nibble

Line Pattern

Line Weight


Message

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Byte 8

Byte 9

"Draw" Rectangle Primitive

0xDA

Pnt 1 X 
Hi Byte
Hi Nibble

Pnt 1 X 
Hi Byte
Lo Nibble

Pnt 1 X 
Lo Byte
Hi Nibble

Pnt 1 X 
Lo Byte
Lo Nibble

Pnt 1 Y 
Hi Byte
Hi Nibble

Pnt 1 Y 
Hi Byte
Lo Nibble

Pnt 1 Y 
Lo Byte
Hi Nibble

Pnt 1 Y 
Lo Byte
Lo Nibble

Byte 10

Byte 11

Byte 12

Byte 13

Byte 14

Byte 15

Byte 16

Byte 17

Byte 18

Byte 19

Delta X 
Hi Byte
Hi Nibble

Delta X 
Hi Byte
Lo Nibble

Delta X 
Lo Byte
Hi Nibble

Delta X 
Lo Byte
Lo Nibble

Delta Y 
Hi Byte
Hi Nibble

Delta Y 
Hi Byte
Lo Nibble

Delta Y 
Lo Byte
Hi Nibble

Delta Y 
Lo Byte
Lo Nibble

Line Pattern

Line Weight


Message

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Byte 8

Byte 9

Amulet Response

0xEA

Pnt 1 X 
Hi Byte
Hi Nibble

Pnt 1 X 
Hi Byte
Lo Nibble

Pnt 1 X 
Lo Byte
Hi Nibble

Pnt 1 X 
Lo Byte
Lo Nibble

Pnt 1 Y 
Hi Byte
Hi Nibble

Pnt 1 Y 
Hi Byte
Lo Nibble

Pnt 1 Y 
Lo Byte
Hi Nibble

Pnt 1 Y 
Lo Byte
Lo Nibble

Byte 10

Byte 11

Byte 12

Byte 13

Byte 14

Byte 15

Byte 16

Byte 17

Byte 18

Byte 19

Delta X 
Hi Byte
Hi Nibble

Delta X 
Hi Byte
Lo Nibble

Delta X 
Lo Byte
Hi Nibble

Delta X 
Lo Byte
Lo Nibble

Delta Y 
Hi Byte
Hi Nibble

Delta Y 
Hi Byte
Lo Nibble

Delta Y 
Lo Byte
Hi Nibble

Delta Y 
Lo Byte
Lo Nibble

Line Pattern

Line Weight


Message

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Byte 8

Byte 9

"Draw"Fill Rectangle Primitive

0xDB

Pnt 1 X 
Hi Byte
Hi Nibble

Pnt 1 X 
Hi Byte
Lo Nibble

Pnt 1 X 
Lo Byte
Hi Nibble

Pnt 1 X 
Lo Byte
Lo Nibble

Pnt 1 Y 
Hi Byte
Hi Nibble

Pnt 1 Y 
Hi Byte
Lo Nibble

Pnt 1 Y 
Lo Byte
Hi Nibble

Pnt 1 Y 
Lo Byte
Lo Nibble

Byte 10

Byte 11

Byte 12

Byte 13

Byte 14

Byte 15

Byte 16

Byte 17

Byte 18

Byte 19

Delta X 
Hi Byte
Hi Nibble

Delta X 
Hi Byte
Lo Nibble

Delta X 
Lo Byte
Hi Nibble

Delta X 
Lo Byte
Lo Nibble

Delta Y 
Hi Byte
Hi Nibble

Delta Y 
Hi Byte
Lo Nibble

Delta Y 
Lo Byte
Hi Nibble

Delta Y 
Lo Byte
Lo Nibble

Fill
Pattern

Line Weight


Message

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Byte 8

Byte 9

Amulet Response

0xEB

Pnt 1 X 
Hi Byte
Hi Nibble

Pnt 1 X 
Hi Byte
Lo Nibble

Pnt 1 X 
Lo Byte
Hi Nibble

Pnt 1 X 
Lo Byte
Lo Nibble

Pnt 1 Y 
Hi Byte
Hi Nibble

Pnt 1 Y 
Hi Byte
Lo Nibble

Pnt 1 Y 
Lo Byte
Hi Nibble

Pnt 1 Y 
Lo Byte
Lo Nibble

Byte 10

Byte 11

Byte 12

Byte 13

Byte 14

Byte 15

Byte 16

Byte 17

Byte 18

Byte 19

Delta X 
Hi Byte
Hi Nibble

Delta X 
Hi Byte
Lo Nibble

Delta X 
Lo Byte
Hi Nibble

Delta X 
Lo Byte
Lo Nibble

Delta Y 
Hi Byte
Hi Nibble

Delta Y 
Hi Byte
Lo Nibble

Delta Y 
Lo Byte
Hi Nibble

Delta Y 
Lo Byte
Lo Nibble

Fill
 Pattern

Line Weight


Message

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Byte 8

Byte 9

"Draw"Pixel Primitive

0xDC

Pixel X 
Hi Byte
Hi Nibble

Pixel X 
Hi Byte
Lo Nibble

Pixel X 
Lo Byte
Hi Nibble

Pixel X 
Lo Byte
Lo Nibble

Pixel Y 
Hi Byte
Hi Nibble

Pixel Y 
Hi Byte
Lo Nibble

Pixel Y 
Lo Byte
Hi Nibble

Pixel Y 
Lo Byte
Lo Nibble

Byte 10

Byte 11

 

Fill
 Pattern

Line Weight


Message

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Byte 8

Byte 9

Amulet Response

0xEC

Pixel X 
Hi Byte
Hi Nibble

Pixel X 
Hi Byte
Lo Nibble

Pixel X 
Lo Byte
Hi Nibble

Pixel X 
Lo Byte
Lo Nibble

Pixel Y 
Hi Byte
Hi Nibble

Pixel Y 
Hi Byte
Lo Nibble

Pixel Y 
Lo Byte
Hi Nibble

Pixel Y 
Lo Byte
Lo Nibble

Byte 10

Byte 11

Fill
 Pattern

Line Weight

Table 2. Four types of messages to draw graphics primitives can be sent between an external processor (master)
and the Amulet LCD module (slave).


Sending "Jump to specific page" Command

It is possible to send a Master Message to the Amulet which will force it to jump to a specific page within the project. The page number is an internal 16-bit number that the Amulet HTMLCompiler generates. All pages and images are assigned an internal number which can be determined by looking at the Amulet link map. When this message is received by the Amulet, it will react as if the Amulet:fileNumber(x) was launched, meaning the Amulet will jump directly to the page specified by the 16-bit internal number. You must NOT jump directly to an image file number, it must be an html file number. If you do errantly jump to a non-valid page, the Amulet OS will respond with a soft reset. This will act exactly as if the reset button was pressed.

The message structure is different than all other Amulet commands. This message is NOT in ASCII. The first two bytes for jumping to a specific page are always 0xA0, 0x02. The next byte is the MSByte of the internal number and the following byte is the LSByte of the internal number. The final byte is the checksum byte, which when added to the first four bytes, should result with the LSByte of the sum being equal to 0x00.

Examples:

To jump to page 0x25:
0xA0,0x02,0x00,0x25,0x39                Notice that 0xA0+0x02+0x00+0x25+0x39 = 0x0100. LSByte of sum is 0x00.

To jump to page 0x103:
0xA0,0x02,0x01,0x03,0x5A               Notice that 0xA0+0x02+0x01+0x03+0x5A = 0x100. LSByte of sum is 0x00.


Sending a Soft Reset Command

It is possible to send a Master Message to the Amulet which will force it to perform a soft reset. It will react exactly as if the reset button was pressed.

The message structure is similar to the Jump To Page command. This message is NOT in ASCII. The first four bytes are 0xA0, 0x02, 0xFF, 0xFF. The final byte is the checksum byte, which when added to the first four bytes, should result with the LSByte of the sum being equal to 0x00. Given that, the entire five byte string is 0xA0, 0x02, 0xFF, 0xFF, 0x60.

Example:

To cause a soft reset:
0xA0,0x02,0xFF,0xFF,0x60                Notice that 0xA0+0x02+0xFF+0xFF+0x60 = 0x0300. LSByte of sum is 0x00.


Sending strings to the Amulet which contain characters between 0x80-0xFF

All data which is sent to the Amulet should be in the ASCII format. More specifically, the lower ASCII range of 0x20-0x7E. Most of the time, this does not pose a problem. But, using the Amulet Font Converter, fonts can be saved that have a character range from 0x20-0xFF. It is illegal to send the Amulet upper-ASCII characters between 0x80-0xFF directly. The main reason for this is that Amulet opcodes are also in that range and it is desireable to separate valid opcodes from valid data characters.

Because of this, we have come up with a way to send upper ASCII characters to the Amulet using the UART protocol by using the DLE(0x10) escape character. When the Amulet sees a DLE as part of a text string, it will add 0x60 to the next character to come up with the upper ASCII character. Using one DLE escape allows you to send characters in the range of 0x80-0xDF. It is legal to concatenate DLE escapes for characters greater than 0xDF. So using two DLE escapes in a row allows you to send characters in the range of 0xE0-0xFF.

For example, to set internalRAM string variable #0 to a string that looks like "aäei©", which in raw ASCII values looks like"[0x61][0xE4][0x65][0x69][0xA9]" The following message would be sent to the Amulet:
[0xD7][0x30][0x30][0x61][0x10][0x10][0x24][0x65][0x69][0x10][0x49][0x00]


Sending strings to the Amulet which contain the font style escape byte

Amulet StringField Widgets can statically set the font style of the dynamic string at compile time. The font styles available are plain, bold, italic, underline and strikethrough. If it is desired to change the font style at runtime, that can be done by using the font style escape character (0x02). The byte following the font style escape character determines the font style of the characters that follow. It is not sent as an ASCII character, but rather a raw byte determined by the font style or styles chosen. Each font style is represented by a single bit within the font style byte. Multiple font styles can be specified at one time, except in the case of plain, which must stand alone.

Font Style

Bit Location

Bold

0x01

Italic

0x02

Strikethrough

0x04

Underline

0x08

Plain

0x80

For example, to set InternalRAM string #1 to a string which looks like this:
Bold and italic and plain.

You would send the following message to the Amulet:
[0xD7][0x30][0x31][0x02][0x01][0x42][0x6F][0x6C][0x64][0x20][0x61][0x6E][0x64][0x20][0x02][0x03]
[0x69][0x74][0x61][0x6C][0x69][0x63][0x20][0x61][0x6E][0x64][0x20][0x02][0x80]
[0x70][0x6C][0x61][0x69][0x6E][0x2E][0x00]

Alternatively written with ASCII characters written out as ASCII characters, it would look like this:
[0xD7][0x30][0x31][0x02][0x01]Bold and [0x02][0x03]italic and [0x02][0x80]plain.[0x00]


Flow Diagram Example

The flow diagram of Table 3 depicts a sample communications session between the Amulet LCD module and an external processor. This sample is setup as a dual master system, with both the Amulet and the external processor sharing the responsibility of being the master. It is possible to have a system where only the Amulet is the master, only the external processor is the master, or as in this case, a dual master setup.

The variables used in this example have the following values:
External processor's byte variable 01 = 0x38
External processor's string variable 01 = "Abc"
External processor's word variable 03 = 0x10E8
Amulet Internal RAM byte variable 0xF4 = 0xA8
Amulet Internal RAM word variable 0x76 = 0x0000
Amulet Internal RAM RPC buffer = 0x52 only

Following the communication session, the following has occurred:
External processor's byte variable 01 = 0xFE
External processor performs user-defined RPC 02. (There are no reserved RPC #'s, so all 256 RPC's can perform any desired function on your processor.)
Amulet Internal RAM word variable 0x76 = 0x02c9
Amulet Internal RAM RPC buffer = empty

Amulet LCD Module
Dir.
External Processor
Description
  0xD0   0x30   0x31
                '0'        '1'
>>
 
  Get byte variable 1
 
<<
  0xE0   0x30   0x31   0x33   0x38
                '0'       '1'       '3'       '8'
  Return byte of byte var 1

  0xD2   0x30   0x31
               '0'        '1'
>>
 
  Get string variable 1
 
<<
  0xE2   0x30   0x31   0x41   0x62   0x63   0x00
                '0'       '1'       'A'       'b'       'c'
  Return string of string var 1

  0xD5   0x30   0x31   0x46   0x45
               '0'        '1'       'F'       'E'
>>
 
  Set byte variable 1 to 0xFE
 
<<
  0xE5   0x30   0x31   0x46   0x45
                '0'       '1'   
    'F'       'E'
  Confirm set byte variable 1

  0xD8   0x30   0x32
               '0'        '2'
>>
 
  Invoke RPC2 (User-defined)
 
<<
  0xE8   0x30   0x32
                '0'       '2'
  Confirm invoke RPC2

  0xD1   0x30   0x33
                '0'        '3'
>>
 
  Get word variable 3
 
<<
  0xE1   0x30   0x33   0x31   0x30   0x45   0x38
                '0'       '3'       '1'        '0'       'E'       '8
  Return word of word var 3

  0xD0   0x30   0x34
                '0'        '4'
>>
 
  Get byte variable 4
  (not on server)*
 
<<
  0xF0
  Acknowledge (no data)

 
<<
  0xD0   0x46   0x34
                'F'        '4'
  Get Internal RAM byte var 0xF4
  0xE0   0x46   0x34   0x41   0x38
               'F'        '4'      'A'       '8'
>>
 
  Return byte of IR byte var 0xF4

 
<<
  0xD6   0x37   0x36   0x30   0x32   0x43   0x39
                '7'        '6'       '0'        '2'       'C'      '9'
  Set IR word var 0x76
  0xE6   0x37   0x36   0x30   0x32   0x43   0x39
                '7'        '6'       '0'        '2'       'C'      '9'
>>
 
  Confrim setting of IR word
  var 0x76

 
<<
  0xD4   0x30   0x30
                '0'        '0'
  Get Internal RAM RPCs
  0xE4   0x30   0x30   0x35   0x32   0x00
               '0'        '0'       '5'       '2'
>>
 
  Return IR RPC buffer
  (null terminated)

*NOTE: If master requests an invalid variable or RPC, the slave should respond with an acknowledgment (0xF0).

Table 3. Data flow diagram depicting several messages transmitted between the Amulet and a fictitious external processor.


Customizing the Amulet protocol command opcodes:

By default, the Amulet protocol uses the Command and Response Opcodes specified in this document. You can customize the Command and Response Opcodes at compile time by including a customization file in your HTML project. The customization file must have an "ini" extension and must reside in the same directory as your GUI project. You must include the customization file in a META tag in the home page of your HTML project. The syntax to include the file is:

<META NAME="initCommands" SRC="filename.ini">

The customization file, filename, must have a .ini extension and it must be located in the same directory as your main html page. Inside the customization file, any line preceded with // is treated as a comment. All customizations must be located in the far left column, so do not tab over. The HTMLCompiler recognizes both decimal and hexadecimal numbers.

The default file, called defaultCommands.ini is located in the Amulet\Configurations\Init folder. If the above META tag is not specified, defaultCommands.ini is used as the opcode definition file. If you are going to make a customization file, you should copy the defaultCommands.ini and place it in the same directory as your main html page. The file can be renamed as long as it retains the .ini extension. The values of the opcodes can be changed to practically any single byte value between (1-254)*. All the names of the opcodes can be cross-referenced with the list below. The opcode names are self documenting.

*There are three opcodes that are off limits. They are 0x00, 0xA0 and 0xFF. These must not be used to customize any of the Command or Response Opcodes.

Note: For users who don't want to change the opcodes from an earlier version of Amulet software, we have included origCommands.ini in the Amulet\Configuration\Init folder. Copy origCommands.ini into your projects main directory and use the initCommands META with origCommands.ini as your SRC file.


Summary of Amulet protocol command opcodes:

Command Opcode

Response Opcode

Description

Command Can Be Sent by Amulet

Command Can Be Sent by External Processor

0xD0

0xE0

Get byte variable

X

X

0xD1

0xE1

Get word variable

X

X

0xD2

0xE2

Get string variable

X

X

0xD3

0xE3

Get label variable

X

 

0xD4

0xE4

Get RPC buffer

 

X

0xD5

0xE5

Set byte variable

X

X

0xD6

0xE6

Set word variable

X

X

0xD7

0xE7

Set string variable

X

X

0xD8

0xE8

Invoke RPC

X

 

0xD9

0xE9

Draw Line

 

X

0xDA

0xEA

Draw Rectangle

 

X

0xDB

0xEB

Draw Filled Rectangle

 

X

0xDC

0xEC

Draw Pixel

 

X

0xDD

0xED

Get byte variable array

X

 

0xDE

0xEE

Get word variable array

X

 

0xDF

0xEF

Set byte variable array

 

X

 

0xF0

Acknowledgment (ACK)

X

X

 

0xF1

Negative Acknowledgment (NAK)

 

X

0xF2

0xF3

Set word variable array

 

X

Table 4. Listing of all Amulet protocol command opcodes and response opcodes.



Amulet HTMLCompiler,
Copyright © 2000-2005 by
Amulet Technologies, LLC

Back to Welcome - Contact Amulet - Amulet Home