Hi,
I've implemented a buzzer service with the following code:
static nrf_pwm_values_common_t sequence_values[(int)(m_top/m_step)];
uint16_t value = 0;
//using the 0th PWM module
static nrfx_pwm_t m_pwm0 = NRFX_PWM_INSTANCE(0);
static void pwm_common_init(void)
{
int max_steps = m_top/m_step;
for(int i=0; i<max_steps; i++){
//1st it: 0+100
value += m_step;
sequence_values[i] = value;
}
//configuration
nrfx_pwm_config_t const config0 =
{
.output_pins =
{
BSP_LED_0 | NRFX_PWM_PIN_INVERTED,
buzzer_external,
NRFX_PWM_PIN_NOT_USED,
NRFX_PWM_PIN_NOT_USED
},
.irq_priority = APP_IRQ_PRIORITY_LOWEST,
.base_clock = NRF_PWM_CLK_1MHz,
.count_mode = NRF_PWM_MODE_UP,
.top_value = m_top,
.load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO
};
// clock = 1MHz
// Counter is 15-bit
// T_pwm(up) = T_pwm_clock*COUNTERTOP
// Do = 532.251Hz
// 1/532 = 1/1e6*COUNTERTOP
// Countertop ~= 1880
APP_ERROR_CHECK(nrfx_pwm_init(&m_pwm0, &config0, NULL));
}
static void pwm_play(void)
{
nrf_pwm_sequence_t const seq0 =
{
.values.p_common = sequence_values,
.length = NRF_PWM_VALUES_LENGTH(sequence_values),
.repeats = 0x00,
.end_delay = 0,
};
for(int i=0;i<20;i++){
(void)nrfx_pwm_simple_playback(&m_pwm0, &seq0, 3, NRFX_PWM_FLAG_STOP);
nrf_delay_ms(500);
}
}
static void pwm_stop(void)
{
(void)nrfx_pwm_stop(&m_pwm0, false);
}
m_top is 1880 such that I get a C note/tone at the buzzer.
I also use the following evt handler function:
static void buzzer_write_handler(ble_buzzer_service_t * p_buzzer_service, ble_buzzer_new_status_t * new_buzzer_status)
{
buzzer_new_status_t new_status = new_buzzer_status->params_command.status_command_data;
if (new_status.p_data[0])
{
pwm_play();
NRF_LOG_INFO("Buzzing.");
}
else if (new_status.p_data[0] == 0x00)
{
pwm_stop();
NRF_LOG_INFO("Buzzer is quiet.");
}
}
The service is very simple, if I write a 0x01 to buzzer characteristic, then buzz. If I write a 0, then stop buzzing.
My problem is that, with this current implementation, the buzzing will not finish until the for-loop has gone through. The program doesn't care that I wrote a 0x00 to the characteristic, it still continues buzzing.
The only way I've been able to make it work (i.e., writing 0 to the characteristic turns off the buzzing) is to just place the ...simple_playback() function standalone, without any for-loop enclosing it, and using the NRFX_PWM_FLAG_LOOP flag.
However, in this way, I can only get a constant tone, a not beeps separated by silences like I do now.
My question is:
How can I implement a function that will make the buzzer sound forever (with spaced tones) that I will be able to stop by writing 0x00 to the characteristic?
Thanks in advance for the reply.