Advertisement
Guest User

Untitled

a guest
Jan 20th, 2020
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.78 KB | None | 0 0
  1. #include "Joystick.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5.  
  6. typedef enum {
  7. UP,
  8. DOWN,
  9. LEFT,
  10. RIGHT,
  11. UP_LEFT,
  12. UP_RIGHT,
  13. X,
  14. Y,
  15. A,
  16. B,
  17. L,
  18. R,
  19. PLUS,
  20. MINUS,
  21. THROW,
  22. NOTHING,
  23. TRIGGERS
  24. } Buttons_t;
  25.  
  26. typedef struct {
  27. Buttons_t button;
  28. uint16_t duration;
  29. } command;
  30.  
  31. struct FooArray {
  32. command* data;
  33. int len;
  34. };
  35.  
  36.  
  37. #ifndef lengthof
  38. #define lengthof(x) (sizeof (x) / sizeof ((x)[0]))
  39. #endif
  40.  
  41. static struct FooArray thing;
  42.  
  43. void repeat(Buttons_t button, uint16_t duration, int countToAdd, bool shouldAddNothing, struct FooArray* array)
  44. {
  45. int finalAmount = array->len + countToAdd;
  46. do
  47. {
  48. command f = { button, duration };
  49. array->data[array->len] = f;
  50. array->len++;
  51. if (shouldAddNothing)
  52. {
  53. command n = { NOTHING, 150 };
  54. array->data[array->len] = n;
  55. array->len++;
  56. }
  57. } while (array->len < finalAmount);
  58. }
  59. const int totalArraySize = 5;
  60.  
  61. void setupSteps()
  62. {
  63. thing.len = 0;
  64. thing.data = (command*)(malloc(totalArraySize * sizeof(command)));
  65. memset(thing.data, 0, sizeof(command) * totalArraySize);
  66.  
  67. repeat(B, 5, 5, false, &thing);
  68. }
  69.  
  70. // Main entry point.
  71. int main(void) {
  72.  
  73. setupSteps();
  74.  
  75. // We'll start by performing hardware and peripheral setup.
  76. SetupHardware();
  77. // We'll then enable global interrupts for our use.
  78. GlobalInterruptEnable();
  79. // Once that's done, we'll enter an infinite loop.
  80. for (;;)
  81. {
  82. // We need to run our task to process and deliver data for our IN and OUT endpoints.
  83. HID_Task();
  84. // We also need to run the main USB management task.
  85. USB_USBTask();
  86. }
  87. }
  88.  
  89. // Configures hardware and peripherals, such as the USB peripherals.
  90. void SetupHardware(void) {
  91. // We need to disable watchdog if enabled by bootloader/fuses.
  92. MCUSR &= ~(1 << WDRF);
  93. wdt_disable();
  94.  
  95. // We need to disable clock division before initializing the USB hardware.
  96. clock_prescale_set(clock_div_1);
  97. // We can then initialize our hardware and peripherals, including the USB stack.
  98.  
  99. #ifdef ALERT_WHEN_DONE
  100. // Both PORTD and PORTB will be used for the optional LED flashing and buzzer.
  101. #warning LEDand Buzzer functionality enabled.All pins on both PORTBand \
  102. PORTD will toggle when printing is done.
  103. DDRD = 0xFF; //Teensy uses PORTD
  104. PORTD = 0x0;
  105. //We'll just flash all pins on both ports since the UNO R3
  106. DDRB = 0xFF; //uses PORTB. Micro can use either or, but both give us 2 LEDs
  107. PORTB = 0x0; //The ATmega328P on the UNO will be resetting, so unplug it?
  108. #endif
  109. // The USB stack should be initialized last.
  110. USB_Init();
  111. }
  112.  
  113. // Fired to indicate that the device is enumerating.
  114. void EVENT_USB_Device_Connect(void) {
  115. // We can indicate that we're enumerating here (via status LEDs, sound, etc.).
  116. }
  117.  
  118. // Fired to indicate that the device is no longer connected to a host.
  119. void EVENT_USB_Device_Disconnect(void) {
  120. // We can indicate that our device is not ready (via status LEDs, sound, etc.).
  121. }
  122.  
  123. // Fired when the host set the current configuration of the USB device after enumeration.
  124. void EVENT_USB_Device_ConfigurationChanged(void) {
  125. bool ConfigSuccess = true;
  126.  
  127. // We setup the HID report endpoints.
  128. ConfigSuccess &= Endpoint_ConfigureEndpoint(JOYSTICK_OUT_EPADDR, EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1);
  129. ConfigSuccess &= Endpoint_ConfigureEndpoint(JOYSTICK_IN_EPADDR, EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1);
  130.  
  131. // We can read ConfigSuccess to indicate a success or failure at this point.
  132. }
  133.  
  134. // Process control requests sent to the device from the USB host.
  135. void EVENT_USB_Device_ControlRequest(void) {
  136. // We can handle two control requests: a GetReport and a SetReport.
  137.  
  138. // Not used here, it looks like we don't receive control request from the Switch.
  139. }
  140.  
  141. // Process and deliver data from IN and OUT endpoints.
  142. void HID_Task(void) {
  143. // If the device isn't connected and properly configured, we can't do anything here.
  144. if (USB_DeviceState != DEVICE_STATE_Configured)
  145. return;
  146.  
  147. // We'll start with the OUT endpoint.
  148. Endpoint_SelectEndpoint(JOYSTICK_OUT_EPADDR);
  149. // We'll check to see if we received something on the OUT endpoint.
  150. if (Endpoint_IsOUTReceived())
  151. {
  152. // If we did, and the packet has data, we'll react to it.
  153. if (Endpoint_IsReadWriteAllowed())
  154. {
  155. // We'll create a place to store our data received from the host.
  156. USB_JoystickReport_Output_t JoystickOutputData;
  157. // We'll then take in that data, setting it up in our storage.
  158. while (Endpoint_Read_Stream_LE(&JoystickOutputData, sizeof(JoystickOutputData), NULL) != ENDPOINT_RWSTREAM_NoError);
  159. // At this point, we can react to this data.
  160.  
  161. // However, since we're not doing anything with this data, we abandon it.
  162. }
  163. // Regardless of whether we reacted to the data, we acknowledge an OUT packet on this endpoint.
  164. Endpoint_ClearOUT();
  165. }
  166.  
  167. // We'll then move on to the IN endpoint.
  168. Endpoint_SelectEndpoint(JOYSTICK_IN_EPADDR);
  169. // We first check to see if the host is ready to accept data.
  170. if (Endpoint_IsINReady())
  171. {
  172. // We'll create an empty report.
  173. USB_JoystickReport_Input_t JoystickInputData;
  174. // We'll then populate this report with what we want to send to the host.
  175. GetNextReport(&JoystickInputData);
  176. // Once populated, we can output this data to the host. We do this by first writing the data to the control stream.
  177. while (Endpoint_Write_Stream_LE(&JoystickInputData, sizeof(JoystickInputData), NULL) != ENDPOINT_RWSTREAM_NoError);
  178. // We then send an IN packet on this endpoint.
  179. Endpoint_ClearIN();
  180. }
  181. }
  182.  
  183. typedef enum {
  184. SYNC_CONTROLLER,
  185. SYNC_POSITION,
  186. BREATHE,
  187. PROCESS,
  188. CLEANUP,
  189. DONE
  190. } State_t;
  191. State_t state = SYNC_CONTROLLER;
  192.  
  193. #define ECHOES 2
  194. int echoes = 0;
  195. USB_JoystickReport_Input_t last_report;
  196.  
  197. int report_count = 0;
  198. int xpos = 0;
  199. int ypos = 0;
  200. int bufindex = 0;
  201. int duration_count = 0;
  202. int portsval = 0;
  203.  
  204. // Prepare the next report for the host.
  205. void GetNextReport(USB_JoystickReport_Input_t* const ReportData) {
  206.  
  207. // Prepare an empty report
  208. memset(ReportData, 0, sizeof(USB_JoystickReport_Input_t));
  209. ReportData->LX = STICK_CENTER;
  210. ReportData->LY = STICK_CENTER;
  211. ReportData->RX = STICK_CENTER;
  212. ReportData->RY = STICK_CENTER;
  213. ReportData->HAT = HAT_CENTER;
  214.  
  215. // Repeat ECHOES times the last report
  216. if (echoes > 0)
  217. {
  218. memcpy(ReportData, &last_report, sizeof(USB_JoystickReport_Input_t));
  219. echoes--;
  220. return;
  221. }
  222.  
  223. // States and moves management
  224. switch (state)
  225. {
  226.  
  227. case SYNC_CONTROLLER:
  228. state = BREATHE;
  229. break;
  230.  
  231. // case SYNC_CONTROLLER:
  232. // if (report_count > 550)
  233. // {
  234. // report_count = 0;
  235. // state = SYNC_POSITION;
  236. // }
  237. // else if (report_count == 250 || report_count == 300 || report_count == 325)
  238. // {
  239. // ReportData->Button |= SWITCH_L | SWITCH_R;
  240. // }
  241. // else if (report_count == 350 || report_count == 375 || report_count == 400)
  242. // {
  243. // ReportData->Button |= SWITCH_A;
  244. // }
  245. // else
  246. // {
  247. // ReportData->Button = 0;
  248. // ReportData->LX = STICK_CENTER;
  249. // ReportData->LY = STICK_CENTER;
  250. // ReportData->RX = STICK_CENTER;
  251. // ReportData->RY = STICK_CENTER;
  252. // ReportData->HAT = HAT_CENTER;
  253. // }
  254. // report_count++;
  255. // break;
  256.  
  257. case SYNC_POSITION:
  258. bufindex = 0;
  259.  
  260.  
  261. ReportData->Button = 0;
  262. ReportData->LX = STICK_CENTER;
  263. ReportData->LY = STICK_CENTER;
  264. ReportData->RX = STICK_CENTER;
  265. ReportData->RY = STICK_CENTER;
  266. ReportData->HAT = HAT_CENTER;
  267.  
  268.  
  269. state = BREATHE;
  270. break;
  271.  
  272. case BREATHE:
  273. state = PROCESS;
  274. break;
  275.  
  276. case PROCESS:
  277.  
  278. switch (thing.data[bufindex].button)
  279. {
  280.  
  281. case UP:
  282. ReportData->LY = STICK_MIN;
  283. break;
  284.  
  285. case LEFT:
  286. ReportData->LX = STICK_MIN;
  287. break;
  288.  
  289. case DOWN:
  290. ReportData->LY = STICK_MAX;
  291. break;
  292.  
  293. case RIGHT:
  294. ReportData->LX = STICK_MAX;
  295. break;
  296.  
  297. case UP_LEFT:
  298. ReportData->RX = STICK_MIN;
  299. ReportData->LX = STICK_MIN;
  300. break;
  301.  
  302. case UP_RIGHT:
  303. ReportData->LY = STICK_MIN;
  304. ReportData->LX = STICK_MAX;
  305. break;
  306.  
  307. case A:
  308. ReportData->Button |= SWITCH_A;
  309. break;
  310.  
  311. case B:
  312. ReportData->Button |= SWITCH_B;
  313. break;
  314.  
  315. case R:
  316. ReportData->Button |= SWITCH_R;
  317. break;
  318.  
  319. case X:
  320. ReportData->Button |= SWITCH_X;
  321. break;
  322.  
  323. case Y:
  324. ReportData->Button |= SWITCH_Y;
  325. break;
  326.  
  327. case PLUS:
  328. ReportData->Button |= SWITCH_PLUS;
  329. break;
  330.  
  331. case MINUS:
  332. ReportData->Button |= SWITCH_MINUS;
  333. break;
  334.  
  335. /*case THROW:
  336. ReportData->LY = STICK_MIN;
  337. ReportData->Button |= SWITCH_R;
  338. break;*/
  339.  
  340. case TRIGGERS:
  341. ReportData->Button |= SWITCH_L | SWITCH_R;
  342. break;
  343.  
  344. default:
  345. ReportData->LX = STICK_CENTER;
  346. ReportData->LY = STICK_CENTER;
  347. ReportData->RX = STICK_CENTER;
  348. ReportData->RY = STICK_CENTER;
  349. ReportData->HAT = HAT_CENTER;
  350. break;
  351. }
  352.  
  353. duration_count++;
  354.  
  355. if (duration_count > thing.data[bufindex].duration)
  356. {
  357. bufindex++;
  358. duration_count = 0;
  359. }
  360.  
  361.  
  362. if (bufindex > thing.len - 1)
  363. {
  364.  
  365. // state = CLEANUP;
  366.  
  367. bufindex = 7;
  368. duration_count = 0;
  369.  
  370. state = BREATHE;
  371.  
  372. ReportData->LX = STICK_CENTER;
  373. ReportData->LY = STICK_CENTER;
  374. ReportData->RX = STICK_CENTER;
  375. ReportData->RY = STICK_CENTER;
  376. ReportData->HAT = HAT_CENTER;
  377.  
  378.  
  379. // state = DONE;
  380. // state = BREATHE;
  381.  
  382. }
  383.  
  384. break;
  385.  
  386. case CLEANUP:
  387. state = DONE;
  388. break;
  389.  
  390. case DONE:
  391. #ifdef ALERT_WHEN_DONE
  392. portsval = ~portsval;
  393. PORTD = portsval; //flash LED(s) and sound buzzer if attached
  394. PORTB = portsval;
  395. _delay_ms(250);
  396. #endif
  397. return;
  398. }
  399.  
  400. // // Inking
  401. // if (state != SYNC_CONTROLLER && state != SYNC_POSITION)
  402. // if (pgm_read_byte(&(image_data[(xpos / 8) + (ypos * 40)])) & 1 << (xpos % 8))
  403. // ReportData->Button |= SWITCH_A;
  404.  
  405. // Prepare to echo this report
  406. memcpy(&last_report, ReportData, sizeof(USB_JoystickReport_Input_t));
  407. echoes = ECHOES;
  408.  
  409. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement