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?

  • Hi,

    1) how does your function freq_timer_event_handler() look like? I tried building your code, but this function was missing.

    2) 

    (from 1250 kHz to 1750 kHz)

    Is this correct? or is it actually from 1.250 kHz to 1.750 kHz ?

  • Thank you for reviewing this issue.  This is a simple operation of a timer.  It has a 16 MHz input and we give it a CC value to divide the frequency by a fixed number.  For example, if we wanted to generate a 1,250 Hz signal, we would divide the 16 MHz by 3200h (12,800 decimal) to get that frequency.  Then every 5.0 mS we may want to get a different frequency, so we will update the CC value to give us the next frequency that we want.  

    You are correct in that we are generating frequencies in the 1,000 Hz to 2,000 Hz range.  The current program is trying to generate frequencies in the 1,250 Hz to 1,750 Hz range.  The original post has a typo in the frequency requirements.  

    This is much more simple that what the Nordic Thingy:52 does to generate audio tones to the speaker with the demo software.  We just want to update the timer every 5.0 mS and get a new frequency without interruption or alteration of the signal.  The frequencies that we want are just 50% duty cycle square waves in that frequency range.  We have had success in doing this on several microcontroller products, including another ARM Cortex M4.  

    The specifics of the freq_timer_event_handler will have to be addressed by the software engineer.  Once again, thank you for your help.  

Reply
  • Thank you for reviewing this issue.  This is a simple operation of a timer.  It has a 16 MHz input and we give it a CC value to divide the frequency by a fixed number.  For example, if we wanted to generate a 1,250 Hz signal, we would divide the 16 MHz by 3200h (12,800 decimal) to get that frequency.  Then every 5.0 mS we may want to get a different frequency, so we will update the CC value to give us the next frequency that we want.  

    You are correct in that we are generating frequencies in the 1,000 Hz to 2,000 Hz range.  The current program is trying to generate frequencies in the 1,250 Hz to 1,750 Hz range.  The original post has a typo in the frequency requirements.  

    This is much more simple that what the Nordic Thingy:52 does to generate audio tones to the speaker with the demo software.  We just want to update the timer every 5.0 mS and get a new frequency without interruption or alteration of the signal.  The frequencies that we want are just 50% duty cycle square waves in that frequency range.  We have had success in doing this on several microcontroller products, including another ARM Cortex M4.  

    The specifics of the freq_timer_event_handler will have to be addressed by the software engineer.  Once again, thank you for your help.  

Children
  • Sorry for the typo in frequency. 
    My freq_timer_event_handler() is just empty. As In some examples on SDK. 


    void freq_timer_event_handler(nrf_timer_event_t event_type, void *p_context)
    {
    }

  • 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?

Related