1 /*
2  * FreeRTOS Kernel V11.1.0
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * https://www.FreeRTOS.org
25  * https://github.com/FreeRTOS
26  *
27  */
28 
29 /*
30 Changes from V3.0.0
31     + ISRcode is pulled inline and portTICKisr() is therefore
32       deleted from this file.
33 
34     + Prescaler logic for Timer1 added to allow for a wider
35       range of TickRates.
36 
37 Changes from V3.0.1
38 */
39 
40 #include <FreeRTOS.h>
41 #include <task.h>
42 
43 /* IO port constants. */
44 #define portBIT_SET     (1)
45 #define portBIT_CLEAR   (0)
46 
47 /*
48  * Hardware setup for the tick.
49  * We use a compare match on timer1. Depending on MPU-frequency
50  * and requested tickrate, a prescaled value with a matching
51  * prescaler are determined.
52  */
53 #define portTIMER_COMPARE_BASE          ((APROCFREQ/4)/configTICK_RATE_HZ)
54 
55 #if portTIMER_COMPARE_BASE   < 0x10000
56     #define portTIMER_COMPARE_VALUE     (portTIMER_COMPARE_BASE)
57     #define portTIMER_COMPARE_PS1       (portBIT_CLEAR)
58     #define portTIMER_COMPARE_PS0       (portBIT_CLEAR)
59 #elif portTIMER_COMPARE_BASE < 0x20000
60     #define portTIMER_COMPARE_VALUE     (portTIMER_COMPARE_BASE / 2)
61     #define portTIMER_COMPARE_PS1       (portBIT_CLEAR)
62     #define portTIMER_COMPARE_PS0       (portBIT_SET)
63 #elif portTIMER_COMPARE_BASE < 0x40000
64     #define portTIMER_COMPARE_VALUE     (portTIMER_COMPARE_BASE / 4)
65     #define portTIMER_COMPARE_PS1       (portBIT_SET)
66     #define portTIMER_COMPARE_PS0       (portBIT_CLEAR)
67 #elif portTIMER_COMPARE_BASE < 0x80000
68     #define portTIMER_COMPARE_VALUE     (portTIMER_COMPARE_BASE / 8)
69     #define portTIMER_COMPARE_PS1       (portBIT_SET)
70     #define portTIMER_COMPARE_PS0       (portBIT_SET)
71 #else
72     #error "TickRate out of range"
73 #endif
74 
75 /*-----------------------------------------------------------*/
76 
77 /*
78  * Setup a timer for a regular tick.
79  */
portSetupTick(void)80 void portSetupTick( void )
81 {
82     /*
83      * Interrupts are disabled when this function is called.
84      */
85 
86     /*
87      * Setup CCP1
88      * Provide the tick interrupt using a compare match on timer1.
89      */
90 
91     /*
92      * Set the compare match value.
93      */
94     CCPR1H = ( uint8_t ) ( ( portTIMER_COMPARE_VALUE >> 8 ) & 0xff );
95     CCPR1L = ( uint8_t )   ( portTIMER_COMPARE_VALUE & 0xff );
96 
97     /*
98      * Set Compare Special Event Trigger Mode
99      */
100     bCCP1M3     = portBIT_SET;
101     bCCP1M2     = portBIT_CLEAR;
102     bCCP1M1     = portBIT_SET;
103     bCCP1M0     = portBIT_SET;
104 
105     /*
106      * Enable CCP1 interrupt
107      */
108     bCCP1IE     = portBIT_SET;
109 
110     /*
111      * We are only going to use the global interrupt bit, so disable
112      * interruptpriorities and enable peripheral interrupts.
113      */
114     bIPEN       = portBIT_CLEAR;
115     bPEIE       = portBIT_SET;
116 
117     /*
118      * Set up timer1
119      * It will produce the system tick.
120      */
121 
122     /*
123      * Clear the time count
124      */
125     TMR1H = ( uint8_t ) 0x00;
126     TMR1L = ( uint8_t ) 0x00;
127 
128     /*
129      * Setup the timer
130      */
131     bRD16       = portBIT_SET;              // 16-bit
132     bT1CKPS1    = portTIMER_COMPARE_PS1;    // prescaler
133     bT1CKPS0    = portTIMER_COMPARE_PS0;    // prescaler
134     bT1OSCEN    = portBIT_SET;              // Oscillator enable
135     bT1SYNC     = portBIT_SET;              // No external clock sync
136     bTMR1CS     = portBIT_CLEAR;            // Internal clock
137 
138     bTMR1ON     = portBIT_SET;              // Start timer1
139 }
140