Skip to content

Commit 5713429

Browse files
Merge pull request #11675 from sensei-hacker/feature-buzzer-unified-output
Add BUZZER as a runtime-assignable timer output mode
2 parents abd4a38 + bfe680a commit 5713429

8 files changed

Lines changed: 73 additions & 23 deletions

File tree

src/main/drivers/pwm_mapping.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,27 +212,27 @@ static bool checkPwmTimerConflicts(const timerHardware_t *timHw)
212212
}
213213

214214
static void timerHardwareOverride(timerHardware_t * timer) {
215-
// Never modify a beeper timer — beeperPwmInit() must find TIM_USE_BEEPER intact
216-
if (timer->usageFlags & TIM_USE_BEEPER) {
217-
return;
218-
}
219215
switch (timerOverrides(timer2id(timer->tim))->outputMode) {
220216
case OUTPUT_MODE_MOTORS:
221-
timer->usageFlags &= ~(TIM_USE_SERVO|TIM_USE_LED);
217+
timer->usageFlags &= ~(TIM_USE_SERVO|TIM_USE_LED|TIM_USE_BEEPER);
222218
timer->usageFlags |= TIM_USE_MOTOR;
223219
break;
224220
case OUTPUT_MODE_SERVOS:
225-
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_LED);
221+
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_LED|TIM_USE_BEEPER);
226222
timer->usageFlags |= TIM_USE_SERVO;
227223
break;
228224
case OUTPUT_MODE_LED:
229-
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_SERVO);
225+
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_SERVO|TIM_USE_BEEPER);
230226
timer->usageFlags |= TIM_USE_LED;
231227
break;
232228
case OUTPUT_MODE_PINIO:
233-
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_SERVO|TIM_USE_LED);
229+
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_SERVO|TIM_USE_LED|TIM_USE_BEEPER);
234230
timer->usageFlags |= TIM_USE_PINIO;
235231
break;
232+
case OUTPUT_MODE_BEEPER:
233+
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_SERVO|TIM_USE_LED|TIM_USE_PINIO);
234+
timer->usageFlags |= TIM_USE_BEEPER;
235+
break;
236236
}
237237
}
238238

src/main/drivers/pwm_mapping.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,9 @@ typedef struct {
8888
const timerHardware_t * timServos[MAX_PWM_OUTPUTS];
8989
} timMotorServoHardware_t;
9090

91-
// Output assignment types for MSP2_INAV_OUTPUT_ASSIGNMENT response
92-
// LED outputs are not reported here; they are already identified by TIM_USE_LED
93-
// in the MSP2_INAV_OUTPUT_MAPPING_EXT2 usageFlags response.
94-
#define OUTPUT_ASSIGNMENT_TYPE_MOTOR 1
95-
#define OUTPUT_ASSIGNMENT_TYPE_SERVO 2
91+
// MSP2_INAV_OUTPUT_ASSIGNMENT type byte: bit index of the TIM_USE_* flag.
92+
// Matches the JavaScript TIM_USE_* constants in outputMapping.js (which are bit indices).
93+
// Use __builtin_ctz(TIM_USE_x) to derive these from the bit-mask definitions in timer.h.
9694
#endif // SITL_BUILD
9795

9896
bool pwmMotorAndServoInit(void);

src/main/drivers/pwm_output.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ void pwmWriteBeeper(bool onoffBeep)
764764
}
765765
}
766766

767-
void beeperPwmInit(ioTag_t tag, uint16_t frequency)
767+
bool beeperPwmInit(ioTag_t tag, uint16_t frequency)
768768
{
769769
beeperPwm = NULL;
770770

@@ -774,14 +774,17 @@ void beeperPwmInit(ioTag_t tag, uint16_t frequency)
774774
// Attempt to allocate TCH
775775
TCH_t * tch = timerGetTCH(timHw);
776776
if (tch == NULL) {
777-
return;
777+
return false;
778778
}
779779

780780
beeperPwm = &beeperPwmPort;
781781
beeperFrequency = frequency;
782782
IOConfigGPIOAF(IOGetByTag(tag), IOCFG_AF_PP, timHw->alternateFunction);
783783
pwmOutConfigTimer(beeperPwm, tch, PWM_TIMER_HZ, 1000000 / beeperFrequency, (1000000 / beeperFrequency) / 2);
784+
return true;
784785
}
786+
787+
return false;
785788
}
786789

