as3993 ST25RU3993 Firmware
ams_stream.h
Go to the documentation of this file.
1 /*
2  *****************************************************************************
3  * AS3993/ST25RU3993 Firmware tech@eleckits.com http://iot.eleckits.com *
4  * STMicroelectronics ST25RU3993 is an EPC Class 1 Gen 2 RFID reader IC *
5  * *
6  * IMPORTANT - PLEASE READ CAREFULLY BEFORE COPYING, INSTALLING OR USING *
7  * THE SOFTWARE. *
8  * *
9  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
10  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
11  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
12  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
13  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
14  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
15  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
16  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
17  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
18  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *
19  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
20  *****************************************************************************
21  */
22 
23 /*
24  * PROJECT: AMS Streaming Communication
25  * $Revision: $
26  * LANGUAGE: C++
27  */
28 
37 #ifndef AMS_STREAM_H
38 #define AMS_STREAM_H
39 
40 
41 
42 
43 /* This is an example describing the streaming communication between
44  a PC Host and a microchip device using USB HID for transporting
45  the streaming packets.
46 
47  If you do not use USB HID but some other protocol your byte stream
48  will look different in point 3.
49 
50  Point 3. was added to show a full stack.
51 
52 
53  =============================================================================
54 
55  From Host to Device:
56 
57  ------------------------------------------------------
58 
59  On the physical line the following byte-stream is seen:
60 
61  Byte 0 1 2 3 4 5 6 7 8 (8 + tx-prot) (9+tx-prot) (10+tx-prot)
62  +------+-------+-------+----------+---------+---------+---------+---------+-------...---+-------------+-----------+-----------+-------
63  | TID |payload|re- | protocol | tx-prot | tx-prot | rx-prot | rx-prot | data | protocol B | tx-prot B | tx-prot B |
64  | | | served| | MSB | LSB | MSB | LSB | | | MSB | LSB |
65  +------+-------+-------+----------+---------+---------+---------+---------+-------...---+-------------+-----------+-----------+-------
66 
67  TID = the transaction ID is changed with every report sent.
68  payload = the amount of data in this report (sent from host to device) - a packet can be longer than
69  this size (i.e. the packet is sent with several reports - note *)
70  tx-prot = number of bytes transmitted (for this protocol packet) from host to device
71  rx-prot = number ob bytes expected to be received (for this protocol packet) from device
72 
73  *) if a packet cannot be sent in one report the next report will not have the "protocol header" set again,
74  but continue with the raw data.
75 
76 
77  This bytestream is build through the following 3 steps:
78 
79  ------------------------------------------------------
80 
81  1. The AmsComObject class provides a single data packet:
82 
83  Byte 0 1 ... tx-size -1
84  +------------+-------- ... ----------------------------+
85  | data |
86  +--------------------- ... ----------------------------+
87 
88 
89  ------------------------------------------------------
90 
91  2. The stream driver on the Host side takes a single data packet and adds the protocol header :
92 
93  Byte 0 1 2 3 4 5 4 + tx-size
94  +------------+---------+---------+---------+---------+-------------------------- ... ------------------+
95  | protocol | tx-prot | tx-prot | rx-prot | rx-prot | data |
96  | | MSB | LSB | MSB | LSB | |
97  +------------+---------+---------+---------+---------+-------------------------- ... ------------------+
98  ^ ^
99  | |
100  +----- this is the protocol header ------------------+
101 
102  ^ ^
103  | |
104  +----this is given to the HID driver as a single packet -----------------------------------------------+
105 
106 
107  Steps 1. and 2. can be repeated several times for sending more than 1 packet in a single HID report.
108 
109  ------------------------------------------------------
110 
111  3. The Hid driver on the Host side adds for each Hid Report (the following report header):
112 
113  a) if the data-buffer fits in one HID-report:
114 
115  Byte 0 1 2 3 2+ payload .... 63
116  +------+-------+------+----------+---... +-------------+------- -----------+
117  | TID |payload|res. | packet(s) | padding if necessary |
118  +------+-------+------+----------+---...-+-------------+-------.... -----------+
119  ^ ^
120  | |
121  +---------------------+
122  this is the HID
123  driver header
124 
125  b) if the packet(s) need more than 1 HID-report
126 
127  Byte 0 1 2 3 .... 63
128  +------+-------+------+----------+---... +-------------+------- -----------+
129  | TID |payload|res. | packet(s) |
130  | | = 61 | | |
131  +------+-------+------+----------+---...-+-------------+-------.... -----------+
132 
133  +------+-------+------+----------+---... +-------------+------- -----------+
134  | new |payload|res. | packet(s) |
135  | TID | = 61 | | continued |
136  +------+-------+------+----------+---...-+-------------+-------.... -----------+
137 
138  .... as many HID reports as needed until the packet(s) are totally
139  transmitted (here is how the final report might look like):
140 
141  +------+-------+------+----------+---... +-------------+------- -----------+
142  | next |payload|res. | packet(s) | padding if necessary |
143  | TID | <= 61 | | continued | |
144  +------+-------+------+----------+---...-+-------------+-------.... -----------+
145 
146 
147  */
148 
149 
150 
151 /* =============================================================================
152 
153  From Device to Host:
154 
155  ------------------------------------------------------
156 
157  On the physical line the following byte-stream is seen:
158 
159  Byte 0 1 2 3 4 5 6 7 8 (8 + tx-prot) (9+tx-prot) (10+tx-prot)
160  +------+-------+-------+----------+---------+---------+---------+---------+-------...---+-------------+-----------+-----------+-------
161  | TID |payload|HID | protocol | reserved| protocol| tx-prot | tx-prot | data | protocol B | reserved | status B |
162  | | | status| | | status | MSB | LSB | | | |
163  +------+-------+-------+----------+---------+---------+---------+---------+-------...---+-------------+-----------+-----------+-------
164 
165  TID = the transaction ID is reflected th every report sent.
166  payload = the amount of data in this report (sent from host to device) - a packet can be longer than
167  this size (i.e. the packet is sent with several reports - note *)
168  HID status = if a protocol was not processed (because e.g. the protocol id was unknown) the next HID
169  packet that is sent back will contain a HID status byte <> 0 indicating that an error
170  occurred (some time in the back).
171  protocol status = a single byte representing the result of the command if the command generated either data to
172  be sent back or is a read command (has the MSBit cleared)
173  tx-prot = number of bytes transmitted (for this protocol packet) from device to host
174 
175  *) if a packet cannot be sent in one report the next report will not have the "protocol header" set again,
176  but continue with the raw data.
177 
178 
179  This bytestream is build by through the following 3 steps:
180 
181  ------------------------------------------------------
182 
183  1. The Firmware-Application provides a single data packet containing the result:
184 
185  Byte 0 1 ... tx-size -1
186  +------------+-------- ... ----------------------------+
187  | data |
188  +--------------------- ... ----------------------------+
189 
190  2. The function processReceivedPackets of file stream_appl_handler.c in the firmware adds the protocol byte,
191  the reserved and the status byte and the tx-prot 16-bit word (from the information provided by the
192  firmware application):
193 
194  Byte 0 1 2 3 4 5 4 + tx-size
195  +------------+---------+---------+---------+---------+-------------------------- ... ------------------+
196  | protocol | reserved| status | tx-prot | tx-prot | data |
197  | | | | MSB | LSB | |
198  +------------+---------+---------+---------+---------+-------------------------- ... ------------------+
199  ^ ^
200  | |
201  +----- this is the protocol header ------------------+
202 
203 
204  Steps 1. and 2. can be repeated several times before handing a single buffer (containing all packets)
205  to the HID driver.
206 
207  ------------------------------------------------------
208 
209  3. The Hid driver on the Device side splits the buffer into Hid Reports and adds for each Hid Report
210  (the following report header):
211 
212  a) if the data-buffer fits in one HID-report:
213 
214  Byte 0 1 3 4 3+ payload .... 63
215  +------+-------+-------+----------+---... +-------------+------- -----------+
216  | TID |payload|status | packet(s) | padding if necessary |
217  +------+-------+-------+----------+---...-+-------------+-------.... -----------+
218  ^ ^
219  | |
220  +----------------------+
221  this is the HID
222  driver header
223 
224  b) if the packet(s) need more than 1 HID-report
225 
226  Byte 0 1 2 3 .... 63
227  +------+-------+------+----------+---... +-------------+------- -----------+
228  | TID |payload|status| packet(s) |
229  | | = 61 | | |
230  +------+-------+------+----------+---...-+-------------+-------.... -----------+
231 
232  +------+-------+------+----------+---... +-------------+------- -----------+
233  | new |payload|status| packet(s) |
234  | TID | = 61 | | continued |
235  +------+-------+------+----------+---...-+-------------+-------.... -----------+
236 
237  .... as many HID reports as needed until the packet(s) are totally
238  transmitted (here is how the final report might look like):
239 
240  +------+-------+------+----------+---... +-------------+------- -----------+
241  | next |payload|status| packet(s) | padding if necessary |
242  | TID | <= 61 | | continued | |
243  +------+-------+------+----------+---...-+-------------+-------.... -----------+
244 
245  */
246 
247 
248 /* =============================================================================
249  TID-Rules:
250 
251  On the host side, the TID is generated as a 4-bit number counting from 0 to 0x0F
252  and than rolling over to 0.
253 
254  The device side takes the TID received from the Host and moves it to the upper
255  nibble, increments its own TID counter by one (range is again 0 to 0x0F) and
256  adds its own TID counter.
257  txTID = (rxTID << 4) | ( ++txTID & 0xF )
258 
259  */
260 
261 /* =============================================================================
262  Protocol-Rules:
263 
264  The MSBit of the protocol byte defines the direction: 1 = write, 0 = read.
265  This bit is set by the Ams Stream class itself during sending or receiving.
266 
267  The following number range is special:
268  0x60 - 0x7F: reserved for generic commands (part of the common firmware)
269  0x60: is a configuration protocol for the firmware itself
270  0x6B: is reserved for the bootloader
271  0x7F: is reserved for the flush
272 
273  An application can use the numbers: 0x00 - 0x5F for its own commands.
274 
275  */
276 
277 
278 
279 /* ------------- defines and macros ---------------------------------------- */
280 
281 /* the stream adds a header to each packet of this size */
282 #define AMS_STREAM_HEADER_SIZE 5
283 
284 /* macros to write the packet on the host side: HT = Host Transmitter */
285 #define AMS_STREAM_HT_SET_PROTOCOL( buf, prot ) do { (buf)[0] = (prot); } while ( 0 )
286 #define AMS_STREAM_HT_SET_TX_LENGTH( buf, len ) do { (buf)[1] = (len) >> 8; (buf)[2] = (len) & 0xFF; } while ( 0 )
287 #define AMS_STREAM_HT_SET_RX_LENGTH( buf, len ) do { (buf)[3] = (len) >> 8; (buf)[4] = (len) & 0xFF; } while ( 0 )
288 
289 /* macros to read the packet on the device side: DR = Device Receiver */
290 #define AMS_STREAM_DR_GET_PROTOCOL( buf ) ( (buf)[0] )
291 #define AMS_STREAM_DR_GET_RX_LENGTH( buf ) ( ( ((unsigned short)((buf)[1])) << 8 ) | (buf)[2] )
292 #define AMS_STREAM_DR_GET_TX_LENGTH( buf ) ( ( ((unsigned short)((buf)[3])) << 8 ) | (buf)[4] )
293 
294 /* macros to write the packet on the device side: DT = Device Transmitter */
295 #define AMS_STREAM_DT_SET_PROTOCOL( buf, prot ) do { (buf)[0] = (prot); } while ( 0 )
296 #define AMS_STREAM_DT_SET_STATUS( buf, stat ) do { (buf)[1] = 0; (buf)[2] = (stat); } while ( 0 )
297 #define AMS_STREAM_DT_SET_TX_LENGTH( buf, len ) do { (buf)[3] = (len) >> 8; (buf)[4] = (len) & 0xFF; } while ( 0 )
298 
299 /* macros to read the packet on the host side: HR = Host Receiver */
300 #define AMS_STREAM_HR_GET_PROTOCOL( buf ) ( (buf)[0] )
301 #define AMS_STREAM_HR_GET_STATUS( buf ) ( (buf)[2] )
302 #define AMS_STREAM_HR_GET_RX_LENGTH( buf ) ( (((unsigned short)((buf)[3])) << 8 ) | (buf)[4] )
303 
304 /* the payload starts after the header */
305 #define AMS_STREAM_PAYLOAD( buf ) ( (buf) + AMS_STREAM_HEADER_SIZE )
306 
307 
308 /* maximum amount of data that can be transported in a single packet */
309 #define AMS_STREAM_MAX_DATA_SIZE (1024 + 64)
310 
311 /* the size of a buffer to hold at least one packet + header */
312 #define AMS_STREAM_BUFFER_SIZE ( AMS_STREAM_HEADER_SIZE + AMS_STREAM_MAX_DATA_SIZE )
313 
314 
315 
316 /* the size of the serialized i2c config object in byte */
317 #define AMS_STREAM_I2C_CONFIG_OBJ_LENGTH 7
318 
319 /* deserializes the i2c_clock_speed (32-bit value) out of a serialized i2c config object */
320 #define AMS_STREAM_I2C_CONFIG_GET_CUSTOM_CLK_SPEED( buf ) ( (((unsigned long)((buf)[3])) << 24 ) | (((unsigned long)((buf)[4])) << 16 ) | (((unsigned long)((buf)[5])) << 8 ) | (buf)[6] )
321 
322 /* serializes the i2c_clock_speed (32-bit value) into a byte array. position according to serialized i2c config object */
323 #define AMS_STREAM_I2C_CONFIG_SET_CUSTOM_CLK_SPEED( buf, speed ) do { (buf)[3] = ((speed) >> 24) & 0xFF; (buf)[4] = ((speed) >> 16) & 0xFF; (buf)[5] = ((speed) >> 8) & 0xFF; (buf)[6] = speed & 0xFF; } while ( 0 )
324 
325 
326 
327 
328 /* all communication protocols that use the AmsComStream for communication
329  must define their protocol identifier here */
330 
331 /* if the MSB bit is set this a command for write, else this is for read */
332 #define AMS_COM_WRITE_READ_NOT 0x80
333 
334 /* protocol ids can range from 0x60 - 0x7f */
335 #define AMS_COM_CONFIG 0x60 /* reserved */
336 #define AMS_COM_I2C 0x61
337 #define AMS_COM_I2C_CONFIG 0x62
338 #define AMS_COM_SPI 0x63
339 #define AMS_COM_SPI_CONFIG 0x64
340 #define AMS_COM_CTRL_CMD_RESET 0x65
341 #define AMS_COM_CTRL_CMD_FW_INFORMATION 0x66 /* returns zero-terminated string with information about fw e.g. chip, board */
342 #define AMS_COM_CTRL_CMD_FW_NUMBER 0x67 /* returns the 3-byte FW number */
343 #define AMS_COM_WRITE_REG 0x68
344 #define AMS_COM_READ_REG 0x69
345 
346 /* 0x6B = reserved protocol id
347  This will become 0xEB at sending because it is:
348  AMS_COM_WRITE_READ_NOT | AMS_COM_CTRL_CMD_ENTER_BOOTLOADER == 0x80 | 0x6B = 0xEB */
349 #define AMS_COM_CTRL_CMD_ENTER_BOOTLOADER 0x6B
350 
351 /* 0x7F = reserved protocol id */
352 #define AMS_COM_FLUSH 0x7F
353 
354 /* currently available reserved numbers are: 0x6A and 0x6C - 0x7E */
355 
356 /* all unused numbers between 0x00 and 0x5F are forwarded in the firmware (by the stream_dispatcher.c)
357  to the function
358  u8 applProcessCmd ( u8 protocol, u16 rxSize, const u8 * rxData, u16 * txSize, u8 * txData )
359  A weak default implementation of this function is provided in weak_stream_functions.c
360  in the firmware that just flags an error. Implement this function in your
361  firmware to override the default behavior.
362 */
363 
364 
365 /* -------- additional defines ------------------------------------------- */
366 
367 #define AMS_COM_RESET_MCU 0x01 /* to reset the MCU use this as the objectToReset parameter */
368 #define AMS_COM_RESET_PERIPHERAL 0x02 /* to reset all peripherals use this */
369 #define AMS_STREAM_SHORT_STRING 0x40 /* a const char * must not point to something longer than this */
370 
371 /* AMS_CONFIG request format:
372  *
373  * Write request: write to Address = (Mask & Value)
374  * buf[ 0 ] = WORD_SIZE (either 1, 2, 4 )
375  * buf[ 1 .. wordSize +1 ] = Address
376  * buf[ ... ] = Mask
377  * buf[ ... ] = Value to be written
378  *
379  * Read request: read from Address a 16-bit value
380  * buf[ 0 ] = WORD_SIZE (either 1, 2, 4 )
381  * buf[ 1 .. wordSize +1 ] = Address
382  * Read response:
383  * buf[ 0 ] = WORD_SIZE (either 1, 2, 4 )
384  * buf[ 1 .. wordSize +1 ] = Value
385  */
386 
387 #define AMS_CONFIG_WORD_SIZE_OFFSET 0 /* at position 0 we find the word size = 1, 2 or 4*/
388 #define AMS_CONFIG_PIC_WORD_SIZE 2 /* on the PIC 24F a word is 16-bit wide */
389 #define AMS_CONFIG_ARM_WORD_SIZE 4 /* on the ARM Cortex M0 a word is 32-bit wide */
390 
391 /* write request is: reg-addr + mask + value == 3 * wordSize */
392 #define AMS_CONFIG_WRITE_REQUEST_LENGTH(wordSize) (3*(wordSize))
393 /* read reqeust is: reg-addr */
394 #define AMS_CONFIG_READ_REQUEST_LENGTH(wordSize) (wordSize)
395 /* read response is: value */
396 #define AMS_CONFIG_READ_RESPONSE_LENGTH(wordSize) (wordSize)
397 
398 #define AMS_SET_32BIT(v,buf) \
399  do { \
400  (buf)[0] = (unsigned char)(((unsigned int)(v)) >> 24); \
401  (buf)[1] = (unsigned char)(((unsigned int)(v)) >> 16); \
402  (buf)[2] = (unsigned char)(((unsigned int)(v)) >> 8); \
403  (buf)[3] = (unsigned char)(((unsigned int)(v)) ); \
404  } while ( 0 )
405 
406 #define AMS_GET_32BIT(buf) \
407  ( (((unsigned int)((buf)[0])) << 24) \
408  | (((unsigned int)((buf)[1])) << 16) \
409  | (((unsigned int)((buf)[2])) << 8) \
410  | (((unsigned int)((buf)[3])) ) \
411  )
412 
413 #define AMS_SET_16BIT(v,buf) \
414  do { \
415  (buf)[0] = (unsigned char)(((unsigned int)(v)) >> 8); \
416  (buf)[1] = (unsigned char)(((unsigned int)(v)) ); \
417  } while ( 0 )
418 
419 #define AMS_GET_16BIT(buf) \
420  ( (((unsigned int)((buf)[0])) << 8) \
421  | (((unsigned int)((buf)[1])) ) \
422  )
423 
424 
425 /* one byte for errors in the dispatcher (and protocols if the protocol
426  was a write request = unconfirmed by the protocol itself)
427 */
428 #define AMS_STREAM_UNHANDLED_PROTOCOL 0x01 /* no function implemented to handle this protocol */
429 #define AMS_STREAM_PROTOCOL_FAILED 0x02 /* function call returned a status <> 0 - and this was an unconfirmed protocol */
430 #define AMS_STREAM_SIZE_ERROR 0x03 /* the rx/tx size is out of allowed range */
431 #define AMS_STREAM_NO_ERROR 0x00 /* no error at all */
432 
433 /* this define is used as a special TID used by the firmware when a request in the old format
434  is received */
435 #define AMS_STREAM_COMPATIBILITY_TID 0xDE
436 
437 /* -------- usb hid defines ---------------------------------------------- */
438 
439 #define USB_HID_REPORT_ID 0
440 #define USB_HID_REPORT_SIZE 64
441 #define USB_HID_HEADER_SIZE 3
442 #define USB_HID_MAX_PAYLOAD_SIZE (USB_HID_REPORT_SIZE - USB_HID_HEADER_SIZE)
443 
444 /* HID header macros for the microchip */
445 #define USB_HID_TID(buf) ((buf)[0])
446 #define USB_HID_PAYLOAD_SIZE(buf) ((buf)[1])
447 #define USB_HID_STATUS(buf) ((buf)[2])
448 #define USB_HID_PAYLOAD(buf) ((buf)+USB_HID_HEADER_SIZE)
449 
450 #define USB_HID_GENERATE_TID_FOR_TX( rxtid, txtid ) \
451  do { \
452  (txtid)++; \
453  (txtid) = ( (rxtid) << 4 ) | ( (txtid) & 0xF );\
454  } while ( 0 )
455 
456 
457 
458 /* -------- uart defines ---------------------------------------------- */
459 
460 #define UART_HEADER_SIZE 4
461 
462 /* uart header macros for the microchip */
463 #define UART_TID(buf) (buf[0])
464 #define UART_STATUS(buf) ((buf)[1])
465 #define UART_SET_PAYLOAD_SIZE( buf, len ) do { (buf)[2] = (len) >> 8; (buf)[3] = (len) & 0xFF; } while ( 0 )
466 #define UART_GET_PAYLOAD_SIZE( buf ) ( ( ((buf)[2]) << 8 ) | ( ((buf)[3]) & 0xFF ) )
467 #define UART_PAYLOAD(buf) ((buf)+UART_HEADER_SIZE)
468 
469 #define UART_GENERATE_TID_FOR_TX( rxtid, txtid ) USB_HID_GENERATE_TID_FOR_TX( rxtid, txtid )
470 
471 
472 #endif /* AMS_STREAM_H */