|
@@ -76,6 +76,65 @@ USB_ClassInfo_CDC_Device_t vcpif = {
|
|
|
},
|
|
|
};
|
|
|
|
|
|
+/*
|
|
|
+ * Motor relay sense. The motor relay is connected to PD1/INT1#, but
|
|
|
+ * the interrupt isn't being used for that purpose. Rather, it is used
|
|
|
+ * to latch an upward flank as on ABC800 this will have the output data
|
|
|
+ * fed back to it. Thus, we can check if *either* it is grounded *or*
|
|
|
+ * there has been a flank.
|
|
|
+ *
|
|
|
+ * Set up timer 3 to wrap around at 100 Hz, use this to poll and
|
|
|
+ * debounce/deglitch the relay, and to delay the sensing of the
|
|
|
+ * motor relay switch with ~160 ms.
|
|
|
+ */
|
|
|
+static void motor_sense_init(void)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Set up INT1# to latch a rising edge, but mask the resulting
|
|
|
+ * interrupt request.
|
|
|
+ */
|
|
|
+ EIMSK = 0; /* all external interrupts masked */
|
|
|
+ EICRA = 3 << ISC10; /* rising edge */
|
|
|
+ EIFR = -1; /* clear all external interrupt flags */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up timer 3 to count at fosc/8 in CTC mode,
|
|
|
+ * with wraparound at 20000 = 100 Hz.
|
|
|
+ */
|
|
|
+ TCCR3B = 0; /* Disable timer */
|
|
|
+ TCCR3A = 0; /* No capture, no waveforms */
|
|
|
+ ICR3 = (F_CPU/(8*100)) - 1; /* Top of counter */
|
|
|
+ TCNT3 = 0;
|
|
|
+ TIMSK3 = TIFR3 = (1 << ICF3); /* Interrupt on ICR3 match */
|
|
|
+ TCCR3B = (3 << WGM32)|(2 << CS30); /* fosc/8, CTC mode, TOP=ICR3 */
|
|
|
+}
|
|
|
+
|
|
|
+bool motor_relay;
|
|
|
+
|
|
|
+ISR(TIMER3_CAPT_vect)
|
|
|
+{
|
|
|
+ static uint8_t relay_ctr;
|
|
|
+ bool relay;
|
|
|
+
|
|
|
+ if (!(PORTD & 2) || (EIFR & 2)) {
|
|
|
+ /* Relay active */
|
|
|
+ EIFR = 2; /* Clear edge detect */
|
|
|
+ if (relay_ctr < 16) {
|
|
|
+ relay_ctr++;
|
|
|
+ } else if (!motor_relay) {
|
|
|
+ motor_relay = true;
|
|
|
+ fmtx_enable();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /* Relay not active */
|
|
|
+ if (relay_ctr) {
|
|
|
+ relay_ctr--;
|
|
|
+ } else {
|
|
|
+ motor_relay = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Probe for modem control status bits and send them if changed,
|
|
|
* or if forced. DSR is always set, DCD indicates if the cassette
|
|
@@ -86,16 +145,9 @@ static void update_modem_status(USB_ClassInfo_CDC_Device_t * const cii,
|
|
|
{
|
|
|
uint16_t lines = CDC_CONTROL_LINE_IN_DSR;
|
|
|
|
|
|
- if (!(PINB & (1 << 4))) /* Cassette relay active */
|
|
|
+ if (motor_relay) /* Cassette relay active */
|
|
|
lines |= CDC_CONTROL_LINE_IN_DCD;
|
|
|
|
|
|
-#if 0
|
|
|
- if (lines & CDC_CONTROL_LINE_IN_DCD)
|
|
|
- PORTB &= ~(1U << 0);
|
|
|
- else
|
|
|
- PORTB |= (1U << 0);
|
|
|
-#endif
|
|
|
-
|
|
|
if (forced || cii->State.ControlLineStates.DeviceToHost != lines) {
|
|
|
cii->State.ControlLineStates.DeviceToHost = lines;
|
|
|
CDC_Device_SendControlLineStateChange(cii);
|
|
@@ -166,7 +218,8 @@ int main(void)
|
|
|
*/
|
|
|
if (byte >= 0) {
|
|
|
RingBuffer_Insert(&u2c_ringbuf, byte);
|
|
|
- fmtx_enable();
|
|
|
+ if (motor_relay)
|
|
|
+ fmtx_enable();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -211,21 +264,80 @@ static uint32_t current_baudrate;
|
|
|
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
|
|
void SetupHardware(void)
|
|
|
{
|
|
|
-#if (ARCH == ARCH_AVR8)
|
|
|
/* Disable watchdog if enabled by bootloader/fuses */
|
|
|
MCUSR &= ~(1 << WDRF);
|
|
|
wdt_disable();
|
|
|
|
|
|
/* Disable clock division */
|
|
|
clock_prescale_set(clock_div_1);
|
|
|
-#endif
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Configure ports.
|
|
|
+ * NC: not connected, but have pads on board. Input/pullup.
|
|
|
+ * NT: not terminated on board. Output/GND.
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * PORT B:
|
|
|
+ * PB0 - RXLED#
|
|
|
+ * PB1 - NC
|
|
|
+ * PB2 - NC
|
|
|
+ * PB3 - NC
|
|
|
+ * PB4 - NC
|
|
|
+ * PB5 - NC
|
|
|
+ * PB6 - NC
|
|
|
+ * PB7 - NT
|
|
|
+ */
|
|
|
+ DDRB = 0x81;
|
|
|
+ PORTB = 0x7f;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * PORT C:
|
|
|
+ * PC6 - NC
|
|
|
+ * PC7 - NP
|
|
|
+ */
|
|
|
+ DDRC = 0x80;
|
|
|
+ PORTC = 0x40;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * PORT D:
|
|
|
+ * PD0 - data in (alt)
|
|
|
+ * PD1 - motor sense#
|
|
|
+ * PD2 - NC
|
|
|
+ * PD3 - data out
|
|
|
+ * PD4 - data in (main)
|
|
|
+ * PD5 - TXLED#
|
|
|
+ * PD6 - NT
|
|
|
+ * PD7 - NC
|
|
|
+ */
|
|
|
+ DDRD = 0x68;
|
|
|
+ PORTD = 0x93;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * PORT E:
|
|
|
+ * PE6 - NC
|
|
|
+ * PE2 - hardware bootloader, tied to GND on board
|
|
|
+ */
|
|
|
+ DDRE = 0x00;
|
|
|
+ PORTE = 0x40;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * PORT F:
|
|
|
+ * PF0 - NT
|
|
|
+ * PF1 - NT
|
|
|
+ * PF4 - NC
|
|
|
+ * PF5 - NC
|
|
|
+ * PF6 - NC
|
|
|
+ * PF7 - NC
|
|
|
+ */
|
|
|
+ DDRF = 0x03;
|
|
|
+ PORTF = 0xf0;
|
|
|
|
|
|
/* Hardware Initialization */
|
|
|
USB_Init();
|
|
|
|
|
|
- /* PORTB: PB0 - RXLED, PB4 - Relay (pullup), PB5 - relay out */
|
|
|
- PORTB |= (1 << 0) | (1 << 4);
|
|
|
- DDRB = (DDRB & ~((1 << 4))) | ((1 << 0) | (1 << 5));
|
|
|
+ /* Initialize motor sense setup */
|
|
|
+ motor_sense_init();
|
|
|
|
|
|
/* Initialize receiver and transmitter */
|
|
|
fmrx_init();
|