ATtiny85 Template Code
Code snippets for the ATtiny85
 All Files Functions Variables Typedefs Enumerations Enumerator Macros
systicks.c
Go to the documentation of this file.
1 /*--------------------------------------------------------------------------*
2 * System ticks implementation
3 *---------------------------------------------------------------------------*
4 * 14-May-2014 ShaneG
5 *
6 * Provide a system tick reference to measuring longer periods of time.
7 *--------------------------------------------------------------------------*/
8 #include <avr/io.h>
9 #include <avr/interrupt.h>
10 #include "../hardware.h"
11 #include "systicks.h"
12 #include "iohelp.h"
13 
14 // Maximum number of software PWM outputs
15 #define SPWM_MAX 4
16 
17 // Number of 'ticklets' per tick
18 #define TICKLETS 64
19 
20 // If software PWM is enabled, we get systick as well
21 #ifdef SOFTPWM_ENABLED
22 # define SYSTICK_ENABLED
23  // Make sure we don't have too many outputs
24 # if SPWM_COUNT > SPWM_MAX
25 # error "You have defined too many software PWM outputs"
26 # endif
27 #endif
28 
29 //---------------------------------------------------------------------------
30 // System ticks implementation
31 //---------------------------------------------------------------------------
32 
33 // Only include if enabled
34 #ifdef SYSTICK_ENABLED
35 
37 static volatile uint16_t g_systicks = 0;
38 
40 static volatile uint8_t g_ticklet = 0;
41 
54 void ticksInit() {
55  // Stop timer and clear prescaler
56  TCCR1 = 0;
57  TCNT1 = 0;
58  GTCCR &= 0x81;
59  GTCCR |= (1 << PSR1);
60  // Set up the prescaler and enable overflow interrupt
61  TCCR1 = (1 << CS12); // Divide by 8
62  TIMSK |= (1 << TOIE1);
63  }
64 
70 uint16_t ticks() {
71  return g_systicks;
72  }
73 
84 uint16_t ticksElapsed(uint16_t reference) {
85  uint16_t now = g_systicks;
86  if(now<reference)
87  return now + (65535 - reference);
88  return now - reference;
89  }
90 
91 #endif /* SYSTICK_ENABLED */
92 
93 //---------------------------------------------------------------------------
94 // Software PWM implementation
95 //---------------------------------------------------------------------------
96 
97 #ifdef SOFTPWM_ENABLED
98 
100 static uint8_t g_pwmout[SPWM_COUNT];
101 
107 void spwmInit() {
108  // Set everything to zero for a start
109  for(uint8_t index=0; index<SPWM_COUNT; index++)
110  g_pwmout[index] = 0;
111  // Make sure all the pins are set as outputs
112 #if SPWM_COUNT >= 1
113  DDRB |= (1 << SPWM_PIN0);
114  PORTB &= ~(1 << SPWM_PIN0);
115 #endif
116 #if SPWM_COUNT >= 2
117  DDRB |= (1 << SPWM_PIN1);
118  PORTB &= ~(1 << SPWM_PIN1);
119 #endif
120 #if SPWM_COUNT >= 3
121  DDRB |= (1 << SPWM_PIN2);
122  PORTB &= ~(1 << SPWM_PIN2);
123 #endif
124 #if SPWM_COUNT >= 4
125  DDRB |= (1 << SPWM_PIN3);
126  PORTB &= ~(1 << SPWM_PIN3);
127 #endif
128  // Make sure ticksInit() gets called to set up the timer
129  ticksInit();
130  }
131 
140 void spwmOut(SPWM pwm, uint8_t value) {
141  if(pwm<SPWM_COUNT)
142  g_pwmout[pwm] = value;
143  }
144 
153 uint8_t spwmValue(SPWM pwm) {
154  if(pwm<SPWM_COUNT)
155  return g_pwmout[pwm];
156  // Invalid pin
157  return 0;
158  }
159 
160 #endif /* SOFTPWM_ENABLED */
161 
162 //---------------------------------------------------------------------------
163 // Shared interrupt handler
164 //---------------------------------------------------------------------------
165 
166 #if defined(SOFTPWM_ENABLED) || defined(SYSTICK_ENABLED)
167 
170 ISR(TIMER1_OVF_vect) {
171  // Update the 'ticklet' count
172  g_ticklet += (256 / TICKLETS);
173 #ifdef SOFTPWM_ENABLED
174  // Update PWM outputs
175 # if SPWM_COUNT >= 1
176  if((g_pwmout[0]>0)&&(g_ticklet<=g_pwmout[0]))
178  else
179  pinLow(SPWM_PIN0);
180 # endif
181 # if SPWM_COUNT >= 2
182  if((g_pwmout[1]!=0)&&(g_ticklet<=g_pwmout[1]))
184  else
185  pinLow(SPWM_PIN1);
186 # endif
187 # if SPWM_COUNT >= 3
188  if((g_pwmout[2]!=0)&&(g_ticklet<=g_pwmout[2]))
190  else
191  pinLow(SPWM_PIN2);
192 # endif
193 # if SPWM_COUNT >= 4
194  if((g_pwmout[3]!=0)&&(g_ticklet<=g_pwmout[3]))
196  else
197  pinLow(SPWM_PIN3);
198 # endif
199 #endif /* SOFTPWM_ENABLED */
200  if(g_ticklet!=0)
201  return;
202  // If 'ticklet' wraps around, update the tick count
203  g_systicks++;
204  }
205 
206 #endif /* SOFTPWM_ENABLED || SYSTICK_ENABLED */
uint16_t ticks()
Definition: systicks.c:70
#define pinHigh(pin)
Definition: iohelp.h:30
#define SPWM_COUNT
Definition: hardware.h:91
void spwmOut(SPWM pwm, uint8_t value)
Definition: systicks.c:140
#define TICKLETS
Definition: systicks.c:18
#define SPWM_PIN0
Definition: hardware.h:94
#define SPWM_PIN2
Definition: hardware.h:100
void spwmInit()
Definition: systicks.c:107
#define SPWM_PIN1
Definition: hardware.h:97
#define pinLow(pin)
Definition: iohelp.h:39
void ticksInit()
Definition: systicks.c:54
enum _SPWM SPWM
#define SPWM_PIN3
Definition: hardware.h:103
uint16_t ticksElapsed(uint16_t reference)
Definition: systicks.c:84
ISR(TIMER1_OVF_vect)
Definition: systicks.c:170
uint8_t spwmValue(SPWM pwm)
Definition: systicks.c:153