This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52 TIMER PPI GPIOTE dropouts/pauses issue

Hi. I'm trying to output frequency (in the 1,250 Hz to 1,750 Hz range) on GPIO. Each frequency should be outputted for 5ms time. For that, I use 2 TIMERs: one for 5ms counter and one for frequency output + PPI + GPIOTE. I have a lookup array with "tones" for certain frequencies. When the 5ms timer fires up I pass the next value from the array to the frequency output timer as the CC value.

The problem is when frequency outputs I can see some dropouts in frequency with logic analyzer. These dropouts occur in different moments but in most cases, they last about 4ms.

I expect to frequency change without any dropouts and pauses. What I'm doing wrong?

Here is the code
(based on ...\nRF5_SDK_17.0.2_d674dde\examples\peripheral\timer)

#define GPIO_FREQ_OUT 4
static const nrf_drv_timer_t timer_inst_t5ms = NRF_DRV_TIMER_INSTANCE(1); //!don't use TIMER0 with softdevice
static const nrf_drv_timer_t timer_inst_freq = NRF_DRV_TIMER_INSTANCE(3); //!don't use TIMER0 with softdevice
static nrf_ppi_channel_t     m_ppi_channel;
uint16_t tone_member = 1;
uint32_t timer_5ms_counter = 0;

/**
 * @brief Handler for timer events.
 */
void t5ms_timer_event_handler(nrf_timer_event_t event_type, void *p_context)
{
    switch (event_type)
    {
    case NRF_TIMER_EVENT_COMPARE0:
        nrf_gpio_pin_toggle(3);
        fm_set_duty(tone_array[tone_member]);
        //**********tone_member table go up
        if (tone_member < TONE_TABLE_MEMBERS)
        {
           tone_member++;
        }
        else if (tone_member >= TONE_TABLE_MEMBERS)
        {
           tone_member = 0;
           nrf_drv_timer_disable(&timer_inst_t5ms);
           nrf_drv_timer_disable(&timer_inst_freq);
           nrf_drv_ppi_channel_disable(m_ppi_channel);
           nrf_drv_gpiote_out_task_disable(GPIO_FREQ_OUT);
        }
        //**********tone table go up
        break;
    }
}

void fm_set_duty(uint32_t period)
{
    nrf_drv_timer_extended_compare(&timer_inst_freq,
                                 NRF_TIMER_CC_CHANNEL0,
                                 period,
                                 NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                 false);
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;

    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    //>>>GPIOTE init
    nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);

    err_code = nrf_drv_gpiote_out_init(GPIO_FREQ_OUT, &config);
    APP_ERROR_CHECK(err_code);
    //<<<GPIOTE init

    ////>>>TIMER init
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16;
    err_code = nrf_drv_timer_init(&timer_inst_freq, &timer_cfg, freq_timer_event_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_timer_extended_compare(&timer_inst_freq,
                                   NRF_TIMER_CC_CHANNEL0,
                                   tone_array[0],
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                   false);
    ////<<<<TIMER init

    //>>>PPI init
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
    APP_ERROR_CHECK(err_code);

    uint32_t compare_evt_addr;
    uint32_t gpiote_task_addr;
    compare_evt_addr = nrf_drv_timer_event_address_get(&timer_inst_freq, NRF_TIMER_EVENT_COMPARE0);
    gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_FREQ_OUT);

    err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, compare_evt_addr, gpiote_task_addr);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_out_task_enable(GPIO_FREQ_OUT);
    //<<<PPI init

    ////>>>TIMER init
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;

    err_code = nrf_drv_timer_init(&timer_inst_t5ms,
                                  &timer_cfg,
                                  t5ms_timer_event_handler);
    APP_ERROR_CHECK(err_code);

    time_ticks = nrf_drv_timer_ms_to_ticks(&timer_inst_t5ms, 5);

    nrf_drv_timer_extended_compare(&timer_inst_t5ms,
                                   NRF_TIMER_CC_CHANNEL0,
                                   time_ticks,
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                   true);

    nrf_drv_timer_enable(&timer_inst_t5ms);
    ////<<<<TIMER init

    nrf_drv_timer_enable(&timer_inst_freq);

    //>>>GPIO init
    nrf_gpio_cfg_output(3);
    //<<<GPIO init

    while (1)
    {
        __WFI();
    }
}