787790
#endif

src/main/drivers/pwm_output.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bool pwmMotorConfig(const struct timerHardware_s *timerHardware, uint8_t motorIn
5959
void pwmServoPreconfigure(void);
6060
bool pwmServoConfig(const struct timerHardware_s *timerHardware, uint8_t servoIndex, uint16_t servoPwmRate, uint16_t servoCenterPulse, bool enableOutput);
6161
void pwmWriteBeeper(bool onoffBeep);
62-
void beeperPwmInit(ioTag_t tag, uint16_t frequency);
62+
bool beeperPwmInit(ioTag_t tag, uint16_t frequency);
6363

6464
void sendDShotCommand(dshotCommands_e cmd);
6565
void initDShotCommands(void);

src/main/drivers/sound_beeper.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "drivers/time.h"
2424
#include "drivers/io.h"
2525

26+
#include "common/log.h"
2627
#include "drivers/timer.h"
2728
#include "drivers/pwm_mapping.h"
2829
#include "drivers/pwm_output.h"
@@ -78,13 +79,41 @@ void beeperInit(const beeperDevConfig_t *config)
7879
#if !defined(BEEPER)
7980
UNUSED(config);
8081
#else
82+
// Runtime output assignment: scan for any pad explicitly set to OUTPUT_MODE_BEEPER.
83+
// pwmBuildTimerOutputList() runs before beeperInit(), so TIM_USE_BEEPER is already
84+
// set on the runtime-assigned pad by the time we get here.
85+
for (int idx = 0; idx < timerHardwareCount; idx++) {
86+
const timerHardware_t *timHw = &timerHardware[idx];
87+
if (timerOverrides(timer2id(timHw->tim))->outputMode == OUTPUT_MODE_BEEPER) {
88+
if (!beeperPwmInit(timHw->tag, BEEPER_PWM_FREQUENCY)) {
89+
LOG_ERROR(PWM, "Beeper PWM init failed on assigned pad, beeper disabled");
90+
return;
91+
}
92+
beeperConfigMutable()->pwmMode = true;
93+
systemBeep(false);
94+
return;
95+
}
96+
}
97+
98+
// Skip compile-time beeper pad if the user has overridden it to another function.
99+
for (int idx = 0; idx < timerHardwareCount; idx++) {
100+
if (timerHardware[idx].tag == config->ioTag) {
101+
if (!(timerHardware[idx].usageFlags & TIM_USE_BEEPER)) {
102+
return;
103+
}
104+
break;
105+
}
106+
}
107+
81108
beeperIO = IOGetByTag(config->ioTag);
82109
beeperInverted = config->isInverted;
83110

84111
if (beeperIO) {
85112
IOInit(beeperIO, OWNER_BEEPER, RESOURCE_OUTPUT, 0);
86113
if (beeperConfig()->pwmMode) {
87-
beeperPwmInit(config->ioTag, BEEPER_PWM_FREQUENCY);
114+
if (!beeperPwmInit(config->ioTag, BEEPER_PWM_FREQUENCY)) {
115+
LOG_ERROR(PWM, "Beeper PWM init failed on compile-time pad, beeper disabled");
116+
}
88117
} else {
89118
IOConfigGPIO(beeperIO, config->isOD ? IOCFG_OUT_OD : IOCFG_OUT_PP);
90119
}

src/main/fc/cli.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ static const char * outputModeNames[] = {
177177
"SERVOS",
178178
"LED",
179179
"PINIO",
180+
"BEEPER",
180181
NULL
181182
};
182183

@@ -3225,6 +3226,8 @@ static void cliTimerOutputMode(char *cmdline)
32253226
mode = OUTPUT_MODE_LED;
32263227
} else if(!sl_strcasecmp("PINIO", tok)) {
32273228
mode = OUTPUT_MODE_PINIO;
3229+
} else if(!sl_strcasecmp("BEEPER", tok)) {
3230+
mode = OUTPUT_MODE_BEEPER;
32283231
} else {
32293232
cliShowParseError();
32303233
return;
@@ -5037,7 +5040,7 @@ const clicmd_t cmdTable[] = {
50375040
#ifdef USE_OSD
50385041
CLI_COMMAND_DEF("osd_layout", "get or set the layout of OSD items", "[<layout> [<item> [<col> <row> [<visible>]]]]", cliOsdLayout),
50395042
#endif
5040-
CLI_COMMAND_DEF("timer_output_mode", "get or set the outputmode for a given timer.", "[<timer> [<AUTO|MOTORS|SERVOS|LED|PINIO>]]", cliTimerOutputMode),
5043+
CLI_COMMAND_DEF("timer_output_mode", "get or set the outputmode for a given timer.", "[<timer> [<AUTO|MOTORS|SERVOS|LED|PINIO|BEEPER>]]", cliTimerOutputMode),
50415044
};
50425045

50435046
static void cliHelp(char *cmdline)

src/main/fc/fc_msp.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,14 +1812,22 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
18121812
const timMotorServoHardware_t *hw = pwmGetOutputAssignment();
18131813
for (int m = 0; m < hw->maxTimMotorCount; m++) {
18141814
sbufWriteU8(dst, (uint8_t)(hw->timMotors[m] - timerHardware));
1815-
sbufWriteU8(dst, OUTPUT_ASSIGNMENT_TYPE_MOTOR);
1815+
sbufWriteU8(dst, __builtin_ctz(TIM_USE_MOTOR));
18161816
sbufWriteU8(dst, (uint8_t)(m + 1));
18171817
}
18181818
for (int s = 0; s < hw->maxTimServoCount; s++) {
18191819
sbufWriteU8(dst, (uint8_t)(hw->timServos[s] - timerHardware));
1820-
sbufWriteU8(dst, OUTPUT_ASSIGNMENT_TYPE_SERVO);
1820+
sbufWriteU8(dst, __builtin_ctz(TIM_USE_SERVO));
18211821
sbufWriteU8(dst, (uint8_t)(s + 1));
18221822
}
1823+
for (int idx = 0; idx < timerHardwareCount; idx++) {
1824+
if (timerOverrides(timer2id(timerHardware[idx].tim))->outputMode == OUTPUT_MODE_BEEPER) {
1825+
sbufWriteU8(dst, (uint8_t)idx);
1826+
sbufWriteU8(dst, __builtin_ctz(TIM_USE_BEEPER));
1827+
sbufWriteU8(dst, 1);
1828+
break;
1829+
}
1830+
}
18231831
}
18241832
break;
18251833
#endif
@@ -4911,14 +4919,22 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu
49114919

49124920
for (int m = 0; m < tempOut.maxTimMotorCount; m++) {
49134921
sbufWriteU8(dst, (uint8_t)(tempOut.timMotors[m] - timerHardware));
4914-
sbufWriteU8(dst, OUTPUT_ASSIGNMENT_TYPE_MOTOR);
4922+
sbufWriteU8(dst, __builtin_ctz(TIM_USE_MOTOR));
49154923
sbufWriteU8(dst, (uint8_t)(m + 1));
49164924
}
49174925
for (int s = 0; s < tempOut.maxTimServoCount; s++) {
49184926
sbufWriteU8(dst, (uint8_t)(tempOut.timServos[s] - timerHardware));
4919-
sbufWriteU8(dst, OUTPUT_ASSIGNMENT_TYPE_SERVO);
4927+
sbufWriteU8(dst, __builtin_ctz(TIM_USE_SERVO));
49204928
sbufWriteU8(dst, (uint8_t)(s + 1));
49214929
}
4930+
for (int idx = 0; idx < timerHardwareCount; idx++) {
4931+
if (proposedModes[timer2id(timerHardware[idx].tim)] == OUTPUT_MODE_BEEPER) {
4932+
sbufWriteU8(dst, (uint8_t)idx);
4933+
sbufWriteU8(dst, __builtin_ctz(TIM_USE_BEEPER));
4934+
sbufWriteU8(dst, 1);
4935+
break;
4936+
}
4937+
}
49224938
*ret = MSP_RESULT_ACK;
49234939
}
49244940
break;

src/main/flight/mixer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ typedef enum {
4949
OUTPUT_MODE_MOTORS,
5050
OUTPUT_MODE_SERVOS,
5151
OUTPUT_MODE_LED,
52-
OUTPUT_MODE_PINIO
52+
OUTPUT_MODE_PINIO,
53+
OUTPUT_MODE_BEEPER
5354
} outputMode_e;
5455

5556
typedef struct motorAxisCorrectionLimits_s {

0 commit comments

Comments
 (0)