[BRLTTY] TSI braille display protocol

Mario Lang mlang at blind.guru
Wed Oct 6 04:38:48 EDT 2021


deniz sincar <dsincar29 at gmail.com> writes:

> what is to and from in the writecells thing?

The TSI protocol supports partial updates.  The `from` and `to` parameters
of the writeCells() function pass the start and end of the cells which
should be updated.

> and translateoutputcell.

translateOutputCells() basically translates the bit patterns used by
BRLTTY internally to that which are being used in TSI models.  Basically,
some manufacturers use different mappings of bits to dots, so BRLTTY has
a way for drivers to declare a dot mapping according to what
the manufacturer uses.  TSI displays actually use the ISO11548-1
mapping, so the bit number directly corresponds to the dot number, and
translateOutputCells() in the TSI driver is effectively a no-op.

> can you explain, do i need to send the dot numbers right afte header?
> and does 1 braille letter with 2 hex numbers?

Lets go through the code in writeCells() and explain what it does:

  static const unsigned char header[] = {
    0XFF, 0XFF, 0X04, 0X00, 0X99, 0X00
  };
        
This defines the header of a write request.  6 bytes in hexadecimal.
It is basically a constant which will be used later to prepare the
outgoing bytes.

  unsigned int length = to - from;

The number of celss which should be written.

  unsigned char packet[sizeof(header) + 2 + (length * 2)];

A memory area for the packet to be constructed in.  sizeof returns the
numbers of bytes in the header, which in this case is 6.  We add 2 to
accomodate for a length and start offset.  Every cell needs 2 bytes in
the TSI protocol, so we also need to carve out memory for that,
multiplying the number of cells (length) by 2.  For a full update of a
40 cell display, packet would be 6 + 2 + 40*2 = 88 bytes.

  unsigned char *byte = packet;

We declare a pointer pointing to the beginning of the memory area we
just defined above.  This is going to be used below.  This is mostly
specific to C.  Some languages would call this an output iterator, I
dont know what your impelemtnation language is, so I cant really
translate the concept into your world.

  unsigned int i;

A loop counter for the loop below.

  byte = mempcpy(byte, header, sizeof(header));

We copy the (constant) header data to the beginning of the packet.

  *byte++ = 2 * length;

We add a byte indicating the length of the packet.  See below.

  *byte++ = from;

This lets the display know where to start the update.  A full update
will always start a 0 (the first cell).

  for (i=0; i<length; i+=1) {
    *byte++ = 0;
    *byte++ = translateOutputCell(brl->data->cells[from + i]);
  }
           
Here we actually do the work and put 2 bytes for each cell into the
packet.
The first byte is always 0, and the second byte contains the dot
pattern.

>From here on, all you need to do is send the packet off via the serial
port.

So to write all 8 dots raised to the first cell of the display, your
packet should look like this:

0XFF, 0XFF, 0X04, 0X00, 0X99, 0X00, 0X02, 0X00, 0X00, 0XFF

* Byte 1-6 are just the (constant) header
* Byte 7 (0X02) is the number of cells times 2
* Byte 8 (0X00) is the start offset (cell #1)
* Byte 9 (0X00) is the padding (0-byte) for the cell
* Byte 10 (0XFF) contains the actual dot pattern written to cell #1

Hope this helps.

-- 
CYa,
  ⡍⠁⠗⠊⠕


More information about the BRLTTY mailing list