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
|
#include "at32f403a_407_board.h"
#include "at32f403a_407_clock.h"
#include "usbd_core.h"
#include "mouse_class.h"
#include "mouse_desc.h"
#include "usbd_int.h"
int main(void)
{
__IO uint32_t delay_index = 0;
/* config nvic priority group */
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
system_clock_config();
at32_board_init();
/* select usb 48m clcok source */
usb_clock48m_select(USB_CLK_HEXT);
#ifdef USB_LOW_POWER_WAKUP
/* enable pwc and bpr clock */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
button_exint_init();
usb_low_power_wakeup_config();
#endif
/* enable usb clock */
crm_periph_clock_enable(CRM_USB_PERIPH_CLOCK, TRUE);
/* enable usb interrupt */
nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn, 0, 0);
/* usb core init */
usbd_core_init(&usb_core_dev, USB, &mouse_class_handler, &mouse_desc_handler, 0);
/* enable usb pull-up */
usbd_connect(&usb_core_dev);
while(1)
{
if(at32_button_press() == USER_BUTTON)
{
if(usbd_connect_state_get(&usb_core_dev) == USB_CONN_STATE_CONFIGURED)
{
usb_hid_mouse_send(&usb_core_dev, RIGHT_BUTTON);
press_mouse = 1;
}
/* remote wakeup */
if(usbd_connect_state_get(&usb_core_dev) == USB_CONN_STATE_SUSPENDED
&&(usb_core_dev.remote_wakup == 1))
{
usbd_remote_wakeup(&usb_core_dev);
}
}
else if(press_mouse == 1)
{
delay_ms(10);
usb_hid_mouse_send(&usb_core_dev, BUTTON_RELEASE);
press_mouse = 0;
}
#ifdef USB_LOW_POWER_WAKUP
/* enter deep sleep */
if(((mouse_type *)(usb_core_dev.class_handler->pdata))->hid_suspend_flag == 1)
{
at32_led_off(LED2);
at32_led_off(LED3);
at32_led_off(LED4);
/* congfig the voltage regulator mode */
pwc_voltage_regulate_set(PWC_REGULATOR_LOW_POWER);
/* enter deep sleep mode */
pwc_deep_sleep_mode_enter(PWC_DEEP_SLEEP_ENTER_WFI);
/* wait 3 LICK cycles to ensure clock stable, delay 120us*/
/* when wakeup from deepsleep,system clock source changes to HICK */
if((CRM->misc3_bit.hick_to_sclk == TRUE) && (CRM->misc1_bit.hickdiv == TRUE))
{
/* HICK is 48MHz */
for(delay_index = 0; delay_index < 750; delay_index++)
{
__NOP();
}
}
else
{
/* HICK is 8MHz */
for(delay_index = 0; delay_index < 125; delay_index++)
{
__NOP();
}
}
system_clock_recover();
((mouse_type *)(usb_core_dev.class_handler->pdata))->hid_suspend_flag = 0;
at32_led_on(LED2);
at32_led_on(LED3);
at32_led_on(LED4);
}
#endif
}
}
void button_exint_init(void)
{
exint_init_type exint_init_struct;
crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE0);
exint_default_para_init(&exint_init_struct);
exint_init_struct.line_enable = TRUE;
exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;
exint_init_struct.line_select = EXINT_LINE_0;
exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
exint_init(&exint_init_struct);
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
nvic_irq_enable(EXINT0_IRQn, 0, 0);
}
void usb_low_power_wakeup_config(void)
{
exint_init_type exint_init_struct;
exint_default_para_init(&exint_init_struct);
exint_init_struct.line_enable = TRUE;
exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;
exint_init_struct.line_select = EXINT_LINE_18;
exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
exint_init(&exint_init_struct);
nvic_irq_enable(USBFSWakeUp_IRQn, 0, 0);
}
|