📄 main.c
字号:
//------------------------------------------------------------------------------
/// Put voltage regulator in normal mode
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
//------------------------------------------------------------------------------
void NormalPowerMode(void)
{
}
#elif defined(at91sam7a3)
//------------------------------------------------------------------------------
/// Put the CPU in 32kHz, disable PLL, main oscillator
//------------------------------------------------------------------------------
void LowPowerMode(void)
{
// MCK=48MHz to MCK=32kHz
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=SLCK : then change prescaler
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// disable PLL
AT91C_BASE_PMC->PMC_PLLR = 0;
// Disable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = 0;
PMC_DisableProcessorClock();
}
//------------------------------------------------------------------------------
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
//------------------------------------------------------------------------------
void NormalPowerMode(void)
{
// MCK=32kHz to MCK=48MHz
// enable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
// enable PLL@96MHz
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
(AT91C_CKGR_MUL & (0x48<<16)));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
// MCK=SLCK/2 : change prescaler first
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=PLLCK/2 : then change source
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
}
#elif defined (at91sam7se)
//------------------------------------------------------------------------------
/// Put the CPU in 32kHz, disable PLL, main oscillator
/// Put voltage regulator in standby mode
//------------------------------------------------------------------------------
void LowPowerMode(void)
{
// MCK=48MHz to MCK=32kHz
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=SLCK : then change prescaler
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// disable PLL
AT91C_BASE_PMC->PMC_PLLR = 0;
// Disable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = 0;
// Voltage regulator in standby mode : Enable VREG Low Power Mode
AT91C_BASE_VREG->VREG_MR |= AT91C_VREG_PSTDBY;
PMC_DisableProcessorClock();
}
//------------------------------------------------------------------------------
/// Put voltage regulator in normal mode
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
//------------------------------------------------------------------------------
void NormalPowerMode(void)
{
// Voltage regulator in normal mode : Disable VREG Low Power Mode
AT91C_BASE_VREG->VREG_MR &= ~AT91C_VREG_PSTDBY;
// MCK=32kHz to MCK=48MHz
// enable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
// enable PLL@96MHz
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
(AT91C_CKGR_MUL & (0x48<<16)));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
// MCK=SLCK/2 : change prescaler first
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=PLLCK/2 : then change source
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
}
#elif defined (at91sam7s)
//------------------------------------------------------------------------------
/// Put the CPU in 32kHz, disable PLL, main oscillator
/// Put voltage regulator in standby mode
//------------------------------------------------------------------------------
void LowPowerMode(void)
{
// MCK=48MHz to MCK=32kHz
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=SLCK : then change prescaler
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// disable PLL
AT91C_BASE_PMC->PMC_PLLR = 0;
// Disable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = 0;
// Voltage regulator in standby mode : Enable VREG Low Power Mode
AT91C_BASE_VREG->VREG_MR |= AT91C_VREG_PSTDBY;
PMC_DisableProcessorClock();
}
//------------------------------------------------------------------------------
/// Put voltage regulator in normal mode
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
//------------------------------------------------------------------------------
void NormalPowerMode(void)
{
// Voltage regulator in normal mode : Disable VREG Low Power Mode
AT91C_BASE_VREG->VREG_MR &= ~AT91C_VREG_PSTDBY;
// MCK=32kHz to MCK=48MHz
// enable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
// enable PLL@96MHz
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
(AT91C_CKGR_MUL & (0x48<<16)));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
// MCK=SLCK/2 : change prescaler first
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=PLLCK/2 : then change source
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
}
#elif defined (at91sam7x) || defined (at91sam7xc)
//------------------------------------------------------------------------------
/// Put the CPU in 32kHz, disable PLL, main oscillator
/// Put voltage regulator in standby mode
//------------------------------------------------------------------------------
void LowPowerMode(void)
{
// MCK=48MHz to MCK=32kHz
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=SLCK : then change prescaler
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// disable PLL
AT91C_BASE_PMC->PMC_PLLR = 0;
// Disable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = 0;
// Voltage regulator in standby mode : Enable VREG Low Power Mode
AT91C_BASE_VREG->VREG_MR |= AT91C_VREG_PSTDBY;
PMC_DisableProcessorClock();
}
//------------------------------------------------------------------------------
/// Put voltage regulator in normal mode
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
//------------------------------------------------------------------------------
void NormalPowerMode(void)
{
// Voltage regulator in normal mode : Disable VREG Low Power Mode
AT91C_BASE_VREG->VREG_MR &= ~AT91C_VREG_PSTDBY;
// MCK=32kHz to MCK=48MHz
// enable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
// enable PLL@96MHz
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
(AT91C_CKGR_MUL & (0x48<<16)));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
// MCK=SLCK/2 : change prescaler first
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=PLLCK/2 : then change source
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
}
#endif
//------------------------------------------------------------------------------
// Callbacks re-implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Invoked when the USB device leaves the Suspended state. By default,
/// configures the LEDs.
//------------------------------------------------------------------------------
void USBDCallbacks_Resumed(void)
{
// Initialize LEDs
LED_Configure(USBD_LEDPOWER);
LED_Set(USBD_LEDPOWER);
LED_Configure(USBD_LEDUSB);
LED_Clear(USBD_LEDUSB);
USBState = STATE_RESUME;
}
//------------------------------------------------------------------------------
/// Invoked when the USB device gets suspended. By default, turns off all LEDs.
//------------------------------------------------------------------------------
void USBDCallbacks_Suspended(void)
{
// Turn off LEDs
LED_Clear(USBD_LEDPOWER);
LED_Clear(USBD_LEDUSB);
USBState = STATE_SUSPEND;
}
//------------------------------------------------------------------------------
/// Invoked when the status of the keyboard LEDs changes. Turns the num. lock
/// LED on or off.
/// \param numLockStatus Indicates the current status of the num. lock key.
/// \param capsLockStatus Indicates the current status of the caps lock key.
/// \param scrollLockStatus Indicates the current status of the scroll lock key.
//------------------------------------------------------------------------------
void HIDDKeyboardCallbacks_LedsChanged(
unsigned char numLockStatus,
unsigned char capsLockStatus,
unsigned char scrollLockStatus)
{
// Num. lock
if (numLockStatus) {
LED_Set(LED_NUMLOCK);
}
else {
LED_Clear(LED_NUMLOCK);
}
}
//------------------------------------------------------------------------------
// Exported function
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Initializes the system and then monitors buttons, sending the
/// corresponding character when one is pressed.
//------------------------------------------------------------------------------
int main()
{
unsigned int i;
TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
printf("-- USB Device HID Keyboard Project %s --\n\r", SOFTPACK_VERSION);
printf("-- %s\n\r", BOARD_NAME);
printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
// If they are present, configure Vbus & Wake-up pins
PIO_InitializeInterrupts(0);
WAKEUP_CONFIGURE();
// Initialize key statuses and configure push buttons
#if defined(at91cap9dk)
const Pin pinRow0 = PIN_KEYBOARD_ROW0;
PIO_Configure(&pinRow0, 1);
#endif
PIO_Configure(pinsPushButtons, PIO_LISTSIZE(pinsPushButtons));
memset(keyStatus, 1, NUM_KEYS);
// Configure LEDs
LED_Configure(LED_NUMLOCK);
// HID driver initialization
HIDDKeyboardDriver_Initialize();
// connect if needed
VBUS_CONFIGURE();
while (USBD_GetState() < USBD_STATE_CONFIGURED);
// Infinite loop
while (1) {
unsigned char pressedKeys[NUM_KEYS];
unsigned char pressedKeysSize = 0;
unsigned char releasedKeys[NUM_KEYS];
unsigned char releasedKeysSize = 0;
// Monitor buttons
for (i=0; i < PIO_LISTSIZE(pinsPushButtons); i++) {
// Check if button state has changed
unsigned char isButtonPressed = PIO_Get(&(pinsPushButtons[i]));
if (isButtonPressed != keyStatus[i]) {
// Update button state
if (!isButtonPressed) {
// Key has been pressed
TRACE_INFO("Key %u has been pressed\n\r", i);
keyStatus[i] = 0;
pressedKeys[pressedKeysSize] = keyCodes[i];
pressedKeysSize++;
HIDDKeyboardDriver_RemoteWakeUp();
}
else {
// Key has been released
TRACE_INFO("Key %u has been released\n\r", i);
keyStatus[i] = 1;
releasedKeys[releasedKeysSize] = keyCodes[i];
releasedKeysSize++;
}
}
}
// Update key status in the HID driver if necessary
if ((pressedKeysSize != 0) || (releasedKeysSize != 0)) {
unsigned char status;
do {
status = HIDDKeyboardDriver_ChangeKeys(pressedKeys,
pressedKeysSize,
releasedKeys,
releasedKeysSize);
}
while (status != USBD_STATUS_SUCCESS);
}
if( USBState == STATE_SUSPEND ) {
TRACE_DEBUG("suspend !\n\r");
LowPowerMode();
USBState = STATE_IDLE;
}
if( USBState == STATE_RESUME ) {
// Return in normal MODE
TRACE_DEBUG("resume !\n\r");
NormalPowerMode();
USBState = STATE_IDLE;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -