📄 main_option3.c
字号:
powermode = PMODE_AWAKE; // And indicate a power up of ATX
}
}
#ifdef USELED
mcu_atxled(z1_rotate_led()); // Alter ATX LED according to blinking sequence, after potentially critical operations!
#endif
} // powermode == PMODE_AUTODOWN
else if (powermode == PMODE_POWERDOWN) {
if (wakeup == WAKE_Z1_INT) {
// Keep reading RXPIN as long as ATX nRF24Z1 is on (i.e. interrupt pin is active on low) or until
// a button is received. In option 3 the ARX goes in and out of sleep mode several times while the ATX is awake.
buttons = BTN_NOKEY;
while ((mcu_z1int_active()) && (buttons == BTN_NOKEY)) {
buttons = z1_singleread(RXPIN) & 0x0F; // Read buttons from ARX. // If ARX is linked and a button is detected, ATX copy is
if (buttons == BTN_NOKEY) { // If nothing from ARX, // overwritten. If not linked, no button from ARX is found
buttons = mcu_buttons(); // Read buttons from local MCU only in user interface option 3
}
else // If button pressed on ARX (i.e. while loop will be broken),
z1_singlewrite(RXPIN, BTN_NOKEY); // Overwrite ATX copy of RXPIN to avoid confusion and double reading of same button
}
if ((buttons == BTN_PLAY) && (mcu_z1int_active())) { // Play button wakes up system, ATX nRF24Z1 must be alive to take cmds
z1_singlewrite(TXWTI, 0x00); // Disable auto power down while sending wakeup commands to ATX
z1_singlewrite(TXMOD, z1_singleread(TXMOD) & ~0x40); // Wake up ATX
z1_singlewrite(RXMOD, z1_singleread(RXMOD) & ~0x80); // Wake up ARX
// In user interface option 3, the ARX is wake-on-timer operating on a fast clock. If the user presses the ATX
// Play button while the ARX is out of range, no link should be established, and the system should go back to the sleep
// mode it was in, PMODE_POWERDOWN.
if (z1_haslink_wait()) { // Wait until a link is established or timeout
// Instruct source to commence playing music
adc_wake(); // Wake up ATX resources
dac_wake(); // Wake up ARX resources, may also test that logical return of dac_wake() indicated success
z1_arx_mute(MUTEOFF); // If ARX was muted at power on remove muting each time units exit sleep mode by user interface
muted = 0; // Simulating Play/Pause functionality
#ifdef USELED
ledsequence = LED_AWAKE; // Blink in a pattern indicating audio streaming
#endif
powermode = PMODE_AWAKE; // Indicate that system is awake
debounce = 1; // Activate software debounce
z1_singlewrite(TXWTI, SLEEP_TXWTI); // Re-enable auto power down = allow for proper TXLTI timing
}
else { // No link found, power things down again, this is same sequence as Stop button performs
z1_singlewrite(RXMOD, z1_singleread(RXMOD) | 0x80); // Put ARX to sleep
z1_singlewrite(TXWTI, SLEEP_TXWTI); // Re-enable auto power down = allow for proper TXLTI timing
z1_singlewrite(TXMOD, z1_singleread(TXMOD) | 0x40); // Put ATX to sleep
} // No link found
} // BTN_PLAY
#ifdef USELED
mcu_atxled(LEDON); // Rotating blink sequence, "mcu_atxled(z1_rotate_led());" takes too much time,
mcu_wait_ms(96); // instead blink once at each wakeup, approximately every 2 seconds. Blinking takes
mcu_atxled(LEDOFF); // Place after any potentially critical button stuff.
#endif
} // PMODE_POWERDOWN / WAKE_Z1_INT
else if (wakeup == WAKE_WAIT) {
// In user interface option 3 ATX is wake-on-timer. Thus waking from MCU timer (i.e. no
// ATX nRF24Z1 interrupt) while in sleep mode means that the security timer of the MCU interrupted
// the MCU without the ATX nRF24Z1 interrupting the MCU. This indicates that the system is
// not working properly. That is because the ATX nRF24Z1 interrupts the MCU whenever it wakes up.
// Also, an unknown interrupt may have struck at an unexpected time.
// Arriving here indicates an error, a wakeup from the MCU timer used as a safety device.
#ifdef TERMINATE_ON_ERROR
booterror = 1;
#endif
} // PMODE_POWERDOWN / WAKE_WAIT
}
else if (powermode == PMODE_AWAKE) {
if (wakeup == WAKE_Z1_INT) {
// In user interface option 3 an arriving nRF24Z1 interrupt while awake means ATX nRF24Z1 went to auto power down
// mode. That is because interrupts from ATX nRF24Z1 are currently set to only occur when it is briefly awake to poll
// the airways. I.e. it did go to auto power down shortly before generating the detected interrupt.
// Unfortunately, there is no way to reach the DAC in the ARX because that nRF24Z1 has probably gone to auto power
// down mode too. Therefore, the DAC will continue to burn power. Instead, power down all ATX resources and indicate
// that the system is in power down mode.
// When in automatic power down, TXMOD and RXMOD are set at the same levels as for audio streaming. They have to be
// set so in order to allow wakeup from automatic power down at a later stage.
// Instruct audio source to stop playing music here!
adc_sleep(); // Then, power down ATX resources
#ifdef USELED
ledsequence = LED_AUTODOWN; // Blink in a pattern indicating auto power down
#endif
powermode = PMODE_AUTODOWN; // Indicate that sleep is due to an automatic power down
} // PMODE_AWAKE / WAKE_Z1_INT
else if (wakeup == WAKE_WAIT) {
// This is audio streaming mode. The MCU is polling ARX buttons and local buttons while awake.
// All buttons are interpreted.
buttons = BTN_NOKEY; // Assume that no button is pressed
if (mcu_z1int_active()) // Is ATX nRF24Z1 awake and listening on the slave interface?
buttons = z1_singleread(RXPIN) & 0x0F; // Read buttons from ARX
if (buttons == BTN_NOKEY) // If nothing pressed on ARX,
buttons = mcu_buttons(); // Process buttons from ATX
if (debounce == 0) {
// The following buttons are single-action (i.e. require that no button is pressed before requested action is taken)
switch (buttons) {
case BTN_STOP:
// Enter your application code to handle a stop button!
dac_sleep(); // First power down DAC before powering down radio ling
adc_sleep(); // Power down resources on ATX
// TXMOD and RXMOD must now be set so that the two devices do not wake up even if they are within
// range and in link mode at the same time. Such a condition would otherwise have woken them up
// again. Wakeup must only happen when the user pressed the Play button, in which case RXMOD and
// TXMOD are set for power on in order to attempt linkup.
#ifdef USELED
z1_arxled(LEDOFF); // Turn off ARX LED before going to sleep and removing link
ledsequence = LED_POWERDOWN; // Blink in a pattern indicating power down
#endif
powermode = PMODE_POWERDOWN;
z1_singlewrite(RXMOD, z1_singleread(RXMOD) | 0x80); // Put ARX to sleep
z1_singlewrite(TXWTI, SLEEP_TXWTI); // Re-enable auto power down = allow for proper TXLTI timing
z1_singlewrite(TXMOD, z1_singleread(TXMOD) | 0x40); // Put ATX to sleep
mcu_wait_ms(3200); // Don't actually sleep for 3.2 seconds but pick up the first (stray) interrupt from ATX
break;
case BTN_PLAY: // Play button detected
// Enter your application code to handle a play/pause button. A pause button simulation is inserted below.
// The pause functionality here does not communicate with the audio source. It does not put any unit
// into power save mode. It is just to simulate a common look-and-feel
if (muted == 0) { // Simulating Play/Pause functionality
z1_arx_mute(MUTEON); // If no mute, turn on mute = Pause
muted = 1;
}
else { // If muted, turn off mute = (de)Pause
z1_arx_mute(MUTEOFF);
muted = 0;
}
break;
case BTN_SKIPF: // Skip forward button detected
// Enter your application code to handle a forward skip button
break;
case BTN_SKIPB: // Skip backward button detected
// Enter your application code to handle a backward skip button
break;
case BTN_BBOOST: // Play detected
// Enter your application code to handle a bass boost button (button not implemented in Headphone Reference Design)
break;
default: // Do not consider other buttons here
break;
} // end of switch
} // debounce == 0
// The following buttons may be held to cause repeated action
switch (buttons) {
case BTN_VOLUP: // Volume up button detected
dac_volume_up(); // This program increases volume in remote DAC
break;
case BTN_VOLDN: // Volume down button detected
dac_volume_down(); // This program decreases volume in remote DAC
break;
case BTN_SCANF: // Scan forward button detected
// Enter your application code to handle a forward scan button (button not implemented in Headphone Reference Design)
break;
case BTN_SCANB: // Scan backward button detected
// Enter your application code to handle a backward scan button (button not implemented in Headphone Reference Design)
break;
default: // Do not consider other buttons here
break;
} // end of switch
// Other buttons may be defined here according to your application
if (buttons == BTN_NOKEY) // If no buttons were detected,
debounce = 0; // Indicate all buttons were released
else // Some button detected
debounce = 1; // Activate software debounce
#ifdef USELED // ATX button polling is called every 64ms. That is an okay period for LED blinking
if (powermode == PMODE_AWAKE) { // If no power down etc has been initiated yet, process LED blinking
if (mcu_z1int_active()) { // If ATX nRF24Z1 is active, (important to check in case of auto power down)
ledtemp = z1_rotate_led(); // Record present state in LED blinking sequence
if (ledstatus != ledtemp) {
mcu_atxled(ledtemp); // Alter ATX LED according to blinking sequence
z1_arxled(ledtemp); // Alter ARX LED according to blinking sequence
ledstatus = ledtemp;
}
}
}
#endif
} // PMODE_AWAKE / WAKE_WAIT
}
} // while (booterror == 0)
// We arrive here with booterror != 0. Bootup or user interface failed. Program terminates.
adc_sleep(); // Power down resources on ATX
z1_singlewrite(TXWTI, 0x01); // Disable any ATX wake-on-timer
z1_singlewrite(TXLTI, 0x31); // Disable any ATX wake-on-timer
z1_singlewrite(TXSTI_0, 0x00); // Disable any ATX wake-on-timer
z1_singlewrite(TXSTI_1, 0x00); // Disable any ATX wake-on-timer
z1_singlewrite(TXMOD, 0x62); // Minimize ATX power consumption: no RF, TX power down, wake-on-interrupt
#ifdef USELED
ledsequence = LED_FAILURE; // Blink in a fast on-off-on-off-on-off pattern
while (1) {
mcu_wait_ms(64); // Use 4 * 64ms blink period, 64ms blink on time
mcu_atxled(z1_rotate_led()); // Left-rotate the led sequence and apply ATX light according to MSB
}
#else
while (1) { // Terminate in infinite loop
}
#endif
return 0; // Insert a return statement despite infinite loop
} // int main()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -