Skip to content

Commit 3f6df05

Browse files
committed
Serial via USB works
Integrated rest of Peter's USB implementation
1 parent 81948ea commit 3f6df05

File tree

8 files changed

+1667
-2
lines changed

8 files changed

+1667
-2
lines changed
+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
2+
3+
/* Copyright (c) 2011, Peter Barrett
4+
**
5+
** Permission to use, copy, modify, and/or distribute this software for
6+
** any purpose with or without fee is hereby granted, provided that the
7+
** above copyright notice and this permission notice appear in all copies.
8+
**
9+
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10+
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11+
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
12+
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
13+
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
14+
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
15+
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16+
** SOFTWARE.
17+
*/
18+
19+
#include "Platform.h"
20+
#include "USBAPI.h"
21+
#include <avr/wdt.h>
22+
23+
#ifdef CDC_ENABLED
24+
25+
// TODO: Should really use the wdt here
26+
// Not currently working for a non-obvious reason
27+
28+
typedef void (*AppPtr_t)(void) __attribute__ ((noreturn));
29+
AppPtr_t Bootloader = (AppPtr_t)(30*1024);
30+
31+
void Reboot()
32+
{
33+
USB.detach();
34+
cli();
35+
Bootloader();
36+
//wdt_enable(WDTO_15MS);
37+
//while(1); // reboot
38+
}
39+
40+
typedef struct
41+
{
42+
u32 dwDTERate;
43+
u8 bCharFormat;
44+
u8 bParityType;
45+
u8 bDataBits;
46+
u8 lineState;
47+
} LineInfo;
48+
49+
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
50+
51+
#define WEAK __attribute__ ((weak))
52+
53+
extern const CDCDescriptor _cdcInterface PROGMEM;
54+
const CDCDescriptor _cdcInterface =
55+
{
56+
D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
57+
58+
// CDC communication interface
59+
D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
60+
D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
61+
D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
62+
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
63+
D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
64+
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40),
65+
66+
// CDC data interface
67+
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
68+
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0),
69+
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0)
70+
};
71+
72+
int WEAK CDC_GetInterface(u8* interfaceNum)
73+
{
74+
interfaceNum[0] += 2; // uses 2
75+
return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface));
76+
}
77+
78+
bool WEAK CDC_Setup(Setup& setup)
79+
{
80+
u8 r = setup.bRequest;
81+
u8 requestType = setup.bmRequestType;
82+
83+
if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
84+
{
85+
if (CDC_GET_LINE_CODING == r)
86+
{
87+
USB_SendControl(0,(void*)&_usbLineInfo,7);
88+
return true;
89+
}
90+
}
91+
92+
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
93+
{
94+
if (CDC_SET_LINE_CODING == r)
95+
{
96+
USB_RecvControl((void*)&_usbLineInfo,7);
97+
return true;
98+
}
99+
100+
if (CDC_SET_CONTROL_LINE_STATE == r)
101+
{
102+
_usbLineInfo.lineState = setup.wValueL;
103+
if (_usbLineInfo.dwDTERate == 115200 && _usbLineInfo.lineState == 0) // Emulate DTR reset hack
104+
Reboot();
105+
return true;
106+
}
107+
}
108+
return false;
109+
}
110+
111+
112+
int _serialPeek = -1;
113+
void Serial_::begin(uint16_t baud_count)
114+
{
115+
}
116+
117+
void Serial_::end(void)
118+
{
119+
}
120+
121+
int Serial_::available(void)
122+
{
123+
u8 avail = USB_Available(CDC_RX);
124+
if (_serialPeek != -1)
125+
avail++;
126+
return avail;
127+
}
128+
129+
// peek is nasty
130+
int Serial_::peek(void)
131+
{
132+
if (_serialPeek == -1)
133+
_serialPeek = read();
134+
return _serialPeek;
135+
}
136+
137+
int Serial_::read(void)
138+
{
139+
int c;
140+
if (_serialPeek != -1)
141+
{
142+
c = _serialPeek;
143+
_serialPeek = -1;
144+
} else {
145+
c = USB_Recv(CDC_RX);
146+
}
147+
return c;
148+
}
149+
150+
void Serial_::flush(void)
151+
{
152+
USB_Flush(CDC_TX);
153+
}
154+
155+
void Serial_::write(uint8_t c)
156+
{
157+
USB_Send(CDC_TX,&c,1);
158+
}
159+
160+
Serial_ Serial;
161+
162+
#endif

0 commit comments

Comments
 (0)