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
|
giuliomoro@301
|
9 #include <Bela.h>
|
andrewm@268
|
10
|
andrewm@268
|
11 #define NUM_PINS 12
|
andrewm@268
|
12
|
andrewm@268
|
13 // Breadboard wiring layout:
|
andrewm@268
|
14 // 11 10 12 9 8 7
|
andrewm@268
|
15 // [ LED DISP ]
|
andrewm@268
|
16 // 1 2 3 6 4 5
|
andrewm@268
|
17
|
andrewm@268
|
18 // Organised by display segments:
|
andrewm@268
|
19 // e d . X c g b X X X f a
|
andrewm@268
|
20 const int kPins[NUM_PINS] = {P8_07, P8_08, P8_09, P8_10, P8_11, P8_12,
|
andrewm@268
|
21 P8_15, P8_16, P8_27, P8_28, P8_29, P8_30};
|
andrewm@268
|
22
|
andrewm@268
|
23 // Indices into the above array: pins 12, 9, 8, 6
|
andrewm@268
|
24 const int kDigits[4] = {9, 8, 7, 3};
|
andrewm@268
|
25
|
andrewm@268
|
26 int gCurrentlyDisplayingDigit = 0;
|
andrewm@268
|
27 int gDigitDisplayTime = 0;
|
andrewm@268
|
28 const int kDigitMaxDisplayTime = 44;
|
andrewm@268
|
29
|
andrewm@268
|
30 int gState = 0;
|
andrewm@268
|
31 int gStateCounter = 0;
|
andrewm@268
|
32 const int kMaxState = 25;
|
andrewm@268
|
33
|
andrewm@268
|
34 // . g f e d c b a
|
andrewm@268
|
35 //const unsigned char kBELA[4] = {0x7C, 0x79, 0x38, 0x77};
|
andrewm@268
|
36 const unsigned char kBELA[4] = {0x7C, 0x7B, 0x38, 0x5F};
|
andrewm@268
|
37 const unsigned char kPerimeter[6] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20};
|
andrewm@268
|
38
|
andrewm@268
|
39 int gCharacterToDisplay[4] = {0, 0, 0, 0};
|
andrewm@268
|
40
|
andrewm@268
|
41 // setup() is called once before the audio rendering starts.
|
andrewm@268
|
42 // Use it to perform any initialisation and allocation which is dependent
|
andrewm@268
|
43 // on the period size or sample rate.
|
andrewm@268
|
44 //
|
andrewm@268
|
45 // userData holds an opaque pointer to a data structure that was passed
|
andrewm@268
|
46 // in from the call to initAudio().
|
andrewm@268
|
47 //
|
andrewm@268
|
48 // Return true on success; returning false halts the program.
|
andrewm@268
|
49
|
giuliomoro@301
|
50 bool setup(BelaContext *context, void *userData)
|
andrewm@268
|
51 {
|
andrewm@268
|
52 // This project makes the assumption that the audio and digital
|
andrewm@268
|
53 // sample rates are the same. But check it to be sure!
|
andrewm@268
|
54 if(context->audioFrames != context->digitalFrames) {
|
andrewm@268
|
55 rt_printf("Error: this project needs the audio and digital sample rates to be the same.\n");
|
andrewm@268
|
56 return false;
|
andrewm@268
|
57 }
|
andrewm@268
|
58
|
andrewm@268
|
59 for(int i = 0; i < NUM_PINS; i++) {
|
andrewm@310
|
60 pinMode(context, 0, kPins[i], OUTPUT);
|
andrewm@268
|
61 }
|
andrewm@268
|
62
|
andrewm@268
|
63 return true;
|
andrewm@268
|
64 }
|
andrewm@268
|
65
|
andrewm@268
|
66 // render() is called regularly at the highest priority by the audio engine.
|
andrewm@268
|
67 // Input and output are given from the audio hardware and the other
|
andrewm@268
|
68 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
|
andrewm@268
|
69 // will be 0.
|
andrewm@268
|
70
|
giuliomoro@301
|
71 void render(BelaContext *context, void *userData)
|
andrewm@268
|
72 {
|
andrewm@268
|
73 for(unsigned int n = 0; n < context->audioFrames; n++) {
|
andrewm@268
|
74 // Check for rotation between digits
|
andrewm@268
|
75 if(--gDigitDisplayTime <= 0) {
|
andrewm@268
|
76 gCurrentlyDisplayingDigit = (gCurrentlyDisplayingDigit + 1) % 4;
|
andrewm@268
|
77 gDigitDisplayTime = kDigitMaxDisplayTime;
|
andrewm@268
|
78 }
|
andrewm@268
|
79
|
andrewm@268
|
80 // Write the currently displaying digit low and the rest high
|
andrewm@268
|
81 for(int i = 0; i < 4; i++)
|
andrewm@308
|
82 digitalWriteOnce(context, n, kPins[kDigits[i]], HIGH);
|
andrewm@308
|
83 digitalWriteOnce(context, n, kPins[kDigits[gCurrentlyDisplayingDigit]], LOW);
|
andrewm@268
|
84
|
andrewm@268
|
85 // Write the digit to the other outputs
|
andrewm@308
|
86 digitalWriteOnce(context, n, kPins[11],
|
andrewm@268
|
87 gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x01); // a
|
andrewm@308
|
88 digitalWriteOnce(context, n, kPins[6],
|
andrewm@268
|
89 gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x02); // b
|
andrewm@308
|
90 digitalWriteOnce(context, n, kPins[4],
|
andrewm@268
|
91 gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x04); // c
|
andrewm@308
|
92 digitalWriteOnce(context, n, kPins[1],
|
andrewm@268
|
93 gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x08); // d
|
andrewm@308
|
94 digitalWriteOnce(context, n, kPins[0],
|
andrewm@268
|
95 gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x10); // e
|
andrewm@308
|
96 digitalWriteOnce(context, n, kPins[10],
|
andrewm@268
|
97 gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x20); // f
|
andrewm@308
|
98 digitalWriteOnce(context, n, kPins[5],
|
andrewm@268
|
99 gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x40); // g
|
andrewm@308
|
100 digitalWriteOnce(context, n, kPins[2],
|
andrewm@268
|
101 gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x80); // .
|
andrewm@268
|
102
|
andrewm@268
|
103 // Check for changing state
|
andrewm@268
|
104 if(--gStateCounter <= 0) {
|
andrewm@268
|
105 gState = (gState + 1) % kMaxState;
|
andrewm@268
|
106 if(gState != (kMaxState - 1)) {
|
andrewm@268
|
107 for(int i = 0; i < 4; i++)
|
andrewm@268
|
108 gCharacterToDisplay[i] = 1 << (gState % 6);
|
andrewm@268
|
109 gStateCounter = 2000;
|
andrewm@268
|
110 }
|
andrewm@268
|
111 else {
|
andrewm@268
|
112 for(int i = 0; i < 4; i++)
|
andrewm@268
|
113 gCharacterToDisplay[i] = kBELA[i];
|
andrewm@268
|
114 gStateCounter = 50000;
|
andrewm@268
|
115 }
|
andrewm@268
|
116 }
|
andrewm@268
|
117 }
|
andrewm@268
|
118 }
|
andrewm@268
|
119
|
andrewm@268
|
120 // cleanup() is called once at the end, after the audio has stopped.
|
andrewm@268
|
121 // Release any resources that were allocated in setup().
|
andrewm@268
|
122
|
giuliomoro@301
|
123 void cleanup(BelaContext *context, void *userData)
|
andrewm@268
|
124 {
|
andrewm@268
|
125
|
andrewm@268
|
126 }
|