-
Notifications
You must be signed in to change notification settings - Fork 1
/
USBModem.c
138 lines (113 loc) · 4.47 KB
/
USBModem.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
LUFA Powered Wireless 3G Modem Host
Copyright (C) Mike Alexander, 2010.
Copyright (C) Dean Camera, 2010.
*/
/*
Copyright 2010 Mike Alexander (mike [at] mikealex [dot] com)
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim 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, 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.
*/
#define INCLUDE_FROM_USBMODEM_C
#include "USBModem.h"
RingBuffer_t Modem_SendBuffer;
uint8_t Modem_SendBuffer_Data[128];
RingBuffer_t Modem_ReceiveBuffer;
uint8_t Modem_ReceiveBuffer_Data[128];
uint8_t WatchdogTicks = 0;
uint16_t SystemTicks = 0; // 10 millseconds counter
ISR(TIMER1_COMPA_vect) // Timer 1 interrupt handler
{
SystemTicks++;
PPP_LinkTimer();
}
ISR(TIMER3_COMPA_vect) // Timeout Timer interrupt handler
{
if (++WatchdogTicks >= 23) // 23 * 8s = 3 minutes. If we've received no data in 3 minutes reboot.
{
Debug_Print("Timeout. Rebooting...\r\n");
Reboot();
}
}
// Once the watchdog is enabled, then it stays enabled, even after a reset!
// A function needs to be added to the .init3 section (i.e. during the startup code, before main()) to disable the watchdog early enough so it does not continually reset the AVR.
void WDT_Init(void)
{
MCUSR = 0; // Clear the source of the reset
wdt_disable();
wdt_reset();
WDTCSR = ((1 << WDCE) | (1 << WDE));
WDTCSR = ((1 << WDE) | (1 << WDP3)); // Watchdog Initialization (4 Second Period)
}
void Reboot(void)
{
WDTCSR = ((1 << WDCE) | (1 << WDE));
WDTCSR = ((1 << WDE)); // Set watchdog timer to 16ms
_delay_ms(30); // Wait longer than 16ms
}
// Main program entry point. This routine configures the hardware required by the application, then runs the application tasks.
int main(void)
{
SetupHardware();
ConnectedState = LINKMANAGEMENT_STATE_Idle;
while(true)
{
wdt_reset();
LinkManagement_ManageConnectionState();
USBManagement_ManageUSBState();
USB_USBTask();
switch (getchar())
{
case '!':
puts("\r\nDebug ON\r\n");
DebugModeEnabled = true;
break;
case '@':
puts("\r\nDebug OFF\r\n");
DebugModeEnabled = false;
break;
}
}
}
void SetupHardware(void)
{
// Disable clock division
clock_prescale_set(clock_div_1);
// Enable interrupts
sei();
Serial_Init(UART_BAUD_RATE, false);
Serial_CreateStream(NULL);
puts("\r\nUSB Modem - Copyright (C) 2011 Mike Alexander and Dean Camera"
"\r\n *** Press '!' to enable debugging, '@' to disable ***\r\n");
USB_Host_SuspendBus(); // If the WDT has reset the AVR, need to give the modem time to reinitialise
_delay_ms(HOST_DEVICE_SETTLE_DELAY_MS);
// Hardware Initialization
LEDs_Init();
USB_Init();
// Timer 1 is used as a general 10ms timekeeping timer (Timer 0 is used by TCP/IP stack)
TCCR1B = ((1 << WGM12) | (1 << CS10) | (1 << CS12)); // CK/1024 prescale, CTC mode
OCR1A = ((F_CPU / 1024) / 100); // 10ms timer period
TIMSK1 = (1 << OCIE1A); // Enable interrupt on Timer compare
// Timer 3 is used as a timeout timer
TCCR3B = ((1 << WGM32) | (1 << CS30) | (1 << CS32)); // CK/1024 prescale, CTC mode
OCR3A = ((F_CPU / 1024) * 8); // 8s timer period
TIMSK3 = (1 << OCIE3A); // Enable interrupt on Timer compare
// Modem Packet Ring Buffer Initialization
RingBuffer_InitBuffer(&Modem_SendBuffer, Modem_SendBuffer_Data, sizeof(Modem_SendBuffer_Data));
RingBuffer_InitBuffer(&Modem_ReceiveBuffer, Modem_ReceiveBuffer_Data, sizeof(Modem_ReceiveBuffer_Data));
}