const uint16_t tone_array[1024] = {
6400, 6398, 6395, 6393, 6390, 6388, 6385, 6383, 6380, 6378, 6375, 6373, 6370, 6368, 6365, 6363,
6360, 6358, 6356, 6353, 6351, 6348, 6346, 6343, 6341, 6338, 6336, 6333, 6331, 6329, 6326, 6324,
6321, 6319, 6316, 6314, 6311, 6309, 6307, 6304, 6302, 6299, 6297, 6295, 6292, 6290, 6287, 6285,
6282, 6280, 6278, 6275, 6273, 6270, 6268, 6266, 6263, 6261, 6258, 6256, 6254, 6251, 6249, 6247,
6244, 6242, 6239, 6237, 6235, 6232, 6230, 6228, 6225, 6223, 6220, 6218, 6216, 6213, 6211, 6209,
6206, 6204, 6202, 6199, 6197, 6195, 6192, 6190, 6188, 6185, 6183, 6181, 6178, 6176, 6174, 6171,
6169, 6167, 6164, 6162, 6160, 6157, 6155, 6153, 6150, 6148, 6146, 6143, 6141, 6139, 6137, 6134,
6132, 6130, 6127, 6125, 6123, 6121, 6118, 6116, 6114, 6111, 6109, 6107, 6105, 6102, 6100, 6098,
6095, 6093, 6091, 6089, 6086, 6084, 6082, 6080, 6077, 6075, 6073, 6071, 6068, 6066, 6064, 6062,
6059, 6057, 6055, 6053, 6050, 6048, 6046, 6044, 6042, 6039, 6037, 6035, 6033, 6030, 6028, 6026,
6024, 6022, 6019, 6017, 6015, 6013, 6011, 6008, 6006, 6004, 6002, 6000, 5997, 5995, 5993, 5991,
5989, 5986, 5984, 5982, 5980, 5978, 5975, 5973, 5971, 5969, 5967, 5965, 5962, 5960, 5958, 5956,
5954, 5952, 5949, 5947, 5945, 5943, 5941, 5939, 5936, 5934, 5932, 5930, 5928, 5926, 5924, 5921,
5919, 5917, 5915, 5913, 5911, 5909, 5907, 5904, 5902, 5900, 5898, 5896, 5894, 5892, 5890, 5887,
5885, 5883, 5881, 5879, 5877, 5875, 5873, 5871, 5868, 5866, 5864, 5862, 5860, 5858, 5856, 5854,
5852, 5850, 5848, 5845, 5843, 5841, 5839, 5837, 5835, 5833, 5831, 5829, 5827, 5825, 5823, 5820,
5818, 5816, 5814, 5812, 5810, 5808, 5806, 5804, 5802, 5800, 5798, 5796, 5794, 5792, 5790, 5788,
5786, 5784, 5781, 5779, 5777, 5775, 5773, 5771, 5769, 5767, 5765, 5763, 5761, 5759, 5757, 5755,
5753, 5751, 5749, 5747, 5745, 5743, 5741, 5739, 5737, 5735, 5733, 5731, 5729, 5727, 5725, 5723,
5721, 5719, 5717, 5715, 5713, 5711, 5709, 5707, 5705, 5703, 5701, 5699, 5697, 5695, 5693, 5691,
5689, 5687, 5685, 5683, 5681, 5679, 5677, 5675, 5673, 5671, 5669, 5667, 5666, 5664, 5662, 5660,
5658, 5656, 5654, 5652, 5650, 5648, 5646, 5644, 5642, 5640, 5638, 5636, 5634, 5632, 5630, 5629,
5627, 5625, 5623, 5621, 5619, 5617, 5615, 5613, 5611, 5609, 5607, 5605, 5604, 5602, 5600, 5598,
5596, 5594, 5592, 5590, 5588, 5586, 5584, 5583, 5581, 5579, 5577, 5575, 5573, 5571, 5569, 5567,
5565, 5564, 5562, 5560, 5558, 5556, 5554, 5552, 5550, 5549, 5547, 5545, 5543, 5541, 5539, 5537,
5535, 5534, 5532, 5530, 5528, 5526, 5524, 5522, 5520, 5519, 5517, 5515, 5513, 5511, 5509, 5507,
5506, 5504, 5502, 5500, 5498, 5496, 5495, 5493, 5491, 5489, 5487, 5485, 5484, 5482, 5480, 5478,
5476, 5474, 5473, 5471, 5469, 5467, 5465, 5463, 5462, 5460, 5458, 5456, 5454, 5452, 5451, 5449,
5447, 5445, 5443, 5442, 5440, 5438, 5436, 5434, 5433, 5431, 5429, 5427, 5425, 5424, 5422, 5420,
5418, 5416, 5415, 5413, 5411, 5409, 5408, 5406, 5404, 5402, 5400, 5399, 5397, 5395, 5393, 5391,
5390, 5388, 5386, 5384, 5383, 5381, 5379, 5377, 5376, 5374, 5372, 5370, 5369, 5367, 5365, 5363,
5362, 5360, 5358, 5356, 5354, 5353, 5351, 5349, 5348, 5346, 5344, 5342, 5341, 5339, 5337, 5335,
5334, 5332, 5330, 5328, 5327, 5325, 5323, 5321, 5320, 5318, 5316, 5315, 5313, 5311, 5309, 5308,
5306, 5304, 5302, 5301, 5299, 5297, 5296, 5294, 5292, 5290, 5289, 5287, 5285, 5284, 5282, 5280,
5278, 5277, 5275, 5273, 5272, 5270, 5268, 5267, 5265, 5263, 5262, 5260, 5258, 5256, 5255, 5253,
5251, 5250, 5248, 5246, 5245, 5243, 5241, 5240, 5238, 5236, 5235, 5233, 5231, 5230, 5228, 5226,
5225, 5223, 5221, 5220, 5218, 5216, 5215, 5213, 5211, 5210, 5208, 5206, 5205, 5203, 5201, 5200,
5198, 5196, 5195, 5193, 5191, 5190, 5188, 5186, 5185, 5183, 5181, 5180, 5178, 5177, 5175, 5173,
5172, 5170, 5168, 5167, 5165, 5163, 5162, 5160, 5159, 5157, 5155, 5154, 5152, 5150, 5149, 5147,
5146, 5144, 5142, 5141, 5139, 5138, 5136, 5134, 5133, 5131, 5129, 5128, 5126, 5125, 5123, 5121,
5120, 5118, 5117, 5115, 5113, 5112, 5110, 5109, 5107, 5105, 5104, 5102, 5101, 5099, 5098, 5096,
5094, 5093, 5091, 5090, 5088, 5086, 5085, 5083, 5082, 5080, 5079, 5077, 5075, 5074, 5072, 5071,
5069, 5067, 5066, 5064, 5063, 5061, 5060, 5058, 5057, 5055, 5053, 5052, 5050, 5049, 5047, 5046,
5044, 5042, 5041, 5039, 5038, 5036, 5035, 5033, 5032, 5030, 5029, 5027, 5025, 5024, 5022, 5021,
5019, 5018, 5016, 5015, 5013, 5012, 5010, 5009, 5007, 5005, 5004, 5002, 5001, 4999, 4998, 4996,
4995, 4993, 4992, 4990, 4989, 4987, 4986, 4984, 4983, 4981, 4980, 4978, 4977, 4975, 4973, 4972,
4970, 4969, 4967, 4966, 4964, 4963, 4961, 4960, 4958, 4957, 4955, 4954, 4952, 4951, 4949, 4948,
4946, 4945, 4943, 4942, 4940, 4939, 4937, 4936, 4934, 4933, 4931, 4930, 4929, 4927, 4926, 4924,
4923, 4921, 4920, 4918, 4917, 4915, 4914, 4912, 4911, 4909, 4908, 4906, 4905, 4903, 4902, 4900,
4899, 4898, 4896, 4895, 4893, 4892, 4890, 4889, 4887, 4886, 4884, 4883, 4881, 4880, 4879, 4877,
4876, 4874, 4873, 4871, 4870, 4868, 4867, 4865, 4864, 4863, 4861, 4860, 4858, 4857, 4855, 4854,
4852, 4851, 4850, 4848, 4847, 4845, 4844, 4842, 4841, 4840, 4838, 4837, 4835, 4834, 4832, 4831,
4830, 4828, 4827, 4825, 4824, 4822, 4821, 4820, 4818, 4817, 4815, 4814, 4812, 4811, 4810, 4808,
4807, 4805, 4804, 4803, 4801, 4800, 4798, 4797, 4796, 4794, 4793, 4791, 4790, 4789, 4787, 4786,
4784, 4783, 4782, 4780, 4779, 4777, 4776, 4775, 4773, 4772, 4770, 4769, 4768, 4766, 4765, 4763,
4762, 4761, 4759, 4758, 4757, 4755, 4754, 4752, 4751, 4750, 4748, 4747, 4745, 4744, 4743, 4741,
4740, 4739, 4737, 4736, 4734, 4733, 4732, 4730, 4729, 4728, 4726, 4725, 4724, 4722, 4721, 4719,
4718, 4717, 4715, 4714, 4713, 4711, 4710, 4709, 4707, 4706, 4705, 4703, 4702, 4700, 4699, 4698,
4696, 4695, 4694, 4692, 4691, 4690, 4688, 4687, 4686, 4684, 4683, 4682, 4680, 4679, 4678, 4676,
4675, 4674, 4672, 4671, 4670, 4668, 4667, 4666, 4664, 4663, 4662, 4660, 4659, 4658, 4656, 4655,
4654, 4652, 4651, 4650, 4648, 4647, 4646, 4644, 4643, 4642, 4640, 4639, 4638, 4636, 4635, 4634,
4633, 4631, 4630, 4629, 4627, 4626, 4625, 4623, 4622, 4621, 4619, 4618, 4617, 4616, 4614, 4613,
4612, 4610, 4609, 4608, 4606, 4605, 4604, 4603, 4601, 4600, 4599, 4597, 4596, 4595, 4594, 4592,
4591, 4590, 4588, 4587, 4586, 4584, 4583, 4582, 4581, 4579, 4578, 4577, 4576, 4574, 4573, 4572
};


