<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.ocetechnology.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=OCEOS%2Foceos_timed_actions%2Foceos_port_external_timer</id>
	<title>OCEOS/oceos timed actions/oceos port external timer - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.ocetechnology.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=OCEOS%2Foceos_timed_actions%2Foceos_port_external_timer"/>
	<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_timed_actions/oceos_port_external_timer&amp;action=history"/>
	<updated>2026-10-22T03:14:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_timed_actions/oceos_port_external_timer&amp;diff=1275&amp;oldid=prev</id>
		<title>Okhoruzhyy: Created page with &quot;&lt;syntaxhighlight lang=&quot;C&quot;&gt; /*  * ARM Cortex-M7 SAMV71Q21 Timer Example.  * oceos_port_external_timer.c  *  *  Created on: 24 march 2022  *  Author: Alex  *    */ #include &lt;std...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=OCEOS/oceos_timed_actions/oceos_port_external_timer&amp;diff=1275&amp;oldid=prev"/>
		<updated>2022-03-24T16:35:52Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;* ARM Cortex-M7 SAMV71Q21 Timer Example.  * oceos_port_external_timer.c  *  *  Created on: 24 march 2022  *  Author: Alex  *: &lt;/span&gt; #include &amp;lt;std...&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * ARM Cortex-M7 SAMV71Q21 Timer Example.&lt;br /&gt;
 * oceos_port_external_timer.c&lt;br /&gt;
 *&lt;br /&gt;
 *  Created on: 24 march 2022&lt;br /&gt;
 *  Author: Alex&lt;br /&gt;
 *  &lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;stddef.h&amp;gt;&lt;br /&gt;
#include &amp;quot;sam.h&amp;quot;&lt;br /&gt;
#include &amp;quot;oceos.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define EXTERNAL_TIMER_INDEX       0&lt;br /&gt;
#define EXTERNAL_TIMER_PRIORITY    1&lt;br /&gt;
#define EXTERNAL_TIMER_COUNER_MSK  0xFFFF&lt;br /&gt;
#define ENABLE_WAVE_MODE           (0x1 &amp;lt;&amp;lt; TC_CMR_WAVE_Pos)&lt;br /&gt;
#define TC_CMR_WAVE_SEL_Pos        13&lt;br /&gt;
#define SET_WAVE_SELECT            (~(0x3 &amp;lt;&amp;lt; TC_CMR_WAVE_SEL_Pos)) //00&lt;br /&gt;
#define TC_CMR_CPCSTOP_Pos         6&lt;br /&gt;
#define TC_CMR_CPCSTOP             (0x1 &amp;lt;&amp;lt; TC_CMR_CPCSTOP_Pos)&lt;br /&gt;
&lt;br /&gt;
extern const unsigned int __oceos_bsp_sysfreq;&lt;br /&gt;
static Tc *timer_regs;&lt;br /&gt;
static TcChannel *tc;&lt;br /&gt;
/**&lt;br /&gt;
 * Used in OCEOS internally, max counter value in microseconds&lt;br /&gt;
 */&lt;br /&gt;
extern unsigned int OCEOS_MAX_TIMER_COUNTER_VALUE;&lt;br /&gt;
&lt;br /&gt;
volatile float base_scaler = 0.0f;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * User has to implement this function to initialize external timer&lt;br /&gt;
 * to be used with timed actions,semaphores and data qs.&lt;br /&gt;
 */&lt;br /&gt;
