Hanna
Sourcecode Batteriemanagementsystem
usb_xm.c
gehe zur Dokumentation dieser Datei
1 
15 #include <util/atomic.h>
16 #include <avr/io.h>
17 #include "usb_xm.h"
18 
21 // IRQ's
24 
26 // global IRQ
28 ISR(USB_BUSEVENT_vect)
29 {
30  if ( USB.INTFLAGSACLR & USB_SOFIF_bm )
31  {
32  USB.INTFLAGSACLR = USB_SOFIF_bm;
33  }
34  else if ( USB.INTFLAGSACLR & (USB_CRCIF_bm | USB_UNFIF_bm | USB_OVFIF_bm) )
35  {
36  USB.INTFLAGSACLR = (USB_CRCIF_bm | USB_UNFIF_bm | USB_OVFIF_bm);
37  }
38  else if ( USB.INTFLAGSACLR & USB_STALLIF_bm )
39  {
40  USB.INTFLAGSACLR = USB_STALLIF_bm;
41  }
42  else
43  {
44  if ( USB.INTFLAGSACLR & USB_SUSPENDIF_bm )
45  {
47  }
48 
49  if ( USB.INTFLAGSACLR & USB_RESUMEIF_bm )
50  {
52  }
53 
54  if ( USB.INTFLAGSACLR & USB_RSTIF_bm )
55  {
56  USB.ADDR = 0;
57  USB_DeviceState = DEVICE_STATE_Default;
58  USB_ResetInterface ();
60  }
61 
62  USB.INTFLAGSACLR = USB_SUSPENDIF_bm | USB_RESUMEIF_bm | USB_RSTIF_bm;
63  USB_Evt_Task ();
64  }
65 }
66 
68 // irq for transaktion complete
70 ISR(USB_TRNCOMPL_vect)
71 {
72  USB.FIFOWP = 0;
73  USB.INTFLAGSBCLR = USB_SETUPIF_bm | USB_TRNIF_bm;
74  USB_Task ();
75 }
76 
79 // USB-Functions
82 inline bool USB_handleSetAddress ( USB_Request_Header_t* req )
83 {
84  uint8_t DeviceAddress = (req->wValue & 0x7F);
85  USB_EP_pair_t* pair = &endpoints[0];
86  USB_EP_t* e = &pair->ep[1];
87  USB_EP_t* b = &pair->ep[1];
88 
89  LACR16( &endpoints[0].out.STATUS,
90  USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm | USB_EP_OVF_bm );
91 
92  b->DATAPTR = (unsigned) ep0_buf_in;
93  b->CNT = 0;
94  LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
95 
96  while ( !(e->STATUS & USB_EP_TRNCOMPL0_bm) )
97  {
98  };
99 
100  USB.ADDR = DeviceAddress;
101  USB_DeviceState =
102  (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
103  return true;
104 }
105 
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 )
109 {
110  //uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
111  //GlobalInterruptDisable();
112 
113  uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS;
114 
115  for ( uint8_t SerialCharNum = 0;
116  SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++ )
117  {
118  uint8_t SerialByte;
119 
120  NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
121  SerialByte = pgm_read_byte( SigReadAddress );
122  NVM_CMD = NVM_CMD_NO_OPERATION_gc;
123 
124  if ( SerialCharNum & 0x01 )
125  {
126  SerialByte >>= 4;
127  SigReadAddress++;
128  }
129 
130  SerialByte &= 0x0F;
131 
132  UnicodeString[SerialCharNum] = (
133  (SerialByte >= 10) ?
134  (('A' - 10) + SerialByte) : ('0' + SerialByte));
135  }
136 
137  //SetGlobalInterruptMask(CurrentGlobalInt);
138 }
139 
140 inline void USB_Device_GetInternalSerialDescriptor ( void )
141 {
142  USB_EP_pair_t* pair = &endpoints[0];
143  USB_EP_t* e = &pair->ep[1];
144  USB_EP_t* b = &pair->ep[1];
145 
146  struct
147  {
148  USB_Descriptor_Header_t Header;
149  uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
150  }* SignatureDescriptor = (void*) ep0_buf_in;
151 
152  SignatureDescriptor->Header.Type = DTYPE_String;
153  SignatureDescriptor->Header.Size = USB_STRING_LEN(
154  INTERNAL_SERIAL_LENGTH_BITS / 4 );
155 
156  USB_Device_GetSerialString ( SignatureDescriptor->UnicodeString );
157 
158  b->DATAPTR = (unsigned) ep0_buf_in;
159  b->CNT = sizeof(*SignatureDescriptor);
160  LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
161 }
162 #endif
163 
164 inline bool USB_handleGetDescriptor ( USB_Request_Header_t* req )
165 {
166  const void* DescriptorPointer;
167  uint16_t DescriptorSize;
168  NVM.CMD = NVM_CMD_NO_OPERATION_gc;
169 
170 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
171  if ( req->wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL) )
172  {
173  USB_Device_GetInternalSerialDescriptor ();
174  return true;
175  }
176 #endif
177 
178  if ( (DescriptorSize = CALLBACK_USB_GetDescriptor ( req->wValue,
179  req->wIndex, &DescriptorPointer )) )
180  {
181  if ( DescriptorSize > req->wLength ) DescriptorSize = req->wLength;
182  USB_ep0_send_progmem ( DescriptorPointer, DescriptorSize );
183  return true;
184  }
185  return false;
186 }
187 
188 inline bool USB_handleSetConfiguration ( USB_Request_Header_t* req )
189 {
190  USB_Descriptor_Device_t* DevDescriptorPtr;
191  USB_EP_pair_t* pair = &endpoints[0];
192  USB_EP_t* e = &pair->ep[1];
193  USB_EP_t* b = &pair->ep[1];
194 
195  uint8_t r = CALLBACK_USB_GetDescriptor ( (DTYPE_Device << 8), 0,
196  (void*) &DevDescriptorPtr );
197  if ( r == NO_DESCRIPTOR ) return false;
198 
199  NVM.CMD = NVM_CMD_NO_OPERATION_gc;
200  uint8_t num_configs = pgm_read_byte(
201  &DevDescriptorPtr->NumberOfConfigurations );
202 
203  if ( (uint8_t) req->wValue > num_configs ) return false;
204 
205  b->DATAPTR = (unsigned) ep0_buf_in;
206  b->CNT = 0;
207  LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
208 
209  USB_Device_ConfigurationNumber = (uint8_t) (req->wValue);
210 
211  if ( USB_Device_ConfigurationNumber )
212  USB_DeviceState = DEVICE_STATE_Configured;
213  else
214  USB_DeviceState =
216 
217  EVENT_USB_Device_ConfigurationChanged ( USB_Device_ConfigurationNumber );
218  return true;
219 }
220 
221 bool USB_HandleSetup ( void )
222 {
223  USB_Request_Header_t* req = (void *) ep0_buf_out;
224  USB_EP_pair_t* pair = &endpoints[0];
225  USB_EP_t* e __attribute__ ((unused)) = &pair->ep[1];
226  USB_EP_t* b = &pair->ep[1];
227 
228  if ( (req->bmRequestType & CONTROL_REQTYPE_TYPE) == REQTYPE_STANDARD )
229  {
230  switch (req->bRequest)
231  {
232  case REQ_GetStatus:
233  ep0_buf_in[0] = 0;
234  ep0_buf_in[1] = 0;
235  b->DATAPTR = (unsigned) ep0_buf_in;
236  b->CNT = 2;
237  LACR16( &(e->STATUS),
238  USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
239  return true;
240  case REQ_ClearFeature:
241  case REQ_SetFeature:
242  b->DATAPTR = (unsigned) ep0_buf_in;
243  b->CNT = 0;
244  LACR16( &(e->STATUS),
245  USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
246  return true;
247  case REQ_SetAddress:
248  return USB_handleSetAddress ( req );
249  case REQ_GetDescriptor:
250  return USB_handleGetDescriptor ( req );
252  ep0_buf_in[0] = USB_Device_ConfigurationNumber;
253  b->DATAPTR = (unsigned) ep0_buf_in;
254  b->CNT = 1;
255  LACR16( &(e->STATUS),
256  USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
257  return true;
259  return USB_handleSetConfiguration ( req );
260  case REQ_SetInterface:
262  req->wValue ) )
263  {
264  b->DATAPTR = (unsigned) ep0_buf_in;
265  b->CNT = 0;
266  LACR16( &(e->STATUS),
267  USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
268  return true;
269  }
270  case REQ_GetInterface:
271  return false;
272  }
273  }
274 
275  return EVENT_USB_Device_ControlRequest ( req );
276 }
277 
278 volatile uint8_t USB_DeviceState;
279 volatile uint8_t USB_Device_ConfigurationNumber;
280 
281 void USB_xm_Init ( void )
282 {
283  //uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
284  //GlobalInterruptDisable();
285 
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;
289 
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;
293 
294  //SetGlobalInterruptMask(CurrentGlobalInt);
295 
296  USB_ResetInterface ();
297 }
298 
299 void USB_ResetInterface ( void )
300 {
301 
302  CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp)
303  | CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm);
304  USB.EPPTR = (unsigned) &endpoints;
305  USB.ADDR = 0;
306 
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;
315 
316  USB.CTRLA = USB_ENABLE_bm | USB_SPEED_bm | (USB_DEF_EP_MAX - 1);
317 
318 // USB_Attach();
319  USB.CTRLB |= USB_ATTACH_bm;
320 }
321 
322 void USB_ep0_send_progmem ( const uint8_t* addr, uint16_t size )
323 {
324  uint8_t *buf = ep0_buf_in;
325  uint16_t remaining = size;
326  NVM.CMD = NVM_CMD_NO_OPERATION_gc;
327 
328  USB_EP_pair_t* pair = &endpoints[0];
329  USB_EP_t* e = &pair->ep[1];
330  USB_EP_t* b = &pair->ep[1];
331 
332  while ( remaining-- )
333  {
334  *buf++ = pgm_read_byte( addr++ );
335  }
336 
337  b->DATAPTR = (unsigned) ep0_buf_in;
338  b->CNT = size;
339  LACR16( &(e->STATUS), USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm );
340 }
341 
342 void USB_ConfigureClock ( void )
343 {
344  // Configure DFLL for 48MHz, calibrated by USB SOF
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; //Xmega AU manual, 4.17.19
350  DFLLRC32M.COMP2 = 0xB7;
351  DFLLRC32M.CTRL = DFLL_ENABLE_bm;
352 
353  CCP = CCP_IOREG_gc; //Security Signature to modify clock
354  OSC.CTRL = OSC_RC32MEN_bm | OSC_RC2MEN_bm; // enable internal 32MHz oscillator
355 
356  while ( !(OSC.STATUS & OSC_RC32MRDY_bm) )
357  ; // wait for oscillator ready
358 
359  OSC.PLLCTRL = OSC_PLLSRC_RC2M_gc | 16; // 2MHz * 16 = 32MHz
360 
361  CCP = CCP_IOREG_gc;
362  OSC.CTRL = OSC_RC32MEN_bm | OSC_PLLEN_bm | OSC_RC2MEN_bm; // Enable PLL
363 
364  while ( !(OSC.STATUS & OSC_PLLRDY_bm) )
365  ; // wait for PLL ready
366 
367  DFLLRC2M.CTRL = DFLL_ENABLE_bm;
368 
369  CCP = CCP_IOREG_gc; //Security Signature to modify clock
370  CLK.CTRL = CLK_SCLKSEL_PLL_gc; // Select PLL
371  CLK.PSCTRL = 0x00; // No peripheral clock prescaler
372 }
373 
376 // USB Tasks
379 void USB_Evt_Task ( void )
380 {
381  if ( USB.STATUS & USB_BUSRST_bm )
382  {
383  USB.STATUS &= ~USB_BUSRST_bm;
384  USB_xm_Init ();
385  }
386 }
387 
389 // is call from irq
391 void USB_Task ( void )
392 {
393  // Read once to prevent race condition where SETUP packet is interpreted as OUT
394  uint8_t status = endpoints[0].out.STATUS;
395 
396  if ( status & USB_EP_SETUP_bm )
397  {
398  if ( !USB_HandleSetup () )
399  {
400  endpoints[0].out.CTRL |= USB_EP_STALL_bm;
401  endpoints[0].in.CTRL |= USB_EP_STALL_bm;
402  }
403  LACR16( &endpoints[0].out.STATUS,
404  USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm | USB_EP_OVF_bm );
405  }
406  else if ( status & USB_EP_TRNCOMPL0_bm )
407  {
408  EVENT_USB_Device_ControlOUT ( (uint8_t *) ep0_buf_out,
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 );
412  }
413 }
414 
bool EVENT_USB_Device_SetInterface(uint8_t interface, uint8_t altsetting)
Definition: usb_cdc.c:183
void EVENT_USB_Device_ControlOUT(uint8_t *data, uint8_t len)
Definition: usb_cdc.c:221
void EVENT_USB_Device_ConfigurationChanged(uint8_t config)
Definition: usb_cdc.c:191
void EVENT_USB_Device_Suspend(void)
Definition: usb_cdc.c:201
Bibliothek zur USB-Kommunikation von Jürgen W.
void EVENT_USB_Device_WakeUp(void)
Definition: usb_cdc.c:208
void EVENT_USB_Device_Reset(void)
Definition: usb_cdc.c:215
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress)
Definition: Descriptors.c:182
#define LACR16(addr, msk)
From Atmel: Macros for XMEGA instructions not yet supported by the toolchain.
Definition: usb_defaults.h:112
bool EVENT_USB_Device_ControlRequest(USB_Request_Header_t *req)
Definition: usb_cdc.c:239