mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-18 03:33:34 +08:00
STM32 driver: Fix code style
This commit is contained in:
@@ -115,7 +115,7 @@ protected:
|
||||
|
||||
private:
|
||||
static const hrt_abstime _tickrate = 10000; /**< 100Hz base rate */
|
||||
|
||||
|
||||
hrt_call _call;
|
||||
perf_counter_t _sample_perf;
|
||||
|
||||
@@ -161,11 +161,13 @@ ADC::ADC(uint32_t channels) :
|
||||
_channel_count++;
|
||||
}
|
||||
}
|
||||
|
||||
_samples = new adc_msg_s[_channel_count];
|
||||
|
||||
/* prefill the channel numbers in the sample array */
|
||||
if (_samples != nullptr) {
|
||||
unsigned index = 0;
|
||||
|
||||
for (unsigned i = 0; i < 32; i++) {
|
||||
if (channels & (1 << i)) {
|
||||
_samples[index].am_channel = i;
|
||||
@@ -178,8 +180,9 @@ ADC::ADC(uint32_t channels) :
|
||||
|
||||
ADC::~ADC()
|
||||
{
|
||||
if (_samples != nullptr)
|
||||
if (_samples != nullptr) {
|
||||
delete _samples;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -189,8 +192,11 @@ ADC::init()
|
||||
#ifdef ADC_CR2_CAL
|
||||
rCR2 |= ADC_CR2_CAL;
|
||||
usleep(100);
|
||||
if (rCR2 & ADC_CR2_CAL)
|
||||
|
||||
if (rCR2 & ADC_CR2_CAL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* arbitrarily configure all channels for 55 cycle sample time */
|
||||
@@ -201,7 +207,7 @@ ADC::init()
|
||||
rCR1 = 0;
|
||||
|
||||
/* enable the temperature sensor / Vrefint channel if supported*/
|
||||
rCR2 =
|
||||
rCR2 =
|
||||
#ifdef ADC_CR2_TSVREFE
|
||||
/* enable the temperature sensor in CR2 */
|
||||
ADC_CR2_TSVREFE |
|
||||
@@ -216,7 +222,7 @@ ADC::init()
|
||||
/* configure for a single-channel sequence */
|
||||
rSQR1 = 0;
|
||||
rSQR2 = 0;
|
||||
rSQR3 = 0; /* will be updated with the channel each tick */
|
||||
rSQR3 = 0; /* will be updated with the channel each tick */
|
||||
|
||||
/* power-cycle the ADC and turn it on */
|
||||
rCR2 &= ~ADC_CR2_ADON;
|
||||
@@ -229,6 +235,7 @@ ADC::init()
|
||||
/* kick off a sample and wait for it to complete */
|
||||
hrt_abstime now = hrt_absolute_time();
|
||||
rCR2 |= ADC_CR2_SWSTART;
|
||||
|
||||
while (!(rSR & ADC_SR_EOC)) {
|
||||
|
||||
/* don't wait for more than 500us, since that means something broke - should reset here if we see this */
|
||||
@@ -256,8 +263,9 @@ ADC::read(file *filp, char *buffer, size_t len)
|
||||
{
|
||||
const size_t maxsize = sizeof(adc_msg_s) * _channel_count;
|
||||
|
||||
if (len > maxsize)
|
||||
if (len > maxsize) {
|
||||
len = maxsize;
|
||||
}
|
||||
|
||||
/* block interrupts while copying samples to avoid racing with an update */
|
||||
irqstate_t flags = irqsave();
|
||||
@@ -296,8 +304,10 @@ void
|
||||
ADC::_tick()
|
||||
{
|
||||
/* scan the channel set and sample each */
|
||||
for (unsigned i = 0; i < _channel_count; i++)
|
||||
for (unsigned i = 0; i < _channel_count; i++) {
|
||||
_samples[i].am_data = _sample(_samples[i].am_channel);
|
||||
}
|
||||
|
||||
update_system_power();
|
||||
}
|
||||
|
||||
@@ -309,6 +319,7 @@ ADC::update_system_power(void)
|
||||
system_power.timestamp = hrt_absolute_time();
|
||||
|
||||
system_power.voltage5V_v = 0;
|
||||
|
||||
for (unsigned i = 0; i < _channel_count; i++) {
|
||||
if (_samples[i].am_channel == 4) {
|
||||
// it is 2:1 scaled
|
||||
@@ -331,9 +342,11 @@ ADC::update_system_power(void)
|
||||
/* lazily publish */
|
||||
if (_to_system_power != nullptr) {
|
||||
orb_publish(ORB_ID(system_power), _to_system_power, &system_power);
|
||||
|
||||
} else {
|
||||
_to_system_power = orb_advertise(ORB_ID(system_power), &system_power);
|
||||
}
|
||||
|
||||
#endif // CONFIG_ARCH_BOARD_PX4FMU_V2
|
||||
}
|
||||
|
||||
@@ -343,8 +356,9 @@ ADC::_sample(unsigned channel)
|
||||
perf_begin(_sample_perf);
|
||||
|
||||
/* clear any previous EOC */
|
||||
if (rSR & ADC_SR_EOC)
|
||||
if (rSR & ADC_SR_EOC) {
|
||||
rSR &= ~ADC_SR_EOC;
|
||||
}
|
||||
|
||||
/* run a single conversion right now - should take about 60 cycles (a few microseconds) max */
|
||||
rSQR3 = channel;
|
||||
@@ -352,6 +366,7 @@ ADC::_sample(unsigned channel)
|
||||
|
||||
/* wait for the conversion to complete */
|
||||
hrt_abstime now = hrt_absolute_time();
|
||||
|
||||
while (!(rSR & ADC_SR_EOC)) {
|
||||
|
||||
/* don't wait for more than 50us, since that means something broke - should reset here if we see this */
|
||||
@@ -382,20 +397,23 @@ test(void)
|
||||
{
|
||||
|
||||
int fd = open(ADC0_DEVICE_PATH, O_RDONLY);
|
||||
if (fd < 0)
|
||||
|
||||
if (fd < 0) {
|
||||
err(1, "can't open ADC device");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < 50; i++) {
|
||||
adc_msg_s data[12];
|
||||
ssize_t count = read(fd, data, sizeof(data));
|
||||
|
||||
if (count < 0)
|
||||
if (count < 0) {
|
||||
errx(1, "read error");
|
||||
}
|
||||
|
||||
unsigned channels = count / sizeof(data[0]);
|
||||
|
||||
for (unsigned j = 0; j < channels; j++) {
|
||||
printf ("%d: %u ", data[j].am_channel, data[j].am_data);
|
||||
printf("%d: %u ", data[j].am_channel, data[j].am_data);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
@@ -410,11 +428,12 @@ int
|
||||
adc_main(int argc, char *argv[])
|
||||
{
|
||||
if (g_adc == nullptr) {
|
||||
/* XXX this hardcodes the default channel set for the board in board_config.h - should be configurable */
|
||||
g_adc = new ADC(ADC_CHANNELS);
|
||||
/* XXX this hardcodes the default channel set for the board in board_config.h - should be configurable */
|
||||
g_adc = new ADC(ADC_CHANNELS);
|
||||
|
||||
if (g_adc == nullptr)
|
||||
if (g_adc == nullptr) {
|
||||
errx(1, "couldn't allocate the ADC driver");
|
||||
}
|
||||
|
||||
if (g_adc->init() != OK) {
|
||||
delete g_adc;
|
||||
@@ -423,8 +442,9 @@ adc_main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
if (!strcmp(argv[1], "test"))
|
||||
if (!strcmp(argv[1], "test")) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
+28
-14
@@ -455,8 +455,9 @@ hrt_ppm_decode(uint32_t status)
|
||||
unsigned i;
|
||||
|
||||
/* if we missed an edge, we have to give up */
|
||||
if (status & SR_OVF_PPM)
|
||||
if (status & SR_OVF_PPM) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* how long since the last edge? - this handles counter wrapping implicitely. */
|
||||
width = count - ppm.last_edge;
|
||||
@@ -464,8 +465,10 @@ hrt_ppm_decode(uint32_t status)
|
||||
#if PPM_DEBUG
|
||||
ppm_edge_history[ppm_edge_next++] = width;
|
||||
|
||||
if (ppm_edge_next >= 32)
|
||||
if (ppm_edge_next >= 32) {
|
||||
ppm_edge_next = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -501,8 +504,9 @@ hrt_ppm_decode(uint32_t status)
|
||||
} else {
|
||||
/* frame channel count matches expected, let's use it */
|
||||
if (ppm.next_channel > PPM_MIN_CHANNELS) {
|
||||
for (i = 0; i < ppm.next_channel; i++)
|
||||
for (i = 0; i < ppm.next_channel; i++) {
|
||||
ppm_buffer[i] = ppm_temp_buffer[i];
|
||||
}
|
||||
|
||||
ppm_last_valid_decode = hrt_absolute_time();
|
||||
|
||||
@@ -527,8 +531,9 @@ hrt_ppm_decode(uint32_t status)
|
||||
case ARM:
|
||||
|
||||
/* we expect a pulse giving us the first mark */
|
||||
if (width < PPM_MIN_PULSE_WIDTH || width > PPM_MAX_PULSE_WIDTH)
|
||||
goto error; /* pulse was too short or too long */
|
||||
if (width < PPM_MIN_PULSE_WIDTH || width > PPM_MAX_PULSE_WIDTH) {
|
||||
goto error; /* pulse was too short or too long */
|
||||
}
|
||||
|
||||
/* record the mark timing, expect an inactive edge */
|
||||
ppm.last_mark = ppm.last_edge;
|
||||
@@ -542,8 +547,9 @@ hrt_ppm_decode(uint32_t status)
|
||||
case INACTIVE:
|
||||
|
||||
/* we expect a short pulse */
|
||||
if (width < PPM_MIN_PULSE_WIDTH || width > PPM_MAX_PULSE_WIDTH)
|
||||
goto error; /* pulse was too short or too long */
|
||||
if (width < PPM_MIN_PULSE_WIDTH || width > PPM_MAX_PULSE_WIDTH) {
|
||||
goto error; /* pulse was too short or too long */
|
||||
}
|
||||
|
||||
/* this edge is not interesting, but now we are ready for the next mark */
|
||||
ppm.phase = ACTIVE;
|
||||
@@ -557,17 +563,21 @@ hrt_ppm_decode(uint32_t status)
|
||||
#if PPM_DEBUG
|
||||
ppm_pulse_history[ppm_pulse_next++] = interval;
|
||||
|
||||
if (ppm_pulse_next >= 32)
|
||||
if (ppm_pulse_next >= 32) {
|
||||
ppm_pulse_next = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* if the mark-mark timing is out of bounds, abandon the frame */
|
||||
if ((interval < PPM_MIN_CHANNEL_VALUE) || (interval > PPM_MAX_CHANNEL_VALUE))
|
||||
if ((interval < PPM_MIN_CHANNEL_VALUE) || (interval > PPM_MAX_CHANNEL_VALUE)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* if we have room to store the value, do so */
|
||||
if (ppm.next_channel < PPM_MAX_CHANNELS)
|
||||
if (ppm.next_channel < PPM_MAX_CHANNELS) {
|
||||
ppm_temp_buffer[ppm.next_channel++] = interval;
|
||||
}
|
||||
|
||||
ppm.phase = INACTIVE;
|
||||
break;
|
||||
@@ -668,8 +678,9 @@ hrt_absolute_time(void)
|
||||
* This simple test is sufficient due to the guarantee that
|
||||
* we are always called at least once per counter period.
|
||||
*/
|
||||
if (count < last_count)
|
||||
if (count < last_count) {
|
||||
base_time += HRT_COUNTER_PERIOD;
|
||||
}
|
||||
|
||||
/* save the count for next time */
|
||||
last_count = count;
|
||||
@@ -800,8 +811,9 @@ hrt_call_internal(struct hrt_call *entry, hrt_abstime deadline, hrt_abstime inte
|
||||
queue for the uninitialised entry->link but we don't do
|
||||
anything actually unsafe.
|
||||
*/
|
||||
if (entry->deadline != 0)
|
||||
if (entry->deadline != 0) {
|
||||
sq_rem(&entry->link, &callout_queue);
|
||||
}
|
||||
|
||||
entry->deadline = deadline;
|
||||
entry->period = interval;
|
||||
@@ -883,11 +895,13 @@ hrt_call_invoke(void)
|
||||
|
||||
call = (struct hrt_call *)sq_peek(&callout_queue);
|
||||
|
||||
if (call == NULL)
|
||||
if (call == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (call->deadline > now)
|
||||
if (call->deadline > now) {
|
||||
break;
|
||||
}
|
||||
|
||||
sq_rem(&call->link, &callout_queue);
|
||||
//lldbg("call pop\n");
|
||||
|
||||
@@ -174,19 +174,22 @@ pwm_channel_init(unsigned channel)
|
||||
int
|
||||
up_pwm_servo_set(unsigned channel, servo_position_t value)
|
||||
{
|
||||
if (channel >= PWM_SERVO_MAX_CHANNELS)
|
||||
if (channel >= PWM_SERVO_MAX_CHANNELS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned timer = pwm_channels[channel].timer_index;
|
||||
|
||||
/* test timer for validity */
|
||||
if ((pwm_timers[timer].base == 0) ||
|
||||
(pwm_channels[channel].gpio == 0))
|
||||
(pwm_channels[channel].gpio == 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* configure the channel */
|
||||
if (value > 0)
|
||||
if (value > 0) {
|
||||
value--;
|
||||
}
|
||||
|
||||
switch (pwm_channels[channel].timer_channel) {
|
||||
case 1:
|
||||
@@ -215,16 +218,18 @@ up_pwm_servo_set(unsigned channel, servo_position_t value)
|
||||
servo_position_t
|
||||
up_pwm_servo_get(unsigned channel)
|
||||
{
|
||||
if (channel >= PWM_SERVO_MAX_CHANNELS)
|
||||
if (channel >= PWM_SERVO_MAX_CHANNELS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned timer = pwm_channels[channel].timer_index;
|
||||
servo_position_t value = 0;
|
||||
|
||||
/* test timer for validity */
|
||||
if ((pwm_timers[timer].base == 0) ||
|
||||
(pwm_channels[channel].timer_channel == 0))
|
||||
(pwm_channels[channel].timer_channel == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* configure the channel */
|
||||
switch (pwm_channels[channel].timer_channel) {
|
||||
@@ -253,15 +258,17 @@ up_pwm_servo_init(uint32_t channel_mask)
|
||||
{
|
||||
/* do basic timer initialisation first */
|
||||
for (unsigned i = 0; i < PWM_SERVO_MAX_TIMERS; i++) {
|
||||
if (pwm_timers[i].base != 0)
|
||||
if (pwm_timers[i].base != 0) {
|
||||
pwm_timer_init(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* now init channels */
|
||||
for (unsigned i = 0; i < PWM_SERVO_MAX_CHANNELS; i++) {
|
||||
/* don't do init for disabled channels; this leaves the pin configs alone */
|
||||
if (((1 << i) & channel_mask) && (pwm_channels[i].timer_channel != 0))
|
||||
if (((1 << i) & channel_mask) && (pwm_channels[i].timer_channel != 0)) {
|
||||
pwm_channel_init(i);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
@@ -278,13 +285,17 @@ int
|
||||
up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate)
|
||||
{
|
||||
/* limit update rate to 1..10000Hz; somewhat arbitrary but safe */
|
||||
if (rate < 1)
|
||||
return -ERANGE;
|
||||
if (rate > 10000)
|
||||
if (rate < 1) {
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if ((group >= PWM_SERVO_MAX_TIMERS) || (pwm_timers[group].base == 0))
|
||||
if (rate > 10000) {
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if ((group >= PWM_SERVO_MAX_TIMERS) || (pwm_timers[group].base == 0)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
pwm_timer_set_rate(group, rate);
|
||||
|
||||
@@ -294,8 +305,9 @@ up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate)
|
||||
int
|
||||
up_pwm_servo_set_rate(unsigned rate)
|
||||
{
|
||||
for (unsigned i = 0; i < PWM_SERVO_MAX_TIMERS; i++)
|
||||
for (unsigned i = 0; i < PWM_SERVO_MAX_TIMERS; i++) {
|
||||
up_pwm_servo_set_rate_group_update(i, rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -306,9 +318,11 @@ up_pwm_servo_get_rate_group(unsigned group)
|
||||
unsigned channels = 0;
|
||||
|
||||
for (unsigned i = 0; i < PWM_SERVO_MAX_CHANNELS; i++) {
|
||||
if ((pwm_channels[i].gpio != 0) && (pwm_channels[i].timer_index == group))
|
||||
if ((pwm_channels[i].gpio != 0) && (pwm_channels[i].timer_index == group)) {
|
||||
channels |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
return channels;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,16 +47,16 @@
|
||||
* From Wikibooks:
|
||||
*
|
||||
* PLAY "[string expression]"
|
||||
*
|
||||
*
|
||||
* Used to play notes and a score ... The tones are indicated by letters A through G.
|
||||
* Accidentals are indicated with a "+" or "#" (for sharp) or "-" (for flat)
|
||||
* Accidentals are indicated with a "+" or "#" (for sharp) or "-" (for flat)
|
||||
* immediately after the note letter. See this example:
|
||||
*
|
||||
*
|
||||
* PLAY "C C# C C#"
|
||||
*
|
||||
* Whitespaces are ignored inside the string expression. There are also codes that
|
||||
* set the duration, octave and tempo. They are all case-insensitive. PLAY executes
|
||||
* the commands or notes the order in which they appear in the string. Any indicators
|
||||
* set the duration, octave and tempo. They are all case-insensitive. PLAY executes
|
||||
* the commands or notes the order in which they appear in the string. Any indicators
|
||||
* that change the properties are effective for the notes following that indicator.
|
||||
*
|
||||
* Ln Sets the duration (length) of the notes. The variable n does not indicate an actual duration
|
||||
@@ -66,15 +66,15 @@
|
||||
* The shorthand notation of length is also provided for a note. For example, "L4 CDE L8 FG L4 AB"
|
||||
* can be shortened to "L4 CDE F8G8 AB". F and G play as eighth notes while others play as quarter notes.
|
||||
* On Sets the current octave. Valid values for n are 0 through 6. An octave begins with C and ends with B.
|
||||
* Remember that C- is equivalent to B.
|
||||
* Remember that C- is equivalent to B.
|
||||
* < > Changes the current octave respectively down or up one level.
|
||||
* Nn Plays a specified note in the seven-octave range. Valid values are from 0 to 84. (0 is a pause.)
|
||||
* Cannot use with sharp and flat. Cannot use with the shorthand notation neither.
|
||||
* MN Stand for Music Normal. Note duration is 7/8ths of the length indicated by Ln. It is the default mode.
|
||||
* ML Stand for Music Legato. Note duration is full length of that indicated by Ln.
|
||||
* MS Stand for Music Staccato. Note duration is 3/4ths of the length indicated by Ln.
|
||||
* Pn Causes a silence (pause) for the length of note indicated (same as Ln).
|
||||
* Tn Sets the number of "L4"s per minute (tempo). Valid values are from 32 to 255. The default value is T120.
|
||||
* Pn Causes a silence (pause) for the length of note indicated (same as Ln).
|
||||
* Tn Sets the number of "L4"s per minute (tempo). Valid values are from 32 to 255. The default value is T120.
|
||||
* . When placed after a note, it causes the duration of the note to be 3/2 of the set duration.
|
||||
* This is how to get "dotted" notes. "L4 C#." would play C sharp as a dotted quarter note.
|
||||
* It can be used for a pause as well.
|
||||
@@ -283,14 +283,15 @@ public:
|
||||
|
||||
virtual int ioctl(file *filp, int cmd, unsigned long arg);
|
||||
virtual ssize_t write(file *filp, const char *buffer, size_t len);
|
||||
inline const char *name(int tune) {
|
||||
inline const char *name(int tune)
|
||||
{
|
||||
return _tune_names[tune];
|
||||
}
|
||||
|
||||
private:
|
||||
static const unsigned _tune_max = 1024 * 8; // be reasonable about user tunes
|
||||
const char * _default_tunes[TONE_NUMBER_OF_TUNES];
|
||||
const char * _tune_names[TONE_NUMBER_OF_TUNES];
|
||||
const char *_default_tunes[TONE_NUMBER_OF_TUNES];
|
||||
const char *_tune_names[TONE_NUMBER_OF_TUNES];
|
||||
static const uint8_t _note_tab[];
|
||||
|
||||
unsigned _default_tune_number; // number of currently playing default tune (0 for none)
|
||||
@@ -314,8 +315,8 @@ private:
|
||||
//
|
||||
unsigned note_to_divisor(unsigned note);
|
||||
|
||||
// Calculate the duration in microseconds of play and silence for a
|
||||
// note given the current tempo, length and mode and the number of
|
||||
// Calculate the duration in microseconds of play and silence for a
|
||||
// note given the current tempo, length and mode and the number of
|
||||
// dots following in the play string.
|
||||
//
|
||||
unsigned note_duration(unsigned &silence, unsigned note_length, unsigned dots);
|
||||
@@ -422,14 +423,15 @@ ToneAlarm::init()
|
||||
|
||||
ret = CDev::init();
|
||||
|
||||
if (ret != OK)
|
||||
if (ret != OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* configure the GPIO to the idle state */
|
||||
stm32_configgpio(GPIO_TONE_ALARM_IDLE);
|
||||
|
||||
/* clock/power on our timer */
|
||||
modifyreg32(TONE_ALARM_CLOCK_POWER_REG, 0, TONE_ALARM_CLOCK_ENABLE);
|
||||
modifyreg32(TONE_ALARM_CLOCK_POWER_REG, 0, TONE_ALARM_CLOCK_ENABLE);
|
||||
|
||||
/* initialise the timer */
|
||||
rCR1 = 0;
|
||||
@@ -443,7 +445,7 @@ ToneAlarm::init()
|
||||
rDCR = 0;
|
||||
|
||||
#ifdef rBDTR // If using an advanced timer, you need to activate the output
|
||||
rBDTR = ATIM_BDTR_MOE; // enable the main output of the advanced timer
|
||||
rBDTR = ATIM_BDTR_MOE; // enable the main output of the advanced timer
|
||||
#endif
|
||||
|
||||
/* toggle the CC output each time the count passes 1 */
|
||||
@@ -478,25 +480,31 @@ ToneAlarm::note_duration(unsigned &silence, unsigned note_length, unsigned dots)
|
||||
{
|
||||
unsigned whole_note_period = (60 * 1000000 * 4) / _tempo;
|
||||
|
||||
if (note_length == 0)
|
||||
if (note_length == 0) {
|
||||
note_length = 1;
|
||||
}
|
||||
|
||||
unsigned note_period = whole_note_period / note_length;
|
||||
|
||||
switch (_note_mode) {
|
||||
case MODE_NORMAL:
|
||||
silence = note_period / 8;
|
||||
break;
|
||||
|
||||
case MODE_STACCATO:
|
||||
silence = note_period / 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
case MODE_LEGATO:
|
||||
silence = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
note_period -= silence;
|
||||
|
||||
unsigned dot_extension = note_period / 2;
|
||||
|
||||
while (dots--) {
|
||||
note_period += dot_extension;
|
||||
dot_extension /= 2;
|
||||
@@ -510,12 +518,14 @@ ToneAlarm::rest_duration(unsigned rest_length, unsigned dots)
|
||||
{
|
||||
unsigned whole_note_period = (60 * 1000000 * 4) / _tempo;
|
||||
|
||||
if (rest_length == 0)
|
||||
if (rest_length == 0) {
|
||||
rest_length = 1;
|
||||
}
|
||||
|
||||
unsigned rest_period = whole_note_period / rest_length;
|
||||
|
||||
unsigned dot_extension = rest_period / 2;
|
||||
|
||||
while (dots--) {
|
||||
rest_period += dot_extension;
|
||||
dot_extension /= 2;
|
||||
@@ -605,115 +615,155 @@ ToneAlarm::next_note()
|
||||
while (note == 0) {
|
||||
// we always need at least one character from the string
|
||||
int c = next_char();
|
||||
if (c == 0)
|
||||
|
||||
if (c == 0) {
|
||||
goto tune_end;
|
||||
}
|
||||
|
||||
_next++;
|
||||
|
||||
switch (c) {
|
||||
case 'L': // select note length
|
||||
_note_length = next_number();
|
||||
if (_note_length < 1)
|
||||
|
||||
if (_note_length < 1) {
|
||||
goto tune_error;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'O': // select octave
|
||||
_octave = next_number();
|
||||
if (_octave > 6)
|
||||
|
||||
if (_octave > 6) {
|
||||
_octave = 6;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '<': // decrease octave
|
||||
if (_octave > 0)
|
||||
if (_octave > 0) {
|
||||
_octave--;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '>': // increase octave
|
||||
if (_octave < 6)
|
||||
if (_octave < 6) {
|
||||
_octave++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'M': // select inter-note gap
|
||||
c = next_char();
|
||||
if (c == 0)
|
||||
|
||||
if (c == 0) {
|
||||
goto tune_error;
|
||||
}
|
||||
|
||||
_next++;
|
||||
|
||||
switch (c) {
|
||||
case 'N':
|
||||
_note_mode = MODE_NORMAL;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
_note_mode = MODE_LEGATO;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
_note_mode = MODE_STACCATO;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
_repeat = false;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
_repeat = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto tune_error;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'P': // pause for a note length
|
||||
stop_note();
|
||||
hrt_call_after(&_note_call,
|
||||
(hrt_abstime)rest_duration(next_number(), next_dots()),
|
||||
(hrt_callout)next_trampoline,
|
||||
this);
|
||||
hrt_call_after(&_note_call,
|
||||
(hrt_abstime)rest_duration(next_number(), next_dots()),
|
||||
(hrt_callout)next_trampoline,
|
||||
this);
|
||||
return;
|
||||
|
||||
case 'T': { // change tempo
|
||||
unsigned nt = next_number();
|
||||
unsigned nt = next_number();
|
||||
|
||||
if ((nt >= 32) && (nt <= 255)) {
|
||||
_tempo = nt;
|
||||
} else {
|
||||
goto tune_error;
|
||||
if ((nt >= 32) && (nt <= 255)) {
|
||||
_tempo = nt;
|
||||
|
||||
} else {
|
||||
goto tune_error;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'N': // play an arbitrary note
|
||||
note = next_number();
|
||||
if (note > 84)
|
||||
|
||||
if (note > 84) {
|
||||
goto tune_error;
|
||||
}
|
||||
|
||||
if (note == 0) {
|
||||
// this is a rest - pause for the current note length
|
||||
hrt_call_after(&_note_call,
|
||||
(hrt_abstime)rest_duration(_note_length, next_dots()),
|
||||
(hrt_callout)next_trampoline,
|
||||
this);
|
||||
return;
|
||||
(hrt_abstime)rest_duration(_note_length, next_dots()),
|
||||
(hrt_callout)next_trampoline,
|
||||
this);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'A'...'G': // play a note in the current octave
|
||||
note = _note_tab[c - 'A'] + (_octave * 12) + 1;
|
||||
c = next_char();
|
||||
|
||||
switch (c) {
|
||||
case '#': // up a semitone
|
||||
case '+':
|
||||
if (note < 84)
|
||||
if (note < 84) {
|
||||
note++;
|
||||
}
|
||||
|
||||
_next++;
|
||||
break;
|
||||
|
||||
case '-': // down a semitone
|
||||
if (note > 1)
|
||||
if (note > 1) {
|
||||
note--;
|
||||
}
|
||||
|
||||
_next++;
|
||||
break;
|
||||
|
||||
default:
|
||||
// 0 / no next char here is OK
|
||||
break;
|
||||
}
|
||||
|
||||
// shorthand length notation
|
||||
note_length = next_number();
|
||||
if (note_length == 0)
|
||||
|
||||
if (note_length == 0) {
|
||||
note_length = _note_length;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -739,12 +789,15 @@ tune_error:
|
||||
// stop (and potentially restart) the tune
|
||||
tune_end:
|
||||
stop_note();
|
||||
|
||||
if (_repeat) {
|
||||
start_tune(_tune);
|
||||
|
||||
} else {
|
||||
_tune = nullptr;
|
||||
_default_tune_number = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -754,6 +807,7 @@ ToneAlarm::next_char()
|
||||
while (isspace(*_next)) {
|
||||
_next++;
|
||||
}
|
||||
|
||||
return toupper(*_next);
|
||||
}
|
||||
|
||||
@@ -765,8 +819,11 @@ ToneAlarm::next_number()
|
||||
|
||||
for (;;) {
|
||||
c = next_char();
|
||||
if (!isdigit(c))
|
||||
|
||||
if (!isdigit(c)) {
|
||||
return number;
|
||||
}
|
||||
|
||||
_next++;
|
||||
number = (number * 10) + (c - '0');
|
||||
}
|
||||
@@ -781,6 +838,7 @@ ToneAlarm::next_dots()
|
||||
_next++;
|
||||
dots++;
|
||||
}
|
||||
|
||||
return dots;
|
||||
}
|
||||
|
||||
@@ -814,6 +872,7 @@ ToneAlarm::ioctl(file *filp, int cmd, unsigned long arg)
|
||||
_next = nullptr;
|
||||
_repeat = false;
|
||||
_default_tune_number = 0;
|
||||
|
||||
} else {
|
||||
/* always interrupt alarms, unless they are repeating and already playing */
|
||||
if (!(_repeat && _default_tune_number == arg)) {
|
||||
@@ -822,6 +881,7 @@ ToneAlarm::ioctl(file *filp, int cmd, unsigned long arg)
|
||||
start_tune(_default_tunes[arg]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
result = -EINVAL;
|
||||
}
|
||||
@@ -836,8 +896,9 @@ ToneAlarm::ioctl(file *filp, int cmd, unsigned long arg)
|
||||
// irqrestore(flags);
|
||||
|
||||
/* give it to the superclass if we didn't like it */
|
||||
if (result == -ENOTTY)
|
||||
if (result == -ENOTTY) {
|
||||
result = CDev::ioctl(filp, cmd, arg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -846,8 +907,9 @@ int
|
||||
ToneAlarm::write(file *filp, const char *buffer, size_t len)
|
||||
{
|
||||
// sanity-check the buffer for length and nul-termination
|
||||
if (len > _tune_max)
|
||||
if (len > _tune_max) {
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
// if we have an existing user tune, free it
|
||||
if (_user_tune != nullptr) {
|
||||
@@ -864,13 +926,16 @@ ToneAlarm::write(file *filp, const char *buffer, size_t len)
|
||||
}
|
||||
|
||||
// if the new tune is empty, we're done
|
||||
if (buffer[0] == '\0')
|
||||
if (buffer[0] == '\0') {
|
||||
return OK;
|
||||
}
|
||||
|
||||
// allocate a copy of the new tune
|
||||
_user_tune = strndup(buffer, len);
|
||||
if (_user_tune == nullptr)
|
||||
|
||||
if (_user_tune == nullptr) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
// and play it
|
||||
start_tune(_user_tune);
|
||||
@@ -893,14 +958,16 @@ play_tune(unsigned tune)
|
||||
|
||||
fd = open(TONEALARM0_DEVICE_PATH, 0);
|
||||
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
err(1, TONEALARM0_DEVICE_PATH);
|
||||
}
|
||||
|
||||
ret = ioctl(fd, TONE_SET_ALARM, tune);
|
||||
close(fd);
|
||||
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
err(1, "TONE_SET_ALARM");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -912,17 +979,21 @@ play_string(const char *str, bool free_buffer)
|
||||
|
||||
fd = open(TONEALARM0_DEVICE_PATH, O_WRONLY);
|
||||
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
err(1, TONEALARM0_DEVICE_PATH);
|
||||
}
|
||||
|
||||
ret = write(fd, str, strlen(str) + 1);
|
||||
close(fd);
|
||||
|
||||
if (free_buffer)
|
||||
if (free_buffer) {
|
||||
free((void *)str);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
err(1, "play tune");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -937,8 +1008,9 @@ tone_alarm_main(int argc, char *argv[])
|
||||
if (g_dev == nullptr) {
|
||||
g_dev = new ToneAlarm;
|
||||
|
||||
if (g_dev == nullptr)
|
||||
if (g_dev == nullptr) {
|
||||
errx(1, "couldn't allocate the ToneAlarm driver");
|
||||
}
|
||||
|
||||
if (g_dev->init() != OK) {
|
||||
delete g_dev;
|
||||
@@ -953,30 +1025,39 @@ tone_alarm_main(int argc, char *argv[])
|
||||
play_tune(TONE_STOP_TUNE);
|
||||
}
|
||||
|
||||
if (!strcmp(argv1, "stop"))
|
||||
if (!strcmp(argv1, "stop")) {
|
||||
play_tune(TONE_STOP_TUNE);
|
||||
}
|
||||
|
||||
if ((tune = strtol(argv1, nullptr, 10)) != 0)
|
||||
if ((tune = strtol(argv1, nullptr, 10)) != 0) {
|
||||
play_tune(tune);
|
||||
}
|
||||
|
||||
/* It might be a tune name */
|
||||
for (tune = 1; tune < TONE_NUMBER_OF_TUNES; tune++)
|
||||
if (!strcmp(g_dev->name(tune), argv1))
|
||||
if (!strcmp(g_dev->name(tune), argv1)) {
|
||||
play_tune(tune);
|
||||
}
|
||||
|
||||
/* If it is a file name then load and play it as a string */
|
||||
if (*argv1 == '/') {
|
||||
FILE *fd = fopen(argv1, "r");
|
||||
int sz;
|
||||
char *buffer;
|
||||
if (fd == nullptr)
|
||||
|
||||
if (fd == nullptr) {
|
||||
errx(1, "couldn't open '%s'", argv1);
|
||||
}
|
||||
|
||||
fseek(fd, 0, SEEK_END);
|
||||
sz = ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
buffer = (char *)malloc(sz + 1);
|
||||
if (buffer == nullptr)
|
||||
|
||||
if (buffer == nullptr) {
|
||||
errx(1, "not enough memory memory");
|
||||
}
|
||||
|
||||
fread(buffer, sz, 1, fd);
|
||||
/* terminate the string */
|
||||
buffer[sz] = 0;
|
||||
|
||||
Reference in New Issue
Block a user