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
|
#include "at32f403a_407_board.h"
#include "at32f403a_407_clock.h"
#include "usbd_core.h"
#include "keyboard_class.h"
#include "keyboard_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, &keyboard_class_handler, &keyboard_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)
{
keyboard_send_string(&usb_core_dev, (uint8_t *)" Keyboard Demo\r\n", 16);
}
/* 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);
}
}
#ifdef USB_LOW_POWER_WAKUP
/* enter deep sleep */
if(((keyboard_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();
((keyboard_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);
}
|