1 | /*
|
---|
2 | LUFA Library
|
---|
3 | Copyright (C) Dean Camera, 2021.
|
---|
4 |
|
---|
5 | dean [at] fourwalledcubicle [dot] com
|
---|
6 | www.lufa-lib.org
|
---|
7 | */
|
---|
8 |
|
---|
9 | /*
|
---|
10 | Copyright 2021 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
---|
11 |
|
---|
12 | Permission to use, copy, modify, distribute, and sell this
|
---|
13 | software and its documentation for any purpose is hereby granted
|
---|
14 | without fee, provided that the above copyright notice appear in
|
---|
15 | all copies and that both that the copyright notice and this
|
---|
16 | permission notice and warranty disclaimer appear in supporting
|
---|
17 | documentation, and that the name of the author not be used in
|
---|
18 | advertising or publicity pertaining to distribution of the
|
---|
19 | software without specific, written prior permission.
|
---|
20 |
|
---|
21 | The author disclaims all warranties with regard to this
|
---|
22 | software, including all implied warranties of merchantability
|
---|
23 | and fitness. In no event shall the author be liable for any
|
---|
24 | special, indirect or consequential damages or any damages
|
---|
25 | whatsoever resulting from loss of use, data or profits, whether
|
---|
26 | in an action of contract, negligence or other tortious action,
|
---|
27 | arising out of or in connection with the use or performance of
|
---|
28 | this software.
|
---|
29 | */
|
---|
30 |
|
---|
31 | /** \file
|
---|
32 | *
|
---|
33 | * Main source file for the Keyboard demo. This file contains the main tasks of
|
---|
34 | * the demo and is responsible for the initial application hardware configuration.
|
---|
35 | */
|
---|
36 |
|
---|
37 | #include "Keyboard.h"
|
---|
38 |
|
---|
39 | extern void PCW_Init(void);
|
---|
40 | extern uint8_t* scanall(void);
|
---|
41 |
|
---|
42 | /** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
|
---|
43 | static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
|
---|
44 |
|
---|
45 | /** LUFA HID Class driver interface configuration and state information. This structure is
|
---|
46 | * passed to all HID Class driver functions, so that multiple instances of the same class
|
---|
47 | * within a device can be differentiated from one another.
|
---|
48 | */
|
---|
49 | USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
---|
50 | {
|
---|
51 | .Config =
|
---|
52 | {
|
---|
53 | .InterfaceNumber = INTERFACE_ID_Keyboard,
|
---|
54 | .ReportINEndpoint =
|
---|
55 | {
|
---|
56 | .Address = KEYBOARD_EPADDR,
|
---|
57 | .Size = KEYBOARD_EPSIZE,
|
---|
58 | .Banks = 1,
|
---|
59 | },
|
---|
60 | .PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
|
---|
61 | .PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
|
---|
62 | },
|
---|
63 | };
|
---|
64 |
|
---|
65 |
|
---|
66 | /** Main program entry point. This routine contains the overall program flow, including initial
|
---|
67 | * setup of all components and the main program loop.
|
---|
68 | */
|
---|
69 | int main(void)
|
---|
70 | {
|
---|
71 | SetupHardware();
|
---|
72 |
|
---|
73 | LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
---|
74 | GlobalInterruptEnable();
|
---|
75 |
|
---|
76 | for (;;)
|
---|
77 | {
|
---|
78 | HID_Device_USBTask(&Keyboard_HID_Interface);
|
---|
79 | USB_USBTask();
|
---|
80 | }
|
---|
81 | }
|
---|
82 |
|
---|
83 | /** Configures the board hardware and chip peripherals for the demo's functionality. */
|
---|
84 | void SetupHardware(void)
|
---|
85 | {
|
---|
86 | #if (ARCH == ARCH_AVR8)
|
---|
87 | /* Disable watchdog if enabled by bootloader/fuses */
|
---|
88 | MCUSR &= ~(1 << WDRF);
|
---|
89 | wdt_disable();
|
---|
90 |
|
---|
91 | /* Disable clock division */
|
---|
92 | clock_prescale_set(clock_div_1);
|
---|
93 | #elif (ARCH == ARCH_XMEGA)
|
---|
94 | /* Start the PLL to multiply the 2MHz RC oscillator to 32MHz and switch the CPU core to run from it */
|
---|
95 | XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU);
|
---|
96 | XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL);
|
---|
97 |
|
---|
98 | /* Start the 32MHz internal RC oscillator and start the DFLL to increase it to 48MHz using the USB SOF as a reference */
|
---|
99 | XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ);
|
---|
100 | XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB);
|
---|
101 |
|
---|
102 | PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
|
---|
103 | #endif
|
---|
104 |
|
---|
105 | /* Hardware Initialization */
|
---|
106 | PCW_Init();
|
---|
107 | LEDs_Init();
|
---|
108 | Buttons_Init();
|
---|
109 | USB_Init();
|
---|
110 | }
|
---|
111 |
|
---|
112 | /** Event handler for the library USB Connection event. */
|
---|
113 | void EVENT_USB_Device_Connect(void)
|
---|
114 | {
|
---|
115 | LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
---|
116 | }
|
---|
117 |
|
---|
118 | /** Event handler for the library USB Disconnection event. */
|
---|
119 | void EVENT_USB_Device_Disconnect(void)
|
---|
120 | {
|
---|
121 | LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
---|
122 | }
|
---|
123 |
|
---|
124 | /** Event handler for the library USB Configuration Changed event. */
|
---|
125 | void EVENT_USB_Device_ConfigurationChanged(void)
|
---|
126 | {
|
---|
127 | bool ConfigSuccess = true;
|
---|
128 |
|
---|
129 | ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
|
---|
130 |
|
---|
131 | USB_Device_EnableSOFEvents();
|
---|
132 |
|
---|
133 | LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
|
---|
134 | }
|
---|
135 |
|
---|
136 | /** Event handler for the library USB Control Request reception event. */
|
---|
137 | void EVENT_USB_Device_ControlRequest(void)
|
---|
138 | {
|
---|
139 | HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
|
---|
140 | }
|
---|
141 |
|
---|
142 | /** Event handler for the USB device Start Of Frame event. */
|
---|
143 | void EVENT_USB_Device_StartOfFrame(void)
|
---|
144 | {
|
---|
145 | HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
|
---|
146 | }
|
---|
147 |
|
---|
148 | /** HID class driver callback function for the creation of HID reports to the host.
|
---|
149 | *
|
---|
150 | * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
|
---|
151 | * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
|
---|
152 | * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature
|
---|
153 | * \param[out] ReportData Pointer to a buffer where the created report should be stored
|
---|
154 | * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent)
|
---|
155 | *
|
---|
156 | * \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent
|
---|
157 | */
|
---|
158 | bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
|
---|
159 | uint8_t* const ReportID,
|
---|
160 | const uint8_t ReportType,
|
---|
161 | void* ReportData,
|
---|
162 | uint16_t* const ReportSize)
|
---|
163 | {
|
---|
164 | USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
|
---|
165 |
|
---|
166 | uint8_t* matrix = scanall();
|
---|
167 |
|
---|
168 | uint8_t UsedKeyCodes = 0;
|
---|
169 |
|
---|
170 | #define MAP(i, j, k) \
|
---|
171 | if (matrix[i] & (1 << j)) \
|
---|
172 | KeyboardReport->KeyCode[UsedKeyCodes++] = k; \
|
---|
173 | if (UsedKeyCodes == 6) \
|
---|
174 | goto full;
|
---|
175 |
|
---|
176 | #define MODIFIER(i, j, k) \
|
---|
177 | if (matrix[i] & (1 << j)) \
|
---|
178 | KeyboardReport->Modifier |= k;
|
---|
179 |
|
---|
180 | MAP(0, 7, HID_KEYBOARD_SC_KEYPAD_2_AND_DOWN_ARROW);
|
---|
181 | MAP(0, 6, HID_KEYBOARD_SC_KEYPAD_3_AND_PAGE_DOWN);
|
---|
182 | MAP(0, 5, HID_KEYBOARD_SC_KEYPAD_6_AND_RIGHT_ARROW);
|
---|
183 | MAP(0, 4, HID_KEYBOARD_SC_KEYPAD_9_AND_PAGE_UP);
|
---|
184 | MAP(0, 3, HID_KEYBOARD_SC_PASTE);
|
---|
185 | MAP(0, 2, HID_KEYBOARD_SC_F1);
|
---|
186 | MAP(0, 1, HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT);
|
---|
187 | MAP(0, 0, HID_KEYBOARD_SC_F3);
|
---|
188 |
|
---|
189 | MAP(1, 7, HID_KEYBOARD_SC_KEYPAD_1_AND_END);
|
---|
190 | MAP(1, 6, HID_KEYBOARD_SC_KEYPAD_5);
|
---|
191 | MAP(1, 5, HID_KEYBOARD_SC_KEYPAD_4_AND_LEFT_ARROW);
|
---|
192 | MAP(1, 4, HID_KEYBOARD_SC_KEYPAD_8_AND_UP_ARROW);
|
---|
193 | MAP(1, 3, HID_KEYBOARD_SC_COPY);
|
---|
194 | MAP(1, 2, HID_KEYBOARD_SC_CUT);
|
---|
195 | MAP(1, 1, HID_KEYBOARD_SC_F2);
|
---|
196 | MAP(1, 0, HID_KEYBOARD_SC_F4);
|
---|
197 |
|
---|
198 | MAP(2, 7, HID_KEYBOARD_SC_KEYPAD_PLUS);
|
---|
199 | MAP(2, 6, HID_KEYBOARD_SC_NON_US_HASHMARK_AND_TILDE);
|
---|
200 | MODIFIER(2, 5, HID_KEYBOARD_MODIFIER_LEFTSHIFT | HID_KEYBOARD_MODIFIER_RIGHTSHIFT);
|
---|
201 | MAP(2, 4, HID_KEYBOARD_SC_KEYPAD_7_AND_HOME);
|
---|
202 | MAP(2, 3, HID_KEYBOARD_SC_BACKSLASH_AND_PIPE);
|
---|
203 | MAP(2, 2, HID_KEYBOARD_SC_ENTER);
|
---|
204 | MAP(2, 1, HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE);
|
---|
205 | MAP(2, 0, HID_KEYBOARD_SC_DELETE);
|
---|
206 |
|
---|
207 | MAP(3, 7, HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN);
|
---|
208 | MAP(3, 6, HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK);
|
---|
209 | MAP(3, 5, HID_KEYBOARD_SC_SEMICOLON_AND_COLON);
|
---|
210 | MAP(3, 4, HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE);
|
---|
211 | MAP(3, 3, HID_KEYBOARD_SC_P);
|
---|
212 | MAP(3, 2, HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE);
|
---|
213 | MAP(3, 1, HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE);
|
---|
214 | MAP(3, 0, HID_KEYBOARD_SC_EQUAL_AND_PLUS);
|
---|
215 |
|
---|
216 | MAP(4, 7, HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN);
|
---|
217 | MAP(4, 6, HID_KEYBOARD_SC_M);
|
---|
218 | MAP(4, 5, HID_KEYBOARD_SC_K);
|
---|
219 | MAP(4, 4, HID_KEYBOARD_SC_L);
|
---|
220 | MAP(4, 3, HID_KEYBOARD_SC_I);
|
---|
221 | MAP(4, 2, HID_KEYBOARD_SC_O);
|
---|
222 | MAP(4, 1, HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS);
|
---|
223 | MAP(4, 0, HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS);
|
---|
224 |
|
---|
225 | MAP(5, 7, HID_KEYBOARD_SC_SPACE);
|
---|
226 | MAP(5, 6, HID_KEYBOARD_SC_N);
|
---|
227 | MAP(5, 5, HID_KEYBOARD_SC_J);
|
---|
228 | MAP(5, 4, HID_KEYBOARD_SC_H);
|
---|
229 | MAP(5, 3, HID_KEYBOARD_SC_Y);
|
---|
230 | MAP(5, 2, HID_KEYBOARD_SC_U);
|
---|
231 | MAP(5, 1, HID_KEYBOARD_SC_7_AND_AMPERSAND);
|
---|
232 | MAP(5, 0, HID_KEYBOARD_SC_8_AND_ASTERISK);
|
---|
233 |
|
---|
234 | MAP(6, 7, HID_KEYBOARD_SC_V);
|
---|
235 | MAP(6, 6, HID_KEYBOARD_SC_B);
|
---|
236 | MAP(6, 5, HID_KEYBOARD_SC_F);
|
---|
237 | MAP(6, 4, HID_KEYBOARD_SC_G);
|
---|
238 | MAP(6, 3, HID_KEYBOARD_SC_T);
|
---|
239 | MAP(6, 2, HID_KEYBOARD_SC_R);
|
---|
240 | MAP(6, 1, HID_KEYBOARD_SC_S);
|
---|
241 | MAP(6, 0, HID_KEYBOARD_SC_6_AND_CARET);
|
---|
242 |
|
---|
243 | MAP(7, 7, HID_KEYBOARD_SC_X);
|
---|
244 | MAP(7, 6, HID_KEYBOARD_SC_C);
|
---|
245 | MAP(7, 5, HID_KEYBOARD_SC_D);
|
---|
246 | MAP(7, 4, HID_KEYBOARD_SC_S);
|
---|
247 | MAP(7, 3, HID_KEYBOARD_SC_W);
|
---|
248 | MAP(7, 2, HID_KEYBOARD_SC_E);
|
---|
249 | MAP(7, 1, HID_KEYBOARD_SC_3_AND_HASHMARK);
|
---|
250 | MAP(7, 0, HID_KEYBOARD_SC_4_AND_DOLLAR);
|
---|
251 |
|
---|
252 | MAP(8, 7, HID_KEYBOARD_SC_Z);
|
---|
253 | MAP(8, 6, HID_KEYBOARD_SC_CAPS_LOCK);
|
---|
254 | MAP(8, 5, HID_KEYBOARD_SC_A);
|
---|
255 | MAP(8, 4, HID_KEYBOARD_SC_TAB);
|
---|
256 | MAP(8, 3, HID_KEYBOARD_SC_Q);
|
---|
257 | MAP(8, 2, HID_KEYBOARD_SC_STOP);
|
---|
258 | MAP(8, 1, HID_KEYBOARD_SC_2_AND_AT);
|
---|
259 | MAP(8, 0, HID_KEYBOARD_SC_1_AND_EXCLAMATION);
|
---|
260 |
|
---|
261 | MAP(9, 7, HID_KEYBOARD_SC_BACKSPACE);
|
---|
262 | //MAP(9, 6, HID_KEYBOARD_SC_CAPS_LOCK);
|
---|
263 | MAP(9, 5, HID_KEYBOARD_SC_F6);
|
---|
264 | MAP(9, 4, HID_KEYBOARD_SC_F8);
|
---|
265 | MAP(9, 3, HID_KEYBOARD_SC_RIGHT_ARROW);
|
---|
266 | MAP(9, 2, HID_KEYBOARD_SC_LEFT_ARROW);
|
---|
267 | MAP(9, 1, HID_KEYBOARD_SC_DOWN_ARROW);
|
---|
268 | MAP(9, 0, HID_KEYBOARD_SC_UP_ARROW);
|
---|
269 |
|
---|
270 | MODIFIER(10, 7, HID_KEYBOARD_MODIFIER_LEFTALT | HID_KEYBOARD_MODIFIER_RIGHTALT);
|
---|
271 | MAP(10, 6, HID_KEYBOARD_SC_KEYPAD_DOT_AND_DELETE);
|
---|
272 | MAP(10, 5, HID_KEYBOARD_SC_KEYPAD_ENTER);
|
---|
273 | MAP(10, 4, HID_KEYBOARD_SC_F7);
|
---|
274 | MAP(10, 3, HID_KEYBOARD_SC_KEYPAD_MINUS);
|
---|
275 | MAP(10, 2, HID_KEYBOARD_SC_CANCEL);
|
---|
276 | MAP(10, 1, HID_KEYBOARD_SC_HOME);
|
---|
277 | MAP(10, 0, HID_KEYBOARD_SC_F5);
|
---|
278 |
|
---|
279 | full:
|
---|
280 | *ReportSize = sizeof(USB_KeyboardReport_Data_t);
|
---|
281 | return false;
|
---|
282 | }
|
---|
283 |
|
---|
284 | /** HID class driver callback function for the processing of HID reports from the host.
|
---|
285 | *
|
---|
286 | * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
|
---|
287 | * \param[in] ReportID Report ID of the received report from the host
|
---|
288 | * \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature
|
---|
289 | * \param[in] ReportData Pointer to a buffer where the received report has been stored
|
---|
290 | * \param[in] ReportSize Size in bytes of the received HID report
|
---|
291 | */
|
---|
292 | void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
|
---|
293 | const uint8_t ReportID,
|
---|
294 | const uint8_t ReportType,
|
---|
295 | const void* ReportData,
|
---|
296 | const uint16_t ReportSize)
|
---|
297 | {
|
---|
298 | // Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
|
---|
299 | }
|
---|
300 |
|
---|