My setup:
nRF52832 (NRF52 DK)
SDK 17.0.2
SES 5.5
SoftDevice none (but in future this code must with it)

Logic analyzer screenshots (bottom channel is a visualization of the 5ms timer)




Hope you can help me. I'm out of ideas.

Parents
  • Hi,

    Could you try this modify your fm_set_duty() function so it looks like this, and see if that helps?

    void fm_set_duty(uint32_t period)
    {
        nrf_drv_timer_extended_compare(&timer_inst_freq,
                                     NRF_TIMER_CC_CHANNEL0,
                                     period,
                                     NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                     false);
          nrf_drv_timer_clear(&timer_inst_freq);
    }

  • Thanks for the suggestion. In search of a problem, I made little modifications to the code just to make few loops of frequency output.

    Your suggestion added smaller pauses (highlighted on screenshot) on each 5ms timer tick and didn't avoid all 4ms dropouts.




    My current code:

    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "nrf_drv_timer.h"
    #include "nrf_drv_ppi.h"
    #include "nrf_drv_gpiote.h"
    #include "nrf_gpiote.h"
    #include "nrf_gpio.h"
    #include "app_error.h"
    #include "nrf_pwr_mgmt.h"
    #include "tone_array.h"
    
    #define GPIO_FREQ_OUT 4
    static const nrf_drv_timer_t timer_inst_t5ms = NRF_DRV_TIMER_INSTANCE(1); //!don't use TIMER0 with softdevice
    static const nrf_drv_timer_t timer_inst_freq = NRF_DRV_TIMER_INSTANCE(3); //!don't use TIMER0 with softdevice
    static nrf_ppi_channel_t     m_ppi_channel;
    uint16_t tone_member = 1;
    uint32_t timer_5ms_counter = 0;
    
    /**
     * @brief Handler for timer events.
     */
    void t5ms_timer_event_handler(nrf_timer_event_t event_type, void *p_context)
    {
        switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE0:
                nrf_gpio_pin_toggle(3);
                fm_set_duty(tone_array[tone_member]);
                //**********tone_member table go up
                if (tone_member < TONE_TABLE_MEMBERS)
                {
                    tone_member++;
                }
                else if (tone_member >= TONE_TABLE_MEMBERS)
                {
                    tone_member = 0;
                    // nrf_drv_timer_disable(&timer_inst_t5ms);
                    // nrf_drv_timer_disable(&timer_inst_freq);
                    // nrf_drv_ppi_channel_disable(m_ppi_channel);
                    // nrf_drv_gpiote_out_task_disable(GPIO_FREQ_OUT);
                }
                //**********tone table go up
    
                //************30 sec ramp from tone table******
                if (timer_5ms_counter >= 6000)
                {
                    nrf_drv_timer_disable(&timer_inst_t5ms);
                    nrf_drv_timer_disable(&timer_inst_freq);
                    nrf_drv_ppi_channel_disable(m_ppi_channel);
                    nrf_drv_gpiote_out_task_disable(GPIO_FREQ_OUT);
                }
                timer_5ms_counter++;
                break;
        }
    }
    
    void fm_set_duty(uint32_t period)
    {
        nrf_drv_timer_extended_compare(&timer_inst_freq,
                                     NRF_TIMER_CC_CHANNEL0,
                                     period,
                                     NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                     false);
        nrf_drv_timer_clear(&timer_inst_freq);
    }
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        uint32_t time_ticks;
        uint32_t err_code = NRF_SUCCESS;
    
        err_code = nrf_drv_ppi_init();
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    
        //>>>GPIOTE init
        nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
    
        err_code = nrf_drv_gpiote_out_init(GPIO_FREQ_OUT, &config);
        APP_ERROR_CHECK(err_code);
        //<<<GPIOTE init
    
        ////>>>TIMER init
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16;
    
        err_code = nrf_drv_timer_init(&timer_inst_freq, &timer_cfg, freq_timer_event_handler);
        APP_ERROR_CHECK(err_code);
    
        //nrf_drv_timer_extended_compare(&timer_inst_freq,
        //                               NRF_TIMER_CC_CHANNEL0,
        //                               tone_array[0],
        //                               NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
        //                               false);
        fm_set_duty(tone_array[0]);
        ////<<<<TIMER init
    
        //>>>PPI init
        err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
        APP_ERROR_CHECK(err_code);
    
        uint32_t compare_evt_addr;
        uint32_t gpiote_task_addr;
        compare_evt_addr = nrf_drv_timer_event_address_get(&timer_inst_freq, NRF_TIMER_EVENT_COMPARE0);
        gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_FREQ_OUT);
    
        err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, compare_evt_addr, gpiote_task_addr);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_out_task_enable(GPIO_FREQ_OUT);
        //<<<PPI init
    
        ////>>>TIMER init
        timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    
        err_code = nrf_drv_timer_init(&timer_inst_t5ms,
                                      &timer_cfg,
                                      t5ms_timer_event_handler);
        APP_ERROR_CHECK(err_code);
    
        time_ticks = nrf_drv_timer_ms_to_ticks(&timer_inst_t5ms, 5);
    
        nrf_drv_timer_extended_compare(&timer_inst_t5ms,
                                       NRF_TIMER_CC_CHANNEL0,
                                       time_ticks,
                                       NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                       true);
    
        nrf_drv_timer_enable(&timer_inst_t5ms);
        ////<<<<TIMER init
    
        nrf_drv_timer_enable(&timer_inst_freq);
    
        //>>>GPIO init
        nrf_gpio_cfg_output(3);
        //<<<GPIO init
    
        while (1)
        {
            __WFI();
        }
    }


    Even if clearing helped, these pauses on each 5ms are definitely not acceptable for our application. Do you have other suggestions?

  • Could you try to stop the timer when setting the new CC value, and see if that helps?

    void fm_set_duty(uint32_t period)
    {
    
      nrf_drv_timer_disable(&timer_inst_freq);
      nrf_drv_timer_clear(&timer_inst_freq);
      nrf_drv_timer_extended_compare(&timer_inst_freq,
                                     NRF_TIMER_CC_CHANNEL0,
                                     period,
                                     NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                     false);
      nrf_drv_timer_enable(&timer_inst_freq);
    
    }

  • Sure. I tried your suggestion but it doesn't resolve our issue.
    Same 4ms pauses from time to time and shorter pauses on each tick off 5ms  timer.

    I tried with both disabling and clearing

    void fm_set_duty(uint32_t period)
    {
    
      nrf_drv_timer_disable(&timer_inst_freq);
      nrf_drv_timer_clear(&timer_inst_freq);
      nrf_drv_timer_extended_compare(&timer_inst_freq,
                                     NRF_TIMER_CC_CHANNEL0,
                                     period,
                                     NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                     false);
      nrf_drv_timer_enable(&timer_inst_freq);
    }

    and only with disabling
    void fm_set_duty(uint32_t period)
    {
    
      nrf_drv_timer_disable(&timer_inst_freq);
      nrf_drv_timer_extended_compare(&timer_inst_freq,
                                     NRF_TIMER_CC_CHANNEL0,
                                     period,
                                     NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                     false);
      nrf_drv_timer_enable(&timer_inst_freq);
    }

    without any luck.

  • Looks like your array index is out of bounds. (tone_array[1024] is not valid). Try this t5ms_timer_event_handler instead:

    void t5ms_timer_event_handler(nrf_timer_event_t event_type, void *p_context)
    {
        switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE0:
                nrf_gpio_pin_toggle(3);
                fm_set_duty(tone_array[tone_member]);
                //**********tone_member table go up
                if (tone_member < (TONE_TABLE_MEMBERS-1))
                {
                    tone_member++;
                }
                else if (tone_member >= (TONE_TABLE_MEMBERS-1))
                {
                    tone_member = 0;
                    // nrf_drv_timer_disable(&timer_inst_t5ms);
                    // nrf_drv_timer_disable(&timer_inst_freq);
                    // nrf_drv_ppi_channel_disable(m_ppi_channel);
                    // nrf_drv_gpiote_out_task_disable(GPIO_FREQ_OUT);
                }
                //**********tone table go up
    
                //************30 sec ramp from tone table******
                if (timer_5ms_counter >= 6000)
                {
                    nrf_drv_timer_disable(&timer_inst_t5ms);
                    nrf_drv_timer_disable(&timer_inst_freq);
                    nrf_drv_ppi_channel_disable(m_ppi_channel);
                    nrf_drv_gpiote_out_task_disable(GPIO_FREQ_OUT);
                }
                timer_5ms_counter++;
                break;
        }
    }

  • Thanks for pointing on that! Can't believe that I can miss that.

    I tested with correct bounds and if I didn't perform a CLEAR task there are 4ms pauses.


    They are caused by Counter overflow? Also, I noticed that pauses only appear when both timers are triggered at the same time. Why this is so?

    The second test was with the CLEAR task on each 5ms timer trigger. This time there are no 4ms pauses, which is good. But as before we got a little pause on each 5ms tick.



    So now we have 2 situations but none of them suits our needs. Any ideas?

  • 1x000 said:
    I tested with correct bounds and if I didn't perform a CLEAR task there are 4ms pauses.
    1x000 said:
    They are caused by Counter overflow? Also, I noticed that pauses only appear when both timers are triggered at the same time. Why this is so?

    No, not overflow, but nrf_drv_timer_extended_compare() disables the shorts briefly, in order to set the new shorts mask specified in nrf_drv_timer_extended_compare(), so then there is a chance that the CC event triggers at the same time the shorts are disabled, and if that happens, then it's not cleared automatically, so you should therefore trigger the clear task manually.

    1x000 said:
    This time there are no 4ms pauses, which is good. But as before we got a little pause on each 5ms tick.

    Was this with disabling the timer and clearing, or is this with only clearing?

