| 107 | } |
| 108 | |
| 109 | void xs_serial_constructor(xsMachine *the) |
| 110 | { |
| 111 | Serial serial; |
| 112 | int baud; |
| 113 | uint8_t hasReadable, hasWritable, format; |
| 114 | xsSlot *onReadable, *onWritable; |
| 115 | int err; |
| 116 | int uart_id = 0; |
| 117 | uint32_t transmit = UART_PIN_NO_CHANGE, receive = UART_PIN_NO_CHANGE; |
| 118 | uart_inst_t *uart; |
| 119 | |
| 120 | xsmcVars(1); |
| 121 | |
| 122 | if (xsmcGet(xsVar(0), xsArg(0), xsID_transmit)) { |
| 123 | transmit = builtinGetPin(the, &xsVar(0)); |
| 124 | if (!builtinIsPinFree(transmit)) |
| 125 | xsUnknownError("in use"); |
| 126 | } |
| 127 | |
| 128 | if (xsmcGet(xsVar(0), xsArg(0), xsID_receive)) { |
| 129 | receive = builtinGetPin(the, &xsVar(0)); |
| 130 | if (!builtinIsPinFree(receive)) |
| 131 | xsUnknownError("in use"); |
| 132 | } |
| 133 | else if (UART_PIN_NO_CHANGE == transmit) |
| 134 | xsUnknownError("invalid"); |
| 135 | |
| 136 | xsmcGet(xsVar(0), xsArg(0), xsID_baud); |
| 137 | baud = xsmcToInteger(xsVar(0)); |
| 138 | if ((baud <= 0) || (baud > 20000000)) |
| 139 | xsRangeError("invalid baud"); |
| 140 | |
| 141 | onReadable = builtinGetCallback(the, xsID_onReadable); |
| 142 | onWritable = builtinGetCallback(the, xsID_onWritable); |
| 143 | |
| 144 | hasReadable = (UART_PIN_NO_CHANGE != receive) && onReadable; |
| 145 | hasWritable = (UART_PIN_NO_CHANGE != transmit) && onWritable; |
| 146 | |
| 147 | builtinInitializeTarget(the); |
| 148 | |
| 149 | format = builtinInitializeFormat(the, kIOFormatBuffer); |
| 150 | if ((kIOFormatNumber != format) && (kIOFormatBuffer != format)) |
| 151 | xsRangeError("invalid format"); |
| 152 | |
| 153 | // check if port is in use |
| 154 | uart_id = uart_for_pin(transmit, receive); |
| 155 | if (-1 == uart_id) |
| 156 | xsUnknownError("invalid"); |
| 157 | |
| 158 | if (uart_in_use[uart_id]) |
| 159 | xsRangeError("port in use"); |
| 160 | |
| 161 | uart = uart_id ? (uart_inst_t*)uart1_hw : (uart_inst_t*)uart0_hw; |
| 162 | |
| 163 | uart_init(uart, baud); |
| 164 | uart_set_format(uart, 8, 1, UART_PARITY_NONE); |
| 165 | |
| 166 | serial = c_calloc((hasReadable || hasWritable) ? sizeof(SerialRecord) : offsetof(SerialRecord, the), 1); |
nothing calls this directly
no test coverage detected