enum DIRECTIVE_STATUS oceos_external_timer_init() {&lt;br /&gt;
&lt;br /&gt;
  // Remove write protect from PMC&lt;br /&gt;
  U32_t pmc_was_enabled = 0U;&lt;br /&gt;
  if (0 != (PMC-&amp;gt;PMC_WPMR &amp;amp; PMC_WPMR_WPEN)) {&lt;br /&gt;
       PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
       pmc_was_enabled = 1U;&lt;br /&gt;
  }&lt;br /&gt;
  // Enable Clock&lt;br /&gt;
  PMC-&amp;gt;PMC_PCER0 |= PMC_PCER0_PID23;&lt;br /&gt;
&lt;br /&gt;
  // Enable write protect&lt;br /&gt;
  if (1U == pmc_was_enabled) {&lt;br /&gt;
    PMC-&amp;gt;PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  timer_regs = (Tc *)TC0;&lt;br /&gt;
  tc = &amp;amp;(timer_regs-&amp;gt;TC_CHANNEL[EXTERNAL_TIMER_INDEX]);&lt;br /&gt;
&lt;br /&gt;
  // Remove Timer Unit protection&lt;br /&gt;
  U32_t tc_was_protected = 0U;&lt;br /&gt;
  if (0U != (timer_regs-&amp;gt;TC_WPMR &amp;amp; TC_WPMR_WPEN)) {&lt;br /&gt;
      timer_regs-&amp;gt;TC_WPMR = TC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
      tc_was_protected = 1U;&lt;br /&gt;
  }&lt;br /&gt;
  // Enable Wave Mode&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= ENABLE_WAVE_MODE;&lt;br /&gt;
  // Set WAVESEL to 00&lt;br /&gt;
  tc-&amp;gt;TC_CMR &amp;amp;= (U32_t)SET_WAVE_SELECT;&lt;br /&gt;
  // Set TC_CMR_CPCSTOP and Clock input&lt;br /&gt;
  tc-&amp;gt;TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK2_Val); // MCK/8&lt;br /&gt;
&lt;br /&gt;
  // Set Block Clock&lt;br /&gt;
  timer_regs-&amp;gt;TC_BMR &amp;amp;= (U32_t)(~(1 &amp;lt;&amp;lt; EXTERNAL_TIMER_INDEX));&lt;br /&gt;
&lt;br /&gt;
  // Enable Timer interrupt (RC Compare)&lt;br /&gt;
  tc-&amp;gt;TC_IER = TC_IER_CPCS;&lt;br /&gt;
&lt;br /&gt;
  // Enable Timer Interrupt in NVIC&lt;br /&gt;
  NVIC_EnableIRQ(TC0_IRQn);&lt;br /&gt;
&lt;br /&gt;
  // Set Priority for interrupt number, should not be zero as this is the highest priority&lt;br /&gt;
  // and used by SysTick to update time counter&lt;br /&gt;
  NVIC_SetPriority(TC0_IRQn, EXTERNAL_TIMER_PRIORITY);&lt;br /&gt;
&lt;br /&gt;
  //TC_CMR_TCCLKS_TIMER_CLOCK1 =&amp;gt; MCK / 8&lt;br /&gt;
  base_scaler        = (float)(__oceos_bsp_sysfreq / 8.0f) / 1000000.0f;&lt;br /&gt;
&lt;br /&gt;
  // Calculate max reload time in ns&lt;br /&gt;
  // Used in OCEOS internally&lt;br /&gt;
  OCEOS_MAX_TIMER_COUNTER_VALUE = EXTERNAL_TIMER_COUNER_MSK / base_scaler;&lt;br /&gt;
&lt;br /&gt;
   // Enable clock&lt;br /&gt;
   tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
&lt;br /&gt;
   // Re-enable Timer Protection if was protected&lt;br /&gt;
   if (1U == tc_was_protected) {&lt;br /&gt;
       timer_regs-&amp;gt;TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 return SUCCESSFUL;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User has to implement this function to start external timer&lt;br /&gt;
 * to be used with timed actions,semaphores and data qs.&lt;br /&gt;
 */&lt;br /&gt;
enum DIRECTIVE_STATUS oceos_external_timer_start(U32_t act_time) {&lt;br /&gt;
  if (NULL == timer_regs || NULL == tc) {&lt;br /&gt;
      oceos_log_add_entry(LOG_TIMED_ACTION_NOT_INIT, 0x1);&lt;br /&gt;
      return NOT_CONFIGURED;&lt;br /&gt;
  }&lt;br /&gt;
  // Remove protection&lt;br /&gt;
  U32_t tc_was_protected = 0U;&lt;br /&gt;
  if (0 != (timer_regs-&amp;gt;TC_WPMR &amp;amp; TC_WPMR_WPEN)) {&lt;br /&gt;
     timer_regs-&amp;gt;TC_WPMR = TC_WPMR_WPKEY_PASSWD;&lt;br /&gt;
     tc_was_protected = 1U;&lt;br /&gt;
  }&lt;br /&gt;
  // Set Register C for compare&lt;br /&gt;
  tc-&amp;gt;TC_RC  = base_scaler * act_time;&lt;br /&gt;
&lt;br /&gt;
  // Enable Protection&lt;br /&gt;
  if (1U == tc_was_protected) {&lt;br /&gt;
      timer_regs-&amp;gt;TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Enable clock&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_CLKEN;&lt;br /&gt;
  if (0 == (tc-&amp;gt;TC_SR &amp;amp; TC_SR_CLKSTA)) {// check if set&lt;br /&gt;
       oceos_log_add_entry(LOG_TIMED_ACTION_NOT_INIT, 0x2);&lt;br /&gt;
       return NOT_CONFIGURED;&lt;br /&gt;
  }&lt;br /&gt;
  // Start clock&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_SWTRG;&lt;br /&gt;
  return SUCCESSFUL;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * User has to implement this function to stop external timer&lt;br /&gt;
 * to be used with timed actions,semaphores and data qs.&lt;br /&gt;
 */&lt;br /&gt;
enum DIRECTIVE_STATUS oceos_external_timer_stop() {&lt;br /&gt;
  if (NULL == tc) {&lt;br /&gt;
      oceos_log_add_entry(LOG_TIMED_ACTION_NOT_INIT, 0x1);&lt;br /&gt;
      return NOT_CONFIGURED;&lt;br /&gt;
  }&lt;br /&gt;
  tc-&amp;gt;TC_CCR = TC_CCR_CLKDIS;&lt;br /&gt;
  if (0 != (tc-&amp;gt;TC_SR &amp;amp; TC_SR_CLKSTA)) {&lt;br /&gt;
      oceos_log_add_entry(LOG_TIMED_ACTION_TIMER_STOP_FAIL, 0x2);&lt;br /&gt;
      return FAILED_TO_SET_REGISTER;&lt;br /&gt;
  }&lt;br /&gt;
  return SUCCESSFUL;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * IRQ handler for timed action timer.&lt;br /&gt;
 * This function label should be present in Vector table&lt;br /&gt;
 */&lt;br /&gt;
void oceos_TC0_IRQHandler() {&lt;br /&gt;
  // Clear timer interrupt Pending bit in register&lt;br /&gt;
  tc-&amp;gt;TC_SR;&lt;br /&gt;
&lt;br /&gt;
  // Call Timed action&lt;br /&gt;
  __oceos_timed_action_do();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Okhoruzhyy</name></author>
	</entry>
</feed>