PropWare  3.0.0.229
C++ objects and CMake build system for Parallax Propeller
squareWave.c
1 /*
2  * @file squareWave.c
3  *
4  * @author Andy Lindsay
5  *
6  * @version 0.85
7  *
8  * @copyright Copyright (C) Parallax, Inc. 2012. See end of file for
9  * terms of use (MIT License).
10  *
11  * @brief squareWave function source, see simpletools.h for documentation.
12  *
13  * @detail Please submit bug reports, suggestions, and improvements to
14  * this code to editor@parallax.com.
15  */
16 
17 #include "simpletools.h"
18 
19 // Counter module values
20 #ifndef CTR_NCO
21 #define CTR_NCO (0b100 << 26);
22 #endif
23 #ifndef CTR_PLL
24 #define CTR_PLL (0b10 << 26);
25 #endif
26 
27 static unsigned int stack[44 + 20];
28 
29 static volatile unsigned int cog = 0;
30 static volatile int ctra, ctrb, frqa, frqb;
31 
32 void square_wave_cog(void *par);
33 void square_wave_setup(int pin, int freq, int* ctr, int* frq);
34 int int_fraction(int a, int b, int shift);
35 
36 //char s[40];
37 
38 void square_wave(int pin, int channel, int freq)
39 {
40  if(!cog) cog = cogstart(square_wave_cog, NULL,
41  stack, sizeof(stack)) + 1;
42 
43  int ctr, frq;
44  square_wave_setup(pin, freq, &ctr, &frq);
45  if(!channel)
46  {
47  ctra = ctr;
48  frqa = frq;
49  if(pin < 0)
50  {
51  pin = -pin;
52  ctra = 0;
53  frqa = 0;
54  }
55  }
56  else
57  {
58  ctrb = ctr;
59  frqb = frq;
60  if(pin < 0)
61  {
62  pin = -pin;
63  ctrb = 0;
64  frqb = 0;
65  }
66  //print("ctrb = %s\n", itoa(ctrb, s, 2));
67  //print("frqb = %s\n", itoa(frqb, s, 2));
68  }
69 }
70 
71 
72 void square_wave_stop(void)
73 {
74  if(cog)
75  {
76  cogstop(cog - 1);
77  cog = 0;
78  ctra = 0;
79  ctrb = 0;
80  frqa = 0;
81  frqb = 0;
82  }
83 }
84 
85 
86 void square_wave_cog(void *par)
87 {
88  int pin;
89  while(1)
90  {
91  if(ctra != CTRA)
92  {
93  if((CTRA & 0b111111) != (ctra & 0b111111))
94  {
95  pin = CTRA & 0b111111;
96  DIRA &= ~(1 << pin);
97  }
98 
99  CTRA = ctra;
100  FRQA = frqa;
101 
102  if(ctra != 0)
103  {
104  pin = CTRA & 0b111111;
105  DIRA |= (1 << pin);
106  }
107  }
108 
109  if(FRQA != frqa)
110  FRQA = frqa;
111 
112  if(ctrb != CTRB)
113  {
114  if((CTRB & 0b111111) != (ctrb & 0b111111))
115  {
116  pin = CTRB & 0b111111;
117  DIRA &= ~(1 << pin);
118  }
119 
120  CTRB = ctrb;
121  FRQB = frqb;
122 
123  if(ctrb != 0)
124  {
125  pin = CTRB & 0b111111;
126  DIRA |= (1 << pin);
127  }
128  }
129  if(FRQB != frqb)
130  FRQB = frqb;
131  }
132 }
133 
134 void square_wave_setup(int pin, int freq, int* _ctr, int* _frq)
135 {
136  int ctr;
137  int frq;
138  int s;
139  int d;
140  if(freq < 500000)
141  {
142  ctr = CTR_NCO;
143  s = 1;
144  d = 0;
145  }
146  else
147  {
148  ctr = CTR_PLL;
149  d = (freq - 1) / 1000000;
150  int i;
151  for(i = 32; i>0; i--)
152  {
153  if(d < 0) break;
154  d <<= 1;
155  }
156  d = i;
157  s = 4 - d;
158  ctr += (d << 23);
159  }
160  frq = int_fraction(freq, CLKFREQ, s);
161  ctr += pin;
162  *_ctr = ctr;
163  *_frq = frq;
164 }
165 
166 
167 int int_fraction(int a, int b, int shift)
168 {
169  if (shift > 0)
170  {
171  a <<= shift;
172  }
173  if(shift < 0)
174  {
175  b <<= -shift;
176  }
177  int f = 0;
178  int i;
179  for(i = 0; i < 32; i++)
180  {
181  f <<= 1;
182  if(a >= b)
183  {
184  a -= b;
185  f++;
186  }
187  a <<= 1;
188  }
189  return f;
190 }
191 
square_wave_stop
void square_wave_stop(void)
Stop the cog that's transmitting a square wave.
Definition: squareWave.c:72
FRQA
#define FRQA
Counter A frequency register.
Definition: propeller1.h:169
simpletools.h
This library provides convenient functions for a variety of microcontroller I/O, timing,...
FRQB
#define FRQB
Counter B frequency register.
Definition: propeller1.h:171
CLKFREQ
#define CLKFREQ
Returns the current clock frequency.
Definition: propeller.h:46
CTR_PLL
#define CTR_PLL
Building block for configuring a cog's counter module to PLL mode. Used by square_wave function....
Definition: simpletools.h:452
CTRB
#define CTRB
Counter B control register.
Definition: propeller1.h:167
square_wave
void square_wave(int pin, int channel, int freq)
Make I/O pin transmit a repeated high/low signal at a certain frequency. High and low times are the s...
Definition: squareWave.c:38
CTR_NCO
#define CTR_NCO
Building block for configuring a cog's counter module to NCO mode. Used by square_wave function....
Definition: simpletools.h:444
cogstop
#define cogstop(a)
Stop a COG.
Definition: propeller.h:100
DIRA
#define DIRA
Use to set pins to input (0) or output (1).
Definition: propeller1.h:161
cogstart
int cogstart(void(*func)(void *), void *par, void *stack, size_t stacksize)
Start a new propeller LMM function/thread in another COG.
CTRA
#define CTRA
Counter A control register.
Definition: propeller1.h:165