-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathnaeusb_default.c
159 lines (132 loc) · 3.78 KB
/
naeusb_default.c
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "naeusb_default.h"
#include "usart_driver.h"
#include <string.h>
#ifndef RSTC_CR_KEY_PASSWD
#define RSTC_CR_KEY_PASSWD RSTC_CR_KEY(0xA5)
#endif
uint8_t LED_SETTING = 0;
uint16_t CURRENT_ERRORS = 0;
volatile const uint8_t fw_major = FW_VER_MAJOR;
volatile const uint8_t fw_minor = FW_VER_MINOR;
volatile const uint8_t fw_debug = FW_VER_DEBUG;
bool naeusb_sam_status_in(void)
{
return false;
}
void naeusb_sam_cfg_out(void)
{
switch(udd_g_ctrlreq.req.wValue & 0xFF)
{
/* Turn on slow clock */
case SAM_SLOW_CLOCK_ON:
osc_enable(OSC_MAINCK_XTAL);
osc_wait_ready(OSC_MAINCK_XTAL);
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
break;
/* Turn off slow clock */
case SAM_SLOW_CLOCK_OFF:
pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES);
break;
/* Jump to ROM-resident bootloader */
case SAM_ENTER_BOOTLOADER:
/* Turn off connected stuff */
board_power(0);
/* Clear ROM-mapping bit. */
efc_perform_command(EFC0, EFC_FCMD_CGPB, 1);
/* Disconnect USB (will kill connection) */
udc_detach();
/* With knowledge that I will rise again, I lay down my life. */
while (RSTC->RSTC_SR & RSTC_SR_SRCMP);
//RSTC->RSTC_CR |= RSTC_CR_KEY(0xA5) | RSTC_CR_PERRST | RSTC_CR_PROCRST;
RSTC->RSTC_CR |= RSTC_CR_KEY_PASSWD | RSTC_CR_PERRST | RSTC_CR_PROCRST;
while(1);
break;
/* Disconnect USB (will kill stuff) */
/* Make the jump */
break;
case SAM_RESET:
udc_detach();
while (RSTC->RSTC_SR & RSTC_SR_SRCMP);
RSTC->RSTC_CR |= RSTC_CR_KEY_PASSWD | RSTC_CR_PERRST | RSTC_CR_PROCRST;
while(1);
break;
case SAM_RELEASE_LOCK: // use in case of pipe error emergency
#if USB_DEVICE_PRODUCT_ID != 0xACE0
FPGA_releaselock();
#endif
break;
case SAM_LED_SETTINGS:
LED_SETTING = (udd_g_ctrlreq.req.wValue >> 8) & 0xFF;
#ifdef LED1_GPIO
if (LED_SETTING == 0) {
LED_Off(LED1_GPIO);
}
#endif
break;
case SAM_CLEAR_ERRORS:
CURRENT_ERRORS = 0;
break;
/* Oh well, sucks to be you */
default:
break;
}
}
bool naeusb_fw_version_in(void)
{
respbuf[0] = fw_major;
respbuf[1] = fw_minor;
respbuf[2] = fw_debug;
udd_g_ctrlreq.payload = respbuf;
udd_g_ctrlreq.payload_size = 3;
return true;
}
static const char BUILD_DATE[] = __DATE__;
static const char BUILD_TIME[] = __TIME__;
bool naeusb_build_date_in(void)
{
strncpy(respbuf, BUILD_TIME, 64);
respbuf[sizeof(BUILD_TIME) - 1] = ' ';
strncpy(respbuf + sizeof(BUILD_TIME), BUILD_DATE, 64 - sizeof(BUILD_TIME));
udd_g_ctrlreq.payload = respbuf;
udd_g_ctrlreq.payload_size = strlen(respbuf);
return true;
}
bool naeusb_status_in(void)
{
respbuf[0] = CURRENT_ERRORS & 0xFF;
respbuf[1] = CURRENT_ERRORS >> 8;
respbuf[2] = LED_SETTING;
udd_g_ctrlreq.payload = respbuf;
udd_g_ctrlreq.payload_size = 3;
return true;
}
bool naeusb_setup_out_received(void)
{
switch (udd_g_ctrlreq.req.bRequest) {
case REQ_SAM_CFG:
udd_g_ctrlreq.callback = naeusb_sam_cfg_out;
return true;
break;
}
return false;
}
bool naeusb_setup_in_received(void)
{
switch (udd_g_ctrlreq.req.bRequest) {
case REQ_FW_VERSION:
return naeusb_fw_version_in();
break;
case REQ_BUILD_DATE:
return naeusb_build_date_in();
break;
case REQ_SAM_STATUS:
return naeusb_status_in();
break;
}
return false;
}
void naeusb_register_handlers(void)
{
naeusb_add_in_handler(naeusb_setup_in_received);
naeusb_add_out_handler(naeusb_setup_out_received);
}