Blame view

atmega16u2/custom/PolytechLille/PAD/PAD.c 3.54 KB
3a6e8ae8   root   Nettoyage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  #include "PAD.h"
  
  /** Main program entry point. This routine contains the overall program flow, including initial
   *  setup of all components and the main program loop.
   */
  int main(void){
  	SetupHardware();
  
  	LEDs_SetAllLEDs(LEDS_LED1 | LEDS_LED2);
  	GlobalInterruptEnable();
  
  	for (;;){
  		USB_USBTask();
  		PAD_Task();
  	}
  }
  
  uint8_t led = 0;
  void PAD_Task(void){
  	if (USB_DeviceState != DEVICE_STATE_Configured)
  		return;
  	LEDs_SetAllLEDs(0);
  
  	// receive from 328p & send to PC
  	/* Notre convention :
  	 *
  	 *  328p -> 12u2 : 0bXYZZZZZZ
  	 * X = 0 -> les Z sont les états de chaque boutons
  	 * X = 1 & Y = 0 -> les Z correspondent à la valeur X du joystick
  	 * X = 1 & Y = 1 -> les Z correspondent à la valeur Y du joystick
  	 * 
  	 * Cas 0b00ZZZZZZ : (boutons)
  	 *  12u2 -> PC (endpoint button 1) : 0b000ZZZZZ
  	 * Z : état d'un bouton
  	
  	 * Cas 0b1YZZZZZZ : (joystick)
  	 *  12u2 -> PC (endpoint button 2) : 0bX0YYYYYY
  	 * X = 0 -> valeur en X du joystick
  	 * X = 1 -> valeur en Y du joystick
  	 */
  	if(Serial_IsCharReceived()){
  		uint8_t byte = Serial_ReceiveByte();
  		if((byte & 0x80) == 0){ // bouttons
  			Endpoint_SelectEndpoint(PAD_IN_EP_BUTTON1);
  			if (Endpoint_IsINReady() && Endpoint_IsReadWriteAllowed()){
  				LEDs_SetAllLEDs(LEDS_LED1); //LED Tx
  				Endpoint_Write_8(byte);
  				Endpoint_ClearIN();
  			}
  		}else if((byte & 0x40) == 0){ // joystick X
  			uint8_t toSend = (byte) & 0x3F;
  			Endpoint_SelectEndpoint(PAD_IN_EP_BUTTON2);
  			if (Endpoint_IsINReady() && Endpoint_IsReadWriteAllowed()){
  				LEDs_SetAllLEDs(LEDS_LED1); //LED Tx
  				Endpoint_Write_8(toSend);
  				Endpoint_ClearIN();
  			}
  		}else{ // joystick Y
  			uint8_t toSend = ((byte) & 0x3F) | 0x80;
  			Endpoint_SelectEndpoint(PAD_IN_EP_BUTTON2);
  			if (Endpoint_IsINReady() && Endpoint_IsReadWriteAllowed()){
  				LEDs_SetAllLEDs(LEDS_LED1); //LED Tx
  				Endpoint_Write_8(toSend);
  				Endpoint_ClearIN();
  			}
  		}
  	}
  
  	// receive from PC & send to 328p
  	/* Notre convention :
  	 *
  	 *  PC (endpoint led 1) -> 16u2 : 0b000XXXXX
  	 * X = état d'une LED (LEDs 8 9 10 11 12)
  	 *
  	 *  PC (endpoint led 2) -> 16u2 : 0b0000000X
  	 * X = état d'une LED (LED 13)
  	 * 
  	 *  16u2 -> 328p : 0bXYYYYYYY
  	 * X = 0 -> pour les LEDs 8 9 10 11 12 13 (Y : les données)
  	 */
  	Endpoint_SelectEndpoint(PAD_OUT_EP_LED1);
  	if (Endpoint_IsOUTReceived() && Endpoint_IsReadWriteAllowed()){
  		LEDs_SetAllLEDs(LEDS_LED2); //LED Rx
  		uint8_t byte = Endpoint_Read_8();
  		led = (led & 0x20) | byte;
  		Serial_SendByte(led);
  		Endpoint_ClearOUT();
  	}
  	Endpoint_SelectEndpoint(PAD_OUT_EP_LED2);
  	if (Endpoint_IsOUTReceived() && Endpoint_IsReadWriteAllowed()){
  		LEDs_SetAllLEDs(LEDS_LED2); //LED Rx
  		uint8_t byte = Endpoint_Read_8();
  		led = (led & 0x1F) | byte << 5;
  		Serial_SendByte(led);
  		Endpoint_ClearOUT();
  	}
  
  	//LED Reset
  	LEDs_SetAllLEDs(0);
  }
  
  /** Configures the board hardware and chip peripherals for the project's functionality. */
  void SetupHardware(void){
  #if (ARCH == ARCH_AVR8)
  	/* Disable watchdog if enabled by bootloader/fuses */
  	MCUSR &= ~(1 << WDRF);
  	wdt_disable();
  
  	/* Disable clock division */
  	clock_prescale_set(clock_div_1);
  #endif
  
  	/* Hardware Initialization */
  	USB_Init();
  	LEDs_Init();
  	Serial_Init(9600, 0);
  }
  
  // endpoints creation
  void EVENT_USB_Device_ConfigurationChanged(void){
  	/* Setup HID Report Endpoints */
  	Endpoint_ConfigureEndpoint(PAD_OUT_EP_LED1  , EP_TYPE_INTERRUPT, PAD_EPSIZE, 1);
  	Endpoint_ConfigureEndpoint(PAD_OUT_EP_LED2  , EP_TYPE_INTERRUPT, PAD_EPSIZE, 1);
  	Endpoint_ConfigureEndpoint(PAD_IN_EP_BUTTON1, EP_TYPE_INTERRUPT, PAD_EPSIZE, 1);
  	Endpoint_ConfigureEndpoint(PAD_IN_EP_BUTTON2, EP_TYPE_INTERRUPT, PAD_EPSIZE, 1);
  }