andrewm@268
|
1 /*
|
andrewm@268
|
2 * render.cpp
|
andrewm@268
|
3 *
|
andrewm@268
|
4 * Created on: Oct 24, 2014
|
andrewm@268
|
5 * Author: parallels
|
andrewm@268
|
6 */
|
andrewm@268
|
7
|
andrewm@268
|
8
|
andrewm@268
|
9 #include <BeagleRT.h>
|
andrewm@268
|
10 #include <Utilities.h>
|
andrewm@268
|
11
|
andrewm@268
|
12 const int kStepLengthSlow = 1000;
|
andrewm@268
|
13 const int kStepLengthFast = 500;
|
andrewm@268
|
14
|
andrewm@268
|
15 int gStepLengthSamples = kStepLengthSlow;
|
andrewm@268
|
16
|
andrewm@268
|
17 const int gPinA1 = P8_27;
|
andrewm@268
|
18 const int gPinA2 = P8_28;
|
andrewm@268
|
19 const int gPinB1 = P8_29;
|
andrewm@268
|
20 const int gPinB2 = P8_30;
|
andrewm@268
|
21 const int gPinServo = P9_16;
|
andrewm@268
|
22
|
andrewm@268
|
23 int gStepCounter = 0;
|
andrewm@268
|
24 int gPhase = 0;
|
andrewm@268
|
25
|
andrewm@268
|
26 int gServoCounter = 0;
|
andrewm@268
|
27
|
andrewm@268
|
28
|
andrewm@268
|
29 enum {
|
andrewm@268
|
30 kStateMoveRight1 = 0,
|
andrewm@268
|
31 kStateMoveLeft1,
|
andrewm@268
|
32 kStateMoveRight2,
|
andrewm@268
|
33 kStateMoveLeft2,
|
andrewm@268
|
34 kStateMoveRight3,
|
andrewm@268
|
35 kStateMoveLeft3,
|
andrewm@268
|
36 kStateSpin,
|
andrewm@268
|
37 kStateMax
|
andrewm@268
|
38 };
|
andrewm@268
|
39
|
andrewm@268
|
40 int gState = 0;
|
andrewm@268
|
41 int gStateCounter = 0;
|
andrewm@268
|
42
|
andrewm@268
|
43 // setup() is called once before the audio rendering starts.
|
andrewm@268
|
44 // Use it to perform any initialisation and allocation which is dependent
|
andrewm@268
|
45 // on the period size or sample rate.
|
andrewm@268
|
46 //
|
andrewm@268
|
47 // userData holds an opaque pointer to a data structure that was passed
|
andrewm@268
|
48 // in from the call to initAudio().
|
andrewm@268
|
49 //
|
andrewm@268
|
50 // Return true on success; returning false halts the program.
|
andrewm@268
|
51
|
andrewm@268
|
52 bool setup(BeagleRTContext *context, void *userData)
|
andrewm@268
|
53 {
|
andrewm@268
|
54 // This project makes the assumption that the audio and digital
|
andrewm@268
|
55 // sample rates are the same. But check it to be sure!
|
andrewm@268
|
56 if(context->audioFrames != context->digitalFrames) {
|
andrewm@268
|
57 rt_printf("Error: this project needs the audio and digital sample rates to be the same.\n");
|
andrewm@268
|
58 return false;
|
andrewm@268
|
59 }
|
andrewm@268
|
60
|
andrewm@268
|
61 pinModeFrame(context, 0, gPinA1, OUTPUT);
|
andrewm@268
|
62 pinModeFrame(context, 0, gPinA2, OUTPUT);
|
andrewm@268
|
63 pinModeFrame(context, 0, gPinB1, OUTPUT);
|
andrewm@268
|
64 pinModeFrame(context, 0, gPinB2, OUTPUT);
|
andrewm@268
|
65 pinModeFrame(context, 0, gPinServo, OUTPUT);
|
andrewm@268
|
66
|
andrewm@268
|
67 return true;
|
andrewm@268
|
68 }
|
andrewm@268
|
69
|
andrewm@268
|
70 // render() is called regularly at the highest priority by the audio engine.
|
andrewm@268
|
71 // Input and output are given from the audio hardware and the other
|
andrewm@268
|
72 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
|
andrewm@268
|
73 // will be 0.
|
andrewm@268
|
74
|
andrewm@268
|
75 void render(BeagleRTContext *context, void *userData)
|
andrewm@268
|
76 {
|
andrewm@268
|
77 for(unsigned int n = 0; n < context->audioFrames; n++) {
|
andrewm@268
|
78 if(gPhase == 0 || gPhase == 1) {
|
andrewm@268
|
79 digitalWriteFrameOnce(context, n, gPinB1, HIGH);
|
andrewm@268
|
80 digitalWriteFrameOnce(context, n, gPinB2, LOW);
|
andrewm@268
|
81 }
|
andrewm@268
|
82 else {
|
andrewm@268
|
83 digitalWriteFrameOnce(context, n, gPinB1, LOW);
|
andrewm@268
|
84 digitalWriteFrameOnce(context, n, gPinB2, HIGH);
|
andrewm@268
|
85 }
|
andrewm@268
|
86
|
andrewm@268
|
87 if(gPhase == 1 || gPhase == 2) {
|
andrewm@268
|
88 digitalWriteFrameOnce(context, n, gPinA1, HIGH);
|
andrewm@268
|
89 digitalWriteFrameOnce(context, n, gPinA2, LOW);
|
andrewm@268
|
90 }
|
andrewm@268
|
91 else {
|
andrewm@268
|
92 digitalWriteFrameOnce(context, n, gPinA1, LOW);
|
andrewm@268
|
93 digitalWriteFrameOnce(context, n, gPinA2, HIGH);
|
andrewm@268
|
94 }
|
andrewm@268
|
95
|
andrewm@268
|
96 if(--gServoCounter > 0)
|
andrewm@268
|
97 digitalWriteFrameOnce(context, n, gPinServo, HIGH);
|
andrewm@268
|
98 else
|
andrewm@268
|
99 digitalWriteFrameOnce(context, n, gPinServo, LOW);
|
andrewm@268
|
100
|
andrewm@268
|
101 if(++gStepCounter >= gStepLengthSamples) {
|
andrewm@268
|
102 gStateCounter++;
|
andrewm@268
|
103
|
andrewm@268
|
104 switch(gState) {
|
andrewm@268
|
105 case kStateMoveRight1:
|
andrewm@268
|
106 case kStateMoveRight2:
|
andrewm@268
|
107 case kStateMoveRight3:
|
andrewm@268
|
108 gPhase = (gPhase + 1) & 3;
|
andrewm@268
|
109 break;
|
andrewm@268
|
110 case kStateMoveLeft1:
|
andrewm@268
|
111 case kStateMoveLeft2:
|
andrewm@268
|
112 case kStateMoveLeft3:
|
andrewm@268
|
113 gPhase = (gPhase + 3) & 3;
|
andrewm@268
|
114 break;
|
andrewm@268
|
115 case kStateSpin:
|
andrewm@268
|
116 gPhase = (gPhase + 1) & 3;
|
andrewm@268
|
117 break;
|
andrewm@268
|
118 }
|
andrewm@268
|
119
|
andrewm@268
|
120 if(gState == kStateSpin) {
|
andrewm@268
|
121 if(gStateCounter >= 48) {
|
andrewm@268
|
122 gStateCounter = 0;
|
andrewm@268
|
123 gState = 0;
|
andrewm@268
|
124 gStepLengthSamples = kStepLengthSlow;
|
andrewm@268
|
125 }
|
andrewm@268
|
126 }
|
andrewm@268
|
127 else {
|
andrewm@268
|
128 if(gStateCounter >= 16) {
|
andrewm@268
|
129 gStateCounter = 0;
|
andrewm@268
|
130 gState++;
|
andrewm@268
|
131 if(gState & 1)
|
andrewm@268
|
132 gServoCounter = 120;
|
andrewm@268
|
133 else
|
andrewm@268
|
134 gServoCounter = 80;
|
andrewm@268
|
135 if(gState == kStateSpin)
|
andrewm@268
|
136 gStepLengthSamples = kStepLengthFast;
|
andrewm@268
|
137 }
|
andrewm@268
|
138 }
|
andrewm@268
|
139
|
andrewm@268
|
140 gStepCounter = 0;
|
andrewm@268
|
141 }
|
andrewm@268
|
142 }
|
andrewm@268
|
143 }
|
andrewm@268
|
144
|
andrewm@268
|
145 // cleanup() is called once at the end, after the audio has stopped.
|
andrewm@268
|
146 // Release any resources that were allocated in setup().
|
andrewm@268
|
147
|
andrewm@268
|
148 void cleanup(BeagleRTContext *context, void *userData)
|
andrewm@268
|
149 {
|
andrewm@268
|
150
|
andrewm@268
|
151 }
|