initial commit
[armstart-ibdap] / src / IBDAP.c
1 /*
2 ===============================================================================
3  Name        : IBDAP.c
4  Author      : $(author)
5  Version     :
6  Copyright   : $(copyright)
7  Description : main definition
8 ===============================================================================
9 */
10
11 #ifdef __USE_CMSIS
12 #include "LPC11Uxx.h"
13 #endif
14
15 #include "DAP_config.h"
16
17 #include "DAP.h"
18
19 #include "usb_driver.h"
20
21
22
23 #define TICKRATE_100msec (10)
24 #define TICKRATE_10msec  (100)
25 #define TICKRATE_1msec   (1000)
26
27 #define TICKRATE                 TICKRATE_1msec
28
29 // Connected LED RED          PIN 21: PIO0_11
30 #define LED_ERROR_PORT         0
31 #define LED_ERROR_BIT          11
32 #define IOCON_ERROR_REG        (LPC_IOCON->TDI_PIO0_11)
33
34 void indicator_code (int code);
35
36 void init_error_led () {
37         IOCON_ERROR_REG = 1 | 1 << 4 | 1 << 7;
38         LPC_GPIO->DIR[LED_ERROR_PORT] |= 1 << LED_ERROR_BIT;
39         LPC_GPIO->SET[LED_ERROR_PORT] = 1 << LED_ERROR_BIT;
40 }
41
42 INLINE void LED_ERROR_ON () {
43         LPC_GPIO->CLR[LED_ERROR_PORT] = 1 << LED_ERROR_BIT;
44 }
45
46 INLINE void LED_ERROR_OFF () {
47         LPC_GPIO->SET[LED_ERROR_PORT] = 1 << LED_ERROR_BIT;
48 }
49
50
51 static volatile uint32_t sys_time = 0;
52
53
54 void SysTick_Handler () {
55         sys_time++;
56 }
57
58 void sleep_ms (int ms) {
59
60         int e = sys_time * (1000/TICKRATE) + ms;
61         while ((sys_time * (1000/TICKRATE)) <= e) {
62                 __WFI ();
63         }
64 }
65
66 // HID callbacks and buffer
67
68 typedef struct _IBDAP_HND_T {
69         volatile uint8_t usb_outs_end_idx;
70         volatile uint8_t usb_outs_start_idx;
71         uint8_t usb_outs[DAP_PACKET_COUNT][DAP_PACKET_SIZE];
72         volatile uint8_t usb_ins_end_idx;
73         volatile uint8_t usb_ins_start_idx;
74         volatile uint8_t usb_ins_busy;
75         uint8_t usb_ins[DAP_PACKET_COUNT][DAP_PACKET_SIZE];
76 }IBDAP_HND_T;
77
78 IBDAP_HND_T* ibdap = 0;
79
80
81 ErrorCode_t DAP_GetReport_Callback( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length) {
82         return LPC_OK;
83 }
84
85 ErrorCode_t DAP_SetReport_Callback( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length) {
86         return LPC_OK;
87 }
88
89 ErrorCode_t DAP_EpInOut_Hdlr_Callback (USBD_HANDLE_T hUsb, void* data, uint32_t event) {
90         USB_HID_CTRL_T *pHidCtrl = (USB_HID_CTRL_T *) data;
91         switch (event) {
92         case USB_EVT_IN:
93                 if (ibdap->usb_ins_start_idx == ibdap->usb_ins_end_idx) {
94                         ibdap->usb_ins_busy = 0;
95                         break;
96                 }
97                 USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, ibdap->usb_ins[ibdap->usb_ins_start_idx], DAP_PACKET_SIZE);
98                 ibdap->usb_ins_start_idx = (ibdap->usb_ins_start_idx+1) % DAP_PACKET_COUNT;
99                 //LED_RUNNING_OUT (1);
100                 //LED_CONNECTED_OUT (0);
101                 break;
102         case USB_EVT_OUT:
103                 USBD_API->hw->ReadEP(hUsb, pHidCtrl->epout_adr, ibdap->usb_outs[ibdap->usb_outs_end_idx]);
104                 ibdap->usb_outs_end_idx = (ibdap->usb_outs_end_idx+1) % DAP_PACKET_COUNT;
105                 //LED_CONNECTED_OUT (1);
106                 //LED_RUNNING_OUT (0);
107                 break;
108         }
109         return LPC_OK;
110 }
111
112 void suspend () {
113         while (1) {
114                 LED_ERROR_ON ();
115                 sleep_ms (1000);
116                 LED_ERROR_OFF ();
117                 sleep_ms (1000);
118         }
119 }
120
121 void error_code (int code) {
122         LED_ERROR_ON ();
123         while (1) {
124                 if (code & 0x01 && !(code & 0x02 )) { // code == 1
125                         LED_CONNECTED_OUT (1);
126                         LED_RUNNING_OUT (0);
127                         sleep_ms (1000);
128                         LED_CONNECTED_OUT (0);
129                 } else if (!(code & 0x01) && (code & 0x02)) { // code == 2
130                         LED_CONNECTED_OUT (0);
131                         LED_RUNNING_OUT (1);
132                         sleep_ms (1000);
133                         LED_RUNNING_OUT (0);
134                 } else if ((code & 0x01) == 3) {
135                         LED_CONNECTED_OUT (1);
136                         LED_RUNNING_OUT (1);
137                         sleep_ms (1000);
138                         LED_CONNECTED_OUT (0);
139                         LED_RUNNING_OUT (0);
140                 } else {
141                         LED_CONNECTED_OUT (1);
142                         LED_RUNNING_OUT (0);
143                         sleep_ms (1000);
144                         LED_CONNECTED_OUT (0);
145                         LED_RUNNING_OUT (1);
146                 }
147
148                 sleep_ms (1000);
149         }
150 }
151
152 void indicator_code (int code) {
153         LED_ERROR_OFF ();
154         while (1) {
155                 if (code & 0x01 && !(code & 0x02 )) { // code == 1
156                         LED_CONNECTED_OUT (1);
157                         LED_RUNNING_OUT (0);
158                         sleep_ms (1000);
159                         LED_CONNECTED_OUT (0);
160                 } else if (!(code & 0x01) && (code & 0x02)) { // code == 2
161                         LED_CONNECTED_OUT (0);
162                         LED_RUNNING_OUT (1);
163                         sleep_ms (1000);
164                         LED_RUNNING_OUT (0);
165                 } else if ((code & 0x01) == 3) {
166                         LED_CONNECTED_OUT (1);
167                         LED_RUNNING_OUT (1);
168                         sleep_ms (1000);
169                         LED_CONNECTED_OUT (0);
170                         LED_RUNNING_OUT (0);
171                 } else {
172                         LED_CONNECTED_OUT (1);
173                         LED_RUNNING_OUT (0);
174                         sleep_ms (1000);
175                         LED_CONNECTED_OUT (0);
176                         LED_RUNNING_OUT (1);
177                 }
178
179                 sleep_ms (1000);
180         }
181 }
182 // TODO: insert other definitions and declarations here
183
184 void device_boot() {
185         LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 6; // enable gpio clock
186 }
187
188 int main(void) {
189
190         device_boot();
191
192         USBD_API_INIT_PARAM_T usb_param;
193
194         SysTick_Config(SystemCoreClock / TICKRATE);
195
196         init_error_led ();
197
198     DAP_Setup ();
199
200
201     init_usb_clock ();
202     init_usb_power ();
203     if (init_usb_driver (&usb_param)) {
204         // printf error;
205         // LED error;
206         suspend ();
207         return -1;
208     }
209
210     if (init_usb_hid (&usb_param,
211                 &DAP_GetReport_Callback, &DAP_SetReport_Callback,
212                         &DAP_EpInOut_Hdlr_Callback, &DAP_EpInOut_Hdlr_Callback,
213                         (uint8_t**)&ibdap, sizeof (IBDAP_HND_T))) {
214         // printf error;
215         // LED error;
216         error_code (1);
217         return -1;
218     }
219
220     connect_to_usb_bus ();
221     //LED_ERROR_ON ();
222     while (1) {
223         /*
224         LED_ERROR_ON ();
225         sleep_ms (500);
226         LED_ERROR_OFF ();
227         sleep_ms (1000);
228         */
229         if (ibdap->usb_outs_start_idx == ibdap->usb_outs_end_idx) {
230                 //LED_ERROR_ON ();
231                 __WFI ();
232                 continue;
233         } else {
234                 LED_CONNECTED_OUT (1);
235         }
236         //LED_ERROR_OFF ();
237         DAP_ProcessCommand (ibdap->usb_outs[ibdap->usb_outs_start_idx], ibdap->usb_ins[ibdap->usb_ins_end_idx]);
238         ibdap->usb_outs_start_idx = (ibdap->usb_outs_start_idx+1) % DAP_PACKET_COUNT;
239         ibdap->usb_ins_end_idx = (ibdap->usb_ins_end_idx+1) % DAP_PACKET_COUNT;
240         if (!ibdap->usb_ins_busy) { // kickstart
241                 ibdap->usb_ins_busy = 1;
242                 uint8_t idx = ibdap->usb_ins_start_idx;
243                 ibdap->usb_ins_start_idx = (ibdap->usb_ins_start_idx+1) % DAP_PACKET_COUNT;
244                 USBD_API->hw->WriteEP(g_usb_hnd, HID_EP_IN, ibdap->usb_ins[idx], DAP_PACKET_SIZE);
245
246                 //LED_RUNNING_OUT (1);
247                 //LED_CONNECTED_OUT (0);
248         }
249
250     }
251 }