Reply
  • 1x000 said:
    I tested with correct bounds and if I didn't perform a CLEAR task there are 4ms pauses.
    1x000 said:
    They are caused by Counter overflow? Also, I noticed that pauses only appear when both timers are triggered at the same time. Why this is so?

    No, not overflow, but nrf_drv_timer_extended_compare() disables the shorts briefly, in order to set the new shorts mask specified in nrf_drv_timer_extended_compare(), so then there is a chance that the CC event triggers at the same time the shorts are disabled, and if that happens, then it's not cleared automatically, so you should therefore trigger the clear task manually.

    1x000 said:
    This time there are no 4ms pauses, which is good. But as before we got a little pause on each 5ms tick.

    Was this with disabling the timer and clearing, or is this with only clearing?

Children
  • This capture from my previous post was taken with the only CLEAR task.

    I've just tried it with both nrf_drv_timer_disable(&timer_inst_freq) and nrf_drv_timer_clear(&timer_inst_freq)
    Here is the result


    The pauses are still present. But they are getting longer and shorter. On this screen on the left side pauses are about 625μs long (when normal wave must be about 310μs). On the right side, pauses are about 316μs (almost invisible)

  • Hi,

    You could try to simply use nrfx_timer_compare(), and see if that helps with the pauses:

    void fm_set_duty(uint32_t period)
    {
    
    nrfx_timer_compare(&timer_inst_freq,
    NRF_TIMER_CC_CHANNEL0,
    period,
    false);
    }


    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "nrf_drv_timer.h"
    #include "nrf_drv_ppi.h"
    #include "nrf_drv_gpiote.h"
    #include "nrf_gpiote.h"
    #include "nrf_gpio.h"
    #include "app_error.h"
    //#include "nrf_pwr_mgmt.h"
    //#include "tone_array.h"
    
    #define GPIO_FREQ_OUT 4
    static const nrf_drv_timer_t timer_inst_t5ms = NRF_DRV_TIMER_INSTANCE(1); //!don't use TIMER0 with softdevice
    static const nrf_drv_timer_t timer_inst_freq = NRF_DRV_TIMER_INSTANCE(3); //!don't use TIMER0 with softdevice
    static nrf_ppi_channel_t     m_ppi_channel;
    uint16_t tone_member = 1;
    uint32_t timer_5ms_counter = 0;
    
    #define TONE_TABLE_MEMBERS 1024 
    const uint32_t tone_array[1024] = {
    6400, 6398, 6395, 6393, 6390, 6388, 6385, 6383, 6380, 6378, 6375, 6373, 6370, 6368, 6365, 6363,
    6360, 6358, 6356, 6353, 6351, 6348, 6346, 6343, 6341, 6338, 6336, 6333, 6331, 6329, 6326, 6324,
    6321, 6319, 6316, 6314, 6311, 6309, 6307, 6304, 6302, 6299, 6297, 6295, 6292, 6290, 6287, 6285,
    6282, 6280, 6278, 6275, 6273, 6270, 6268, 6266, 6263, 6261, 6258, 6256, 6254, 6251, 6249, 6247,
    6244, 6242, 6239, 6237, 6235, 6232, 6230, 6228, 6225, 6223, 6220, 6218, 6216, 6213, 6211, 6209,
    6206, 6204, 6202, 6199, 6197, 6195, 6192, 6190, 6188, 6185, 6183, 6181, 6178, 6176, 6174, 6171,
    6169, 6167, 6164, 6162, 6160, 6157, 6155, 6153, 6150, 6148, 6146, 6143, 6141, 6139, 6137, 6134,
    6132, 6130, 6127, 6125, 6123, 6121, 6118, 6116, 6114, 6111, 6109, 6107, 6105, 6102, 6100, 6098,
    6095, 6093, 6091, 6089, 6086, 6084, 6082, 6080, 6077, 6075, 6073, 6071, 6068, 6066, 6064, 6062,
    6059, 6057, 6055, 6053, 6050, 6048, 6046, 6044, 6042, 6039, 6037, 6035, 6033, 6030, 6028, 6026,
    6024, 6022, 6019, 6017, 6015, 6013, 6011, 6008, 6006, 6004, 6002, 6000, 5997, 5995, 5993, 5991,
    5989, 5986, 5984, 5982, 5980, 5978, 5975, 5973, 5971, 5969, 5967, 5965, 5962, 5960, 5958, 5956,
    5954, 5952, 5949, 5947, 5945, 5943, 5941, 5939, 5936, 5934, 5932, 5930, 5928, 5926, 5924, 5921,
    5919, 5917, 5915, 5913, 5911, 5909, 5907, 5904, 5902, 5900, 5898, 5896, 5894, 5892, 5890, 5887,
    5885, 5883, 5881, 5879, 5877, 5875, 5873, 5871, 5868, 5866, 5864, 5862, 5860, 5858, 5856, 5854,
    5852, 5850, 5848, 5845, 5843, 5841, 5839, 5837, 5835, 5833, 5831, 5829, 5827, 5825, 5823, 5820,
    5818, 5816, 5814, 5812, 5810, 5808, 5806, 5804, 5802, 5800, 5798, 5796, 5794, 5792, 5790, 5788,
    5786, 5784, 5781, 5779, 5777, 5775, 5773, 5771, 5769, 5767, 5765, 5763, 5761, 5759, 5757, 5755,
    5753, 5751, 5749, 5747, 5745, 5743, 5741, 5739, 5737, 5735, 5733, 5731, 5729, 5727, 5725, 5723,
    5721, 5719, 5717, 5715, 5713, 5711, 5709, 5707, 5705, 5703, 5701, 5699, 5697, 5695, 5693, 5691,
    5689, 5687, 5685, 5683, 5681, 5679, 5677, 5675, 5673, 5671, 5669, 5667, 5666, 5664, 5662, 5660,
    5658, 5656, 5654, 5652, 5650, 5648, 5646, 5644, 5642, 5640, 5638, 5636, 5634, 5632, 5630, 5629,
    5627, 5625, 5623, 5621, 5619, 5617, 5615, 5613, 5611, 5609, 5607, 5605, 5604, 5602, 5600, 5598,
    5596, 5594, 5592, 5590, 5588, 5586, 5584, 5583, 5581, 5579, 5577, 5575, 5573, 5571, 5569, 5567,
    5565, 5564, 5562, 5560, 5558, 5556, 5554, 5552, 5550, 5549, 5547, 5545, 5543, 5541, 5539, 5537,
    5535, 5534, 5532, 5530, 5528, 5526, 5524, 5522, 5520, 5519, 5517, 5515, 5513, 5511, 5509, 5507,
    5506, 5504, 5502, 5500, 5498, 5496, 5495, 5493, 5491, 5489, 5487, 5485, 5484, 5482, 5480, 5478,
    5476, 5474, 5473, 5471, 5469, 5467, 5465, 5463, 5462, 5460, 5458, 5456, 5454, 5452, 5451, 5449,
    5447, 5445, 5443, 5442, 5440, 5438, 5436, 5434, 5433, 5431, 5429, 5427, 5425, 5424, 5422, 5420,
    5418, 5416, 5415, 5413, 5411, 5409, 5408, 5406, 5404, 5402, 5400, 5399, 5397, 5395, 5393, 5391,
    5390, 5388, 5386, 5384, 5383, 5381, 5379, 5377, 5376, 5374, 5372, 5370, 5369, 5367, 5365, 5363,
    5362, 5360, 5358, 5356, 5354, 5353, 5351, 5349, 5348, 5346, 5344, 5342, 5341, 5339, 5337, 5335,
    5334, 5332, 5330, 5328, 5327, 5325, 5323, 5321, 5320, 5318, 5316, 5315, 5313, 5311, 5309, 5308,
    5306, 5304, 5302, 5301, 5299, 5297, 5296, 5294, 5292, 5290, 5289, 5287, 5285, 5284, 5282, 5280,
    5278, 5277, 5275, 5273, 5272, 5270, 5268, 5267, 5265, 5263, 5262, 5260, 5258, 5256, 5255, 5253,
    5251, 5250, 5248, 5246, 5245, 5243, 5241, 5240, 5238, 5236, 5235, 5233, 5231, 5230, 5228, 5226,
    5225, 5223, 5221, 5220, 5218, 5216, 5215, 5213, 5211, 5210, 5208, 5206, 5205, 5203, 5201, 5200,
    5198, 5196, 5195, 5193, 5191, 5190, 5188, 5186, 5185, 5183, 5181, 5180, 5178, 5177, 5175, 5173,
    5172, 5170, 5168, 5167, 5165, 5163, 5162, 5160, 5159, 5157, 5155, 5154, 5152, 5150, 5149, 5147,
    5146, 5144, 5142, 5141, 5139, 5138, 5136, 5134, 5133, 5131, 5129, 5128, 5126, 5125, 5123, 5121,
    5120, 5118, 5117, 5115, 5113, 5112, 5110, 5109, 5107, 5105, 5104, 5102, 5101, 5099, 5098, 5096,
    5094, 5093, 5091, 5090, 5088, 5086, 5085, 5083, 5082, 5080, 5079, 5077, 5075, 5074, 5072, 5071,
    5069, 5067, 5066, 5064, 5063, 5061, 5060, 5058, 5057, 5055, 5053, 5052, 5050, 5049, 5047, 5046,
    5044, 5042, 5041, 5039, 5038, 5036, 5035, 5033, 5032, 5030, 5029, 5027, 5025, 5024, 5022, 5021,
    5019, 5018, 5016, 5015, 5013, 5012, 5010, 5009, 5007, 5005, 5004, 5002, 5001, 4999, 4998, 4996,
    4995, 4993, 4992, 4990, 4989, 4987, 4986, 4984, 4983, 4981, 4980, 4978, 4977, 4975, 4973, 4972,
    4970, 4969, 4967, 4966, 4964, 4963, 4961, 4960, 4958, 4957, 4955, 4954, 4952, 4951, 4949, 4948,
    4946, 4945, 4943, 4942, 4940, 4939, 4937, 4936, 4934, 4933, 4931, 4930, 4929, 4927, 4926, 4924,
    4923, 4921, 4920, 4918, 4917, 4915, 4914, 4912, 4911, 4909, 4908, 4906, 4905, 4903, 4902, 4900,
    4899, 4898, 4896, 4895, 4893, 4892, 4890, 4889, 4887, 4886, 4884, 4883, 4881, 4880, 4879, 4877,
    4876, 4874, 4873, 4871, 4870, 4868, 4867, 4865, 4864, 4863, 4861, 4860, 4858, 4857, 4855, 4854,
    4852, 4851, 4850, 4848, 4847, 4845, 4844, 4842, 4841, 4840, 4838, 4837, 4835, 4834, 4832, 4831,
    4830, 4828, 4827, 4825, 4824, 4822, 4821, 4820, 4818, 4817, 4815, 4814, 4812, 4811, 4810, 4808,
    4807, 4805, 4804, 4803, 4801, 4800, 4798, 4797, 4796, 4794, 4793, 4791, 4790, 4789, 4787, 4786,
    4784, 4783, 4782, 4780, 4779, 4777, 4776, 4775, 4773, 4772, 4770, 4769, 4768, 4766, 4765, 4763,
    4762, 4761, 4759, 4758, 4757, 4755, 4754, 4752, 4751, 4750, 4748, 4747, 4745, 4744, 4743, 4741,
    4740, 4739, 4737, 4736, 4734, 4733, 4732, 4730, 4729, 4728, 4726, 4725, 4724, 4722, 4721, 4719,
    4718, 4717, 4715, 4714, 4713, 4711, 4710, 4709, 4707, 4706, 4705, 4703, 4702, 4700, 4699, 4698,
    4696, 4695, 4694, 4692, 4691, 4690, 4688, 4687, 4686, 4684, 4683, 4682, 4680, 4679, 4678, 4676,
    4675, 4674, 4672, 4671, 4670, 4668, 4667, 4666, 4664, 4663, 4662, 4660, 4659, 4658, 4656, 4655,
    4654, 4652, 4651, 4650, 4648, 4647, 4646, 4644, 4643, 4642, 4640, 4639, 4638, 4636, 4635, 4634,
    4633, 4631, 4630, 4629, 4627, 4626, 4625, 4623, 4622, 4621, 4619, 4618, 4617, 4616, 4614, 4613,
    4612, 4610, 4609, 4608, 4606, 4605, 4604, 4603, 4601, 4600, 4599, 4597, 4596, 4595, 4594, 4592,
    4591, 4590, 4588, 4587, 4586, 4584, 4583, 4582, 4581, 4579, 4578, 4577, 4576, 4574, 4573, 4572
    };
    
    
    void fm_set_duty(uint32_t period)
    {
    
      nrfx_timer_compare(&timer_inst_freq,
                         NRF_TIMER_CC_CHANNEL0,
                         period,
                        false);
    }
    
    
    /**
     * @brief Handler for timer events.
     */
    void t5ms_timer_event_handler(nrf_timer_event_t event_type, void *p_context)
    {
        switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE0:
                nrf_gpio_pin_toggle(3);
                fm_set_duty(tone_array[tone_member]);
                //**********tone_member table go up
                if (tone_member < (TONE_TABLE_MEMBERS-1))
                {
                    tone_member++;
                }
                else if (tone_member >= (TONE_TABLE_MEMBERS-1))
                {
                    tone_member = 0;
                    // nrf_drv_timer_disable(&timer_inst_t5ms);
                    // nrf_drv_timer_disable(&timer_inst_freq);
                    // nrf_drv_ppi_channel_disable(m_ppi_channel);
                    // nrf_drv_gpiote_out_task_disable(GPIO_FREQ_OUT);
                }
                //**********tone table go up
    
                //************30 sec ramp from tone table******
                if (timer_5ms_counter >= 6000)
                {
                    nrf_drv_timer_disable(&timer_inst_t5ms);
                    nrf_drv_timer_disable(&timer_inst_freq);
                    nrf_drv_ppi_channel_disable(m_ppi_channel);
                    nrf_drv_gpiote_out_task_disable(GPIO_FREQ_OUT);
                }
                timer_5ms_counter++;
                break;
        }
    }
    
    
    void freq_timer_event_handler(nrf_timer_event_t event_type, void *p_context)
    {
    }
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        uint32_t time_ticks;
        uint32_t err_code = NRF_SUCCESS;
    
        err_code = nrf_drv_ppi_init();
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    
        //>>>GPIOTE init
        nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
    
        err_code = nrf_drv_gpiote_out_init(GPIO_FREQ_OUT, &config);
        APP_ERROR_CHECK(err_code);
        //<<<GPIOTE init
    
        ////>>>TIMER init
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16;
    
        err_code = nrf_drv_timer_init(&timer_inst_freq, &timer_cfg, freq_timer_event_handler);
        APP_ERROR_CHECK(err_code);
    
        //nrf_drv_timer_extended_compare(&timer_inst_freq,
        //                               NRF_TIMER_CC_CHANNEL0,
        //                               tone_array[0],
        //                               NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
        //                               false);
       // fm_set_duty(tone_array[0]); // MOVED
        ////<<<<TIMER init
    
        //>>>PPI init
        err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
        APP_ERROR_CHECK(err_code);
    
        uint32_t compare_evt_addr;
        uint32_t gpiote_task_addr;
        compare_evt_addr = nrf_drv_timer_event_address_get(&timer_inst_freq, NRF_TIMER_EVENT_COMPARE0);
        gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_FREQ_OUT);
    
        err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, compare_evt_addr, gpiote_task_addr);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_out_task_enable(GPIO_FREQ_OUT);
        //<<<PPI init
    
        ////>>>TIMER init
        timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    
        err_code = nrf_drv_timer_init(&timer_inst_t5ms,
                                      &timer_cfg,
                                      t5ms_timer_event_handler);
        APP_ERROR_CHECK(err_code);
    
        time_ticks = nrf_drv_timer_ms_to_ticks(&timer_inst_t5ms, 5);
    
        nrf_drv_timer_extended_compare(&timer_inst_t5ms,
                                       NRF_TIMER_CC_CHANNEL0,
                                       time_ticks,
                                       NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                       true);
    
        nrf_drv_timer_enable(&timer_inst_t5ms);
        ////<<<<TIMER init
    
        
    
         //fm_set_duty(tone_array[tone_member]);
         tone_member++;
    
        //>>>GPIO init
        nrf_gpio_cfg_output(3);
         
           nrf_drv_timer_disable(&timer_inst_freq);
      nrf_drv_timer_clear(&timer_inst_freq);
        nrf_drv_timer_extended_compare(&timer_inst_freq,
                                     NRF_TIMER_CC_CHANNEL0,
                                     tone_array[tone_member],
                                     NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                     false);
    
        nrf_drv_timer_enable(&timer_inst_freq);
       
    
        //<<<GPIO init
    
        while (1)
        {
            __WFI();
        }
    }

Related