/*====================================================================* Copyright (c) 2013,2020 Qualcomm Technologies, Inc. All Rights Reserved. Confidential and Proprietary - Qualcomm Technologies, Inc. ****************************************************************** 2013 Qualcomm Atheros, Inc. *====================================================================*/ /*====================================================================* * * int6kbaud.c - Qualcomm Atheros Serial Line Device Manager; * * Contributor(s): * Nathaniel Houghton * *--------------------------------------------------------------------*/ /*====================================================================* * system header files; *--------------------------------------------------------------------*/ #include #include #include #include #if defined (WIN32) #elif defined (__linux__) # include #elif defined (__APPLE__) # include #elif defined (__OpenBSD__) # include #else #error "Unknown Environment" #endif /*====================================================================* * custom header files; *--------------------------------------------------------------------*/ #include "../tools/getoptv.h" #include "../tools/putoptv.h" #include "../tools/number.h" #include "../tools/memory.h" #include "../tools/endian.h" #include "../tools/symbol.h" #include "../tools/files.h" #include "../tools/flags.h" #include "../tools/error.h" #include "../tools/types.h" #include "../serial/serial.h" #include "../plc/plc.h" /*====================================================================* * custom source files; *--------------------------------------------------------------------*/ #ifndef MAKEFILE #include "../tools/getoptv.c" #include "../tools/putoptv.c" #include "../tools/version.c" #include "../tools/uintspec.c" #include "../tools/basespec.c" #include "../tools/synonym.c" #include "../tools/todigit.c" #include "../tools/error.c" #include "../tools/checksum32.c" #include "../tools/hexencode.c" #include "../tools/hexdump.c" #include "../tools/hexstring.c" #include "../tools/hexdecode.c" #include "../tools/synonym.c" #include "../tools/error.c" #endif #ifndef MAKEFILE #include "../serial/openport.c" #include "../serial/closeport.c" #include "../serial/serial.c" #endif /*====================================================================* * program variables; *--------------------------------------------------------------------*/ typedef struct uart { struct _file_ port; char const * string; byte mode; uint64_t baudrate; byte databits; byte parity; byte stopbits; byte flowctrl; unsigned flags; } uart; /*====================================================================* * program variables; *--------------------------------------------------------------------*/ static const struct _term_ modes [] = { { "command", "2" }, { "transparent", "1" } }; static const struct _term_ paritybits [] = { { "even", "2" }, { "none", "0" }, { "odd", "1" } }; static const struct _term_ flowctrls [] = { { "none", "0" }, { "off", "0" }, { "on", "1" } }; /*====================================================================* * program constants; *--------------------------------------------------------------------*/ #define MODES (sizeof (modes) / sizeof (struct _term_)) #define PARITYBITS (sizeof (paritybits) / sizeof (struct _term_)) #define FLOWCTRLS (sizeof (flowctrls) / sizeof (struct _term_)) /*====================================================================* * * void at_command (struct uart * uart); * *--------------------------------------------------------------------*/ static void at_command (struct uart * uart) { clearcommand (); while (* uart->string) { insert (* uart->string++); } insert ('\r'); sendcommand (& uart->port, uart->flags); readcommand (& uart->port, uart->flags); return; } /*====================================================================* * * void at_wake (struct uart * uart); * * send wake command "+++" to enter command mode; * *--------------------------------------------------------------------*/ static void at_wake (struct uart * uart) { clearcommand (); insert ('+'); insert ('+'); insert ('+'); sendcommand (& uart->port, uart->flags); readcommand (& uart->port, uart->flags); mustbe ('O'); mustbe ('K'); mustbe ('\r'); return; } /*====================================================================* * * void atbr (struct uart * uart); * * set serial line parameters; * *--------------------------------------------------------------------*/ static void atbr (struct uart * uart) { clearcommand (); insert ('A'); insert ('T'); insert ('B'); insert ('R'); decode (& uart->mode, sizeof (uart->mode)); insert (','); uart->baudrate = HTOBE64 (uart->baudrate); decode (& uart->baudrate, sizeof (uart->baudrate)); uart->baudrate = BE64TOH (uart->baudrate); insert (','); decode (& uart->databits, sizeof (uart->databits)); insert (','); decode (& uart->parity, sizeof (uart->parity)); insert (','); decode (& uart->stopbits, sizeof (uart->stopbits)); insert (','); decode (& uart->flowctrl, sizeof (uart->flowctrl)); insert ('\r'); sendcommand (& uart->port, uart->flags); readcommand (& uart->port, uart->flags); mustbe ('O'); mustbe ('K'); mustbe ('\r'); return; } /*====================================================================* * * void manager (struct uart * uart); * * examine flagword in struct uart and perform requested operations * in the order that bits are tested; the order that bits are tested * may be changed as needed; * *--------------------------------------------------------------------*/ static void manager (struct uart * uart) { if (_anyset (uart->flags, UART_WAKE)) { at_wake (uart); } if (_anyset (uart->flags, UART_COMMAND)) { at_command (uart); } if (_anyset (uart->flags, UART_ATBR)) { atbr (uart); } return; } /*====================================================================* * * int main (int argc, char const * argv []); * *--------------------------------------------------------------------*/ int main (int argc, char const * argv []) { static char const * optv [] = { "B:c:D:F:m:p:P:q:S:uvw", "", "Qualcomm Atheros Serial Line Device Settings", "B n\tbaud rate is (n) [" LITERAL (UART_BAUDRATE) "]", "c s\tsend custom serial line command (s)", "D n\tuse (n) data bits [" LITERAL (UART_DATABITS) "]", "F n\tflow control is (n) [" LITERAL (UART_FLOWCTRL) "]", "m n\tcommand mode is (n)", "p f\tserial port is (f) [" DEVICE "]", "P n\tuse (n) parity bits [" LITERAL (UART_PARITY) "]", "q\tquiet mode", "S n\tuse (n) stop bits [" LITERAL (UART_STOPBITS) "]", "u\tforce default host port settings [115200 8N1]", "v\tverbose mode", "w\twake device [+++]", (char const *) (0) }; struct uart uart = { { 0, DEVICE }, (char *) (0), UART_MODE, UART_BAUDRATE, UART_DATABITS, UART_PARITY, UART_STOPBITS, UART_FLOWCTRL, 0 }; signed c; if (getenv (UART_PORT)) { uart.port.name = strdup (getenv (UART_PORT)); } while (~ (c = getoptv (argc, argv, optv))) { switch (c) { case 'B': _setbits (uart.flags, UART_ATBR); uart.baudrate = (uint64_t) (uintspec (optarg, 1, ULONG_MAX)); break; case 'c': _setbits (uart.flags, UART_COMMAND); uart.string = optarg; break; case 'D': _setbits (uart.flags, UART_ATBR); uart.databits = (byte) (uintspec (optarg, 7, 8)); break; case 'F': _setbits (uart.flags, UART_ATBR); uart.flowctrl = (byte) (uintspec (synonym (optarg, flowctrls, FLOWCTRLS), 0, UCHAR_MAX)); break; case 'm': _setbits (uart.flags, UART_ATBR); uart.mode = (byte) (uintspec (synonym (optarg, modes, MODES), 0, UCHAR_MAX)); break; case 'P': _setbits (uart.flags, UART_ATBR); uart.parity = (byte) (uintspec (synonym (optarg, paritybits, PARITYBITS), 0, UCHAR_MAX)); break; case 'q': _setbits (uart.flags, UART_SILENCE); break; case 'p': uart.port.name = optarg; break; case 'S': _setbits (uart.flags, UART_ATBR); uart.stopbits = (unsigned) (uintspec (optarg, 1, 2)); break; case 'u': _setbits (uart.flags, UART_DEFAULT); break; case 'v': _setbits (uart.flags, UART_VERBOSE); break; case 'w': _setbits (uart.flags, UART_WAKE); break; default: break; } } argc -= optind; argv += optind; if (argc) { error (1, ENOTSUP, ERROR_TOOMANY); } openport (& uart.port, uart.flags); manager (& uart); closeport (& uart.port); return (0); }