15 #include <util/atomic.h> 28 ISR(USB_BUSEVENT_vect)
30 if ( USB.INTFLAGSACLR & USB_SOFIF_bm )
32 USB.INTFLAGSACLR = USB_SOFIF_bm;
34 else if ( USB.INTFLAGSACLR & (USB_CRCIF_bm | USB_UNFIF_bm | USB_OVFIF_bm) )
36 USB.INTFLAGSACLR = (USB_CRCIF_bm | USB_UNFIF_bm | USB_OVFIF_bm);
38 else if ( USB.INTFLAGSACLR & USB_STALLIF_bm )
40 USB.INTFLAGSACLR = USB_STALLIF_bm;
44 if ( USB.INTFLAGSACLR & USB_SUSPENDIF_bm )
49 if ( USB.INTFLAGSACLR & USB_RESUMEIF_bm )
54 if ( USB.INTFLAGSACLR & USB_RSTIF_bm )
58 USB_ResetInterface ();
62 USB.INTFLAGSACLR = USB_SUSPENDIF_bm | USB_RESUMEIF_bm | USB_RSTIF_bm;
70 ISR(USB_TRNCOMPL_vect)
73 USB.INTFLAGSBCLR = USB_SETUPIF_bm | USB_TRNIF_bm;
84 uint8_t DeviceAddress = (req->
wValue & 0x7F);
86 USB_EP_t* e = &pair->ep[1];
87 USB_EP_t* b = &pair->ep[1];
89 LACR16( &endpoints[0].out.STATUS,
90 USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm | USB_EP_OVF_bm );
92 b->DATAPTR = (unsigned) ep0_buf_in;
94 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
96 while ( !(e->STATUS & USB_EP_TRNCOMPL0_bm) )
100 USB.ADDR = DeviceAddress;
106 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) 107 inline void USB_Device_GetSerialString ( uint16_t*
const UnicodeString ) ATTR_NON_NULL_PTR_ARG(1);
108 inline void USB_Device_GetSerialString ( uint16_t*
const UnicodeString )
113 uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS;
115 for ( uint8_t SerialCharNum = 0;
116 SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++ )
120 NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
121 SerialByte = pgm_read_byte( SigReadAddress );
122 NVM_CMD = NVM_CMD_NO_OPERATION_gc;
124 if ( SerialCharNum & 0x01 )
132 UnicodeString[SerialCharNum] = (
134 ((
'A' - 10) + SerialByte) : (
'0' + SerialByte));
140 inline void USB_Device_GetInternalSerialDescriptor (
void )
143 USB_EP_t* e = &pair->ep[1];
144 USB_EP_t* b = &pair->ep[1];
148 USB_Descriptor_Header_t Header;
149 uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
150 }* SignatureDescriptor = (
void*) ep0_buf_in;
153 SignatureDescriptor->Header.Size = USB_STRING_LEN(
154 INTERNAL_SERIAL_LENGTH_BITS / 4 );
156 USB_Device_GetSerialString ( SignatureDescriptor->UnicodeString );
158 b->DATAPTR = (unsigned) ep0_buf_in;
159 b->CNT =
sizeof(*SignatureDescriptor);
160 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
166 const void* DescriptorPointer;
167 uint16_t DescriptorSize;
168 NVM.CMD = NVM_CMD_NO_OPERATION_gc;
170 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) 173 USB_Device_GetInternalSerialDescriptor ();
179 req->
wIndex, &DescriptorPointer )) )
181 if ( DescriptorSize > req->
wLength ) DescriptorSize = req->
wLength;
182 USB_ep0_send_progmem ( DescriptorPointer, DescriptorSize );
190 USB_Descriptor_Device_t* DevDescriptorPtr;
192 USB_EP_t* e = &pair->ep[1];
193 USB_EP_t* b = &pair->ep[1];
196 (
void*) &DevDescriptorPtr );
197 if ( r == NO_DESCRIPTOR )
return false;
199 NVM.CMD = NVM_CMD_NO_OPERATION_gc;
200 uint8_t num_configs = pgm_read_byte(
201 &DevDescriptorPtr->NumberOfConfigurations );
203 if ( (uint8_t) req->
wValue > num_configs )
return false;
205 b->DATAPTR = (unsigned) ep0_buf_in;
207 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
209 USB_Device_ConfigurationNumber = (uint8_t) (req->
wValue);
211 if ( USB_Device_ConfigurationNumber )
221 bool USB_HandleSetup (
void )
225 USB_EP_t* e __attribute__ ((unused)) = &pair->ep[1];
226 USB_EP_t* b = &pair->ep[1];
228 if ( (req->
bmRequestType & CONTROL_REQTYPE_TYPE) == REQTYPE_STANDARD )
235 b->DATAPTR = (unsigned) ep0_buf_in;
238 USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
242 b->DATAPTR = (unsigned) ep0_buf_in;
245 USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
248 return USB_handleSetAddress ( req );
250 return USB_handleGetDescriptor ( req );
252 ep0_buf_in[0] = USB_Device_ConfigurationNumber;
253 b->DATAPTR = (unsigned) ep0_buf_in;
256 USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
259 return USB_handleSetConfiguration ( req );
264 b->DATAPTR = (unsigned) ep0_buf_in;
267 USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
278 volatile uint8_t USB_DeviceState;
279 volatile uint8_t USB_Device_ConfigurationNumber;
281 void USB_xm_Init (
void )
286 NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
287 USB.CAL0 = pgm_read_byte( offsetof(NVM_PROD_SIGNATURES_t, USBCAL0) );
288 NVM_CMD = NVM_CMD_NO_OPERATION_gc;
290 NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
291 USB.CAL1 = pgm_read_byte( offsetof(NVM_PROD_SIGNATURES_t, USBCAL1) );
292 NVM_CMD = NVM_CMD_NO_OPERATION_gc;
296 USB_ResetInterface ();
299 void USB_ResetInterface (
void )
302 CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp)
303 | CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm);
304 USB.EPPTR = (unsigned) &endpoints;
307 endpoints[0].out.STATUS = 0;
308 endpoints[0].out.CTRL = USB_EP_TYPE_CONTROL_gc
309 | USB_EP_size_to_gc( USB_DEF_EP0_SIZE );
310 endpoints[0].out.DATAPTR = (unsigned) &ep0_buf_out;
311 endpoints[0].in.STATUS = USB_EP_BUSNACK0_bm;
312 endpoints[0].in.CTRL = USB_EP_TYPE_CONTROL_gc
313 | USB_EP_size_to_gc( USB_DEF_EP0_SIZE );
314 endpoints[0].in.DATAPTR = (unsigned) &ep0_buf_in;
316 USB.CTRLA = USB_ENABLE_bm | USB_SPEED_bm | (USB_DEF_EP_MAX - 1);
319 USB.CTRLB |= USB_ATTACH_bm;
322 void USB_ep0_send_progmem (
const uint8_t* addr, uint16_t size )
324 uint8_t *buf = ep0_buf_in;
325 uint16_t remaining = size;
326 NVM.CMD = NVM_CMD_NO_OPERATION_gc;
329 USB_EP_t* e = &pair->ep[1];
330 USB_EP_t* b = &pair->ep[1];
332 while ( remaining-- )
334 *buf++ = pgm_read_byte( addr++ );
337 b->DATAPTR = (unsigned) ep0_buf_in;
339 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
342 void USB_ConfigureClock (
void )
345 OSC.DFLLCTRL = OSC_RC32MCREF_USBSOF_gc;
346 NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
347 DFLLRC32M.CALB = pgm_read_byte( offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC) );
348 NVM_CMD = NVM_CMD_NO_OPERATION_gc;
349 DFLLRC32M.COMP1 = 0x1B;
350 DFLLRC32M.COMP2 = 0xB7;
351 DFLLRC32M.CTRL = DFLL_ENABLE_bm;
354 OSC.CTRL = OSC_RC32MEN_bm | OSC_RC2MEN_bm;
356 while ( !(OSC.STATUS & OSC_RC32MRDY_bm) )
359 OSC.PLLCTRL = OSC_PLLSRC_RC2M_gc | 16;
362 OSC.CTRL = OSC_RC32MEN_bm | OSC_PLLEN_bm | OSC_RC2MEN_bm;
364 while ( !(OSC.STATUS & OSC_PLLRDY_bm) )
367 DFLLRC2M.CTRL = DFLL_ENABLE_bm;
370 CLK.CTRL = CLK_SCLKSEL_PLL_gc;
379 void USB_Evt_Task (
void )
381 if ( USB.STATUS & USB_BUSRST_bm )
383 USB.STATUS &= ~USB_BUSRST_bm;
391 void USB_Task (
void )
394 uint8_t status = endpoints[0].out.STATUS;
396 if ( status & USB_EP_SETUP_bm )
398 if ( !USB_HandleSetup () )
400 endpoints[0].out.CTRL |= USB_EP_STALL_bm;
401 endpoints[0].in.CTRL |= USB_EP_STALL_bm;
403 LACR16( &endpoints[0].out.STATUS,
404 USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm | USB_EP_OVF_bm );
406 else if ( status & USB_EP_TRNCOMPL0_bm )
409 endpoints[0].out.CNT );
410 LACR16( &endpoints[0].out.STATUS,
411 USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm | USB_EP_OVF_bm );
bool EVENT_USB_Device_SetInterface(uint8_t interface, uint8_t altsetting)
void EVENT_USB_Device_ControlOUT(uint8_t *data, uint8_t len)
void EVENT_USB_Device_ConfigurationChanged(uint8_t config)
void EVENT_USB_Device_Suspend(void)
Bibliothek zur USB-Kommunikation von Jürgen W.
void EVENT_USB_Device_WakeUp(void)
void EVENT_USB_Device_Reset(void)
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress)
#define LACR16(addr, msk)
From Atmel: Macros for XMEGA instructions not yet supported by the toolchain.
bool EVENT_USB_Device_ControlRequest(USB_Request_Header_t *req)