Hello DevZone,
Is there a way for hardware to update the timer capture register?
I want to create different frequencies using a single timer. Next to the timer, Bluetooth is active.
Example, (values are random and not the values I actually need)
CC0 = 20
CC1 = 40,
CC2 = 125,
CC3 = 189,
CC4 = 323,
CC5 = 6104700 (least common multiple)
I have a short set that on compare 5 the timer will reset.
I have set interrupt enable for every capture register and in the interrupt handler I manually increment every capture register with the value I loaded initially.
The thing is that I do not want to handle this using software, using more timers is not really an option since the frequencies I need to generate will certainly require more timers than there are timers present in the nRF52832.
I've added my code, it might be useful to show what I mean.
Kind regards,
T IJ
/********************************************************************* * SEGGER Microcontroller GmbH * * The Embedded Experts * ********************************************************************** * * * (c) 2014 - 2020 SEGGER Microcontroller GmbH * * * * www.segger.com Support: [email protected] * * * ********************************************************************** * * * All rights reserved. * * * * Redistribution and use in source and binary forms, with or * * without modification, are permitted provided that the following * * conditions are met: * * * * - Redistributions of source code must retain the above copyright * * notice, this list of conditions and the following disclaimer. * * * * - Neither the name of SEGGER Microcontroller GmbH * * nor the names of its contributors may be used to endorse or * * promote products derived from this software without specific * * prior written permission. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * DISCLAIMED. * * IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * DAMAGE. * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- File : main.c Purpose : Generic application start */ #include "nrf.h" #include <stdio.h> #include <stdlib.h> #define CC1 2000U #define CC2 4000U #define CC3 12500U #define CC4 18900U #define CC5 32300U #define CC6 610470000UL #define TIMER3_HANDLER TIMER3_IRQHandler void TIMER3_HANDLER(void) { static uint8_t a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0; if (NRF_TIMER3->EVENTS_COMPARE[0] == 1) { NRF_TIMER3->CC[0] += CC1; NRF_TIMER3->EVENTS_COMPARE[0] = 0; } if (NRF_TIMER3->EVENTS_COMPARE[1] == 1) { NRF_TIMER3->CC[1] += CC2; a2++; if (a2 == 2) a2 = 0; switch (a2) { case 0: NRF_P0->OUTCLR = 1 << 17; break; case 1: NRF_P0->OUTSET = 1 << 17; break; default: break; } NRF_TIMER3->EVENTS_COMPARE[1] = 0; } if (NRF_TIMER3->EVENTS_COMPARE[2] == 1) { NRF_TIMER3->CC[2] += CC3; a3++; if (a3 == 2) a3 = 0; switch (a3) { case 0: NRF_P0->OUTCLR = 1 << 18; break; case 1: NRF_P0->OUTSET = 1 << 18; break; default: break; } NRF_TIMER3->EVENTS_COMPARE[2] = 0; } if (NRF_TIMER3->EVENTS_COMPARE[3] == 1) { NRF_TIMER3->CC[3] += CC4; a4++; if (a4 == 2) a4 = 0; switch (a4) { case 0: NRF_P0->OUTCLR = 1 << 19; break; case 1: NRF_P0->OUTSET = 1 << 19; break; default: break; } NRF_TIMER3->EVENTS_COMPARE[3] = 0; } if (NRF_TIMER3->EVENTS_COMPARE[4] == 1) { NRF_TIMER3->CC[4] += CC5; a5++; if (a5 == 2) a5 = 0; switch (a5) { case 0: NRF_P0->OUTCLR = 1 << 20; break; case 1: NRF_P0->OUTSET = 1 << 20; break; default: break; } NRF_TIMER3->EVENTS_COMPARE[4] = 0; } if (NRF_TIMER3->EVENTS_COMPARE[5] == 1) { NRF_TIMER3->CC[0] = CC1; NRF_TIMER3->CC[1] = CC2; NRF_TIMER3->CC[2] = CC3; NRF_TIMER3->CC[3] = CC4; NRF_TIMER3->CC[4] = CC5; NRF_TIMER3->EVENTS_COMPARE[5] = 0; } } /** * @brief Function for application main entry. */ int main(void) { NRF_P0->DIRSET = (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20); NRF_P0->OUT = (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20); NRF_TIMER3->TASKS_CLEAR = 1; NRF_TIMER3->MODE = TIMER_MODE_MODE_Timer; NRF_TIMER3->BITMODE = TIMER_BITMODE_BITMODE_32Bit; NRF_TIMER3->PRESCALER = 9; NRF_TIMER3->CC[0] = CC1; NRF_TIMER3->CC[1] = CC2; NRF_TIMER3->CC[2] = CC3; NRF_TIMER3->CC[3] = CC4; NRF_TIMER3->CC[4] = CC5; NRF_TIMER3->CC[5] = CC6; NRF_TIMER3->INTENSET = (1 << 16) | (1 << 17) | (1 << 18) | (1 << 20) | (1 << 21); NRF_TIMER3->SHORTS = TIMER_SHORTS_COMPARE5_CLEAR_Msk; NVIC_SetPriority(TIMER3_IRQn, 2); NVIC_EnableIRQ(TIMER3_IRQn); NRF_TIMER3->TASKS_START = 1; while (1) { __WFI(); // Do nothing. } } /*************************** End of file ****************************/