diff --git a/docs/Buzzer.md b/docs/Buzzer.md index 63d1300dc..8e2c41afb 100644 --- a/docs/Buzzer.md +++ b/docs/Buzzer.md @@ -14,6 +14,24 @@ If the arm/disarm is via the control stick, holding the stick in the disarm posi There is a special arming tone used if a GPS fix has been attained, and there's a "ready" tone sounded after a GPS fix has been attained (only happens once). The tone sounded via the TX-AUX-switch will count out the number of satellites (if GPS fix). +The CLI command `play_sound` is useful for demonstrating the buzzer tones. Repeatedly entering the command will play the various tones in turn. Entering the command with a numeric-index parameter will play the associated tone. + +Available buzzer tones include the following: + + RX_LOST_LANDING Beeps SOS when armed and TX is turned off or signal lost (autolanding/autodisarm) + RX_LOST Beeps when TX is turned off or signal lost (repeat until TX is okay) + DISARMING Beep when disarming the board + ARMING Beep when arming the board + ARMING_GPS_FIX Beep a special tone when arming the board and GPS has fix + BAT_CRIT_LOW Longer warning beeps when battery is critically low (repeats) + BAT_LOW Warning beeps when battery is getting low (repeats) + RX_SET Beeps when aux channel is set for beep or beep sequence how many satellites has found if GPS enabled + DISARM_REPEAT Beeps sounded while stick held in disarm position + ACC_CALIBRATION ACC inflight calibration completed confirmation + ACC_CALIBRATION_FAIL ACC inflight calibration failed + READY_BEEP Ring a tone when GPS is locked and ready + ARMED Warning beeps when board is armed (repeats until board is disarmed or throttle is increased) + Buzzer is enabled by default on platforms that have buzzer connections. ## Types of buzzer supported diff --git a/docs/Cli.md b/docs/Cli.md index d026c550a..55cfddbcd 100644 --- a/docs/Cli.md +++ b/docs/Cli.md @@ -88,6 +88,7 @@ Re-apply any new defaults as desired. | map | mapping of rc channel order | | mixer | mixer name or list | | motor | get/set motor output value | +| play_sound | index, or none for next | | profile | index (0 to 2) | | rateprofile | index (0 to 2) | | save | save and reboot | diff --git a/src/main/io/beeper.c b/src/main/io/beeper.c index 4fbd637cb..a2a72cc21 100644 --- a/src/main/io/beeper.c +++ b/src/main/io/beeper.c @@ -24,7 +24,6 @@ #include "drivers/gpio.h" #include "drivers/sound_beeper.h" #include "drivers/system.h" -#include "flight/failsafe.h" #include "sensors/battery.h" #include "sensors/sensors.h" @@ -102,9 +101,9 @@ static const uint8_t beep_readyBeep[] = { static const uint8_t beep_2shortBeeps[] = { 5, 5, 5, 5, BEEPER_COMMAND_STOP }; -// 3 fast short beeps -static const uint8_t beep_3shortBeeps[] = { - 5, 5, 5, 5, 5, 5, BEEPER_COMMAND_STOP +// 2 longer beeps +static const uint8_t beep_2longerBeeps[] = { + 20, 15, 35, 5, BEEPER_COMMAND_STOP }; // array used for variable # of beeps (reporting GPS sat count, etc) static uint8_t beep_multiBeeps[MAX_MULTI_BEEPS + 2]; @@ -129,24 +128,25 @@ typedef struct beeperTableEntry_s { uint8_t mode; uint8_t priority; // 0 = Highest const uint8_t *sequence; + const char *name; } beeperTableEntry_t; static const beeperTableEntry_t const beeperTable[] = { - { BEEPER_RX_LOST_LANDING, 0, beep_sos }, - { BEEPER_RX_LOST, 1, beep_txLostBeep }, - { BEEPER_DISARMING, 2, beep_disarmBeep }, - { BEEPER_ARMING, 3, beep_armingBeep }, - { BEEPER_ARMING_GPS_FIX, 4, beep_armedGpsFix }, - { BEEPER_BAT_CRIT_LOW, 5, beep_critBatteryBeep }, - { BEEPER_BAT_LOW, 6, beep_lowBatteryBeep }, - { BEEPER_GPS_STATUS, 7, beep_multiBeeps }, - { BEEPER_RX_SET, 8, beep_shortBeep }, - { BEEPER_DISARM_REPEAT, 9, beep_disarmRepeatBeep }, - { BEEPER_ACC_CALIBRATION, 10, beep_2shortBeeps }, - { BEEPER_ACC_CALIBRATION_FAIL, 11, beep_3shortBeeps }, - { BEEPER_READY_BEEP, 12, beep_readyBeep }, - { BEEPER_MULTI_BEEPS, 13, beep_multiBeeps }, // FIXME having this listed makes no sense since the beep array will not be initialised. - { BEEPER_ARMED, 14, beep_armedBeep }, + { BEEPER_RX_LOST_LANDING, 0, beep_sos, "RX_LOST_LANDING" }, + { BEEPER_RX_LOST, 1, beep_txLostBeep, "RX_LOST" }, + { BEEPER_DISARMING, 2, beep_disarmBeep, "DISARMING" }, + { BEEPER_ARMING, 3, beep_armingBeep, "ARMING" }, + { BEEPER_ARMING_GPS_FIX, 4, beep_armedGpsFix, "ARMING_GPS_FIX" }, + { BEEPER_BAT_CRIT_LOW, 5, beep_critBatteryBeep, "BAT_CRIT_LOW" }, + { BEEPER_BAT_LOW, 6, beep_lowBatteryBeep, "BAT_LOW" }, + { BEEPER_GPS_STATUS, 7, beep_multiBeeps, NULL }, + { BEEPER_RX_SET, 8, beep_shortBeep, "RX_SET" }, + { BEEPER_DISARM_REPEAT, 9, beep_disarmRepeatBeep, "DISARM_REPEAT" }, + { BEEPER_ACC_CALIBRATION, 10, beep_2shortBeeps, "ACC_CALIBRATION" }, + { BEEPER_ACC_CALIBRATION_FAIL, 11, beep_2longerBeeps, "ACC_CALIBRATION_FAIL" }, + { BEEPER_READY_BEEP, 12, beep_readyBeep, "READY_BEEP" }, + { BEEPER_MULTI_BEEPS, 13, beep_multiBeeps, NULL }, // FIXME having this listed makes no sense since the beep array will not be initialised. + { BEEPER_ARMED, 14, beep_armedBeep, "ARMED" }, }; static const beeperTableEntry_t *currentBeeperEntry = NULL; @@ -320,3 +320,30 @@ uint32_t getArmingBeepTimeMicros(void) { return armingBeepTimeMicros; } + +/* + * Returns the 'beeperMode_e' value for the given beeper-table index, + * or BEEPER_SILENCE if none. + */ +beeperMode_e beeperModeForTableIndex(int idx) +{ + return (idx >= 0 && idx < (int)BEEPER_TABLE_ENTRY_COUNT) ? + beeperTable[idx].mode : BEEPER_SILENCE; +} + +/* + * Returns the name for the given beeper-table index, or NULL if none. + */ +const char *beeperNameForTableIndex(int idx) +{ + return (idx >= 0 && idx < (int)BEEPER_TABLE_ENTRY_COUNT) ? + beeperTable[idx].name : NULL; +} + +/* + * Returns the number of entries in the beeper-sounds table. + */ +int beeperTableEntryCount(void) +{ + return (int)BEEPER_TABLE_ENTRY_COUNT; +} diff --git a/src/main/io/beeper.h b/src/main/io/beeper.h index 2ffa1c501..66c993dd3 100644 --- a/src/main/io/beeper.h +++ b/src/main/io/beeper.h @@ -25,17 +25,17 @@ typedef enum { BEEPER_RX_LOST, // Beeps when TX is turned off or signal lost (repeat until TX is okay) BEEPER_DISARMING, // Beep when disarming the board BEEPER_ARMING, // Beep when arming the board - BEEPER_ARMING_GPS_FIX, // Beep a tone when arming the board and GPS has fix - BEEPER_BAT_CRIT_LOW, // Faster warning beeps when battery is critically low (repeats) + BEEPER_ARMING_GPS_FIX, // Beep a special tone when arming the board and GPS has fix + BEEPER_BAT_CRIT_LOW, // Longer warning beeps when battery is critically low (repeats) BEEPER_BAT_LOW, // Warning beeps when battery is getting low (repeats) BEEPER_GPS_STATUS, - BEEPER_RX_SET, // Beeps when aux channel is set for beep or beep sequence how many satellites has found if GPS enabled. + BEEPER_RX_SET, // Beeps when aux channel is set for beep or beep sequence how many satellites has found if GPS enabled BEEPER_DISARM_REPEAT, // Beeps sounded while stick held in disarm position BEEPER_ACC_CALIBRATION, // ACC inflight calibration completed confirmation BEEPER_ACC_CALIBRATION_FAIL, // ACC inflight calibration failed - BEEPER_READY_BEEP, // Ring a tone when board is ready to flight (GPS ready). + BEEPER_READY_BEEP, // Ring a tone when GPS is locked and ready BEEPER_MULTI_BEEPS, // Internal value used by 'beeperConfirmationBeeps()'. - BEEPER_ARMED, // Warning beeps when board is armed. (repeats until board is disarmed or throttle is increased) + BEEPER_ARMED, // Warning beeps when board is armed (repeats until board is disarmed or throttle is increased) } beeperMode_e; void beeper(beeperMode_e mode); @@ -43,3 +43,6 @@ void beeperSilence(void); void beeperUpdate(void); void beeperConfirmationBeeps(uint8_t beepCount); uint32_t getArmingBeepTimeMicros(void); +beeperMode_e beeperModeForTableIndex(int idx); +const char *beeperNameForTableIndex(int idx); +int beeperTableEntryCount(void); diff --git a/src/main/io/serial_cli.c b/src/main/io/serial_cli.c index 28f23f34a..7862fa4fb 100644 --- a/src/main/io/serial_cli.c +++ b/src/main/io/serial_cli.c @@ -53,6 +53,7 @@ #include "io/serial.h" #include "io/ledstrip.h" #include "io/flashfs.h" +#include "io/beeper.h" #include "rx/rx.h" #include "rx/spektrum.h" @@ -97,6 +98,7 @@ static void cliDump(char *cmdLine); static void cliExit(char *cmdline); static void cliFeature(char *cmdline); static void cliMotor(char *cmdline); +static void cliPlaySound(char *cmdline); static void cliProfile(char *cmdline); static void cliRateProfile(char *cmdline); static void cliReboot(void); @@ -211,6 +213,7 @@ const clicmd_t cmdTable[] = { { "mixer", "mixer name or list", cliMixer }, #endif { "motor", "get/set motor output value", cliMotor }, + { "play_sound", "index, or none for next", cliPlaySound }, { "profile", "index (0 to 2)", cliProfile }, { "rateprofile", "index (0 to 2)", cliRateProfile }, { "save", "save and reboot", cliSave }, @@ -1327,6 +1330,39 @@ static void cliMotor(char *cmdline) motor_disarmed[motor_index] = motor_value; } +static void cliPlaySound(char *cmdline) +{ + int i; + const char *name; + static int lastSoundIdx = -1; + + if (isEmpty(cmdline)) { + i = lastSoundIdx + 1; //next sound index + if ((name=beeperNameForTableIndex(i)) == NULL) { + while (true) { //no name for index; try next one + if (++i >= beeperTableEntryCount()) + i = 0; //if end then wrap around to first entry + if ((name=beeperNameForTableIndex(i)) != NULL) + break; //if name OK then play sound below + if (i == lastSoundIdx + 1) { //prevent infinite loop + printf("Error playing sound\r\n"); + return; + } + } + } + } else { //index value was given + i = atoi(cmdline); + if ((name=beeperNameForTableIndex(i)) == NULL) { + printf("No sound for index %d\r\n", i); + return; + } + } + lastSoundIdx = i; + beeperSilence(); + printf("Playing sound %d: %s\r\n", i, name); + beeper(beeperModeForTableIndex(i)); +} + static void cliProfile(char *cmdline) { int i;