mirror of
https://github.com/lowobservable/coax.git
synced 2026-02-26 17:13:24 +00:00
Initial commit
This commit is contained in:
13
LICENSE
Normal file
13
LICENSE
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright (c) 2019, Andrew Kay
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
14
README.md
Normal file
14
README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# coax-interface
|
||||
|
||||
> Hello mainframe!
|
||||
|
||||
coax-interface is a set of tools for interfacing with [IBM 3270](https://en.wikipedia.org/wiki/IBM_3270) type terminals.
|
||||
|
||||
## Contents
|
||||
|
||||
* [pycoax](pycoax) - Python IBM 3270 coaxial interface library
|
||||
* [interface1](interface1) - A serial attached Arduino interface using the National Semiconductor DP8340 and DP8341
|
||||
|
||||
## See Also
|
||||
|
||||
* [oec](https://github.com/lowobservable/oec) - An open replacement for the IBM 3174 Establishment Controller
|
||||
32
interface1/README.md
Normal file
32
interface1/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# interface1
|
||||
|
||||
A serial attached Arduino interface using the National Semiconductor DP8340 and DP8341.
|
||||
|
||||
## Schematic
|
||||
|
||||

|
||||
|
||||
## Materials
|
||||
|
||||
This interface requires an [Arduino Mega](https://store.arduino.cc/usa/mega-2560-r3).
|
||||
|
||||
Item | Quantity | Description | Reference | Part Number | Source
|
||||
:----:|---------:|-------------------------------|-----------|-------------------------------|----------------
|
||||
1 | 1 | IBM 3270 Protocol Transmitter | U1 | National Semiconductor DP8340 | eBay - Obsolete
|
||||
2 | 1 | IBM 3270 Protocol Receiver | U2 | National Semiconductor DP8341 | eBay - Obsolete
|
||||
3 | 1 | Quad RS-422 Line Driver | U3 | Texas Instruments DS3487 | eBay - Obsolete
|
||||
4 | 1 | Pulse Transformer - 1:1:1 | T1 | Pulse PE-5762 | eBay - Obsolete
|
||||
5 | 1 | Crystal - 18.867 MHz | Y1 | IQD LFXTAL057125 * | [Mouser](https://www.mouser.com/ProductDetail/IQD/LFXTAL057125Bulk?qs=%2Fha2pyFaduieSzBxw7UAJRZlCXjBZuIKPyofrMyYW7wVunrhuBMeiQd4MCF50LLz)
|
||||
6 | 2 | Resistor - 33 ohm | R2, R4 | | [Mouser](https://www.mouser.com/ProductDetail/Xicon/271-33-RC?qs=sGAEpiMZZMu61qfTUdNhGzoeXLT9qgk%252BV159XfY8c4Q%3D)
|
||||
7 | 1 | Resistor - 120 ohm | R6 | | [Mouser](https://www.mouser.com/ProductDetail/Xicon/271-120-RC?qs=sGAEpiMZZMu61qfTUdNhG7Of23Pr6gu8rRE5UXBJoDw%3D)
|
||||
8 | 2 | Resistor - 150 ohm | R1, R5 | | [Mouser](https://www.mouser.com/ProductDetail/Xicon/271-150-RC?qs=sGAEpiMZZMu61qfTUdNhG2ZzrN2CiS9nBcPQNrtAXYk%3D)
|
||||
9 | 1 | Resistor - 500 ohm | R7 | | [Mouser](https://www.mouser.com/ProductDetail/Xicon/271-499-RC?qs=sGAEpiMZZMu61qfTUdNhG6lpw21m8SOsvE2iEnaSg1s%3D)
|
||||
10 | 1 | Resistor - 510 ohm | R3 | | [Mouser](https://www.mouser.com/ProductDetail/Xicon/271-510-RC?qs=sGAEpiMZZMu61qfTUdNhG9RrhBeDi8B8FBVTnOgGHiw%3D)
|
||||
11 | 1 | Capacitor - 30pF | C1 | | [Mouser](https://www.mouser.com/ProductDetail/Vishay-Cera-Mite/561R10TCCQ30?qs=sGAEpiMZZMt1mVBmZSXTPNbSVgF1iSv4q4pBhPBLwuM%3D)
|
||||
12 | 1 | Coax Connector | J1 | |
|
||||
|
||||
\* - SMD
|
||||
|
||||
## Firmware
|
||||
|
||||
The firmware currently provides the ability to send commands and receive responses - it is designed to be used to implement a terminal controller, not to emulate a terminal.
|
||||
305
interface1/firmware/CoaxTransceiver.cpp
Normal file
305
interface1/firmware/CoaxTransceiver.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
// Copyright (c) 2019, Andrew Kay
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "CoaxTransceiver.h"
|
||||
|
||||
// Arduino Mega pins...
|
||||
//
|
||||
// Arduino Arduino Port Label DP8340N DP8341N
|
||||
// Pin and Mask Pin Pin
|
||||
// ---------|--------------|-----------------|---------|---------
|
||||
// 36 | PC1 | D2 | 10 | 14
|
||||
// 37 | PC0 | D3 | 9 | 15
|
||||
// 29 | PA7 | D4 | 8 | 16
|
||||
// 28 | PA6 | D5 | 7 | 17
|
||||
// 27 | PA5 | D6 | 6 | 18
|
||||
// 26 | PA4 | D7 | 5 | 19
|
||||
// 25 | PA3 | D8 | 4 | 20
|
||||
// 24 | PA2 | D9 | 3 | 21
|
||||
// 23 | PA1 | D10 | 2 | 22
|
||||
// 22 | PA0 | D11 | 1 | 23
|
||||
// --------- -------------- ----------------- --------- ---------
|
||||
// 8 | PH5 0x20 | REGISTER LOAD | 23 |
|
||||
// 9 | PH6 0x40 | REGISTERS FULL | 22 |
|
||||
// 10 | | AUTO RESPONSE | 21 |
|
||||
// 11 | | EVEN/ODD PARITY | 18 |
|
||||
// 12 | PB6 0x40 | PARITY CONTROL | 19 |
|
||||
// --------- -------------- ----------------- --------- ---------
|
||||
// 18* | PD3 0x08 | RECEIVER ACTIVE | | 7
|
||||
// 2 | PE4 0x10 | DATA AVAILABLE | | 10
|
||||
// 3 | PE5 0x20 | ERROR | | 8
|
||||
// 4 | | DATA CONTROL | | 5
|
||||
// 5 | PE3 0x08 | REGISTER READ | | 9
|
||||
// 6 | PH3 0x08 | OUTPUT CONTROL | | 11
|
||||
// 7 | PH4 0x10 | OUTPUT ENABLE | | 13
|
||||
//
|
||||
// * - Interrupt capable pin
|
||||
|
||||
#define TX_REGISTER_LOAD_PIN 8
|
||||
#define TX_REGISTERS_FULL_PIN 9
|
||||
#define TX_AUTO_RESPONSE_PIN 10
|
||||
#define TX_EVEN_ODD_PARITY_PIN 11
|
||||
#define TX_PARITY_CONTROL_PIN 12
|
||||
|
||||
#define RX_ACTIVE_PIN 18
|
||||
#define RX_DATA_AVAILABLE_PIN 2
|
||||
#define RX_ERROR_PIN 3
|
||||
#define RX_DATA_CONTROL_PIN 4
|
||||
#define RX_REGISTER_READ_PIN 5
|
||||
#define RX_OUTPUT_CONTROL_PIN 6
|
||||
#define RX_OUTPUT_ENABLE_PIN 7
|
||||
|
||||
#define RX_STATE_DISABLED 0
|
||||
#define RX_STATE_WAITING 1
|
||||
#define RX_STATE_RECEIVING 2
|
||||
#define RX_STATE_RECEIVED 3
|
||||
|
||||
static volatile uint8_t CoaxTransceiver::rxState;
|
||||
static volatile uint16_t *CoaxTransceiver::rxBuffer;
|
||||
static volatile size_t CoaxTransceiver::rxBufferSize;
|
||||
static volatile int /* ssize_t */ CoaxTransceiver::rxBufferCount;
|
||||
|
||||
#define NOP __asm__("nop\n\t")
|
||||
|
||||
static void CoaxTransceiver::setup() {
|
||||
// Configure data bus.
|
||||
dataBusSetup();
|
||||
|
||||
// Configure receiver (DP8341N).
|
||||
rxSetup();
|
||||
|
||||
// Configure transmitter (DP8340N).
|
||||
txSetup();
|
||||
}
|
||||
|
||||
static int /* ssize_t */ CoaxTransceiver::transmitReceive(uint16_t commandWord, uint8_t *dataBuffer, size_t dataBufferCount, uint16_t *receiveBuffer, size_t receiveBufferSize, uint16_t timeout) {
|
||||
int returnValue = transmit(commandWord, dataBuffer, dataBufferCount);
|
||||
|
||||
if (returnValue < 0) {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
return receive(receiveBuffer, receiveBufferSize, timeout);
|
||||
}
|
||||
|
||||
static void CoaxTransceiver::dataBusSetup() {
|
||||
DDRA = B00000000;
|
||||
DDRC = B00000000;
|
||||
}
|
||||
|
||||
static void CoaxTransceiver::rxSetup() {
|
||||
// Data Control - Amplifier Inputs
|
||||
pinMode(RX_DATA_CONTROL_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(RX_DATA_CONTROL_PIN, HIGH);
|
||||
|
||||
// Register Read
|
||||
pinMode(RX_REGISTER_READ_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(RX_REGISTER_READ_PIN, HIGH);
|
||||
|
||||
// Output Control - Data
|
||||
pinMode(RX_OUTPUT_CONTROL_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(RX_OUTPUT_CONTROL_PIN, HIGH);
|
||||
|
||||
// Output Enable - Active
|
||||
pinMode(RX_OUTPUT_ENABLE_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(RX_OUTPUT_ENABLE_PIN, HIGH);
|
||||
|
||||
// Receiver Active
|
||||
pinMode(RX_ACTIVE_PIN, INPUT);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(RX_ACTIVE_PIN), rxActiveInterrupt, RISING);
|
||||
|
||||
// Data Available
|
||||
pinMode(RX_DATA_AVAILABLE_PIN, INPUT);
|
||||
|
||||
// Error
|
||||
pinMode(RX_ERROR_PIN, INPUT);
|
||||
}
|
||||
|
||||
static void CoaxTransceiver::txSetup() {
|
||||
// Register Load
|
||||
pinMode(TX_REGISTER_LOAD_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(TX_REGISTER_LOAD_PIN, HIGH);
|
||||
|
||||
// Auto Response - Data
|
||||
pinMode(TX_AUTO_RESPONSE_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(TX_AUTO_RESPONSE_PIN, HIGH);
|
||||
|
||||
// Even/Odd Parity - Even
|
||||
pinMode(TX_EVEN_ODD_PARITY_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(TX_EVEN_ODD_PARITY_PIN, HIGH);
|
||||
|
||||
// Parity Control - Data
|
||||
pinMode(TX_PARITY_CONTROL_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(TX_PARITY_CONTROL_PIN, HIGH);
|
||||
|
||||
// Registers Full
|
||||
pinMode(TX_REGISTERS_FULL_PIN, INPUT);
|
||||
}
|
||||
|
||||
static int /* ssize_t */ CoaxTransceiver::transmit(uint16_t commandWord, uint8_t *dataBuffer, size_t dataCount) {
|
||||
// Ensure receiver is inactive.
|
||||
if (rxState != RX_STATE_DISABLED) {
|
||||
return ERROR_TX_RECEIVER_ACTIVE;
|
||||
}
|
||||
|
||||
if ((PIND & 0x8) == 0x8) {
|
||||
return ERROR_TX_RECEIVER_ACTIVE;
|
||||
}
|
||||
|
||||
// Disable interrupts.
|
||||
noInterrupts();
|
||||
|
||||
// Disable receiver output.
|
||||
PORTH &= ~0x10; // RX Output Enable - Low (Disable)
|
||||
|
||||
// Configure data bus for output.
|
||||
DDRA = B11111111;
|
||||
DDRC = B00000011;
|
||||
|
||||
// Send command word - we make an assumption here that TX_REGISTERS_FULL is not set.
|
||||
PORTC = (PINC & 0xfc) | ((commandWord >> 8) & 0x3);
|
||||
PORTA = commandWord & 0xff;
|
||||
|
||||
PORTH &= ~0x20; // TX Register Load - Low (Load)
|
||||
PORTH |= 0x20; // TX Register Load - High
|
||||
|
||||
// Send data - offload parity computation to DP8340.
|
||||
if (dataCount > 0) {
|
||||
// Enable transmitter parity calculation.
|
||||
PORTB &= ~0x40; // TX Parity Control - Low
|
||||
|
||||
for (int index = 0; index < dataCount; index++) {
|
||||
// Wait while TX Registers Full is high.
|
||||
while ((PINH & 0x40) == 0x40) {
|
||||
NOP;
|
||||
}
|
||||
|
||||
uint8_t data = dataBuffer[index];
|
||||
|
||||
PORTC = (PINC & 0xfc) | ((data >> 6) & 0x3);
|
||||
PORTA = (data << 2);
|
||||
|
||||
PORTH &= ~0x20; // TX Register Load - Low (Load)
|
||||
PORTH |= 0x20; // TX Register Load - High
|
||||
}
|
||||
|
||||
// Disable transmitter parity calculation.
|
||||
PORTB |= 0x40; // TX Parity Control - High
|
||||
}
|
||||
|
||||
// Configure data bus for input.
|
||||
DDRA = B00000000;
|
||||
DDRC = B00000000;
|
||||
|
||||
// Enable receiver output.
|
||||
PORTH |= 0x10; // RX Output Enable - High (Enable)
|
||||
|
||||
// Enable interrupts.
|
||||
interrupts();
|
||||
|
||||
return dataCount;
|
||||
}
|
||||
|
||||
static int /* ssize_t */ CoaxTransceiver::receive(uint16_t *buffer, size_t bufferSize, uint16_t timeout) {
|
||||
rxBuffer = buffer;
|
||||
rxBufferSize = bufferSize;
|
||||
|
||||
rxState = RX_STATE_WAITING;
|
||||
|
||||
if (timeout > 0) {
|
||||
unsigned long startTime = millis();
|
||||
|
||||
while (rxState == RX_STATE_WAITING) {
|
||||
// https://www.forward.com.au/pfod/ArduinoProgramming/TimingDelaysInArduino.html#unsigned
|
||||
if ((millis() - startTime) > timeout) {
|
||||
rxState = RX_STATE_DISABLED;
|
||||
return ERROR_RX_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (rxState != RX_STATE_RECEIVED) {
|
||||
NOP;
|
||||
}
|
||||
|
||||
rxState = RX_STATE_DISABLED;
|
||||
|
||||
return rxBufferCount;
|
||||
}
|
||||
|
||||
static void CoaxTransceiver::rxActiveInterrupt() {
|
||||
uint16_t data;
|
||||
uint8_t mask;
|
||||
|
||||
if (rxState == RX_STATE_DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
rxState = RX_STATE_RECEIVING;
|
||||
|
||||
rxBufferCount = 0;
|
||||
|
||||
do {
|
||||
while ((PINE & 0x30) == 0) {
|
||||
NOP;
|
||||
}
|
||||
|
||||
if (/* ERROR */ (PINE & 0x20) == 0x20) {
|
||||
mask = 0x20;
|
||||
|
||||
PORTH &= ~0x8; // Output Control - Low (Error)
|
||||
PORTE &= ~0x8; // Register Read - Low
|
||||
|
||||
// Read and mark as error.
|
||||
data = (((PINC & 0x3) | 0x80) << 8) | PINA;
|
||||
|
||||
PORTE |= 0x8; // Register Read - High
|
||||
PORTH |= 0x8; // Output Control - High (Data)
|
||||
} else if (/* DATA AVAILABLE */ (PINE & 0x10) == 0x10) {
|
||||
mask = 0x10;
|
||||
|
||||
PORTE &= ~0x8; // Register Read - Low
|
||||
|
||||
// Read.
|
||||
data = ((PINC & 0x3) << 8) | PINA;
|
||||
|
||||
PORTE |= 0x8; // Register Read - High
|
||||
}
|
||||
|
||||
if (rxBufferCount >= rxBufferSize) {
|
||||
rxBufferCount = ERROR_RX_OVERFLOW;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
rxBuffer[rxBufferCount++] = data;
|
||||
|
||||
while ((PINE & mask) == mask) {
|
||||
NOP;
|
||||
}
|
||||
} while ((PIND & 0x8) == 0x8);
|
||||
|
||||
EXIT:
|
||||
rxState = RX_STATE_RECEIVED;
|
||||
}
|
||||
40
interface1/firmware/CoaxTransceiver.h
Normal file
40
interface1/firmware/CoaxTransceiver.h
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2019, Andrew Kay
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#define ERROR_TX_RECEIVER_ACTIVE -1
|
||||
#define ERROR_RX_TIMEOUT -2
|
||||
#define ERROR_RX_OVERFLOW -3
|
||||
|
||||
class CoaxTransceiver {
|
||||
public:
|
||||
static void setup();
|
||||
static int /* ssize_t */ transmitReceive(uint16_t commandWord, uint8_t *dataBuffer, size_t dataBufferCount, uint16_t *receiveBuffer, size_t receiveBufferSize, uint16_t timeout);
|
||||
|
||||
private:
|
||||
static void dataBusSetup();
|
||||
static void rxSetup();
|
||||
static void txSetup();
|
||||
static int /* ssize_t */ transmit(uint16_t commandWord, uint8_t *dataBuffer, size_t dataCount);
|
||||
static int /* ssize_t */ receive(uint16_t *buffer, size_t bufferSize, uint16_t timeout);
|
||||
static void rxActiveInterrupt();
|
||||
|
||||
static volatile uint8_t rxState;
|
||||
static volatile uint16_t *rxBuffer;
|
||||
static volatile size_t rxBufferSize;
|
||||
static volatile int /* ssize_t */ rxBufferCount;
|
||||
};
|
||||
304
interface1/firmware/firmware.ino
Normal file
304
interface1/firmware/firmware.ino
Normal file
@@ -0,0 +1,304 @@
|
||||
// Copyright (c) 2019, Andrew Kay
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "CoaxTransceiver.h"
|
||||
|
||||
#define COMMAND_RESET 0x01
|
||||
#define COMMAND_EXECUTE 0x02
|
||||
#define COMMAND_EXECUTE_OFFLOAD 0x03
|
||||
|
||||
#define ERROR_INVALID_MESSAGE 1
|
||||
#define ERROR_UNKNOWN_COMMAND 2
|
||||
#define ERROR_UNKNOWN_OFFLOAD_COMMAND 3
|
||||
|
||||
#define UNPACK_DATA_WORD(w) (uint8_t) ((w >> 2) & 0xff)
|
||||
|
||||
void handleResetCommand(uint8_t *buffer, int bufferCount) {
|
||||
uint8_t response[] = { 0x01, 0x00, 0x00, 0x01 };
|
||||
|
||||
sendMessage(response, 4);
|
||||
}
|
||||
|
||||
void handleExecuteCommand(uint8_t *buffer, int bufferCount) {
|
||||
if (bufferCount < 6) {
|
||||
sendErrorMessage(ERROR_INVALID_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t commandWord = (buffer[0] << 8) | buffer[1];
|
||||
uint16_t receiveCount = (buffer[2] << 8) | buffer[3];
|
||||
uint16_t timeout = (buffer[4] << 8) | buffer[5];
|
||||
|
||||
uint8_t *dataBuffer = buffer + 6;
|
||||
uint16_t dataBufferCount = bufferCount - 6;
|
||||
|
||||
uint16_t *receiveBuffer = (uint16_t *) (buffer + 2);
|
||||
|
||||
bufferCount = CoaxTransceiver::transmitReceive(commandWord, dataBuffer, dataBufferCount, receiveBuffer, receiveCount, timeout);
|
||||
|
||||
if (bufferCount < 0) {
|
||||
sendErrorMessage(100 + ((-1) * bufferCount));
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the response message.
|
||||
buffer[1] = 0x01;
|
||||
|
||||
bufferCount = 1 + (bufferCount * 2);
|
||||
|
||||
sendMessage(buffer + 1, bufferCount);
|
||||
}
|
||||
|
||||
void handleExecuteOffloadCommand(uint8_t *buffer, int bufferCount) {
|
||||
if (bufferCount < 1) {
|
||||
sendErrorMessage(ERROR_INVALID_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t command = buffer[0];
|
||||
|
||||
if (command == 0x01) {
|
||||
handleOffloadLoadAddressCounter(buffer + 1, bufferCount - 1);
|
||||
} else if (command == 0x02) {
|
||||
handleOffloadWrite(buffer + 1, bufferCount - 1);
|
||||
} else {
|
||||
sendErrorMessage(ERROR_UNKNOWN_OFFLOAD_COMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
void handleOffloadLoadAddressCounter(uint8_t *buffer, int bufferCount) {
|
||||
uint16_t response;
|
||||
|
||||
if (bufferCount < 2) {
|
||||
sendErrorMessage(ERROR_INVALID_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t hi = buffer[0];
|
||||
uint8_t lo = buffer[1];
|
||||
|
||||
// TODO: error handling...
|
||||
CoaxTransceiver::transmitReceive(/* LOAD_ADDRESS_COUNTER_HI */ 0x11, &hi, 1, &response, 1, 0);
|
||||
CoaxTransceiver::transmitReceive(/* LOAD_ADDRESS_COUNTER_LO */ 0x51, &lo, 1, &response, 1, 0);
|
||||
|
||||
// Send the response message.
|
||||
uint8_t message[] = { 0x01 };
|
||||
|
||||
sendMessage(message, 1);
|
||||
}
|
||||
|
||||
void handleOffloadWrite(uint8_t *buffer, int bufferCount) {
|
||||
uint16_t response;
|
||||
|
||||
if (bufferCount < 5) {
|
||||
sendErrorMessage(ERROR_INVALID_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t addressHi = buffer[0];
|
||||
uint8_t addressLo = buffer[1];
|
||||
bool restoreOriginalAddress = buffer[2];
|
||||
uint16_t repeatCount = (buffer[3] << 8) | buffer[4];
|
||||
|
||||
uint8_t *dataBuffer = buffer + 5;
|
||||
uint16_t dataBufferCount = bufferCount - 5;
|
||||
|
||||
if (dataBufferCount < 1) {
|
||||
sendErrorMessage(ERROR_INVALID_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Repeat the provided data if applicable.
|
||||
if (repeatCount > 0) {
|
||||
uint16_t dataBufferIndex = dataBufferCount;
|
||||
|
||||
for (int repeatIndex = 0; repeatIndex < repeatCount; repeatIndex++) {
|
||||
for (int index = 0; index < dataBufferCount; index++) {
|
||||
dataBuffer[dataBufferIndex++] = dataBuffer[index];
|
||||
}
|
||||
}
|
||||
|
||||
dataBufferCount *= (repeatCount + 1);
|
||||
}
|
||||
|
||||
// Store original address if applicable.
|
||||
uint8_t originalAddressHi;
|
||||
uint8_t originalAddressLo;
|
||||
|
||||
if (restoreOriginalAddress) {
|
||||
CoaxTransceiver::transmitReceive(/* READ_ADDRESS_COUNTER_HI */ 0x15, NULL, 0, &response, 1, 0);
|
||||
|
||||
originalAddressHi = UNPACK_DATA_WORD(response);
|
||||
|
||||
CoaxTransceiver::transmitReceive(/* READ_ADDRESS_COUNTER_LO */ 0x55, NULL, 0, &response, 1, 0);
|
||||
|
||||
originalAddressLo = UNPACK_DATA_WORD(response);
|
||||
}
|
||||
|
||||
// Move to start address if applicable.
|
||||
if (!(addressHi == 0xff && addressLo == 0xff)) {
|
||||
CoaxTransceiver::transmitReceive(/* LOAD_ADDRESS_COUNTER_HI */ 0x11, &addressHi, 1, &response, 1, 0);
|
||||
CoaxTransceiver::transmitReceive(/* LOAD_ADDRESS_COUNTER_LO */ 0x51, &addressLo, 1, &response, 1, 0);
|
||||
}
|
||||
|
||||
// Write buffer.
|
||||
CoaxTransceiver::transmitReceive(/* WRITE_DATA */ 0x31, dataBuffer, dataBufferCount, &response, 1, 0);
|
||||
|
||||
// Restore original address if applicable.
|
||||
if (restoreOriginalAddress) {
|
||||
CoaxTransceiver::transmitReceive(/* LOAD_ADDRESS_COUNTER_HI */ 0x11, &originalAddressHi, 1, &response, 1, 0);
|
||||
CoaxTransceiver::transmitReceive(/* LOAD_ADDRESS_COUNTER_LO */ 0x51, &originalAddressLo, 1, &response, 1, 0);
|
||||
}
|
||||
|
||||
// Send the response message.
|
||||
uint8_t message[] = { 0x01 };
|
||||
|
||||
sendMessage(message, 1);
|
||||
}
|
||||
|
||||
void handleMessage(uint8_t *buffer, int bufferCount) {
|
||||
if (bufferCount < 1) {
|
||||
sendErrorMessage(ERROR_INVALID_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t command = buffer[0];
|
||||
|
||||
if (command == COMMAND_RESET) {
|
||||
handleResetCommand(buffer + 1, bufferCount - 1);
|
||||
} else if (command == COMMAND_EXECUTE) {
|
||||
handleExecuteCommand(buffer + 1, bufferCount - 1);
|
||||
} else if (command == COMMAND_EXECUTE_OFFLOAD) {
|
||||
handleExecuteOffloadCommand(buffer + 1, bufferCount - 1);
|
||||
} else {
|
||||
sendErrorMessage(ERROR_UNKNOWN_COMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
#define FRAME_END 0xc0
|
||||
#define FRAME_ESCAPE 0xdb
|
||||
#define FRAME_ESCAPE_END 0xdc
|
||||
#define FRAME_ESCAPE_ESCAPE 0xdd
|
||||
|
||||
enum {
|
||||
WAIT_START,
|
||||
DATA,
|
||||
ESCAPE
|
||||
} frameState;
|
||||
|
||||
#define FRAME_BUFFER_SIZE (25 * 80) + 32
|
||||
|
||||
uint8_t frameBuffer[FRAME_BUFFER_SIZE];
|
||||
int frameBufferCount = 0;
|
||||
|
||||
void handleFrame(uint8_t *buffer, int bufferCount) {
|
||||
if (bufferCount < 4) {
|
||||
sendErrorMessage(ERROR_INVALID_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
int count = (buffer[0] << 8) | buffer[1];
|
||||
|
||||
if (bufferCount - 4 != count) {
|
||||
sendErrorMessage(ERROR_INVALID_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
handleMessage(buffer + 2, count);
|
||||
}
|
||||
|
||||
void sendMessage(uint8_t *buffer, int bufferCount) {
|
||||
Serial.write((char) FRAME_END);
|
||||
|
||||
// Write the length.
|
||||
Serial.write((char) bufferCount >> 8);
|
||||
Serial.write((char) bufferCount);
|
||||
|
||||
for (int index = 0; index < bufferCount; index++) {
|
||||
if (buffer[index] == FRAME_END) {
|
||||
Serial.write((char) FRAME_ESCAPE);
|
||||
Serial.write((char) FRAME_ESCAPE_END);
|
||||
} else if (buffer[index] == FRAME_ESCAPE) {
|
||||
Serial.write((char) FRAME_ESCAPE);
|
||||
Serial.write((char) FRAME_ESCAPE_ESCAPE);
|
||||
} else {
|
||||
Serial.write((char) buffer[index]);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the placeholder for checksum.
|
||||
Serial.write((char) 0x00);
|
||||
Serial.write((char) 0x00);
|
||||
|
||||
Serial.write((char) FRAME_END);
|
||||
|
||||
Serial.flush();
|
||||
}
|
||||
|
||||
void sendErrorMessage(uint8_t code) {
|
||||
uint8_t message[] = { 0x02, code };
|
||||
|
||||
sendMessage(message, 2);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// Configure serial port and state machine.
|
||||
Serial.begin(115200);
|
||||
|
||||
frameState = WAIT_START;
|
||||
|
||||
while (Serial.available() > 0) {
|
||||
Serial.read();
|
||||
}
|
||||
|
||||
// Configure the transceiver.
|
||||
CoaxTransceiver::setup();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.available() > 0) {
|
||||
uint8_t byte = Serial.read();
|
||||
|
||||
if (frameState == WAIT_START) {
|
||||
if (byte == FRAME_END) {
|
||||
frameState = DATA;
|
||||
}
|
||||
} else if (frameState == DATA) {
|
||||
if (byte == FRAME_END) {
|
||||
if (frameBufferCount > 0) {
|
||||
handleFrame(frameBuffer, frameBufferCount);
|
||||
}
|
||||
|
||||
frameBufferCount = 0;
|
||||
} else if (byte == FRAME_ESCAPE) {
|
||||
frameState = ESCAPE;
|
||||
} else {
|
||||
// TODO: overflow...
|
||||
frameBuffer[frameBufferCount++] = byte;
|
||||
}
|
||||
} else if (frameState == ESCAPE) {
|
||||
if (byte == FRAME_ESCAPE_END) {
|
||||
// TODO: overflow...
|
||||
frameBuffer[frameBufferCount++] = FRAME_END;
|
||||
} else if (byte == FRAME_ESCAPE_ESCAPE) {
|
||||
// TODO: overflow...
|
||||
frameBuffer[frameBufferCount++] = FRAME_ESCAPE;
|
||||
}
|
||||
|
||||
frameState = DATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
256
interface1/hardware/hardware-cache.lib
Normal file
256
interface1/hardware/hardware-cache.lib
Normal file
@@ -0,0 +1,256 @@
|
||||
EESchema-LIBRARY Version 2.4
|
||||
#encoding utf-8
|
||||
#
|
||||
# Connector_Conn_Coaxial
|
||||
#
|
||||
DEF Connector_Conn_Coaxial J 0 40 Y N 1 F N
|
||||
F0 "J" 10 120 50 H V C CNN
|
||||
F1 "Connector_Conn_Coaxial" 115 0 50 V V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
*BNC*
|
||||
*SMA*
|
||||
*SMB*
|
||||
*SMC*
|
||||
*Cinch*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
A -2 0 71 1636 0 0 1 10 N -70 20 70 0
|
||||
A -1 0 71 0 -1638 0 1 10 N 70 0 -70 -20
|
||||
C 0 0 20 0 1 8 N
|
||||
P 2 0 1 0 -100 0 -20 0 N
|
||||
P 2 0 1 0 0 -100 0 -70 N
|
||||
X In 1 -200 0 100 R 50 50 1 1 P
|
||||
X Ext 2 0 -200 100 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Device_C
|
||||
#
|
||||
DEF Device_C C 0 10 N Y 1 F N
|
||||
F0 "C" 25 100 50 H V L CNN
|
||||
F1 "Device_C" 25 -100 50 H V L CNN
|
||||
F2 "" 38 -150 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
C_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
P 2 0 1 20 -80 -30 80 -30 N
|
||||
P 2 0 1 20 -80 30 80 30 N
|
||||
X ~ 1 0 150 110 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 110 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Device_Crystal
|
||||
#
|
||||
DEF Device_Crystal Y 0 40 N N 1 F N
|
||||
F0 "Y" 0 150 50 H V C CNN
|
||||
F1 "Device_Crystal" 0 -150 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Crystal*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -45 100 45 -100 0 1 12 N
|
||||
P 2 0 1 0 -100 0 -75 0 N
|
||||
P 2 0 1 20 -75 -50 -75 50 N
|
||||
P 2 0 1 20 75 -50 75 50 N
|
||||
P 2 0 1 0 100 0 75 0 N
|
||||
X 1 1 -150 0 50 R 50 50 1 1 P
|
||||
X 2 2 150 0 50 L 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Device_R_US
|
||||
#
|
||||
DEF Device_R_US R 0 0 N Y 1 F N
|
||||
F0 "R" 100 0 50 V V C CNN
|
||||
F1 "Device_R_US" -100 0 50 V V C CNN
|
||||
F2 "" 40 -10 50 V I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
R_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
P 2 0 1 0 0 -90 0 -100 N
|
||||
P 2 0 1 0 0 90 0 100 N
|
||||
P 5 0 1 0 0 -30 40 -45 0 -60 -40 -75 0 -90 N
|
||||
P 5 0 1 0 0 30 40 15 0 0 -40 -15 0 -30 N
|
||||
P 5 0 1 0 0 90 40 75 0 60 -40 45 0 30 N
|
||||
X ~ 1 0 150 50 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 50 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# library_DP8340
|
||||
#
|
||||
DEF library_DP8340 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 -100 50 H V C CNN
|
||||
F1 "library_DP8340" 0 100 50 H V C CNN
|
||||
F2 "MODULE" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
S -450 -750 450 750 1 0 0 N
|
||||
X DI11 1 -750 550 300 R 50 50 1 1 U
|
||||
X DI2 10 -750 -350 300 R 50 50 1 1 U
|
||||
X CLK_OUT 11 -750 -450 300 R 50 50 1 1 U
|
||||
X GND 12 -750 -550 300 R 50 50 1 1 U
|
||||
X X1 13 750 -550 300 L 50 50 1 1 U
|
||||
X X2 14 750 -450 300 L 50 50 1 1 U
|
||||
X DATA_DLY 15 750 -350 300 L 50 50 1 1 U
|
||||
X DATA_OUT1 16 750 -250 300 L 50 50 1 1 U
|
||||
X DATA_OUT2 17 750 -150 300 L 50 50 1 1 U
|
||||
X EVEN_ODD 18 750 -50 300 L 50 50 1 1 U
|
||||
X PARITY_CTL 19 750 50 300 L 50 50 1 1 U
|
||||
X DI10 2 -750 450 300 R 50 50 1 1 U
|
||||
X TX_ACTIVE 20 750 150 300 L 50 50 1 1 U
|
||||
X AUTO_RESP 21 750 250 300 L 50 50 1 1 U
|
||||
X REG_FULL 22 750 350 300 L 50 50 1 1 U
|
||||
X REG_LOAD 23 750 450 300 L 50 50 1 1 U
|
||||
X VCC 24 750 550 300 L 50 50 1 1 U
|
||||
X DI9 3 -750 350 300 R 50 50 1 1 U
|
||||
X DI8 4 -750 250 300 R 50 50 1 1 U
|
||||
X DI7 5 -750 150 300 R 50 50 1 1 U
|
||||
X DI6 6 -750 50 300 R 50 50 1 1 U
|
||||
X DI5 7 -750 -50 300 R 50 50 1 1 U
|
||||
X DI4 8 -750 -150 300 R 50 50 1 1 U
|
||||
X DI3 9 -750 -250 300 R 50 50 1 1 U
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# library_DP8341
|
||||
#
|
||||
DEF library_DP8341 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 -100 50 H V C CNN
|
||||
F1 "library_DP8341" 0 100 50 H V C CNN
|
||||
F2 "MODULE" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
S -450 -750 450 750 1 0 0 N
|
||||
X RX_DISABLE 1 -750 550 300 R 50 50 1 1 U
|
||||
X DATA_AVAIL 10 -750 -350 300 R 50 50 1 1 U
|
||||
X OUTPUT_CTL 11 -750 -450 300 R 50 50 1 1 U
|
||||
X GND 12 -750 -550 300 R 50 50 1 1 U
|
||||
X OUTPUT_EN 13 750 -550 300 L 50 50 1 1 U
|
||||
X DO2 14 750 -450 300 L 50 50 1 1 U
|
||||
X DO3 15 750 -350 300 L 50 50 1 1 U
|
||||
X DO4 16 750 -250 300 L 50 50 1 1 U
|
||||
X DO5 17 750 -150 300 L 50 50 1 1 U
|
||||
X DO6 18 750 -50 300 L 50 50 1 1 U
|
||||
X DO7 19 750 50 300 L 50 50 1 1 U
|
||||
X +AMP_IN 2 -750 450 300 R 50 50 1 1 U
|
||||
X DO8 20 750 150 300 L 50 50 1 1 U
|
||||
X DO9 21 750 250 300 L 50 50 1 1 U
|
||||
X DO10 22 750 350 300 L 50 50 1 1 U
|
||||
X DO11 23 750 450 300 L 50 50 1 1 U
|
||||
X VCC 24 750 550 300 L 50 50 1 1 U
|
||||
X -AMP_IN 3 -750 350 300 R 50 50 1 1 U
|
||||
X DATA 4 -750 250 300 R 50 50 1 1 U
|
||||
X DATA_CTL 5 -750 150 300 R 50 50 1 1 U
|
||||
X CLOCK 6 -750 50 300 R 50 50 1 1 U
|
||||
X RX_ACTIVE 7 -750 -50 300 R 50 50 1 1 U
|
||||
X ERROR 8 -750 -150 300 R 50 50 1 1 U
|
||||
X REG_READ 9 -750 -250 300 R 50 50 1 1 U
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# library_DS3487
|
||||
#
|
||||
DEF library_DS3487 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 -100 50 H V C CNN
|
||||
F1 "library_DS3487" 0 100 50 H V C CNN
|
||||
F2 "MODULE" 0 0 50 H I C CNN
|
||||
F3 "DOCUMENTATION" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
S -450 -550 450 550 1 0 0 N
|
||||
X PIN1 1 -750 350 300 R 50 50 1 1 U
|
||||
X PIN10 10 750 -250 300 L 50 50 1 1 U
|
||||
X PIN11 11 750 -150 300 L 50 50 1 1 U
|
||||
X PIN12 12 750 -50 300 L 50 50 1 1 U
|
||||
X PIN13 13 750 50 300 L 50 50 1 1 U
|
||||
X PIN14 14 750 150 300 L 50 50 1 1 U
|
||||
X PIN15 15 750 250 300 L 50 50 1 1 U
|
||||
X PIN16 16 750 350 300 L 50 50 1 1 U
|
||||
X PIN2 2 -750 250 300 R 50 50 1 1 U
|
||||
X PIN3 3 -750 150 300 R 50 50 1 1 U
|
||||
X PIN4 4 -750 50 300 R 50 50 1 1 U
|
||||
X PIN5 5 -750 -50 300 R 50 50 1 1 U
|
||||
X PIN6 6 -750 -150 300 R 50 50 1 1 U
|
||||
X PIN7 7 -750 -250 300 R 50 50 1 1 U
|
||||
X PIN8 8 -750 -350 300 R 50 50 1 1 U
|
||||
X PIN9 9 750 -350 300 L 50 50 1 1 U
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# library_xxxx
|
||||
#
|
||||
DEF library_xxxx T 0 20 Y N 1 F N
|
||||
F0 "T" 0 550 50 H V C CNN
|
||||
F1 "library_xxxx" 0 -550 50 H V C CNN
|
||||
F2 "Transformer_SMD:Pulse_PA2002NL-PA2008NL-PA2009NL" 0 0 50 H I C CNN
|
||||
F3 "" -300 0 50 H I C CNN
|
||||
DRAW
|
||||
A -100 -90 30 900 -900 0 1 8 N -100 -60 -100 -120
|
||||
A -100 -30 30 900 -900 0 1 8 N -100 0 -100 -60
|
||||
A -100 30 30 900 -900 0 1 8 N -100 60 -100 0
|
||||
A 100 -390 30 -900 900 0 1 8 N 100 -420 100 -360
|
||||
A 100 -330 30 -900 900 0 1 8 N 100 -360 100 -300
|
||||
A 100 -270 30 -900 900 0 1 8 N 100 -300 100 -240
|
||||
A 100 -210 30 -900 900 0 1 8 N 100 -240 100 -180
|
||||
A 100 210 30 -900 900 0 1 8 N 100 180 100 240
|
||||
A 100 270 30 -900 900 0 1 8 N 100 240 100 300
|
||||
A 100 330 30 -900 900 0 1 8 N 100 300 100 360
|
||||
A 100 390 30 -900 900 0 1 8 N 100 360 100 420
|
||||
A -100 90 30 900 -900 1 1 8 N -100 120 -100 60
|
||||
C -100 90 10 0 1 0 F
|
||||
C 100 -210 10 0 1 0 F
|
||||
C 100 390 10 0 1 0 F
|
||||
P 2 0 1 0 -100 -120 -100 -200 N
|
||||
P 2 0 1 0 -100 200 -100 120 N
|
||||
P 2 0 1 0 -25 425 -25 -425 N
|
||||
P 2 0 1 0 25 425 25 -425 N
|
||||
P 2 0 1 0 100 -420 100 -500 N
|
||||
P 2 0 1 0 100 -100 100 -180 N
|
||||
P 2 0 1 0 100 180 100 100 N
|
||||
P 2 0 1 0 100 500 100 420 N
|
||||
X ~ 1 200 500 100 L 50 50 1 1 P
|
||||
X ~ 2 200 100 100 L 50 50 1 1 P
|
||||
X ~ 3 -200 200 100 R 50 50 1 1 P
|
||||
X ~ 4 -200 -200 100 R 50 50 1 1 P
|
||||
X ~ 5 200 -100 100 L 50 50 1 1 P
|
||||
X ~ 6 200 -500 100 L 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# power_GND
|
||||
#
|
||||
DEF power_GND #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -250 50 H I C CNN
|
||||
F1 "power_GND" 0 -150 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
|
||||
X GND 1 0 0 0 D 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# power_VCC
|
||||
#
|
||||
DEF power_VCC #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -150 50 H I C CNN
|
||||
F1 "power_VCC" 0 150 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
C 0 75 25 0 1 0 N
|
||||
P 2 0 1 0 0 0 0 50 N
|
||||
X VCC 1 0 0 0 U 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
3
interface1/hardware/hardware-rescue.dcm
Normal file
3
interface1/hardware/hardware-rescue.dcm
Normal file
@@ -0,0 +1,3 @@
|
||||
EESchema-DOCLIB Version 2.0
|
||||
#
|
||||
#End Doc Library
|
||||
557
interface1/hardware/hardware.bak
Normal file
557
interface1/hardware/hardware.bak
Normal file
@@ -0,0 +1,557 @@
|
||||
EESchema Schematic File Version 4
|
||||
EELAYER 29 0
|
||||
EELAYER END
|
||||
$Descr USLetter 11000 8500
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title ""
|
||||
Date ""
|
||||
Rev ""
|
||||
Comp ""
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 "Based on the typical application from the DP8340 and DP8341 data sheets"
|
||||
$EndDescr
|
||||
$Comp
|
||||
L library:DP8340 U1
|
||||
U 1 1 5CFF4259
|
||||
P 4200 2500
|
||||
F 0 "U1" H 4200 3415 50 0000 C CNN
|
||||
F 1 "DP8340" H 4200 3324 50 0000 C CNN
|
||||
F 2 "MODULE" H 4200 2500 50 0001 C CNN
|
||||
F 3 "" H 4200 2500 50 0001 C CNN
|
||||
1 4200 2500
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R7
|
||||
U 1 1 5D005C33
|
||||
P 5450 3200
|
||||
F 0 "R7" H 5518 3246 50 0000 L CNN
|
||||
F 1 "500" H 5518 3155 50 0000 L CNN
|
||||
F 2 "" V 5490 3190 50 0001 C CNN
|
||||
F 3 "~" H 5450 3200 50 0001 C CNN
|
||||
1 5450 3200
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:Crystal Y1
|
||||
U 1 1 5D0074D0
|
||||
P 4950 3200
|
||||
F 0 "Y1" V 4996 3069 50 0000 R CNN
|
||||
F 1 "Crystal" V 4905 3069 50 0000 R CNN
|
||||
F 2 "" H 4950 3200 50 0001 C CNN
|
||||
F 3 "~" H 4950 3200 50 0001 C CNN
|
||||
1 4950 3200
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L power:VCC #PWR?
|
||||
U 1 1 5D0081F3
|
||||
P 5200 3750
|
||||
F 0 "#PWR?" H 5200 3600 50 0001 C CNN
|
||||
F 1 "VCC" H 5218 3923 50 0000 C CNN
|
||||
F 2 "" H 5200 3750 50 0001 C CNN
|
||||
F 3 "" H 5200 3750 50 0001 C CNN
|
||||
1 5200 3750
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R1
|
||||
U 1 1 5D01411B
|
||||
P 8300 1800
|
||||
F 0 "R1" V 8505 1800 50 0000 C CNN
|
||||
F 1 "150" V 8414 1800 50 0000 C CNN
|
||||
F 2 "" V 8340 1790 50 0001 C CNN
|
||||
F 3 "~" H 8300 1800 50 0001 C CNN
|
||||
1 8300 1800
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R2
|
||||
U 1 1 5D014636
|
||||
P 8300 2200
|
||||
F 0 "R2" V 8505 2200 50 0000 C CNN
|
||||
F 1 "33" V 8414 2200 50 0000 C CNN
|
||||
F 2 "" V 8340 2190 50 0001 C CNN
|
||||
F 3 "~" H 8300 2200 50 0001 C CNN
|
||||
1 8300 2200
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R4
|
||||
U 1 1 5D01DB0F
|
||||
P 8300 2600
|
||||
F 0 "R4" V 8505 2600 50 0000 C CNN
|
||||
F 1 "33" V 8414 2600 50 0000 C CNN
|
||||
F 2 "" V 8340 2590 50 0001 C CNN
|
||||
F 3 "~" H 8300 2600 50 0001 C CNN
|
||||
1 8300 2600
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R5
|
||||
U 1 1 5D01DE87
|
||||
P 8300 3000
|
||||
F 0 "R5" V 8505 3000 50 0000 C CNN
|
||||
F 1 "150" V 8414 3000 50 0000 C CNN
|
||||
F 2 "" V 8340 2990 50 0001 C CNN
|
||||
F 3 "~" H 8300 3000 50 0001 C CNN
|
||||
1 8300 3000
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R3
|
||||
U 1 1 5D026837
|
||||
P 8550 2400
|
||||
F 0 "R3" H 8618 2446 50 0000 L CNN
|
||||
F 1 "510" H 8618 2355 50 0000 L CNN
|
||||
F 2 "" V 8590 2390 50 0001 C CNN
|
||||
F 3 "~" H 8550 2400 50 0001 C CNN
|
||||
1 8550 2400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
7850 1500 7850 2200
|
||||
Wire Wire Line
|
||||
7850 2200 8150 2200
|
||||
Wire Wire Line
|
||||
6250 2250 6050 2250
|
||||
Wire Wire Line
|
||||
6050 2250 6050 1400
|
||||
Wire Wire Line
|
||||
6050 1400 7950 1400
|
||||
Wire Wire Line
|
||||
7950 1400 7950 1800
|
||||
Wire Wire Line
|
||||
7950 1800 8150 1800
|
||||
Wire Wire Line
|
||||
7850 2600 8150 2600
|
||||
Wire Wire Line
|
||||
8450 1800 8550 1800
|
||||
Wire Wire Line
|
||||
8550 1800 8550 2200
|
||||
Wire Wire Line
|
||||
8450 3000 8550 3000
|
||||
Wire Wire Line
|
||||
8550 3000 8550 2600
|
||||
Wire Wire Line
|
||||
8450 2200 8550 2200
|
||||
Connection ~ 8550 2200
|
||||
Wire Wire Line
|
||||
8550 2200 8550 2250
|
||||
Wire Wire Line
|
||||
8450 2600 8550 2600
|
||||
Connection ~ 8550 2600
|
||||
Wire Wire Line
|
||||
8550 2600 8550 2550
|
||||
Wire Wire Line
|
||||
4950 2850 5600 2850
|
||||
Wire Wire Line
|
||||
5600 2850 5600 2050
|
||||
Wire Wire Line
|
||||
5600 2050 6250 2050
|
||||
$Comp
|
||||
L library:DS3487 U?
|
||||
U 1 1 5D035700
|
||||
P 7000 2400
|
||||
F 0 "U?" H 7000 3115 50 0000 C CNN
|
||||
F 1 "DS3487" H 7000 3024 50 0000 C CNN
|
||||
F 2 "MODULE" H 7000 2400 50 0001 C CNN
|
||||
F 3 "" H 7000 2400 50 0001 C CNN
|
||||
1 7000 2400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L library:xxxx T1
|
||||
U 1 1 5D03C013
|
||||
P 9100 2700
|
||||
F 0 "T1" H 9100 3381 50 0000 C CNN
|
||||
F 1 "xxxx" H 9100 3290 50 0000 C CNN
|
||||
F 2 "Transformer_SMD:Pulse_PA2002NL-PA2008NL-PA2009NL" H 9100 2700 50 0001 C CNN
|
||||
F 3 "https://productfinder.pulseeng.com/products/datasheets/P663.pdf" H 8800 2700 50 0001 C CNN
|
||||
1 9100 2700
|
||||
-1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
8550 2200 8900 2200
|
||||
Wire Wire Line
|
||||
8550 2600 8900 2600
|
||||
$Comp
|
||||
L Connector:Conn_Coaxial J1
|
||||
U 1 1 5D047BD2
|
||||
P 9700 2500
|
||||
F 0 "J1" H 9800 2475 50 0000 L CNN
|
||||
F 1 "RG62" H 9800 2384 50 0000 L CNN
|
||||
F 2 "" H 9700 2500 50 0001 C CNN
|
||||
F 3 " ~" H 9700 2500 50 0001 C CNN
|
||||
1 9700 2500
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
9700 2700 9700 2900
|
||||
Wire Wire Line
|
||||
9700 2900 9450 2900
|
||||
Wire Wire Line
|
||||
9300 2500 9450 2500
|
||||
$Comp
|
||||
L Device:R_US R6
|
||||
U 1 1 5D04B24C
|
||||
P 9450 2700
|
||||
F 0 "R6" H 9518 2746 50 0000 L CNN
|
||||
F 1 "120" H 9518 2655 50 0000 L CNN
|
||||
F 2 "" V 9490 2690 50 0001 C CNN
|
||||
F 3 "~" H 9450 2700 50 0001 C CNN
|
||||
1 9450 2700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
9450 2550 9450 2500
|
||||
Connection ~ 9450 2500
|
||||
Wire Wire Line
|
||||
9450 2500 9500 2500
|
||||
Wire Wire Line
|
||||
9450 2850 9450 2900
|
||||
Connection ~ 9450 2900
|
||||
Wire Wire Line
|
||||
9450 2900 9300 2900
|
||||
$Comp
|
||||
L power:GND #PWR?
|
||||
U 1 1 5D04EB7E
|
||||
P 6250 3000
|
||||
F 0 "#PWR?" H 6250 2750 50 0001 C CNN
|
||||
F 1 "GND" H 6255 2827 50 0000 C CNN
|
||||
F 2 "" H 6250 3000 50 0001 C CNN
|
||||
F 3 "" H 6250 3000 50 0001 C CNN
|
||||
1 6250 3000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L power:GND #PWR?
|
||||
U 1 1 5D051C9E
|
||||
P 3450 3350
|
||||
F 0 "#PWR?" H 3450 3100 50 0001 C CNN
|
||||
F 1 "GND" H 3455 3177 50 0000 C CNN
|
||||
F 2 "" H 3450 3350 50 0001 C CNN
|
||||
F 3 "" H 3450 3350 50 0001 C CNN
|
||||
1 3450 3350
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
3450 3350 3450 3050
|
||||
$Comp
|
||||
L Device:C C1
|
||||
U 1 1 5D05AC0A
|
||||
P 5200 3600
|
||||
F 0 "C1" H 5315 3646 50 0000 L CNN
|
||||
F 1 "30 pF" H 5315 3555 50 0000 L CNN
|
||||
F 2 "" H 5238 3450 50 0001 C CNN
|
||||
F 3 "~" H 5200 3600 50 0001 C CNN
|
||||
1 5200 3600
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L library:DP8341 U2
|
||||
U 1 1 5D0650F6
|
||||
P 4200 5100
|
||||
F 0 "U2" H 4200 4185 50 0000 C CNN
|
||||
F 1 "DP8341" H 4200 4276 50 0000 C CNN
|
||||
F 2 "MODULE" H 4200 5100 50 0001 C CNN
|
||||
F 3 "" H 4200 5100 50 0001 C CNN
|
||||
1 4200 5100
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
4950 5550 8700 5550
|
||||
Wire Wire Line
|
||||
8700 2800 8900 2800
|
||||
Wire Wire Line
|
||||
4950 5450 8800 5450
|
||||
Wire Wire Line
|
||||
8800 3200 8900 3200
|
||||
Wire Wire Line
|
||||
4950 5650 5750 5650
|
||||
Wire Wire Line
|
||||
3450 2950 3200 2950
|
||||
Wire Wire Line
|
||||
3200 4050 5250 4050
|
||||
Wire Wire Line
|
||||
5250 4050 5250 5150
|
||||
Wire Wire Line
|
||||
5250 5150 4950 5150
|
||||
Wire Wire Line
|
||||
3450 4650 3100 4650
|
||||
Wire Wire Line
|
||||
3100 2850 3450 2850
|
||||
Wire Wire Line
|
||||
3450 4750 3000 4750
|
||||
Wire Wire Line
|
||||
3000 2750 3450 2750
|
||||
Wire Wire Line
|
||||
3450 4850 2900 4850
|
||||
Wire Wire Line
|
||||
2900 2650 3450 2650
|
||||
Wire Wire Line
|
||||
3450 4950 2800 4950
|
||||
Wire Wire Line
|
||||
2800 2550 3450 2550
|
||||
Wire Wire Line
|
||||
3450 2450 2700 2450
|
||||
Wire Wire Line
|
||||
2700 5050 3450 5050
|
||||
Wire Wire Line
|
||||
3450 2350 2600 2350
|
||||
Wire Wire Line
|
||||
2600 5150 3450 5150
|
||||
Wire Wire Line
|
||||
3450 2250 2500 2250
|
||||
Wire Wire Line
|
||||
2500 5250 3450 5250
|
||||
Wire Wire Line
|
||||
3450 2150 2400 2150
|
||||
Wire Wire Line
|
||||
2400 5350 3450 5350
|
||||
Wire Wire Line
|
||||
3450 2050 2300 2050
|
||||
Wire Wire Line
|
||||
2300 5450 3450 5450
|
||||
Wire Wire Line
|
||||
3450 1950 2200 1950
|
||||
Wire Wire Line
|
||||
2200 5550 3450 5550
|
||||
Text GLabel 1100 5550 0 50 Input ~ 0
|
||||
MEGA22
|
||||
Wire Wire Line
|
||||
1100 5550 2200 5550
|
||||
Connection ~ 2200 5550
|
||||
Text GLabel 1100 5450 0 50 Input ~ 0
|
||||
MEGA23
|
||||
Wire Wire Line
|
||||
1100 5450 2300 5450
|
||||
Connection ~ 2300 5450
|
||||
Text GLabel 1100 5350 0 50 Input ~ 0
|
||||
MEGA24
|
||||
Text GLabel 1100 5250 0 50 Input ~ 0
|
||||
MEGA25
|
||||
Text GLabel 1100 5150 0 50 Input ~ 0
|
||||
MEGA26
|
||||
Text GLabel 1100 5050 0 50 Input ~ 0
|
||||
MEGA27
|
||||
Text GLabel 1100 4950 0 50 Input ~ 0
|
||||
MEGA28
|
||||
Text GLabel 1100 4850 0 50 Input ~ 0
|
||||
MEGA29
|
||||
Text GLabel 1100 4750 0 50 Input ~ 0
|
||||
MEGA37
|
||||
Text GLabel 1100 4650 0 50 Input ~ 0
|
||||
MEGA36
|
||||
Wire Wire Line
|
||||
1100 4650 3100 4650
|
||||
Connection ~ 3100 4650
|
||||
Wire Wire Line
|
||||
1100 4750 3000 4750
|
||||
Connection ~ 3000 4750
|
||||
Wire Wire Line
|
||||
1100 4850 2900 4850
|
||||
Connection ~ 2900 4850
|
||||
Wire Wire Line
|
||||
1100 4950 2800 4950
|
||||
Connection ~ 2800 4950
|
||||
Wire Wire Line
|
||||
1100 5050 2700 5050
|
||||
Connection ~ 2700 5050
|
||||
Wire Wire Line
|
||||
1100 5150 2600 5150
|
||||
Connection ~ 2600 5150
|
||||
Wire Wire Line
|
||||
1100 5250 2500 5250
|
||||
Connection ~ 2500 5250
|
||||
Wire Wire Line
|
||||
1100 5350 2400 5350
|
||||
Connection ~ 2400 5350
|
||||
Text GLabel 1050 4550 0 50 Input ~ 0
|
||||
MEGA7
|
||||
Wire Wire Line
|
||||
1050 4550 3450 4550
|
||||
Text GLabel 6100 4750 2 50 Input ~ 0
|
||||
MEGA2
|
||||
Text GLabel 6100 4950 2 50 Input ~ 0
|
||||
MEGA3
|
||||
Text GLabel 6100 4850 2 50 Input ~ 0
|
||||
MEGA5
|
||||
Text GLabel 6100 5250 2 50 Input ~ 0
|
||||
MEGA4
|
||||
Text GLabel 6100 4650 2 50 Input ~ 0
|
||||
MEGA6
|
||||
Wire Wire Line
|
||||
4950 4650 6100 4650
|
||||
Wire Wire Line
|
||||
4950 4750 6100 4750
|
||||
Wire Wire Line
|
||||
4950 4850 6100 4850
|
||||
Wire Wire Line
|
||||
4950 4950 6100 4950
|
||||
Wire Wire Line
|
||||
4950 5250 6100 5250
|
||||
$Comp
|
||||
L power:GND #PWR?
|
||||
U 1 1 5D0CF15F
|
||||
P 4950 4350
|
||||
F 0 "#PWR?" H 4950 4100 50 0001 C CNN
|
||||
F 1 "GND" H 4955 4177 50 0000 C CNN
|
||||
F 2 "" H 4950 4350 50 0001 C CNN
|
||||
F 3 "" H 4950 4350 50 0001 C CNN
|
||||
1 4950 4350
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
4950 4350 4950 4550
|
||||
Text GLabel 6100 5050 2 50 Input ~ 0
|
||||
MEGA18
|
||||
Wire Wire Line
|
||||
4950 5050 6100 5050
|
||||
Text GLabel 5050 1050 1 50 Input ~ 0
|
||||
MEGA8
|
||||
Text GLabel 5150 1050 1 50 Input ~ 0
|
||||
META9
|
||||
Text GLabel 5250 1050 1 50 Input ~ 0
|
||||
MEGA10
|
||||
Text GLabel 5450 1050 1 50 Input ~ 0
|
||||
MEGA11
|
||||
Text GLabel 5350 1050 1 50 Input ~ 0
|
||||
MEGA12
|
||||
Wire Wire Line
|
||||
4950 2150 5150 2150
|
||||
Wire Wire Line
|
||||
5150 2150 5150 1050
|
||||
Wire Wire Line
|
||||
4950 2250 5250 2250
|
||||
Wire Wire Line
|
||||
5250 2250 5250 1050
|
||||
Wire Wire Line
|
||||
5350 1050 5350 2450
|
||||
Wire Wire Line
|
||||
5350 2450 4950 2450
|
||||
Wire Wire Line
|
||||
4950 2550 5450 2550
|
||||
Wire Wire Line
|
||||
5450 2550 5450 1050
|
||||
Wire Wire Line
|
||||
4950 2050 5050 2050
|
||||
Wire Wire Line
|
||||
5050 2050 5050 1050
|
||||
$Comp
|
||||
L power:VCC #PWR?
|
||||
U 1 1 5D110504
|
||||
P 3450 5900
|
||||
F 0 "#PWR?" H 3450 5750 50 0001 C CNN
|
||||
F 1 "VCC" H 3468 6073 50 0000 C CNN
|
||||
F 2 "" H 3450 5900 50 0001 C CNN
|
||||
F 3 "" H 3450 5900 50 0001 C CNN
|
||||
1 3450 5900
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
3450 5650 3450 5900
|
||||
$Comp
|
||||
L power:VCC #PWR?
|
||||
U 1 1 5D118163
|
||||
P 4950 1600
|
||||
F 0 "#PWR?" H 4950 1450 50 0001 C CNN
|
||||
F 1 "VCC" H 4967 1773 50 0000 C CNN
|
||||
F 2 "" H 4950 1600 50 0001 C CNN
|
||||
F 3 "" H 4950 1600 50 0001 C CNN
|
||||
1 4950 1600
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
4950 1600 4950 1950
|
||||
Wire Wire Line
|
||||
4950 2950 5450 2950
|
||||
Wire Wire Line
|
||||
5450 2950 5450 3050
|
||||
Wire Wire Line
|
||||
4950 2350 5750 2350
|
||||
Wire Wire Line
|
||||
4950 3350 4950 3450
|
||||
Wire Wire Line
|
||||
4950 3450 5200 3450
|
||||
Wire Wire Line
|
||||
5200 3450 5450 3450
|
||||
Wire Wire Line
|
||||
5450 3450 5450 3350
|
||||
Connection ~ 5200 3450
|
||||
Wire Wire Line
|
||||
4950 2650 6250 2650
|
||||
Wire Wire Line
|
||||
5750 5650 5750 2350
|
||||
Connection ~ 5750 2350
|
||||
Wire Wire Line
|
||||
5750 2350 6250 2350
|
||||
Wire Wire Line
|
||||
3200 2950 3200 4050
|
||||
Wire Wire Line
|
||||
3100 2850 3100 4650
|
||||
Wire Wire Line
|
||||
3000 2750 3000 4750
|
||||
Wire Wire Line
|
||||
2900 2650 2900 4850
|
||||
Wire Wire Line
|
||||
2800 2550 2800 4950
|
||||
Wire Wire Line
|
||||
2700 2450 2700 5050
|
||||
Wire Wire Line
|
||||
2600 2350 2600 5150
|
||||
Wire Wire Line
|
||||
2500 2250 2500 5250
|
||||
Wire Wire Line
|
||||
2400 2150 2400 5350
|
||||
Wire Wire Line
|
||||
2300 2050 2300 5450
|
||||
Wire Wire Line
|
||||
2200 1950 2200 5550
|
||||
Wire Wire Line
|
||||
8700 2800 8700 5550
|
||||
Wire Wire Line
|
||||
8800 3200 8800 5450
|
||||
$Comp
|
||||
L power:VCC #PWR?
|
||||
U 1 1 5D1B82CE
|
||||
P 7750 1750
|
||||
F 0 "#PWR?" H 7750 1600 50 0001 C CNN
|
||||
F 1 "VCC" H 7767 1923 50 0000 C CNN
|
||||
F 2 "" H 7750 1750 50 0001 C CNN
|
||||
F 3 "" H 7750 1750 50 0001 C CNN
|
||||
1 7750 1750
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6250 2750 6250 3000
|
||||
Wire Wire Line
|
||||
7850 3300 6050 3300
|
||||
Wire Wire Line
|
||||
6050 3300 6050 2550
|
||||
Wire Wire Line
|
||||
6050 2550 6250 2550
|
||||
Wire Wire Line
|
||||
7850 2600 7850 3300
|
||||
Wire Wire Line
|
||||
6250 2450 6150 2450
|
||||
Wire Wire Line
|
||||
6150 2450 6150 1500
|
||||
Wire Wire Line
|
||||
6150 1500 7850 1500
|
||||
Wire Wire Line
|
||||
6250 2150 5950 2150
|
||||
Wire Wire Line
|
||||
5950 2150 5950 3400
|
||||
Wire Wire Line
|
||||
5950 3400 7950 3400
|
||||
Wire Wire Line
|
||||
7950 3400 7950 3000
|
||||
Wire Wire Line
|
||||
7950 3000 8150 3000
|
||||
Wire Wire Line
|
||||
7750 1750 7750 2050
|
||||
$EndSCHEMATC
|
||||
1
interface1/hardware/hardware.kicad_pcb
Normal file
1
interface1/hardware/hardware.kicad_pcb
Normal file
@@ -0,0 +1 @@
|
||||
(kicad_pcb (version 4) (host kicad "dummy file") )
|
||||
33
interface1/hardware/hardware.pro
Normal file
33
interface1/hardware/hardware.pro
Normal file
@@ -0,0 +1,33 @@
|
||||
update=22/05/2015 07:44:53
|
||||
version=1
|
||||
last_client=kicad
|
||||
[general]
|
||||
version=1
|
||||
RootSch=
|
||||
BoardNm=
|
||||
[pcbnew]
|
||||
version=1
|
||||
LastNetListRead=
|
||||
UseCmpFile=1
|
||||
PadDrill=0.600000000000
|
||||
PadDrillOvalY=0.600000000000
|
||||
PadSizeH=1.500000000000
|
||||
PadSizeV=1.500000000000
|
||||
PcbTextSizeV=1.500000000000
|
||||
PcbTextSizeH=1.500000000000
|
||||
PcbTextThickness=0.300000000000
|
||||
ModuleTextSizeV=1.000000000000
|
||||
ModuleTextSizeH=1.000000000000
|
||||
ModuleTextSizeThickness=0.150000000000
|
||||
SolderMaskClearance=0.000000000000
|
||||
SolderMaskMinWidth=0.000000000000
|
||||
DrawSegmentWidth=0.200000000000
|
||||
BoardOutlineThickness=0.100000000000
|
||||
ModuleOutlineThickness=0.150000000000
|
||||
[cvpcb]
|
||||
version=1
|
||||
NetIExt=net
|
||||
[eeschema]
|
||||
version=1
|
||||
LibDir=
|
||||
[eeschema/libraries]
|
||||
557
interface1/hardware/hardware.sch
Normal file
557
interface1/hardware/hardware.sch
Normal file
@@ -0,0 +1,557 @@
|
||||
EESchema Schematic File Version 4
|
||||
EELAYER 29 0
|
||||
EELAYER END
|
||||
$Descr USLetter 11000 8500
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title ""
|
||||
Date ""
|
||||
Rev ""
|
||||
Comp ""
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 "Based on the typical application from the DP8340 and DP8341 data sheets"
|
||||
$EndDescr
|
||||
$Comp
|
||||
L library:DP8340 U1
|
||||
U 1 1 5CFF4259
|
||||
P 4200 2500
|
||||
F 0 "U1" H 4200 3415 50 0000 C CNN
|
||||
F 1 "DP8340" H 4200 3324 50 0000 C CNN
|
||||
F 2 "MODULE" H 4200 2500 50 0001 C CNN
|
||||
F 3 "" H 4200 2500 50 0001 C CNN
|
||||
1 4200 2500
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R7
|
||||
U 1 1 5D005C33
|
||||
P 5450 3200
|
||||
F 0 "R7" H 5518 3246 50 0000 L CNN
|
||||
F 1 "500" H 5518 3155 50 0000 L CNN
|
||||
F 2 "" V 5490 3190 50 0001 C CNN
|
||||
F 3 "~" H 5450 3200 50 0001 C CNN
|
||||
1 5450 3200
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:Crystal Y1
|
||||
U 1 1 5D0074D0
|
||||
P 4950 3200
|
||||
F 0 "Y1" V 4996 3069 50 0000 R CNN
|
||||
F 1 "Crystal" V 4905 3069 50 0000 R CNN
|
||||
F 2 "" H 4950 3200 50 0001 C CNN
|
||||
F 3 "~" H 4950 3200 50 0001 C CNN
|
||||
1 4950 3200
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L power:VCC #PWR?
|
||||
U 1 1 5D0081F3
|
||||
P 5200 3750
|
||||
F 0 "#PWR?" H 5200 3600 50 0001 C CNN
|
||||
F 1 "VCC" H 5218 3923 50 0000 C CNN
|
||||
F 2 "" H 5200 3750 50 0001 C CNN
|
||||
F 3 "" H 5200 3750 50 0001 C CNN
|
||||
1 5200 3750
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R1
|
||||
U 1 1 5D01411B
|
||||
P 8300 1800
|
||||
F 0 "R1" V 8505 1800 50 0000 C CNN
|
||||
F 1 "150" V 8414 1800 50 0000 C CNN
|
||||
F 2 "" V 8340 1790 50 0001 C CNN
|
||||
F 3 "~" H 8300 1800 50 0001 C CNN
|
||||
1 8300 1800
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R2
|
||||
U 1 1 5D014636
|
||||
P 8300 2200
|
||||
F 0 "R2" V 8505 2200 50 0000 C CNN
|
||||
F 1 "33" V 8414 2200 50 0000 C CNN
|
||||
F 2 "" V 8340 2190 50 0001 C CNN
|
||||
F 3 "~" H 8300 2200 50 0001 C CNN
|
||||
1 8300 2200
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R4
|
||||
U 1 1 5D01DB0F
|
||||
P 8300 2600
|
||||
F 0 "R4" V 8505 2600 50 0000 C CNN
|
||||
F 1 "33" V 8414 2600 50 0000 C CNN
|
||||
F 2 "" V 8340 2590 50 0001 C CNN
|
||||
F 3 "~" H 8300 2600 50 0001 C CNN
|
||||
1 8300 2600
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R5
|
||||
U 1 1 5D01DE87
|
||||
P 8300 3000
|
||||
F 0 "R5" V 8505 3000 50 0000 C CNN
|
||||
F 1 "150" V 8414 3000 50 0000 C CNN
|
||||
F 2 "" V 8340 2990 50 0001 C CNN
|
||||
F 3 "~" H 8300 3000 50 0001 C CNN
|
||||
1 8300 3000
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_US R3
|
||||
U 1 1 5D026837
|
||||
P 8550 2400
|
||||
F 0 "R3" H 8618 2446 50 0000 L CNN
|
||||
F 1 "510" H 8618 2355 50 0000 L CNN
|
||||
F 2 "" V 8590 2390 50 0001 C CNN
|
||||
F 3 "~" H 8550 2400 50 0001 C CNN
|
||||
1 8550 2400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
7850 1500 7850 2200
|
||||
Wire Wire Line
|
||||
7850 2200 8150 2200
|
||||
Wire Wire Line
|
||||
6250 2250 6050 2250
|
||||
Wire Wire Line
|
||||
6050 2250 6050 1400
|
||||
Wire Wire Line
|
||||
6050 1400 7950 1400
|
||||
Wire Wire Line
|
||||
7950 1400 7950 1800
|
||||
Wire Wire Line
|
||||
7950 1800 8150 1800
|
||||
Wire Wire Line
|
||||
7850 2600 8150 2600
|
||||
Wire Wire Line
|
||||
8450 1800 8550 1800
|
||||
Wire Wire Line
|
||||
8550 1800 8550 2200
|
||||
Wire Wire Line
|
||||
8450 3000 8550 3000
|
||||
Wire Wire Line
|
||||
8550 3000 8550 2600
|
||||
Wire Wire Line
|
||||
8450 2200 8550 2200
|
||||
Connection ~ 8550 2200
|
||||
Wire Wire Line
|
||||
8550 2200 8550 2250
|
||||
Wire Wire Line
|
||||
8450 2600 8550 2600
|
||||
Connection ~ 8550 2600
|
||||
Wire Wire Line
|
||||
8550 2600 8550 2550
|
||||
Wire Wire Line
|
||||
4950 2850 5600 2850
|
||||
Wire Wire Line
|
||||
5600 2850 5600 2050
|
||||
Wire Wire Line
|
||||
5600 2050 6250 2050
|
||||
$Comp
|
||||
L library:DS3487 U3
|
||||
U 1 1 5D035700
|
||||
P 7000 2400
|
||||
F 0 "U3" H 7000 3115 50 0000 C CNN
|
||||
F 1 "DS3487" H 7000 3024 50 0000 C CNN
|
||||
F 2 "MODULE" H 7000 2400 50 0001 C CNN
|
||||
F 3 "" H 7000 2400 50 0001 C CNN
|
||||
1 7000 2400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L library:xxxx T1
|
||||
U 1 1 5D03C013
|
||||
P 9100 2700
|
||||
F 0 "T1" H 9100 3381 50 0000 C CNN
|
||||
F 1 "PE-5762" H 9100 3290 50 0000 C CNN
|
||||
F 2 "Transformer_SMD:Pulse_PA2002NL-PA2008NL-PA2009NL" H 9100 2700 50 0001 C CNN
|
||||
F 3 "https://productfinder.pulseeng.com/products/datasheets/P663.pdf" H 8800 2700 50 0001 C CNN
|
||||
1 9100 2700
|
||||
-1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
8550 2200 8900 2200
|
||||
Wire Wire Line
|
||||
8550 2600 8900 2600
|
||||
$Comp
|
||||
L Connector:Conn_Coaxial J1
|
||||
U 1 1 5D047BD2
|
||||
P 9700 2500
|
||||
F 0 "J1" H 9800 2475 50 0000 L CNN
|
||||
F 1 "RG62" H 9800 2384 50 0000 L CNN
|
||||
F 2 "" H 9700 2500 50 0001 C CNN
|
||||
F 3 " ~" H 9700 2500 50 0001 C CNN
|
||||
1 9700 2500
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
9700 2700 9700 2900
|
||||
Wire Wire Line
|
||||
9700 2900 9450 2900
|
||||
Wire Wire Line
|
||||
9300 2500 9450 2500
|
||||
$Comp
|
||||
L Device:R_US R6
|
||||
U 1 1 5D04B24C
|
||||
P 9450 2700
|
||||
F 0 "R6" H 9518 2746 50 0000 L CNN
|
||||
F 1 "120" H 9518 2655 50 0000 L CNN
|
||||
F 2 "" V 9490 2690 50 0001 C CNN
|
||||
F 3 "~" H 9450 2700 50 0001 C CNN
|
||||
1 9450 2700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
9450 2550 9450 2500
|
||||
Connection ~ 9450 2500
|
||||
Wire Wire Line
|
||||
9450 2500 9500 2500
|
||||
Wire Wire Line
|
||||
9450 2850 9450 2900
|
||||
Connection ~ 9450 2900
|
||||
Wire Wire Line
|
||||
9450 2900 9300 2900
|
||||
$Comp
|
||||
L power:GND #PWR?
|
||||
U 1 1 5D04EB7E
|
||||
P 6250 3000
|
||||
F 0 "#PWR?" H 6250 2750 50 0001 C CNN
|
||||
F 1 "GND" H 6255 2827 50 0000 C CNN
|
||||
F 2 "" H 6250 3000 50 0001 C CNN
|
||||
F 3 "" H 6250 3000 50 0001 C CNN
|
||||
1 6250 3000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L power:GND #PWR?
|
||||
U 1 1 5D051C9E
|
||||
P 3450 3350
|
||||
F 0 "#PWR?" H 3450 3100 50 0001 C CNN
|
||||
F 1 "GND" H 3455 3177 50 0000 C CNN
|
||||
F 2 "" H 3450 3350 50 0001 C CNN
|
||||
F 3 "" H 3450 3350 50 0001 C CNN
|
||||
1 3450 3350
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
3450 3350 3450 3050
|
||||
$Comp
|
||||
L Device:C C1
|
||||
U 1 1 5D05AC0A
|
||||
P 5200 3600
|
||||
F 0 "C1" H 5315 3646 50 0000 L CNN
|
||||
F 1 "30 pF" H 5315 3555 50 0000 L CNN
|
||||
F 2 "" H 5238 3450 50 0001 C CNN
|
||||
F 3 "~" H 5200 3600 50 0001 C CNN
|
||||
1 5200 3600
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L library:DP8341 U2
|
||||
U 1 1 5D0650F6
|
||||
P 4200 5100
|
||||
F 0 "U2" H 4200 4185 50 0000 C CNN
|
||||
F 1 "DP8341" H 4200 4276 50 0000 C CNN
|
||||
F 2 "MODULE" H 4200 5100 50 0001 C CNN
|
||||
F 3 "" H 4200 5100 50 0001 C CNN
|
||||
1 4200 5100
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
4950 5550 8700 5550
|
||||
Wire Wire Line
|
||||
8700 2800 8900 2800
|
||||
Wire Wire Line
|
||||
4950 5450 8800 5450
|
||||
Wire Wire Line
|
||||
8800 3200 8900 3200
|
||||
Wire Wire Line
|
||||
4950 5650 5750 5650
|
||||
Wire Wire Line
|
||||
3450 2950 3200 2950
|
||||
Wire Wire Line
|
||||
3200 4050 5250 4050
|
||||
Wire Wire Line
|
||||
5250 4050 5250 5150
|
||||
Wire Wire Line
|
||||
5250 5150 4950 5150
|
||||
Wire Wire Line
|
||||
3450 4650 3100 4650
|
||||
Wire Wire Line
|
||||
3100 2850 3450 2850
|
||||
Wire Wire Line
|
||||
3450 4750 3000 4750
|
||||
Wire Wire Line
|
||||
3000 2750 3450 2750
|
||||
Wire Wire Line
|
||||
3450 4850 2900 4850
|
||||
Wire Wire Line
|
||||
2900 2650 3450 2650
|
||||
Wire Wire Line
|
||||
3450 4950 2800 4950
|
||||
Wire Wire Line
|
||||
2800 2550 3450 2550
|
||||
Wire Wire Line
|
||||
3450 2450 2700 2450
|
||||
Wire Wire Line
|
||||
2700 5050 3450 5050
|
||||
Wire Wire Line
|
||||
3450 2350 2600 2350
|
||||
Wire Wire Line
|
||||
2600 5150 3450 5150
|
||||
Wire Wire Line
|
||||
3450 2250 2500 2250
|
||||
Wire Wire Line
|
||||
2500 5250 3450 5250
|
||||
Wire Wire Line
|
||||
3450 2150 2400 2150
|
||||
Wire Wire Line
|
||||
2400 5350 3450 5350
|
||||
Wire Wire Line
|
||||
3450 2050 2300 2050
|
||||
Wire Wire Line
|
||||
2300 5450 3450 5450
|
||||
Wire Wire Line
|
||||
3450 1950 2200 1950
|
||||
Wire Wire Line
|
||||
2200 5550 3450 5550
|
||||
Text GLabel 1100 5550 0 50 Input ~ 0
|
||||
MEGA22
|
||||
Wire Wire Line
|
||||
1100 5550 2200 5550
|
||||
Connection ~ 2200 5550
|
||||
Text GLabel 1100 5450 0 50 Input ~ 0
|
||||
MEGA23
|
||||
Wire Wire Line
|
||||
1100 5450 2300 5450
|
||||
Connection ~ 2300 5450
|
||||
Text GLabel 1100 5350 0 50 Input ~ 0
|
||||
MEGA24
|
||||
Text GLabel 1100 5250 0 50 Input ~ 0
|
||||
MEGA25
|
||||
Text GLabel 1100 5150 0 50 Input ~ 0
|
||||
MEGA26
|
||||
Text GLabel 1100 5050 0 50 Input ~ 0
|
||||
MEGA27
|
||||
Text GLabel 1100 4950 0 50 Input ~ 0
|
||||
MEGA28
|
||||
Text GLabel 1100 4850 0 50 Input ~ 0
|
||||
MEGA29
|
||||
Text GLabel 1100 4750 0 50 Input ~ 0
|
||||
MEGA37
|
||||
Text GLabel 1100 4650 0 50 Input ~ 0
|
||||
MEGA36
|
||||
Wire Wire Line
|
||||
1100 4650 3100 4650
|
||||
Connection ~ 3100 4650
|
||||
Wire Wire Line
|
||||
1100 4750 3000 4750
|
||||
Connection ~ 3000 4750
|
||||
Wire Wire Line
|
||||
1100 4850 2900 4850
|
||||
Connection ~ 2900 4850
|
||||
Wire Wire Line
|
||||
1100 4950 2800 4950
|
||||
Connection ~ 2800 4950
|
||||
Wire Wire Line
|
||||
1100 5050 2700 5050
|
||||
Connection ~ 2700 5050
|
||||
Wire Wire Line
|
||||
1100 5150 2600 5150
|
||||
Connection ~ 2600 5150
|
||||
Wire Wire Line
|
||||
1100 5250 2500 5250
|
||||
Connection ~ 2500 5250
|
||||
Wire Wire Line
|
||||
1100 5350 2400 5350
|
||||
Connection ~ 2400 5350
|
||||
Text GLabel 1050 4550 0 50 Input ~ 0
|
||||
MEGA7
|
||||
Wire Wire Line
|
||||
1050 4550 3450 4550
|
||||
Text GLabel 6100 4750 2 50 Input ~ 0
|
||||
MEGA2
|
||||
Text GLabel 6100 4950 2 50 Input ~ 0
|
||||
MEGA3
|
||||
Text GLabel 6100 4850 2 50 Input ~ 0
|
||||
MEGA5
|
||||
Text GLabel 6100 5250 2 50 Input ~ 0
|
||||
MEGA4
|
||||
Text GLabel 6100 4650 2 50 Input ~ 0
|
||||
MEGA6
|
||||
Wire Wire Line
|
||||
4950 4650 6100 4650
|
||||
Wire Wire Line
|
||||
4950 4750 6100 4750
|
||||
Wire Wire Line
|
||||
4950 4850 6100 4850
|
||||
Wire Wire Line
|
||||
4950 4950 6100 4950
|
||||
Wire Wire Line
|
||||
4950 5250 6100 5250
|
||||
$Comp
|
||||
L power:GND #PWR?
|
||||
U 1 1 5D0CF15F
|
||||
P 4950 4350
|
||||
F 0 "#PWR?" H 4950 4100 50 0001 C CNN
|
||||
F 1 "GND" H 4955 4177 50 0000 C CNN
|
||||
F 2 "" H 4950 4350 50 0001 C CNN
|
||||
F 3 "" H 4950 4350 50 0001 C CNN
|
||||
1 4950 4350
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
4950 4350 4950 4550
|
||||
Text GLabel 6100 5050 2 50 Input ~ 0
|
||||
MEGA18
|
||||
Wire Wire Line
|
||||
4950 5050 6100 5050
|
||||
Text GLabel 5050 1050 1 50 Input ~ 0
|
||||
MEGA8
|
||||
Text GLabel 5150 1050 1 50 Input ~ 0
|
||||
META9
|
||||
Text GLabel 5250 1050 1 50 Input ~ 0
|
||||
MEGA10
|
||||
Text GLabel 5450 1050 1 50 Input ~ 0
|
||||
MEGA11
|
||||
Text GLabel 5350 1050 1 50 Input ~ 0
|
||||
MEGA12
|
||||
Wire Wire Line
|
||||
4950 2150 5150 2150
|
||||
Wire Wire Line
|
||||
5150 2150 5150 1050
|
||||
Wire Wire Line
|
||||
4950 2250 5250 2250
|
||||
Wire Wire Line
|
||||
5250 2250 5250 1050
|
||||
Wire Wire Line
|
||||
5350 1050 5350 2450
|
||||
Wire Wire Line
|
||||
5350 2450 4950 2450
|
||||
Wire Wire Line
|
||||
4950 2550 5450 2550
|
||||
Wire Wire Line
|
||||
5450 2550 5450 1050
|
||||
Wire Wire Line
|
||||
4950 2050 5050 2050
|
||||
Wire Wire Line
|
||||
5050 2050 5050 1050
|
||||
$Comp
|
||||
L power:VCC #PWR?
|
||||
U 1 1 5D110504
|
||||
P 3450 5900
|
||||
F 0 "#PWR?" H 3450 5750 50 0001 C CNN
|
||||
F 1 "VCC" H 3468 6073 50 0000 C CNN
|
||||
F 2 "" H 3450 5900 50 0001 C CNN
|
||||
F 3 "" H 3450 5900 50 0001 C CNN
|
||||
1 3450 5900
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
3450 5650 3450 5900
|
||||
$Comp
|
||||
L power:VCC #PWR?
|
||||
U 1 1 5D118163
|
||||
P 4950 1600
|
||||
F 0 "#PWR?" H 4950 1450 50 0001 C CNN
|
||||
F 1 "VCC" H 4967 1773 50 0000 C CNN
|
||||
F 2 "" H 4950 1600 50 0001 C CNN
|
||||
F 3 "" H 4950 1600 50 0001 C CNN
|
||||
1 4950 1600
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
4950 1600 4950 1950
|
||||
Wire Wire Line
|
||||
4950 2950 5450 2950
|
||||
Wire Wire Line
|
||||
5450 2950 5450 3050
|
||||
Wire Wire Line
|
||||
4950 2350 5750 2350
|
||||
Wire Wire Line
|
||||
4950 3350 4950 3450
|
||||
Wire Wire Line
|
||||
4950 3450 5200 3450
|
||||
Wire Wire Line
|
||||
5200 3450 5450 3450
|
||||
Wire Wire Line
|
||||
5450 3450 5450 3350
|
||||
Connection ~ 5200 3450
|
||||
Wire Wire Line
|
||||
4950 2650 6250 2650
|
||||
Wire Wire Line
|
||||
5750 5650 5750 2350
|
||||
Connection ~ 5750 2350
|
||||
Wire Wire Line
|
||||
5750 2350 6250 2350
|
||||
Wire Wire Line
|
||||
3200 2950 3200 4050
|
||||
Wire Wire Line
|
||||
3100 2850 3100 4650
|
||||
Wire Wire Line
|
||||
3000 2750 3000 4750
|
||||
Wire Wire Line
|
||||
2900 2650 2900 4850
|
||||
Wire Wire Line
|
||||
2800 2550 2800 4950
|
||||
Wire Wire Line
|
||||
2700 2450 2700 5050
|
||||
Wire Wire Line
|
||||
2600 2350 2600 5150
|
||||
Wire Wire Line
|
||||
2500 2250 2500 5250
|
||||
Wire Wire Line
|
||||
2400 2150 2400 5350
|
||||
Wire Wire Line
|
||||
2300 2050 2300 5450
|
||||
Wire Wire Line
|
||||
2200 1950 2200 5550
|
||||
Wire Wire Line
|
||||
8700 2800 8700 5550
|
||||
Wire Wire Line
|
||||
8800 3200 8800 5450
|
||||
$Comp
|
||||
L power:VCC #PWR?
|
||||
U 1 1 5D1B82CE
|
||||
P 7750 1750
|
||||
F 0 "#PWR?" H 7750 1600 50 0001 C CNN
|
||||
F 1 "VCC" H 7767 1923 50 0000 C CNN
|
||||
F 2 "" H 7750 1750 50 0001 C CNN
|
||||
F 3 "" H 7750 1750 50 0001 C CNN
|
||||
1 7750 1750
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6250 2750 6250 3000
|
||||
Wire Wire Line
|
||||
7850 3300 6050 3300
|
||||
Wire Wire Line
|
||||
6050 3300 6050 2550
|
||||
Wire Wire Line
|
||||
6050 2550 6250 2550
|
||||
Wire Wire Line
|
||||
7850 2600 7850 3300
|
||||
Wire Wire Line
|
||||
6250 2450 6150 2450
|
||||
Wire Wire Line
|
||||
6150 2450 6150 1500
|
||||
Wire Wire Line
|
||||
6150 1500 7850 1500
|
||||
Wire Wire Line
|
||||
6250 2150 5950 2150
|
||||
Wire Wire Line
|
||||
5950 2150 5950 3400
|
||||
Wire Wire Line
|
||||
5950 3400 7950 3400
|
||||
Wire Wire Line
|
||||
7950 3400 7950 3000
|
||||
Wire Wire Line
|
||||
7950 3000 8150 3000
|
||||
Wire Wire Line
|
||||
7750 1750 7750 2050
|
||||
$EndSCHEMATC
|
||||
9
interface1/hardware/library.bck
Normal file
9
interface1/hardware/library.bck
Normal file
@@ -0,0 +1,9 @@
|
||||
EESchema-DOCLIB Version 2.0
|
||||
#
|
||||
$CMP xxxx
|
||||
D xxxx
|
||||
K pulse
|
||||
F https://productfinder.pulseeng.com/products/datasheets/P663.pdf
|
||||
$ENDCMP
|
||||
#
|
||||
#End Doc Library
|
||||
9
interface1/hardware/library.dcm
Normal file
9
interface1/hardware/library.dcm
Normal file
@@ -0,0 +1,9 @@
|
||||
EESchema-DOCLIB Version 2.0
|
||||
#
|
||||
$CMP xxxx
|
||||
D xxxx
|
||||
K pulse
|
||||
F https://productfinder.pulseeng.com/products/datasheets/P663.pdf
|
||||
$ENDCMP
|
||||
#
|
||||
#End Doc Library
|
||||
144
interface1/hardware/library.lib
Normal file
144
interface1/hardware/library.lib
Normal file
@@ -0,0 +1,144 @@
|
||||
EESchema-LIBRARY Version 2.4
|
||||
#encoding utf-8
|
||||
#
|
||||
# DP8340
|
||||
#
|
||||
DEF DP8340 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 -100 50 H V C CNN
|
||||
F1 "DP8340" 0 100 50 H V C CNN
|
||||
F2 "MODULE" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
S -450 -750 450 750 1 0 0 N
|
||||
X DI11 1 -750 550 300 R 50 50 1 1 U
|
||||
X DI2 10 -750 -350 300 R 50 50 1 1 U
|
||||
X CLK_OUT 11 -750 -450 300 R 50 50 1 1 U
|
||||
X GND 12 -750 -550 300 R 50 50 1 1 U
|
||||
X X1 13 750 -550 300 L 50 50 1 1 U
|
||||
X X2 14 750 -450 300 L 50 50 1 1 U
|
||||
X DATA_DLY 15 750 -350 300 L 50 50 1 1 U
|
||||
X DATA_OUT1 16 750 -250 300 L 50 50 1 1 U
|
||||
X DATA_OUT2 17 750 -150 300 L 50 50 1 1 U
|
||||
X EVEN_ODD 18 750 -50 300 L 50 50 1 1 U
|
||||
X PARITY_CTL 19 750 50 300 L 50 50 1 1 U
|
||||
X DI10 2 -750 450 300 R 50 50 1 1 U
|
||||
X TX_ACTIVE 20 750 150 300 L 50 50 1 1 U
|
||||
X AUTO_RESP 21 750 250 300 L 50 50 1 1 U
|
||||
X REG_FULL 22 750 350 300 L 50 50 1 1 U
|
||||
X REG_LOAD 23 750 450 300 L 50 50 1 1 U
|
||||
X VCC 24 750 550 300 L 50 50 1 1 U
|
||||
X DI9 3 -750 350 300 R 50 50 1 1 U
|
||||
X DI8 4 -750 250 300 R 50 50 1 1 U
|
||||
X DI7 5 -750 150 300 R 50 50 1 1 U
|
||||
X DI6 6 -750 50 300 R 50 50 1 1 U
|
||||
X DI5 7 -750 -50 300 R 50 50 1 1 U
|
||||
X DI4 8 -750 -150 300 R 50 50 1 1 U
|
||||
X DI3 9 -750 -250 300 R 50 50 1 1 U
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# DP8341
|
||||
#
|
||||
DEF DP8341 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 -100 50 H V C CNN
|
||||
F1 "DP8341" 0 100 50 H V C CNN
|
||||
F2 "MODULE" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
S -450 -750 450 750 1 0 0 N
|
||||
X RX_DISABLE 1 -750 550 300 R 50 50 1 1 U
|
||||
X DATA_AVAIL 10 -750 -350 300 R 50 50 1 1 U
|
||||
X OUTPUT_CTL 11 -750 -450 300 R 50 50 1 1 U
|
||||
X GND 12 -750 -550 300 R 50 50 1 1 U
|
||||
X OUTPUT_EN 13 750 -550 300 L 50 50 1 1 U
|
||||
X DO2 14 750 -450 300 L 50 50 1 1 U
|
||||
X DO3 15 750 -350 300 L 50 50 1 1 U
|
||||
X DO4 16 750 -250 300 L 50 50 1 1 U
|
||||
X DO5 17 750 -150 300 L 50 50 1 1 U
|
||||
X DO6 18 750 -50 300 L 50 50 1 1 U
|
||||
X DO7 19 750 50 300 L 50 50 1 1 U
|
||||
X +AMP_IN 2 -750 450 300 R 50 50 1 1 U
|
||||
X DO8 20 750 150 300 L 50 50 1 1 U
|
||||
X DO9 21 750 250 300 L 50 50 1 1 U
|
||||
X DO10 22 750 350 300 L 50 50 1 1 U
|
||||
X DO11 23 750 450 300 L 50 50 1 1 U
|
||||
X VCC 24 750 550 300 L 50 50 1 1 U
|
||||
X -AMP_IN 3 -750 350 300 R 50 50 1 1 U
|
||||
X DATA 4 -750 250 300 R 50 50 1 1 U
|
||||
X DATA_CTL 5 -750 150 300 R 50 50 1 1 U
|
||||
X CLOCK 6 -750 50 300 R 50 50 1 1 U
|
||||
X RX_ACTIVE 7 -750 -50 300 R 50 50 1 1 U
|
||||
X ERROR 8 -750 -150 300 R 50 50 1 1 U
|
||||
X REG_READ 9 -750 -250 300 R 50 50 1 1 U
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# DS3487
|
||||
#
|
||||
DEF DS3487 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 -100 50 H V C CNN
|
||||
F1 "DS3487" 0 100 50 H V C CNN
|
||||
F2 "MODULE" 0 0 50 H I C CNN
|
||||
F3 "DOCUMENTATION" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
S -450 -550 450 550 1 0 0 N
|
||||
X PIN1 1 -750 350 300 R 50 50 1 1 U
|
||||
X PIN10 10 750 -250 300 L 50 50 1 1 U
|
||||
X PIN11 11 750 -150 300 L 50 50 1 1 U
|
||||
X PIN12 12 750 -50 300 L 50 50 1 1 U
|
||||
X PIN13 13 750 50 300 L 50 50 1 1 U
|
||||
X PIN14 14 750 150 300 L 50 50 1 1 U
|
||||
X PIN15 15 750 250 300 L 50 50 1 1 U
|
||||
X PIN16 16 750 350 300 L 50 50 1 1 U
|
||||
X PIN2 2 -750 250 300 R 50 50 1 1 U
|
||||
X PIN3 3 -750 150 300 R 50 50 1 1 U
|
||||
X PIN4 4 -750 50 300 R 50 50 1 1 U
|
||||
X PIN5 5 -750 -50 300 R 50 50 1 1 U
|
||||
X PIN6 6 -750 -150 300 R 50 50 1 1 U
|
||||
X PIN7 7 -750 -250 300 R 50 50 1 1 U
|
||||
X PIN8 8 -750 -350 300 R 50 50 1 1 U
|
||||
X PIN9 9 750 -350 300 L 50 50 1 1 U
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# xxxx
|
||||
#
|
||||
DEF xxxx T 0 20 Y N 1 F N
|
||||
F0 "T" 0 550 50 H V C CNN
|
||||
F1 "xxxx" 0 -550 50 H V C CNN
|
||||
F2 "Transformer_SMD:Pulse_PA2002NL-PA2008NL-PA2009NL" 0 0 50 H I C CNN
|
||||
F3 "" -300 0 50 H I C CNN
|
||||
DRAW
|
||||
A -100 -90 30 900 -900 0 1 8 N -100 -60 -100 -120
|
||||
A -100 -30 30 900 -900 0 1 8 N -100 0 -100 -60
|
||||
A -100 30 30 900 -900 0 1 8 N -100 60 -100 0
|
||||
A 100 -390 30 -900 900 0 1 8 N 100 -420 100 -360
|
||||
A 100 -330 30 -900 900 0 1 8 N 100 -360 100 -300
|
||||
A 100 -270 30 -900 900 0 1 8 N 100 -300 100 -240
|
||||
A 100 -210 30 -900 900 0 1 8 N 100 -240 100 -180
|
||||
A 100 210 30 -900 900 0 1 8 N 100 180 100 240
|
||||
A 100 270 30 -900 900 0 1 8 N 100 240 100 300
|
||||
A 100 330 30 -900 900 0 1 8 N 100 300 100 360
|
||||
A 100 390 30 -900 900 0 1 8 N 100 360 100 420
|
||||
A -100 90 30 900 -900 1 1 8 N -100 120 -100 60
|
||||
C -100 90 10 0 1 0 F
|
||||
C 100 -210 10 0 1 0 F
|
||||
C 100 390 10 0 1 0 F
|
||||
P 2 0 1 0 -100 -120 -100 -200 N
|
||||
P 2 0 1 0 -100 200 -100 120 N
|
||||
P 2 0 1 0 -25 425 -25 -425 N
|
||||
P 2 0 1 0 25 425 25 -425 N
|
||||
P 2 0 1 0 100 -420 100 -500 N
|
||||
P 2 0 1 0 100 -100 100 -180 N
|
||||
P 2 0 1 0 100 180 100 100 N
|
||||
P 2 0 1 0 100 500 100 420 N
|
||||
X ~ 1 200 500 100 L 50 50 1 1 P
|
||||
X ~ 2 200 100 100 L 50 50 1 1 P
|
||||
X ~ 3 -200 200 100 R 50 50 1 1 P
|
||||
X ~ 4 -200 -200 100 R 50 50 1 1 P
|
||||
X ~ 5 200 -100 100 L 50 50 1 1 P
|
||||
X ~ 6 200 -500 100 L 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
12844
interface1/hardware/schematic.svg
Normal file
12844
interface1/hardware/schematic.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 216 KiB |
3
interface1/hardware/sym-lib-table
Normal file
3
interface1/hardware/sym-lib-table
Normal file
@@ -0,0 +1,3 @@
|
||||
(sym_lib_table
|
||||
(lib (name library)(type Legacy)(uri ${KIPRJMOD}/library.lib)(options "")(descr ""))
|
||||
)
|
||||
112
pycoax/.gitignore
vendored
Normal file
112
pycoax/.gitignore
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
VIRTUALENV/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
13
pycoax/LICENSE
Normal file
13
pycoax/LICENSE
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright (c) 2019, Andrew Kay
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
9
pycoax/README.md
Normal file
9
pycoax/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# pycoax
|
||||
|
||||
Python IBM 3270 coaxial interface library.
|
||||
|
||||
## Use
|
||||
|
||||
You will need to build a [interface](../interface1) and connect it to your computer.
|
||||
|
||||
See [examples](examples) for complete examples.
|
||||
1
pycoax/coax/__about__.py
Normal file
1
pycoax/coax/__about__.py
Normal file
@@ -0,0 +1 @@
|
||||
__version__ = '0.1.0'
|
||||
39
pycoax/coax/__init__.py
Normal file
39
pycoax/coax/__init__.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from .__about__ import __version__
|
||||
|
||||
from .interface1 import Interface1
|
||||
|
||||
from .protocol import (
|
||||
PollResponse,
|
||||
PowerOnResetCompletePollResponse,
|
||||
KeystrokePollResponse,
|
||||
poll,
|
||||
poll_ack,
|
||||
read_status,
|
||||
read_terminal_id,
|
||||
read_extended_id,
|
||||
read_address_counter_hi,
|
||||
read_address_counter_lo,
|
||||
read_data,
|
||||
read_multiple,
|
||||
reset,
|
||||
load_control_register,
|
||||
load_secondary_control,
|
||||
load_mask,
|
||||
load_address_counter_hi,
|
||||
load_address_counter_lo,
|
||||
write_data,
|
||||
clear,
|
||||
search_forward,
|
||||
search_backward,
|
||||
insert_byte,
|
||||
start_operation,
|
||||
diagnostic_reset
|
||||
)
|
||||
|
||||
from .exceptions import (
|
||||
InterfaceError,
|
||||
ReceiveError,
|
||||
InterfaceTimeout,
|
||||
ReceiveTimeout,
|
||||
ProtocolError
|
||||
)
|
||||
19
pycoax/coax/exceptions.py
Normal file
19
pycoax/coax/exceptions.py
Normal file
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
coax.exceptions
|
||||
~~~~~~~~~~~~~~~
|
||||
"""
|
||||
|
||||
class InterfaceError(Exception):
|
||||
"""An interface error occurred."""
|
||||
|
||||
class ReceiveError(Exception):
|
||||
"""A receive error occurred."""
|
||||
|
||||
class InterfaceTimeout(Exception):
|
||||
"""The interface timed out."""
|
||||
|
||||
class ReceiveTimeout(Exception):
|
||||
"""The receive operation timed out."""
|
||||
|
||||
class ProtocolError(Exception):
|
||||
"""A protocol error occurred."""
|
||||
218
pycoax/coax/interface1.py
Normal file
218
pycoax/coax/interface1.py
Normal file
@@ -0,0 +1,218 @@
|
||||
"""
|
||||
coax.interface1
|
||||
~~~~~~~~~~~~~~~
|
||||
"""
|
||||
|
||||
from enum import Flag
|
||||
import itertools
|
||||
import struct
|
||||
from sliplib import SlipWrapper, ProtocolError
|
||||
|
||||
from .exceptions import InterfaceError, InterfaceTimeout, ReceiveError, ReceiveTimeout
|
||||
|
||||
class Interface1:
|
||||
"""A serial attached Arduino interface using the National Semiconductor
|
||||
DP8340 and DP8341.
|
||||
"""
|
||||
|
||||
def __init__(self, serial):
|
||||
if serial is None:
|
||||
raise ValueError('Serial port is required')
|
||||
|
||||
self.serial = serial
|
||||
|
||||
self.slip_serial = SlipSerial(self.serial)
|
||||
|
||||
def reset(self):
|
||||
"""Reset the interface."""
|
||||
original_serial_timeout = self.serial.timeout
|
||||
|
||||
self.serial.reset_input_buffer()
|
||||
|
||||
self._write_message(b'\x01')
|
||||
|
||||
self.serial.timeout = 5
|
||||
|
||||
try:
|
||||
message = self._read_message()
|
||||
finally:
|
||||
self.serial.timeout = original_serial_timeout
|
||||
|
||||
if message[0] != 0x01:
|
||||
raise _convert_error(message)
|
||||
|
||||
if len(message) != 4:
|
||||
raise InterfaceError('Invalid reset response')
|
||||
|
||||
(major, minor, patch) = struct.unpack('BBB', message[1:])
|
||||
|
||||
return '{}.{}.{}'.format(major, minor, patch)
|
||||
|
||||
def execute(self, command_word, data=None, response_length=1, timeout=None):
|
||||
"""Executes a command.
|
||||
|
||||
:param command_word: the command to execute
|
||||
:param data: optional bytearray containing command data
|
||||
:param response_length: the expected response length
|
||||
:param timeout: optional timeout in seconds
|
||||
"""
|
||||
timeout_milliseconds = 0
|
||||
|
||||
if timeout:
|
||||
if self.serial.timeout and timeout > self.serial.timeout:
|
||||
raise ValueError('Timeout cannot be greater than serial timeout')
|
||||
|
||||
timeout_milliseconds = int(timeout * 1000)
|
||||
|
||||
message = struct.pack(">BHHH", 0x02, command_word, response_length,
|
||||
timeout_milliseconds)
|
||||
|
||||
if data is not None:
|
||||
message += data
|
||||
|
||||
self._write_message(message)
|
||||
|
||||
message = self._read_message()
|
||||
|
||||
if message[0] != 0x01:
|
||||
raise _convert_error(message)
|
||||
|
||||
response_bytes = message[1:]
|
||||
|
||||
response_words = [(hi << 8) | lo for (lo, hi) in zip(response_bytes[::2],
|
||||
response_bytes[1::2])]
|
||||
|
||||
# Handle any receiver (DP8341) errors that are included in the response words.
|
||||
error_words = [word for word in response_words if (word & 0x8000) == 0x8000]
|
||||
|
||||
if error_words:
|
||||
raise _convert_receiver_errors(error_words)
|
||||
|
||||
return response_words
|
||||
|
||||
def offload_load_address_counter(self, address):
|
||||
"""Executes a combined LO and HI address counter load.
|
||||
|
||||
:param address: the address
|
||||
"""
|
||||
parameters = struct.pack(">H", address)
|
||||
|
||||
self._execute_offload(0x01, parameters)
|
||||
|
||||
def offload_write(self, data, address=None, restore_original_address=False, repeat=0):
|
||||
"""Executes a complex write operation.
|
||||
|
||||
:param data: the data
|
||||
:param address: optional address to load before WRITE_DATA command
|
||||
:param restore_original_address: restore the original data after write
|
||||
:param repeat: repeat the data
|
||||
"""
|
||||
parameters = struct.pack(">HBH", 0xffff if address is None else address,
|
||||
0x01 if restore_original_address else 0x00,
|
||||
repeat) + data
|
||||
|
||||
self._execute_offload(0x02, parameters)
|
||||
|
||||
def _execute_offload(self, command, parameters=None):
|
||||
"""Executes an offloaded command."""
|
||||
message = struct.pack("BB", 0x03, command)
|
||||
|
||||
if parameters:
|
||||
message += parameters
|
||||
|
||||
self._write_message(message)
|
||||
|
||||
message = self._read_message()
|
||||
|
||||
if message[0] != 0x01:
|
||||
raise _convert_error(message)
|
||||
|
||||
def _read_message(self):
|
||||
try:
|
||||
message = self.slip_serial.recv_msg()
|
||||
except ProtocolError:
|
||||
raise InterfaceError('SLIP protocol error')
|
||||
|
||||
if len(message) < 4:
|
||||
raise InterfaceError('Invalid response message')
|
||||
|
||||
(length,) = struct.unpack(">H", message[:2])
|
||||
|
||||
if length != len(message) - 4:
|
||||
raise InterfaceError('Response message length mismatch')
|
||||
|
||||
if length < 1:
|
||||
raise InterfaceError('Empty response message')
|
||||
|
||||
return message[2:-2]
|
||||
|
||||
def _write_message(self, message):
|
||||
self.slip_serial.send_msg(struct.pack(">H", len(message)) + message + struct.pack(">H", 0))
|
||||
|
||||
ERROR_MAP = {
|
||||
1: InterfaceError('Invalid request message'),
|
||||
2: InterfaceError('Unknown command'),
|
||||
3: InterfaceError('Unknown offload command'),
|
||||
|
||||
101: InterfaceError('Receiver active'),
|
||||
102: ReceiveTimeout(),
|
||||
103: ReceiveError('Receiver buffer overflow')
|
||||
}
|
||||
|
||||
def _convert_error(message):
|
||||
if message[0] != 0x02:
|
||||
return InterfaceError('Invalid response')
|
||||
|
||||
if len(message) < 2:
|
||||
return InterfaceError('Invalid error response')
|
||||
|
||||
if message[1] in ERROR_MAP:
|
||||
return ERROR_MAP[message[1]]
|
||||
|
||||
return InterfaceError('Unknown error')
|
||||
|
||||
class ReceiverErrorCode(Flag):
|
||||
"""Receiver (DP8341) error code."""
|
||||
DATA_OVERFLOW = 0x01
|
||||
PARITY = 0x02
|
||||
TRANSMIT_CHECK_CONDITIONS = 0x04
|
||||
INVALID_ENDING_SEQUENCE = 0x08
|
||||
MID_BID_TRANSITION = 0x10
|
||||
STARTING_SEQUENCE = 0x20
|
||||
RECEIVER_DISABLED = 0x40
|
||||
|
||||
def _parse_receiver_error(word):
|
||||
return [code for code in ReceiverErrorCode if code & ReceiverErrorCode(word & 0x7f)]
|
||||
|
||||
def _convert_receiver_errors(words):
|
||||
codes = set(itertools.chain.from_iterable([_parse_receiver_error(word) for word
|
||||
in words]))
|
||||
|
||||
message = 'Receiver ' + ', '.join([code.name for code in codes]) + ' error'
|
||||
|
||||
raise ReceiveError(message)
|
||||
|
||||
class SlipSerial(SlipWrapper):
|
||||
"""sliplib wrapper for pySerial."""
|
||||
|
||||
def send_bytes(self, packet):
|
||||
"""Sends a packet over the serial port."""
|
||||
self.stream.write(packet)
|
||||
self.stream.flush()
|
||||
|
||||
def recv_bytes(self):
|
||||
"""Receive data from the serial port."""
|
||||
if self.stream.closed:
|
||||
return b''
|
||||
|
||||
count = self.stream.in_waiting
|
||||
|
||||
if count:
|
||||
return self.stream.read(count)
|
||||
|
||||
byte = self.stream.read(1)
|
||||
|
||||
if byte == b'':
|
||||
raise InterfaceTimeout()
|
||||
|
||||
return byte
|
||||
26
pycoax/coax/parity.py
Normal file
26
pycoax/coax/parity.py
Normal file
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
coax.parity
|
||||
~~~~~~~~~~~
|
||||
|
||||
Single byte parity computation
|
||||
"""
|
||||
|
||||
# From http://p-nand-q.com/python/algorithms/math/bit-parity.html
|
||||
def _parallel_swar(i):
|
||||
i = i - ((i >> 1) & 0x55555555)
|
||||
i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
|
||||
i = (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24
|
||||
return int(i % 2)
|
||||
|
||||
_PARITY_LOOKUP = [_parallel_swar(i) for i in range(256)]
|
||||
|
||||
def even_parity(byte):
|
||||
"""Compute even parity"""
|
||||
if byte < 0 or byte > 255:
|
||||
raise ValueError('Input must be between 0 and 255')
|
||||
|
||||
return _PARITY_LOOKUP[byte]
|
||||
|
||||
def odd_parity(byte):
|
||||
"""Compute odd parity"""
|
||||
return int(not even_parity(byte))
|
||||
238
pycoax/coax/protocol.py
Normal file
238
pycoax/coax/protocol.py
Normal file
@@ -0,0 +1,238 @@
|
||||
"""
|
||||
coax.protocol
|
||||
~~~~~~~~~~~~~
|
||||
"""
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from .exceptions import ProtocolError
|
||||
from .parity import odd_parity
|
||||
|
||||
class Command(Enum):
|
||||
"""Terminal command."""
|
||||
|
||||
# Read Commands
|
||||
POLL = 0x01
|
||||
POLL_ACK = 0x11
|
||||
READ_STATUS = 0x0d
|
||||
READ_TERMINAL_ID = 0x09
|
||||
READ_EXTENDED_ID = 0x07
|
||||
READ_ADDRESS_COUNTER_HI = 0x05
|
||||
READ_ADDRESS_COUNTER_LO = 0x15
|
||||
READ_DATA = 0x03
|
||||
READ_MULTIPLE = 0x0b
|
||||
|
||||
# Write Commands
|
||||
RESET = 0x02
|
||||
LOAD_CONTROL_REGISTER = 0x0a
|
||||
LOAD_SECONDARY_CONTROL = 0x1a
|
||||
LOAD_MASK = 0x16
|
||||
LOAD_ADDRESS_COUNTER_HI = 0x04
|
||||
LOAD_ADDRESS_COUNTER_LO = 0x14
|
||||
WRITE_DATA = 0x0c
|
||||
CLEAR = 0x06
|
||||
SEARCH_FORWARD = 0x10
|
||||
SEARCH_BACKWARD = 0x12
|
||||
INSERT_BYTE = 0x0e
|
||||
START_OPERATION = 0x08
|
||||
DIAGNOSTIC_RESET = 0x1c
|
||||
|
||||
class PollResponse:
|
||||
"""Terminal POLL response."""
|
||||
|
||||
@staticmethod
|
||||
def is_power_on_reset_complete(value):
|
||||
"""Is the response word a power on reset complete response?"""
|
||||
return value == 0xa
|
||||
|
||||
@staticmethod
|
||||
def is_keystroke(value):
|
||||
"""Is the response word a keystroke response?"""
|
||||
return ((value & 0x2) == 0x2) and ((value & 0x1) == 0)
|
||||
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
class PowerOnResetCompletePollResponse(PollResponse):
|
||||
"""Terminal power-on-reset complete poll response."""
|
||||
|
||||
def __init__(self, value):
|
||||
if not PollResponse.is_power_on_reset_complete(value):
|
||||
raise ValueError('Invalid POR poll response')
|
||||
|
||||
super().__init__(value)
|
||||
|
||||
class KeystrokePollResponse(PollResponse):
|
||||
"""Terminal keystroke poll response."""
|
||||
|
||||
def __init__(self, value):
|
||||
if not PollResponse.is_keystroke(value):
|
||||
raise ValueError('Invalid keystroke poll response')
|
||||
|
||||
super().__init__(value)
|
||||
|
||||
self.scan_code = (value >> 2) & 0xff
|
||||
|
||||
class TerminalId:
|
||||
"""Terminal model and keyboard."""
|
||||
|
||||
def __init__(self, value):
|
||||
if (value & 0x1) != 0:
|
||||
raise ValueError('Invalid terminal identifier')
|
||||
|
||||
self.value = value
|
||||
|
||||
self.model = (value & 0x0e) >> 1
|
||||
self.keyboard = (value & 0xf0) >> 4
|
||||
|
||||
def poll(interface, **kwargs):
|
||||
"""Execute a POLL command."""
|
||||
command_word = _pack_command_word(Command.POLL)
|
||||
|
||||
response = interface.execute(command_word, **kwargs)
|
||||
|
||||
if len(response) != 1:
|
||||
raise ProtocolError('Expected 1 word POLL response')
|
||||
|
||||
word = response[0]
|
||||
|
||||
if word == 0:
|
||||
return None
|
||||
|
||||
if PollResponse.is_power_on_reset_complete(word):
|
||||
return PowerOnResetCompletePollResponse(word)
|
||||
|
||||
if PollResponse.is_keystroke(word):
|
||||
return KeystrokePollResponse(word)
|
||||
|
||||
return PollResponse(word)
|
||||
|
||||
def poll_ack(interface, **kwargs):
|
||||
"""Execute a POLL_ACK command."""
|
||||
_execute_write_command(interface, Command.POLL_ACK, **kwargs)
|
||||
|
||||
def read_status(interface):
|
||||
"""Execute a READ_STATUS command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def read_terminal_id(interface, **kwargs):
|
||||
"""Execute a READ_TERMINAL_ID command."""
|
||||
response = _execute_read_command(interface, Command.READ_TERMINAL_ID, **kwargs)
|
||||
|
||||
return TerminalId(response[0])
|
||||
|
||||
def read_extended_id(interface, **kwargs):
|
||||
"""Execute a READ_EXTENDED_ID command."""
|
||||
return _execute_read_command(interface, Command.READ_EXTENDED_ID, 4, **kwargs)
|
||||
|
||||
def read_address_counter_hi(interface, **kwargs):
|
||||
"""Execute a READ_ADDRESS_COUNTER_HI command."""
|
||||
return _execute_read_command(interface, Command.READ_ADDRESS_COUNTER_HI, **kwargs)[0]
|
||||
|
||||
def read_address_counter_lo(interface, **kwargs):
|
||||
"""Execute a READ_ADDRESS_COUTER_LO command."""
|
||||
return _execute_read_command(interface, Command.READ_ADDRESS_COUNTER_LO, **kwargs)[0]
|
||||
|
||||
def read_data(interface):
|
||||
"""Execute a READ_DATA command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def read_multiple(interface):
|
||||
"""Execute a READ_MULTIPLE command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def reset(interface):
|
||||
"""Execute a RESET command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def load_control_register(interface):
|
||||
"""Execute a LOAD_CONTROL_REGISTER command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def load_secondary_control(interface):
|
||||
"""Execute a LOAD_SECONDARY_CONTROL command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def load_mask(interface):
|
||||
"""Execute a LOAD_MASK command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def load_address_counter_hi(interface, address, **kwargs):
|
||||
"""Execute a LOAD_ADDRESS_COUNTER_HI command."""
|
||||
_execute_write_command(interface, Command.LOAD_ADDRESS_COUNTER_HI, bytes([address]), **kwargs)
|
||||
|
||||
def load_address_counter_lo(interface, address, **kwargs):
|
||||
"""Execute a LOAD_ADDRESS_COUNTER_LO command."""
|
||||
_execute_write_command(interface, Command.LOAD_ADDRESS_COUNTER_LO, bytes([address]), **kwargs)
|
||||
|
||||
def write_data(interface, data, **kwargs):
|
||||
"""Execute a WRITE_DATA command."""
|
||||
_execute_write_command(interface, Command.WRITE_DATA, data, **kwargs)
|
||||
|
||||
def clear(interface):
|
||||
"""Execute a CLEAR command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def search_forward(interface):
|
||||
"""Execute a SEARCH_FORWARD command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def search_backward(interface):
|
||||
"""Execute a SEARCH_BACKWARD command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def insert_byte(interface):
|
||||
"""Execute a INSERT_BYTE command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def start_operation(interface):
|
||||
"""Execute a START_OPERATION command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def diagnostic_reset(interface):
|
||||
"""Execute a DIAGNOSTIC_RESET command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def _execute_read_command(interface, command, response_length=1):
|
||||
"""Execute a standard read command."""
|
||||
command_word = _pack_command_word(command)
|
||||
|
||||
response_words = interface.execute(command_word, response_length=response_length)
|
||||
|
||||
if len(response_words) != response_length:
|
||||
raise ProtocolError(f'Expected {response_length} word {command.name} response')
|
||||
|
||||
return _unpack_data_words(response_words)
|
||||
|
||||
def _execute_write_command(interface, command, data=None):
|
||||
"""Execute a standard write command."""
|
||||
command_word = _pack_command_word(command)
|
||||
|
||||
response_words = interface.execute(command_word, data)
|
||||
|
||||
if len(response_words) != 1:
|
||||
raise ProtocolError(f'Expected 1 word {command.name} response')
|
||||
|
||||
if response_words[0] != 0:
|
||||
raise ProtocolError('Expected TR/TA response')
|
||||
|
||||
def _pack_command_word(command, address=0):
|
||||
"""Pack a command and address into a 10-bit command word for the interface."""
|
||||
return (address << 7) | (command.value << 2) | 0x1
|
||||
|
||||
def _unpack_data_words(words):
|
||||
"""Unpack the data bytes from 10-bit data words, performs parity checking."""
|
||||
return bytes([_unpack_data_word(word) for word in words])
|
||||
|
||||
def _unpack_data_word(word):
|
||||
"""Unpack the data byte from a 10-bit data word, performs parity checking."""
|
||||
if not (word & 0x1) == 0x0:
|
||||
raise ProtocolError('Word does not have data bit set')
|
||||
|
||||
byte = (word >> 2) & 0xff
|
||||
parity = (word >> 1) & 0x1
|
||||
|
||||
if not odd_parity(byte) == parity:
|
||||
raise ProtocolError('Parity error')
|
||||
|
||||
return byte
|
||||
24
pycoax/examples/01_reset.py
Executable file
24
pycoax/examples/01_reset.py
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import time
|
||||
from serial import Serial
|
||||
|
||||
sys.path.append('..')
|
||||
|
||||
from coax import Interface1, poll, poll_ack
|
||||
|
||||
print('Opening serial port...')
|
||||
|
||||
with Serial('/dev/ttyUSB0', 115200) as serial:
|
||||
print('Sleeping to allow interface time to wake up...')
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
interface = Interface1(serial)
|
||||
|
||||
print('Resetting interface...')
|
||||
|
||||
version = interface.reset()
|
||||
|
||||
print(f'Firmware version is {version}')
|
||||
35
pycoax/examples/02_poll.py
Executable file
35
pycoax/examples/02_poll.py
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import time
|
||||
from serial import Serial
|
||||
|
||||
sys.path.append('..')
|
||||
|
||||
from coax import Interface1, poll, poll_ack
|
||||
|
||||
print('Opening serial port...')
|
||||
|
||||
with Serial('/dev/ttyUSB0', 115200) as serial:
|
||||
print('Sleeping to allow interface time to wake up...')
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
interface = Interface1(serial)
|
||||
|
||||
print('Resetting interface...')
|
||||
|
||||
version = interface.reset()
|
||||
|
||||
print(f'Firmware version is {version}')
|
||||
|
||||
print('POLL...')
|
||||
|
||||
poll_response = poll(interface, timeout=5)
|
||||
|
||||
print(poll_response)
|
||||
|
||||
if poll_response:
|
||||
print('POLL_ACK...')
|
||||
|
||||
poll_ack(interface)
|
||||
30
pycoax/examples/03_read_terminal_id.py
Executable file
30
pycoax/examples/03_read_terminal_id.py
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import time
|
||||
from serial import Serial
|
||||
|
||||
sys.path.append('..')
|
||||
|
||||
from coax import Interface1, read_terminal_id
|
||||
|
||||
print('Opening serial port...')
|
||||
|
||||
with Serial('/dev/ttyUSB0', 115200) as serial:
|
||||
print('Sleeping to allow interface time to wake up...')
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
interface = Interface1(serial)
|
||||
|
||||
print('Resetting interface...')
|
||||
|
||||
version = interface.reset()
|
||||
|
||||
print(f'Firmware version is {version}')
|
||||
|
||||
print('READ_TERMINAL_ID...')
|
||||
|
||||
terminal_id = read_terminal_id(interface)
|
||||
|
||||
print(terminal_id)
|
||||
46
pycoax/examples/04_hello_world.py
Executable file
46
pycoax/examples/04_hello_world.py
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import time
|
||||
from serial import Serial
|
||||
|
||||
sys.path.append('..')
|
||||
|
||||
from coax import Interface1, read_address_counter_hi, read_address_counter_lo, load_address_counter_hi, load_address_counter_lo, write_data
|
||||
|
||||
print('Opening serial port...')
|
||||
|
||||
with Serial('/dev/ttyUSB0', 115200) as serial:
|
||||
print('Sleeping to allow interface time to wake up...')
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
interface = Interface1(serial)
|
||||
|
||||
print('Resetting interface...')
|
||||
|
||||
version = interface.reset()
|
||||
|
||||
print(f'Firmware version is {version}')
|
||||
|
||||
print('LOAD_ADDRESS_COUNTER_HI...')
|
||||
|
||||
load_address_counter_hi(interface, 0)
|
||||
|
||||
print('LOAD_ADDRESS_COUNTER_LO...')
|
||||
|
||||
load_address_counter_lo(interface, 80)
|
||||
|
||||
print('WRITE_DATA...')
|
||||
|
||||
write_data(interface, bytes.fromhex('a7 84 8b 8b 8e 33 00 96 8e 91 8b 83 19'))
|
||||
|
||||
print('READ_ADDRESS_COUNTER_HI...')
|
||||
|
||||
hi = read_address_counter_hi(interface)
|
||||
|
||||
print('READ_ADDRESS_COUNTER_LO...')
|
||||
|
||||
lo = read_address_counter_lo(interface)
|
||||
|
||||
print(f'hi = {hi:02x}, lo = {lo:02x}')
|
||||
31
pycoax/examples/05_offload_write.py
Executable file
31
pycoax/examples/05_offload_write.py
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import time
|
||||
from serial import Serial
|
||||
|
||||
sys.path.append('..')
|
||||
|
||||
from coax import Interface1
|
||||
|
||||
print('Opening serial port...')
|
||||
|
||||
with Serial('/dev/ttyUSB0', 115200) as serial:
|
||||
print('Sleeping to allow interface time to wake up...')
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
interface = Interface1(serial)
|
||||
|
||||
print('Resetting interface...')
|
||||
|
||||
version = interface.reset()
|
||||
|
||||
print(f'Firmware version is {version}')
|
||||
|
||||
for n in range(10):
|
||||
print(f'Writing line {n + 1}...')
|
||||
|
||||
address = ((7 + n) * 80) + 80
|
||||
|
||||
interface.offload_write(b'\x80', address=address, repeat=n)
|
||||
2
pycoax/requirements.txt
Normal file
2
pycoax/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
pyserial==3.4
|
||||
sliplib==0.3.0
|
||||
3
pycoax/run_unit_tests.sh
Executable file
3
pycoax/run_unit_tests.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
python -m unittest discover tests
|
||||
35
pycoax/setup.py
Normal file
35
pycoax/setup.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import os
|
||||
from setuptools import setup
|
||||
|
||||
ABOUT = {}
|
||||
|
||||
with open(os.path.join(os.path.dirname(__file__), "coax", "__about__.py")) as file:
|
||||
exec(file.read(), ABOUT)
|
||||
|
||||
LONG_DESCRIPTION = """# pycoax
|
||||
|
||||
Python IBM 3270 coaxial interface library.
|
||||
|
||||
See [GitHub](https://github.com/lowobservable/coax-interface#readme) for more information.
|
||||
"""
|
||||
|
||||
setup(
|
||||
name='pycoax',
|
||||
version=ABOUT['__version__'],
|
||||
description='IBM 3270 coaxial interface',
|
||||
url='https://github.com/lowobservable/coax-interface',
|
||||
author='Andrew Kay',
|
||||
author_email='projects@ajk.me',
|
||||
packages=['coax'],
|
||||
install_requires=['pyserial==3.4', 'sliplib==0.3.0'],
|
||||
long_description=LONG_DESCRIPTION,
|
||||
long_description_content_type='text/markdown',
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'License :: OSI Approved :: ISC License (ISCL)',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Topic :: Communications',
|
||||
'Topic :: Terminals'
|
||||
]
|
||||
)
|
||||
0
pycoax/tests/__init__.py
Normal file
0
pycoax/tests/__init__.py
Normal file
4
pycoax/tests/context.py
Normal file
4
pycoax/tests/context.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||
264
pycoax/tests/test_interface1.py
Normal file
264
pycoax/tests/test_interface1.py
Normal file
@@ -0,0 +1,264 @@
|
||||
import unittest
|
||||
from unittest.mock import Mock
|
||||
import sliplib
|
||||
|
||||
import context
|
||||
|
||||
from coax import Interface1, InterfaceError, ReceiveError, ReceiveTimeout
|
||||
|
||||
class Interface1ResetTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serial = Mock()
|
||||
|
||||
self.serial.timeout = None
|
||||
|
||||
self.interface = Interface1(self.serial)
|
||||
|
||||
self.interface._write_message = Mock()
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('01 01 02 03'))
|
||||
|
||||
def test_message_is_sent(self):
|
||||
# Act
|
||||
self.interface.reset()
|
||||
|
||||
# Assert
|
||||
self.interface._write_message.assert_called_with(bytes.fromhex('01'))
|
||||
|
||||
def test_version_is_formatted_correctly(self):
|
||||
self.assertEqual(self.interface.reset(), '1.2.3')
|
||||
|
||||
def test_timeout_is_restored_after_reset(self):
|
||||
# Arrange
|
||||
self.serial.timeout = 123
|
||||
|
||||
# Act
|
||||
self.interface.reset()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(self.serial.timeout, 123)
|
||||
|
||||
def test_invalid_message_length_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('01 01'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(InterfaceError, 'Invalid reset response'):
|
||||
self.interface.reset()
|
||||
|
||||
def test_error_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('02 01'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(InterfaceError, 'Invalid request message'):
|
||||
self.interface.reset()
|
||||
|
||||
class Interface1ExecuteTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serial = Mock()
|
||||
|
||||
self.serial.timeout = None
|
||||
|
||||
self.interface = Interface1(self.serial)
|
||||
|
||||
self.interface._write_message = Mock()
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('01 00'))
|
||||
|
||||
def test_message_is_sent_without_data(self):
|
||||
# Act
|
||||
self.interface.execute(0b0000001001)
|
||||
|
||||
# Assert
|
||||
self.interface._write_message.assert_called_with(bytes.fromhex('02 00 09 00 01 00 00'))
|
||||
|
||||
def test_message_is_sent_with_data(self):
|
||||
# Act
|
||||
self.interface.execute(0b0000110001, data=bytes.fromhex('de ad be ef'))
|
||||
|
||||
# Assert
|
||||
self.interface._write_message.assert_called_with(bytes.fromhex('02 00 31 00 01 00 00 de ad be ef'))
|
||||
|
||||
def test_message_is_sent_with_response_length(self):
|
||||
# Act
|
||||
self.interface.execute(0b0000011101, response_length=4)
|
||||
|
||||
# Assert
|
||||
self.interface._write_message.assert_called_with(bytes.fromhex('02 00 1d 00 04 00 00'))
|
||||
|
||||
def test_timeout_cannot_exceed_serial_timeout(self):
|
||||
# Arrange
|
||||
self.serial.timeout = 2.0
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(ValueError, 'Timeout cannot be greater than serial timeout'):
|
||||
self.interface.execute(0b0000000101, timeout=3)
|
||||
|
||||
def test_message_is_sent_with_timeout(self):
|
||||
# Act
|
||||
self.interface.execute(0b0000000101, timeout=3)
|
||||
|
||||
# Assert
|
||||
self.interface._write_message.assert_called_with(bytes.fromhex('02 00 05 00 01 0b b8'))
|
||||
|
||||
# TODO... interface timeout...
|
||||
|
||||
def test_receive_timeout_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('02 66'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaises(ReceiveTimeout):
|
||||
self.interface.execute(0b0000000101)
|
||||
|
||||
def test_receive_error_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('02 67'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(ReceiveError, 'Receiver buffer overflow'):
|
||||
self.interface.execute(0b0000000101)
|
||||
|
||||
def test_interface_error_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('03'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(InterfaceError, 'Invalid response'):
|
||||
self.interface.execute(0b0000000101)
|
||||
|
||||
def test_response_words_are_unpacked(self):
|
||||
# Arrange
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('01 01 02 03 04'))
|
||||
|
||||
# Act
|
||||
response_words = self.interface.execute(0b0000011101, response_length=4)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(response_words, [0x0201, 0x0403])
|
||||
|
||||
def test_receiver_error_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface._read_message = Mock(return_value=bytes.fromhex('01 a0 80'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(ReceiveError, 'Receiver STARTING_SEQUENCE error'):
|
||||
self.interface.execute(0b0000011101, response_length=4)
|
||||
|
||||
class Interface1OffloadLoadAddressCounterTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serial = Mock()
|
||||
|
||||
self.interface = Interface1(self.serial)
|
||||
|
||||
self.interface._execute_offload = Mock()
|
||||
|
||||
def test(self):
|
||||
# Act
|
||||
self.interface.offload_load_address_counter(960)
|
||||
|
||||
# Assert
|
||||
self.interface._execute_offload.assert_called_with(0x01, bytes.fromhex('03 c0'))
|
||||
|
||||
class Interface1OffloadWriteTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serial = Mock()
|
||||
|
||||
self.interface = Interface1(self.serial)
|
||||
|
||||
self.interface._execute_offload = Mock()
|
||||
|
||||
def test_message_is_sent_with_data(self):
|
||||
# Act
|
||||
self.interface.offload_write(bytes.fromhex('de ad be ef'))
|
||||
|
||||
# Assert
|
||||
self.interface._execute_offload.assert_called_with(0x02, bytes.fromhex('ff ff 00 00 00 de ad be ef'))
|
||||
|
||||
def test_message_is_sent_with_address(self):
|
||||
# Act
|
||||
self.interface.offload_write(bytes.fromhex('de ad be ef'), address=960)
|
||||
|
||||
# Assert
|
||||
self.interface._execute_offload.assert_called_with(0x02, bytes.fromhex('03 c0 00 00 00 de ad be ef'))
|
||||
|
||||
def test_message_is_sent_with_restore_original_address(self):
|
||||
# Act
|
||||
self.interface.offload_write(bytes.fromhex('de ad be ef'), restore_original_address=True)
|
||||
|
||||
# Assert
|
||||
self.interface._execute_offload.assert_called_with(0x02, bytes.fromhex('ff ff 01 00 00 de ad be ef'))
|
||||
|
||||
def test_message_is_sent_with_repeat(self):
|
||||
# Act
|
||||
self.interface.offload_write(bytes.fromhex('de ad be ef'), repeat=1)
|
||||
|
||||
# Assert
|
||||
self.interface._execute_offload.assert_called_with(0x02, bytes.fromhex('ff ff 00 00 01 de ad be ef'))
|
||||
|
||||
class Interface1ReadMessageTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serial = Mock()
|
||||
|
||||
self.interface = Interface1(self.serial)
|
||||
|
||||
self.interface.slip_serial = Mock()
|
||||
|
||||
def test(self):
|
||||
# Arrange
|
||||
self.interface.slip_serial.recv_msg = Mock(return_value=bytes.fromhex('00 04 01 02 03 04 00 00'))
|
||||
|
||||
# Act
|
||||
message = self.interface._read_message()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(message, bytes.fromhex('01 02 03 04'))
|
||||
|
||||
def test_protocol_error_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface.slip_serial.recv_msg = Mock(side_effect=sliplib.ProtocolError)
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(InterfaceError, 'SLIP protocol error'):
|
||||
self.interface._read_message()
|
||||
|
||||
def test_invalid_message_length_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface.slip_serial.recv_msg = Mock(return_value=bytes.fromhex('00'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(InterfaceError, 'Invalid response message'):
|
||||
self.interface._read_message()
|
||||
|
||||
def test_message_length_mismatch_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface.slip_serial.recv_msg = Mock(return_value=bytes.fromhex('00 05 01 02 03 04 00 00'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(InterfaceError, 'Response message length mismatch'):
|
||||
self.interface._read_message()
|
||||
|
||||
def test_empty_message_is_handled_correctly(self):
|
||||
# Arrange
|
||||
self.interface.slip_serial.recv_msg = Mock(return_value=bytes.fromhex('00 00 00 00'))
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(InterfaceError, 'Empty response message'):
|
||||
self.interface._read_message()
|
||||
|
||||
class Interface1WriteMessageTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serial = Mock()
|
||||
|
||||
self.interface = Interface1(self.serial)
|
||||
|
||||
self.interface.slip_serial = Mock()
|
||||
|
||||
def test(self):
|
||||
# Act
|
||||
self.interface._write_message(bytes.fromhex('01 02 03 04'))
|
||||
|
||||
# Assert
|
||||
self.interface.slip_serial.send_msg.assert_called_with(bytes.fromhex('00 04 01 02 03 04 00 00'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
34
pycoax/tests/test_parity.py
Normal file
34
pycoax/tests/test_parity.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import unittest
|
||||
|
||||
import context
|
||||
|
||||
from coax.parity import even_parity, odd_parity
|
||||
|
||||
class EvenParityTestCase(unittest.TestCase):
|
||||
def test_with_even_input(self):
|
||||
self.assertEqual(even_parity(0b00000000), 0)
|
||||
|
||||
def test_with_odd_input(self):
|
||||
self.assertEqual(even_parity(0b00000001), 1)
|
||||
|
||||
def test_with_out_of_range_input(self):
|
||||
for input in [-1, 256]:
|
||||
with self.subTest(input=input):
|
||||
with self.assertRaises(ValueError):
|
||||
even_parity(input)
|
||||
|
||||
class OddParityTestCase(unittest.TestCase):
|
||||
def test_with_even_input(self):
|
||||
self.assertEqual(odd_parity(0b00000000), 1)
|
||||
|
||||
def test_with_odd_input(self):
|
||||
self.assertEqual(odd_parity(0b00000001), 0)
|
||||
|
||||
def test_with_out_of_range_input(self):
|
||||
for input in [-1, 256]:
|
||||
with self.subTest(input=input):
|
||||
with self.assertRaises(ValueError):
|
||||
odd_parity(input)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
99
pycoax/tests/test_protocol.py
Normal file
99
pycoax/tests/test_protocol.py
Normal file
@@ -0,0 +1,99 @@
|
||||
import unittest
|
||||
from unittest.mock import Mock
|
||||
|
||||
import context
|
||||
|
||||
from coax import PollResponse, KeystrokePollResponse, ProtocolError
|
||||
from coax.protocol import Command, _execute_read_command, _execute_write_command, _pack_command_word, _unpack_data_words, _unpack_data_word
|
||||
|
||||
class PollResponseTestCase(unittest.TestCase):
|
||||
def test_is_power_on_reset_complete(self):
|
||||
self.assertTrue(PollResponse.is_power_on_reset_complete(0b0000001010))
|
||||
|
||||
def test_is_keystroke(self):
|
||||
self.assertTrue(PollResponse.is_keystroke(0b1111111110))
|
||||
|
||||
class KeystrokePollResponseTestCase(unittest.TestCase):
|
||||
def test(self):
|
||||
# Act
|
||||
response = KeystrokePollResponse(0b1111111110)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(response.scan_code, 0xff)
|
||||
|
||||
def test_not_a_keystroke(self):
|
||||
with self.assertRaisesRegex(ValueError, 'Invalid keystroke poll response'):
|
||||
response = KeystrokePollResponse(0b0000001000)
|
||||
|
||||
class ExecuteReadCommandTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.interface = Mock()
|
||||
|
||||
def test(self):
|
||||
# Arrange
|
||||
self.interface.execute = Mock(return_value=[0b0000000010])
|
||||
|
||||
# Act and assert
|
||||
self.assertEqual(_execute_read_command(self.interface, Command.READ_TERMINAL_ID), bytes.fromhex('00'))
|
||||
|
||||
def test_unexpected_response_length(self):
|
||||
# Arrange
|
||||
self.interface.execute = Mock(return_value=[])
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(ProtocolError, 'Expected 1 word READ_TERMINAL_ID response'):
|
||||
_execute_read_command(self.interface, Command.READ_TERMINAL_ID)
|
||||
|
||||
class ExecuteWriteCommandTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.interface = Mock()
|
||||
|
||||
def test(self):
|
||||
# Arrange
|
||||
self.interface.execute = Mock(return_value=[0b0000000000])
|
||||
|
||||
# Act and assert
|
||||
_execute_write_command(self.interface, Command.WRITE_DATA, bytes.fromhex('de ad be ef'))
|
||||
|
||||
def test_unexpected_response_length(self):
|
||||
# Arrange
|
||||
self.interface.execute = Mock(return_value=[])
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(ProtocolError, 'Expected 1 word WRITE_DATA response'):
|
||||
_execute_write_command(self.interface, Command.WRITE_DATA, bytes.fromhex('de ad be ef'))
|
||||
|
||||
def test_not_tr_ta_response(self):
|
||||
# Arrange
|
||||
self.interface.execute = Mock(return_value=[0b0000000010])
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaisesRegex(ProtocolError, 'Expected TR/TA response'):
|
||||
_execute_write_command(self.interface, Command.WRITE_DATA, bytes.fromhex('de ad be ef'))
|
||||
|
||||
class PackCommandWordTestCase(unittest.TestCase):
|
||||
def test_without_address(self):
|
||||
self.assertEqual(_pack_command_word(Command.POLL_ACK), 0b001000101)
|
||||
|
||||
def test_with_address(self):
|
||||
self.assertEqual(_pack_command_word(Command.POLL_ACK, address=3), 0b111000101)
|
||||
|
||||
class UnpackDataWordsTestCase(unittest.TestCase):
|
||||
def test(self):
|
||||
self.assertEqual(_unpack_data_words([0b0000000010, 0b1111111110]), bytes.fromhex('00 ff'))
|
||||
|
||||
class UnpackDataWordTestCase(unittest.TestCase):
|
||||
def test(self):
|
||||
self.assertEqual(_unpack_data_word(0b0000000010), 0x00)
|
||||
self.assertEqual(_unpack_data_word(0b1111111110), 0xff)
|
||||
|
||||
def test_data_bit_not_set_error(self):
|
||||
with self.assertRaisesRegex(ProtocolError, 'Word does not have data bit set'):
|
||||
_unpack_data_word(0b0000000011)
|
||||
|
||||
def test_parity_error(self):
|
||||
with self.assertRaisesRegex(ProtocolError, 'Parity error'):
|
||||
_unpack_data_word(0b0000000000)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user