| From e86200fb1ecfe1b5c4598540eb8c173cfd44dc16 Mon Sep 17 00:00:00 2001 |
| From: Dominic Mazzoni <dmazzoni@chromium.org> |
| Date: Wed, 14 Dec 2016 10:04:27 -0800 |
| Subject: [PATCH 1/2] Dot Pad prototype |
| |
| --- |
| Drivers/Braille/DOT/Makefile.in | 28 ++++ |
| Drivers/Braille/DOT/braille.c | 267 +++++++++++++++++++++++++++++++++++++++ |
| Drivers/Braille/DOT/brldefs-do.h | 23 ++++ |
| Drivers/Braille/DOT/reldeps.mk | 26 ++++ |
| Programs/config.c | 2 +- |
| Programs/usb_serial.c | 3 +- |
| configure.ac | 1 + |
| 7 files changed, 348 insertions(+), 2 deletions(-) |
| create mode 100644 Drivers/Braille/DOT/Makefile.in |
| create mode 100644 Drivers/Braille/DOT/braille.c |
| create mode 100644 Drivers/Braille/DOT/brldefs-do.h |
| create mode 100644 Drivers/Braille/DOT/reldeps.mk |
| |
| diff --git a/Drivers/Braille/DOT/Makefile.in b/Drivers/Braille/DOT/Makefile.in |
| new file mode 100644 |
| index 000000000..35641bb06 |
| --- /dev/null |
| +++ b/Drivers/Braille/DOT/Makefile.in |
| @@ -0,0 +1,28 @@ |
| +############################################################################### |
| +# BRLTTY - A background process providing access to the console screen (when in |
| +# text mode) for a blind person using a refreshable braille display. |
| +# |
| +# Copyright (C) 1995-2016 by The BRLTTY Developers. |
| +# |
| +# BRLTTY comes with ABSOLUTELY NO WARRANTY. |
| +# |
| +# This is free software, placed under the terms of the |
| +# GNU General Public License, as published by the Free Software |
| +# Foundation; either version 2 of the License, or (at your option) any |
| +# later version. Please see the file LICENSE-GPL for details. |
| +# |
| +# Web Page: http://brltty.com/ |
| +# |
| +# This software is maintained by Dave Mielke <dave@mielke.cc>. |
| +############################################################################### |
| + |
| +DRIVER_CODE = do |
| +DRIVER_NAME = DOT |
| +DRIVER_COMMENT = Light board |
| +DRIVER_VERSION = |
| +DRIVER_DEVELOPERS = Dominic Mazzoni <dmazzoni@google.com> |
| +include $(SRC_TOP)braille.mk |
| + |
| +braille.$O: |
| + $(CC) $(BRL_CFLAGS) -c $(SRC_DIR)/braille.c |
| + |
| diff --git a/Drivers/Braille/DOT/braille.c b/Drivers/Braille/DOT/braille.c |
| new file mode 100644 |
| index 000000000..0a8b50d87 |
| --- /dev/null |
| +++ b/Drivers/Braille/DOT/braille.c |
| @@ -0,0 +1,267 @@ |
| +/* |
| + * BRLTTY - A background process providing access to the console screen (when in |
| + * text mode) for a blind person using a refreshable braille display. |
| + * |
| + * Copyright (C) 1995-2017 by The BRLTTY Developers. |
| + * |
| + * BRLTTY comes with ABSOLUTELY NO WARRANTY. |
| + * |
| + * This is free software, placed under the terms of the |
| + * GNU General Public License, as published by the Free Software |
| + * Foundation; either version 2 of the License, or (at your option) any |
| + * later version. Please see the file LICENSE-GPL for details. |
| + * |
| + * Web Page: http://brltty.com/ |
| + * |
| + * This software is maintained by Dave Mielke <dave@mielke.cc>. |
| + */ |
| + |
| +#include <string.h> |
| +#include <errno.h> |
| + |
| +#include "log.h" |
| + |
| +#include "brl_driver.h" |
| +#include "brldefs-do.h" |
| + |
| +#define PROBE_RETRY_LIMIT 2 |
| +#define PROBE_INPUT_TIMEOUT 500 |
| +#define MAXIMUM_RESPONSE_SIZE (0XFF + 4) |
| +#define MAXIMUM_TEXT_CELLS 0XFF |
| +#define MAX_CELLS_PER_PACKET 33 |
| + |
| +struct BrailleDataStruct { |
| + struct { |
| + unsigned char rewrite; |
| + unsigned char cells[MAXIMUM_TEXT_CELLS]; |
| + } braille; |
| + |
| + struct { |
| + unsigned char rewrite; |
| + wchar_t characters[MAXIMUM_TEXT_CELLS]; |
| + } text; |
| + |
| + struct { |
| + unsigned char rewrite; |
| + int position; |
| + } cursor; |
| +}; |
| + |
| +static int |
| +writeBytes (BrailleDisplay *brl, const unsigned char *bytes, size_t count) { |
| + return writeBraillePacket(brl, NULL, bytes, count); |
| +} |
| + |
| +static int |
| +writePacket (BrailleDisplay *brl, const unsigned char *packet, size_t size) { |
| + unsigned char bytes[size]; |
| + unsigned char *byte = bytes; |
| + |
| + byte = mempcpy(byte, packet, size); |
| + return writeBytes(brl, bytes, byte-bytes); |
| +} |
| + |
| +static size_t |
| +readPacket (BrailleDisplay *brl, void *packet, size_t size) { |
| + if (size < 2) |
| + return 0; |
| + |
| + unsigned char* buffer = packet; |
| + GioEndpoint *endpoint = brl->gioEndpoint; |
| + if (!gioReadByte(endpoint, &buffer[0], 0)) return 0; |
| + if (!gioReadByte(endpoint, &buffer[1], 1)) return 0; |
| + |
| + unsigned char packet_type = buffer[0]; |
| + unsigned char count = buffer[1]; |
| + |
| + if (count + 2 > size) return 0; |
| + |
| + for (unsigned char i = 0; i < count; i++) { |
| + if (!gioReadByte(endpoint, &buffer[i + 2], 1)) return 0; |
| + } |
| + |
| + logInputPacket(packet, count + 2); |
| + |
| + // Send an ACK, unless it's an ACK we just read |
| + if (packet_type != 0) { |
| + unsigned char ack[4]; |
| + ack[0] = 0; // GEN_ACK |
| + ack[1] = 2; // data length |
| + ack[2] = packet_type; // Ack the packet type |
| + ack[3] = 0; // OK result code |
| + |
| + if (gioWriteData(endpoint, ack, sizeof(ack)) == -1) return 0; |
| + } |
| + |
| + return count + 2; |
| +} |
| + |
| +static int |
| +connectResource (BrailleDisplay *brl, const char *identifier) { |
| + static const SerialParameters serialParameters = { |
| + SERIAL_DEFAULT_PARAMETERS, |
| + .baud = 19200 |
| + }; |
| + |
| + BEGIN_USB_CHANNEL_DEFINITIONS |
| + { /* DOT braille tablet (66 cells) */ |
| + .vendor=0X1366, .product=0X1015, |
| + .configuration=1, .interface=1, .alternative=0, |
| + .inputEndpoint=0x03, .outputEndpoint=0x04, |
| + .serial = &serialParameters |
| + }, |
| + END_USB_CHANNEL_DEFINITIONS |
| + |
| + GioDescriptor descriptor; |
| + gioInitializeDescriptor(&descriptor); |
| + descriptor.serial.parameters = &serialParameters; |
| + descriptor.usb.channelDefinitions = usbChannelDefinitions; |
| + |
| + if (connectBrailleResource(brl, identifier, &descriptor, NULL)) return 1; |
| + |
| + return 0; |
| +} |
| + |
| +static int |
| +writeInitRequest (BrailleDisplay *brl) { |
| + static const unsigned char packet[] = {0x01, 0x03, 0x03, 0x01, 0x01}; |
| + return writePacket(brl, packet, sizeof(packet)); |
| +} |
| + |
| +static BrailleResponseResult |
| +isInitResponse (BrailleDisplay *brl, const void *packet, size_t size) { |
| + const unsigned char* data = packet; |
| + if (size != 9) return BRL_RSP_FAIL; |
| + if (data[0] != 0x02) return BRL_RSP_FAIL; |
| + return BRL_RSP_DONE; |
| +} |
| + |
| +static int |
| +brl_construct (BrailleDisplay *brl, char **parameters, const char *device) { |
| + if ((brl->data = malloc(sizeof(*brl->data)))) { |
| + memset(brl->data, 0, sizeof(*brl->data)); |
| + |
| + if (connectResource(brl, device)) { |
| + unsigned char response[MAXIMUM_RESPONSE_SIZE]; |
| + if (probeBrailleDisplay(brl, PROBE_RETRY_LIMIT, NULL, PROBE_INPUT_TIMEOUT, |
| + writeInitRequest, |
| + readPacket, &response, sizeof(response), |
| + isInitResponse)) { |
| + brl->textColumns = response[5]; |
| + brl->textRows = response[6]; |
| + |
| + brl->statusRows = 0; |
| + brl->statusColumns = 0; |
| + |
| + brl->data->braille.rewrite = 1; |
| + brl->data->text.rewrite = 1; |
| + brl->data->cursor.rewrite = 1; |
| + |
| + if (gioAwaitInput(brl->gioEndpoint, PROBE_INPUT_TIMEOUT)) { |
| + unsigned char cap[MAXIMUM_RESPONSE_SIZE]; |
| + readPacket(brl, cap, sizeof(cap)); |
| + // TODO: interpret capabilities. |
| + } |
| + |
| + // Set all dots down |
| + { |
| + unsigned char packet[3]; |
| + packet[0] = 0x26; // SYS_SET_ALL_DOTS_DN |
| + packet[1] = 1; |
| + packet[2] = 0; |
| + writePacket(brl, packet, sizeof(packet)); |
| + |
| + if (gioAwaitInput(brl->gioEndpoint, PROBE_INPUT_TIMEOUT)) { |
| + unsigned char ack[4]; |
| + readPacket(brl, ack, sizeof(ack)); |
| + } |
| + } |
| + |
| + return 1; |
| + } |
| + |
| + disconnectBrailleResource(brl, NULL); |
| + } |
| + |
| + free(brl->data); |
| + } else { |
| + logMallocError(); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +static void |
| +brl_destruct (BrailleDisplay *brl) { |
| + disconnectBrailleResource(brl, NULL); |
| + |
| + if (brl->data) { |
| + free(brl->data); |
| + brl->data = NULL; |
| + } |
| +} |
| + |
| +static int |
| +brl_writeWindow (BrailleDisplay *brl, const wchar_t *text) { |
| + size_t cellCount = brl->textColumns * brl->textRows; |
| + |
| + int newBraille = |
| + cellsHaveChanged(brl->data->braille.cells, brl->buffer, cellCount, |
| + NULL, NULL, &brl->data->braille.rewrite); |
| + |
| + int newText = |
| + textHasChanged(brl->data->text.characters, text, cellCount, |
| + NULL, NULL, &brl->data->text.rewrite); |
| + |
| + int newCursor = |
| + cursorHasChanged(&brl->data->cursor.position, brl->cursor, |
| + &brl->data->cursor.rewrite); |
| + |
| + if (!newBraille && !newText && !newCursor) |
| + return 1; |
| + |
| + unsigned char cells[cellCount]; |
| + translateOutputCells(cells, brl->data->braille.cells, cellCount); |
| + |
| + // Send multiple packets because the device has trouble updating |
| + // too many cells at the same time. |
| + size_t startCell = 0; |
| + while (startCell < cellCount) { |
| + size_t packetCellCount = MIN(cellCount - startCell, MAX_CELLS_PER_PACKET); |
| + unsigned char packet[packetCellCount + 3]; |
| + packet[0] = 0x82; // USB_SET_BRAILLE_CODE |
| + packet[1] = packetCellCount + 1; |
| + packet[2] = startCell; |
| + |
| + for (int j = 0; j < packetCellCount; j++) |
| + packet[j + 3] = cells[startCell + j] & 0x3F; |
| + |
| + if (!writePacket(brl, packet, sizeof(packet))) return 0; |
| + |
| + if (!gioAwaitInput(brl->gioEndpoint, PROBE_INPUT_TIMEOUT)) { |
| + // We sometimes don't get an ACK, don't treat it as a fatal error. |
| + startCell += packetCellCount; |
| + continue; |
| + } |
| + |
| + // If we do get something make sure it's a valid ACK. |
| + unsigned char ack[4]; |
| + size_t ack_result = readPacket(brl, ack, sizeof(ack)); |
| + if (!ack_result) { |
| + fprintf(stderr, "ack_result is 0\n"); |
| + return 0; |
| + } |
| + if (ack[2] != 0x82 || ack[3] != 0x00) return 0; |
| + |
| + startCell += packetCellCount; |
| + } |
| + |
| + return 1; |
| +} |
| + |
| +static int |
| +brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) { |
| + // The prototype board from DOT doesn't have any input keys yet. |
| + // This driver currently only supports braille output. |
| + return EOF; |
| +} |
| diff --git a/Drivers/Braille/DOT/brldefs-do.h b/Drivers/Braille/DOT/brldefs-do.h |
| new file mode 100644 |
| index 000000000..f0842116b |
| --- /dev/null |
| +++ b/Drivers/Braille/DOT/brldefs-do.h |
| @@ -0,0 +1,23 @@ |
| + |
| +/* |
| + * BRLTTY - A background process providing access to the console screen (when in |
| + * text mode) for a blind person using a refreshable braille display. |
| + * |
| + * Copyright (C) 1995-2016 by The BRLTTY Developers. |
| + * |
| + * BRLTTY comes with ABSOLUTELY NO WARRANTY. |
| + * |
| + * This is free software, placed under the terms of the |
| + * GNU Lesser General Public License, as published by the Free Software |
| + * Foundation; either version 2.1 of the License, or (at your option) any |
| + * later version. Please see the file LICENSE-LGPL for details. |
| + * |
| + * Web Page: http://brltty.com/ |
| + * |
| + * This software is maintained by Dave Mielke <dave@mielke.cc>. |
| + */ |
| + |
| +#ifndef BRLTTY_INCLUDED_DO_BRLDEFS |
| +#define BRLTTY_INCLUDED_DO_BRLDEFS |
| + |
| +#endif /* BRLTTY_INCLUDED_DO_BRLDEFS */ |
| diff --git a/Drivers/Braille/DOT/reldeps.mk b/Drivers/Braille/DOT/reldeps.mk |
| new file mode 100644 |
| index 000000000..9227472d9 |
| --- /dev/null |
| +++ b/Drivers/Braille/DOT/reldeps.mk |
| @@ -0,0 +1,26 @@ |
| +# Dependencies for braille.$O: |
| +braille.$O: $(SRC_DIR)/braille.c |
| +braille.$O: $(SRC_TOP)Headers/prologue.h |
| +braille.$O: $(BLD_TOP)config.h |
| +braille.$O: $(BLD_TOP)forbuild.h |
| +braille.$O: $(SRC_TOP)Headers/log.h |
| +braille.$O: $(SRC_TOP)Headers/api_types.h |
| +braille.$O: $(SRC_TOP)Headers/async.h |
| +braille.$O: $(SRC_TOP)Headers/async_io.h |
| +braille.$O: $(SRC_TOP)Headers/brl_base.h |
| +braille.$O: $(SRC_TOP)Headers/brl_cmds.h |
| +braille.$O: $(SRC_TOP)Headers/brl_dots.h |
| +braille.$O: $(SRC_TOP)Headers/brl_driver.h |
| +braille.$O: $(SRC_TOP)Headers/brl_types.h |
| +braille.$O: $(SRC_TOP)Headers/brl_utils.h |
| +braille.$O: $(SRC_TOP)Headers/cmd_enqueue.h |
| +braille.$O: $(SRC_TOP)Headers/driver.h |
| +braille.$O: $(SRC_TOP)Headers/gio_types.h |
| +braille.$O: $(SRC_TOP)Headers/io_generic.h |
| +braille.$O: $(SRC_TOP)Headers/ktb_types.h |
| +braille.$O: $(SRC_TOP)Headers/queue.h |
| +braille.$O: $(SRC_TOP)Headers/serial_types.h |
| +braille.$O: $(SRC_TOP)Headers/status_types.h |
| +braille.$O: $(SRC_TOP)Headers/usb_types.h |
| +braille.$O: $(SRC_DIR)/brldefs-do.h |
| + |
| diff --git a/Programs/config.c b/Programs/config.c |
| index 4a59cd70d..e62f78527 100644 |
| --- a/Programs/config.c |
| +++ b/Programs/config.c |
| @@ -1446,7 +1446,7 @@ activateBrailleDriver (int verify) { |
| autodetectableDrivers = serialDrivers; |
| } else if (isUsbDevice(&dev)) { |
| static const char *const usbDrivers[] = { |
| - "al", "bm", "eu", "fs", "hd", "hm", "ht", "hw", "mt", "pg", "pm", "sk", "vo", |
| + "al", "bm", "do", "eu", "fs", "hd", "hm", "ht", "hw", "mt", "pg", "pm", "sk", "vo", |
| NULL |
| }; |
| autodetectableDrivers = usbDrivers; |
| diff --git a/Programs/usb_serial.c b/Programs/usb_serial.c |
| index e3ffaa7dd..24c4e0e1a 100644 |
| --- a/Programs/usb_serial.c |
| +++ b/Programs/usb_serial.c |
| @@ -131,7 +131,8 @@ usbSetSerialOperations (UsbDevice *device) { |
| } |
| |
| if (!uso) { |
| - if (device->descriptor.bDeviceClass == 0X02) { |
| + if (device->descriptor.bDeviceClass == 0X02 |
| + || device->descriptor.bDeviceClass == 239) { /////////////////////////////// |
| uso = &usbSerialOperations_CDC_ACM; |
| } |
| } |
| diff --git a/configure.ac b/configure.ac |
| index a4adc4ee4..812373a4f 100644 |
| --- a/configure.ac |
| +++ b/configure.ac |
| @@ -1465,6 +1465,7 @@ BRLTTY_BRAILLE_DRIVER([bm], [Baum]) |
| BRLTTY_BRAILLE_DRIVER([bn], [BrailleNote]) |
| BRLTTY_BRAILLE_DRIVER([cb], [CombiBraille]) |
| BRLTTY_BRAILLE_DRIVER([ce], [Cebra]) |
| +BRLTTY_BRAILLE_DRIVER([do], [DOT]) |
| BRLTTY_BRAILLE_DRIVER([ec], [EcoBraille]) |
| BRLTTY_BRAILLE_DRIVER([eu], [EuroBraille]) |
| BRLTTY_BRAILLE_DRIVER([fs], [FreedomScientific]) |
| -- |
| 2.11.0.483.g087da7b7c-goog |
| |