|
| 1 | +////////////////////////////////////////////////////////////////////////////// |
| 2 | +// // |
| 3 | +// ____ ____ ____ // |
| 4 | +// / ___|| _ \ / ___| ___ _ __ _ __ // |
| 5 | +// | | | | | || | / __|| '_ \ | '_ \ // |
| 6 | +// | |___ | |_| || |___ _| (__ | |_) || |_) | // |
| 7 | +// \____||____/ \____|(_)\___|| .__/ | .__/ // |
| 8 | +// |_| |_| // |
| 9 | +// // |
| 10 | +////////////////////////////////////////////////////////////////////////////// |
| 11 | + |
1 | 12 | /* Copyright (c) 2011, Peter Barrett
|
2 | 13 | **
|
3 | 14 | ** Permission to use, copy, modify, and/or distribute this software for
|
|
14 | 25 | ** SOFTWARE.
|
15 | 26 | */
|
16 | 27 |
|
| 28 | +///////////////////////////////////////////////////////////////////////////////// |
| 29 | +// XMEGA NOTES: |
| 30 | +// |
| 31 | +// a) it appears that, at one time at least, this was intended to be overridden |
| 32 | +// by user code, hence the use of 'WEAK' all over the place; |
| 33 | +// b) This API is *VERY* 'tricky' in that it's tied in heavily with the atmega |
| 34 | +// USB implementation and (in some cases) does 'magic things' that are not |
| 35 | +// apparently obvious to someone trying to port it to another processor |
| 36 | +// (for an example see original use of CDC_GetInterface - lame!) |
| 37 | +// c) Given the fact that it's (in my view) POORLY WRITTEN, it deserves a makeover. |
| 38 | +// d) K&R style is hard to read. I won't use it. Hard tabs are evil. Same. |
| 39 | +// |
| 40 | +///////////////////////////////////////////////////////////////////////////////// |
| 41 | + |
17 | 42 | #include "Platform.h"
|
18 | 43 | #include "USBAPI.h"
|
19 | 44 | #include <avr/wdt.h>
|
@@ -68,10 +93,28 @@ const CDCDescriptor _cdcInterface =
|
68 | 93 | D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0)
|
69 | 94 | };
|
70 | 95 |
|
71 |
| -int WEAK CDC_GetInterface(u8* interfaceNum) |
| 96 | +int WEAK CDC_GetInterface(u8* interfaceNum, bool bSendPacket) |
72 | 97 | {
|
73 |
| - interfaceNum[0] += 2; // uses 2 |
74 |
| - return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); |
| 98 | + interfaceNum[0] += 2; // uses 2 interfaces |
| 99 | + |
| 100 | + // NOTE: the original version of this, when calling 'USB_SendControl', may NOT |
| 101 | + // actually send a packet. In fact, something upstream was likely to |
| 102 | + // "just erase" the packet buffer until an actual packet was to be sent. |
| 103 | + // Not only is this _LAME_, it his HORRIBLE DESIGN PRACTICE, UN-INTUITIVE, |
| 104 | + // and JUST! PLAIN! WRONG!!! Therefore, I added a parameter 'bSendPacket' |
| 105 | + // to determine whether or not you actually send a packet. it makes a |
| 106 | + // LOT more sense. Besides, this API doesn't have official documentation. |
| 107 | + // So I'm changing it. Please modify your own version of 'CDC_GetInterface' |
| 108 | + // if you're overriding this version with your own. |
| 109 | + |
| 110 | + if(bSendPacket) |
| 111 | + { |
| 112 | + return USB_SendControl(TRANSFER_PGM, &_cdcInterface, sizeof(_cdcInterface)); |
| 113 | + } |
| 114 | + else |
| 115 | + { |
| 116 | + return 1; |
| 117 | + } |
75 | 118 | }
|
76 | 119 |
|
77 | 120 | bool WEAK CDC_Setup(Setup& setup)
|
@@ -120,10 +163,25 @@ bool WEAK CDC_Setup(Setup& setup)
|
120 | 163 | //
|
121 | 164 | // *(uint16_t *)0x0800 = 0x7777; note that on XMEGA this is a VERY bad thing
|
122 | 165 | // wdt_enable(WDTO_120MS);
|
| 166 | +// |
| 167 | +// on the atmega, address 800H is the start of the final 256-byte page in RAM space for 2k RAM |
| 168 | +// |
| 169 | +// atmega328(p) RAM goes from 0x100 through 0x8ff - see datasheet for atmega 328 [etc.] section 8.3 |
| 170 | +// 32U4 RAM goes through 0xaff - see datasheet for U4 processors, section 5.2 |
| 171 | +// 8/16/32U2 RAM goes through 4FFH so this won't even work - see datasheet for U2 processors, section 7.2 |
| 172 | +// basically it's a 'hack' and needs to be re-evaluated |
| 173 | + |
| 174 | + // TODO: would it be safe to enable interrupts, NOT return from this function, |
| 175 | + // and simply wait until the appropriate time has elapsed? Or, as is |
| 176 | + // handled in the section below, this 'wait period' is canceled |
| 177 | + |
| 178 | + // TODO: if I use a function that's part of the USB driver to trigger a soft boot, I can detect |
| 179 | + // that a soft boot has taken place using the bits in the 'RESET' status register. If all |
| 180 | + // I have to do is detect this, it's not a problem, and I won't need "magic memory locations" |
123 | 181 |
|
124 | 182 | // TODO: timeout-based reboot
|
125 | 183 | }
|
126 |
| - else // 3 lines better than 1 - ALLMAN STYLE! - do *NOT* do '} else {' - BLEAH! |
| 184 | + else |
127 | 185 | {
|
128 | 186 | // Most OSs do some intermediate steps when configuring ports and DTR can
|
129 | 187 | // twiggle more than once before stabilizing.
|
|
0 commit comments