14 #include <util/atomic.h> 27 ISR(USB_BUSEVENT_vect)
29 if ( USB.INTFLAGSACLR & USB_SOFIF_bm )
31 USB.INTFLAGSACLR = USB_SOFIF_bm;
33 else if ( USB.INTFLAGSACLR & (USB_CRCIF_bm | USB_UNFIF_bm | USB_OVFIF_bm) )
35 USB.INTFLAGSACLR = (USB_CRCIF_bm | USB_UNFIF_bm | USB_OVFIF_bm);
37 else if ( USB.INTFLAGSACLR & USB_STALLIF_bm )
39 USB.INTFLAGSACLR = USB_STALLIF_bm;
43 if ( USB.INTFLAGSACLR & USB_SUSPENDIF_bm )
48 if ( USB.INTFLAGSACLR & USB_RESUMEIF_bm )
53 if ( USB.INTFLAGSACLR & USB_RSTIF_bm )
57 USB_ResetInterface ();
61 USB.INTFLAGSACLR = USB_SUSPENDIF_bm | USB_RESUMEIF_bm | USB_RSTIF_bm;
69 ISR(USB_TRNCOMPL_vect)
72 USB.INTFLAGSBCLR = USB_SETUPIF_bm | USB_TRNIF_bm;
83 uint8_t DeviceAddress = (req->
wValue & 0x7F);
85 USB_EP_t* e = &pair->ep[1];
86 USB_EP_t* b = &pair->ep[1];
88 LACR16( &endpoints[0].out.STATUS, USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm | USB_EP_OVF_bm );
90 b->DATAPTR = (unsigned) ep0_buf_in;
92 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
94 while ( !(e->STATUS & USB_EP_TRNCOMPL0_bm) )
98 USB.ADDR = DeviceAddress;
103 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) 104 inline void USB_Device_GetSerialString ( uint16_t*
const UnicodeString ) ATTR_NON_NULL_PTR_ARG(1);
105 inline void USB_Device_GetSerialString ( uint16_t*
const UnicodeString )
110 uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS;
112 for ( uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++ )
116 NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
117 SerialByte = pgm_read_byte( SigReadAddress );
118 NVM_CMD = NVM_CMD_NO_OPERATION_gc;
120 if ( SerialCharNum & 0x01 )
128 UnicodeString[SerialCharNum] = ((SerialByte >= 10) ? ((
'A' - 10) + SerialByte) : (
'0' + SerialByte));
134 inline void USB_Device_GetInternalSerialDescriptor (
void )
137 USB_EP_t* e = &pair->ep[1];
138 USB_EP_t* b = &pair->ep[1];
142 USB_Descriptor_Header_t Header;
143 uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
144 }* SignatureDescriptor = (
void*) ep0_buf_in;
147 SignatureDescriptor->Header.Size = USB_STRING_LEN( INTERNAL_SERIAL_LENGTH_BITS / 4 );
149 USB_Device_GetSerialString ( SignatureDescriptor->UnicodeString );
151 b->DATAPTR = (unsigned) ep0_buf_in;
152 b->CNT =
sizeof(*SignatureDescriptor);
153 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
159 const void* DescriptorPointer;
160 uint16_t DescriptorSize;
161 NVM.CMD = NVM_CMD_NO_OPERATION_gc;
163 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) 166 USB_Device_GetInternalSerialDescriptor ();
173 if ( DescriptorSize > req->
wLength ) DescriptorSize = req->
wLength;
174 USB_ep0_send_progmem ( DescriptorPointer, DescriptorSize );
182 USB_Descriptor_Device_t* DevDescriptorPtr;
184 USB_EP_t* e = &pair->ep[1];
185 USB_EP_t* b = &pair->ep[1];
188 if ( r == NO_DESCRIPTOR )
return false;
190 NVM.CMD = NVM_CMD_NO_OPERATION_gc;
191 uint8_t num_configs = pgm_read_byte( &DevDescriptorPtr->NumberOfConfigurations );
193 if ( (uint8_t) req->
wValue > num_configs )
return false;
195 b->DATAPTR = (unsigned) ep0_buf_in;
197 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
199 USB_Device_ConfigurationNumber = (uint8_t) (req->
wValue);
201 if ( USB_Device_ConfigurationNumber )
210 bool USB_HandleSetup (
void )
214 USB_EP_t* e __attribute__ ((unused)) = &pair->ep[1];
215 USB_EP_t* b = &pair->ep[1];
217 if ( (req->
bmRequestType & CONTROL_REQTYPE_TYPE) == REQTYPE_STANDARD )
224 b->DATAPTR = (unsigned) ep0_buf_in;
226 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
230 b->DATAPTR = (unsigned) ep0_buf_in;
232 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
235 return USB_handleSetAddress ( req );
237 return USB_handleGetDescriptor ( req );
239 ep0_buf_in[0] = USB_Device_ConfigurationNumber;
240 b->DATAPTR = (unsigned) ep0_buf_in;
242 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
245 return USB_handleSetConfiguration ( req );
249 b->DATAPTR = (unsigned) ep0_buf_in;
251 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
263 volatile uint8_t USB_DeviceState;
264 volatile uint8_t USB_Device_ConfigurationNumber;
266 void USB_xm_Init (
void )
271 NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
272 USB.CAL0 = pgm_read_byte( offsetof(NVM_PROD_SIGNATURES_t, USBCAL0) );
273 NVM_CMD = NVM_CMD_NO_OPERATION_gc;
275 NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
276 USB.CAL1 = pgm_read_byte( offsetof(NVM_PROD_SIGNATURES_t, USBCAL1) );
277 NVM_CMD = NVM_CMD_NO_OPERATION_gc;
281 USB_ResetInterface ();
284 void USB_ResetInterface (
void )
287 CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm);
288 USB.EPPTR = (unsigned) &endpoints;
291 endpoints[0].out.STATUS = 0;
292 endpoints[0].out.CTRL = USB_EP_TYPE_CONTROL_gc | USB_EP_size_to_gc( USB_DEF_EP0_SIZE );
293 endpoints[0].out.DATAPTR = (unsigned) &ep0_buf_out;
294 endpoints[0].in.STATUS = USB_EP_BUSNACK0_bm;
295 endpoints[0].in.CTRL = USB_EP_TYPE_CONTROL_gc | USB_EP_size_to_gc( USB_DEF_EP0_SIZE );
296 endpoints[0].in.DATAPTR = (unsigned) &ep0_buf_in;
298 USB.CTRLA = USB_ENABLE_bm | USB_SPEED_bm | (USB_DEF_EP_MAX - 1);
301 USB.CTRLB |= USB_ATTACH_bm;
304 void USB_ep0_send_progmem (
const uint8_t* addr, uint16_t size )
306 uint8_t *buf = ep0_buf_in;
307 uint16_t remaining = size;
308 NVM.CMD = NVM_CMD_NO_OPERATION_gc;
311 USB_EP_t* e = &pair->ep[1];
312 USB_EP_t* b = &pair->ep[1];
314 while ( remaining-- )
316 *buf++ = pgm_read_byte( addr++ );
319 b->DATAPTR = (unsigned) ep0_buf_in;
321 LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
324 void USB_ConfigureClock (
void )
327 OSC.DFLLCTRL = OSC_RC32MCREF_USBSOF_gc;
328 NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
329 DFLLRC32M.CALB = pgm_read_byte( offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC) );
330 NVM_CMD = NVM_CMD_NO_OPERATION_gc;
331 DFLLRC32M.COMP1 = 0x1B;
332 DFLLRC32M.COMP2 = 0xB7;
333 DFLLRC32M.CTRL = DFLL_ENABLE_bm;
336 OSC.CTRL = OSC_RC32MEN_bm | OSC_RC2MEN_bm;
338 while ( !(OSC.STATUS & OSC_RC32MRDY_bm) )
341 OSC.PLLCTRL = OSC_PLLSRC_RC2M_gc | 16;
344 OSC.CTRL = OSC_RC32MEN_bm | OSC_PLLEN_bm | OSC_RC2MEN_bm;
346 while ( !(OSC.STATUS & OSC_PLLRDY_bm) )
349 DFLLRC2M.CTRL = DFLL_ENABLE_bm;
352 CLK.CTRL = CLK_SCLKSEL_PLL_gc;
361 void USB_Evt_Task (
void )
363 if ( USB.STATUS & USB_BUSRST_bm )
365 USB.STATUS &= ~USB_BUSRST_bm;
373 void USB_Task (
void )
376 uint8_t status = endpoints[0].out.STATUS;
378 if ( status & USB_EP_SETUP_bm )
380 if ( !USB_HandleSetup () )
382 endpoints[0].out.CTRL |= USB_EP_STALL_bm;
383 endpoints[0].in.CTRL |= USB_EP_STALL_bm;
385 LACR16( &endpoints[0].out.STATUS, USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm | USB_EP_OVF_bm );
387 else if ( status & USB_EP_TRNCOMPL0_bm )
390 LACR16( &endpoints[0].out.STATUS, USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm | USB_EP_OVF_bm );
void EVENT_USB_Device_WakeUp(void)
bool EVENT_USB_Device_SetInterface(uint8_t interface, uint8_t altsetting)
void EVENT_USB_Device_ControlOUT(uint8_t *data, uint8_t len)
bool EVENT_USB_Device_ControlRequest(USB_Request_Header_t *req)
void EVENT_USB_Device_Reset(void)
void EVENT_USB_Device_Suspend(void)
#define LACR16(addr, msk)
From Atmel: Macros for XMEGA instructions not yet supported by the toolchain.
Bibliothek zur USB-Kommunikation von Jürgen W.
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress)
void EVENT_USB_Device_ConfigurationChanged(uint8_t config)