Skip to content

Commit 97c3091

Browse files
authored
Merge pull request arduino#58 from bcmi-labs/LED-matrix-plus
New methods and flags + API refactoring
2 parents cc19255 + 20348ce commit 97c3091

File tree

8 files changed

+85
-21
lines changed

8 files changed

+85
-21
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
cores/arduino/mydebug.cpp
33
libraries/Storage/.development
44
cores/arduino/mydebug.cpp.donotuse
5+
.DS_Store
6+
.DS_Store?

libraries/LED_Matrix/src/LED_Matrix.h renamed to libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h

Lines changed: 83 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,15 @@ static uint32_t reverse(uint32_t x)
133133
}
134134

135135
// TODO: this is dangerous, use with care
136-
#define load(x) load_wrapper(x, sizeof(x))
136+
#define loadSequence(frames) loadWrapper(frames, sizeof(frames))
137+
#define renderBitmap(bitmap, rows, columns) loadPixels(&bitmap[0][0], rows*columns)
137138

138139
static uint8_t __attribute__((aligned)) framebuffer[NUM_LEDS / 8];
139140

140-
class LED_Matrix {
141+
class ArduinoLEDMatrix {
141142

142143
public:
143-
LED_Matrix() {}
144+
ArduinoLEDMatrix() {}
144145
// TODO: find a better name
145146
// autoscroll will be slower than calling next() at precise times
146147
void autoscroll(uint32_t interval_ms) {
@@ -156,41 +157,102 @@ class LED_Matrix {
156157
uint8_t type;
157158
uint8_t ch = FspTimer::get_available_timer(type);
158159
// TODO: avoid passing "this" argument to remove autoscroll
159-
led_timer.begin(TIMER_MODE_PERIODIC, type, ch, 10000.0, 50.0, turnOnLedISR, this);
160-
led_timer.setup_overflow_irq();
161-
led_timer.open();
162-
led_timer.start();
160+
_ledTimer.begin(TIMER_MODE_PERIODIC, type, ch, 10000.0, 50.0, turnOnLedISR, this);
161+
_ledTimer.setup_overflow_irq();
162+
_ledTimer.open();
163+
_ledTimer.start();
163164
}
164165
void next() {
165166
uint32_t frame[3];
166-
static int j = 0;
167-
frame[0] = reverse(*(_frames+(j*4)+0));
168-
frame[1] = reverse(*(_frames+(j*4)+1));
169-
frame[2] = reverse(*(_frames+(j*4)+2));
170-
_interval = *(_frames+(j*4)+3);
171-
j = (j + 1) % _lines;
167+
frame[0] = reverse(*(_frames+(_currentFrame*4)+0));
168+
frame[1] = reverse(*(_frames+(_currentFrame*4)+1));
169+
frame[2] = reverse(*(_frames+(_currentFrame*4)+2));
170+
_interval = *(_frames+(_currentFrame*4)+3);
171+
_currentFrame = (_currentFrame + 1) % _framesCount;
172+
if(_currentFrame == 0){
173+
if(!_loop){
174+
_interval = 0;
175+
}
176+
if(_callBack != nullptr){
177+
_callBack();
178+
_sequenceDone = true;
179+
}
180+
}
172181
memcpy(framebuffer, (uint32_t*)frame, sizeof(frame));
173182
}
174-
void load_wrapper(const uint32_t frames[][4], uint32_t howMany) {
183+
void loadFrame(const uint32_t buffer[3]){
184+
uint32_t tempBuffer[][4] = {{
185+
buffer[0], buffer[1], buffer[2], 0
186+
}};
187+
loadSequence(tempBuffer);
188+
next();
189+
_interval = 0;
190+
}
191+
void renderFrame(uint8_t frameNumber){
192+
_currentFrame = frameNumber % _framesCount;
193+
next();
194+
_interval = 0;
195+
}
196+
void play(bool loop = false){
197+
_loop = loop;
198+
_sequenceDone = false;
199+
next();
200+
}
201+
bool sequenceDone(){
202+
if(_sequenceDone){
203+
_sequenceDone = false;
204+
return true;
205+
}
206+
return false;
207+
}
208+
209+
void loadPixels(uint8_t *arr, size_t size){
210+
uint32_t partialBuffer = 0;
211+
uint8_t pixelIndex = 0;
212+
uint8_t *frameP = arr;
213+
uint32_t *frameHolderP = _frameHolder;
214+
while (pixelIndex < size) {
215+
partialBuffer |= *frameP++;
216+
if ((pixelIndex + 1) % 32 == 0) {
217+
*(frameHolderP++) = partialBuffer;
218+
}
219+
partialBuffer = partialBuffer << 1;
220+
pixelIndex++;
221+
}
222+
loadFrame(_frameHolder);
223+
};
224+
225+
void loadWrapper(const uint32_t frames[][4], uint32_t howMany) {
226+
_currentFrame = 0;
175227
_frames = (uint32_t*)frames;
176-
_lines = (howMany / 4) / sizeof(uint32_t);
228+
_framesCount = (howMany / 4) / sizeof(uint32_t);
229+
}
230+
// WARNING: callbacks are fired from ISR. The execution time will be limited.
231+
void setCallback(voidFuncPtr callBack){
232+
_callBack = callBack;
177233
}
234+
178235
private:
236+
int _currentFrame = 0;
237+
uint32_t _frameHolder[3];
179238
uint32_t* _frames;
180-
uint32_t _lines;
239+
uint32_t _framesCount;
181240
uint32_t _interval = 0;
182-
uint32_t _last_interval = 0;
183-
FspTimer led_timer;
241+
uint32_t _lastInterval = 0;
242+
bool _loop = false;
243+
FspTimer _ledTimer;
244+
bool _sequenceDone = false;
245+
voidFuncPtr _callBack;
184246

185247
static void turnOnLedISR(timer_callback_args_t *arg) {
186248
static volatile int i_isr = 0;
187249
turnLed(i_isr, ((framebuffer[i_isr >> 3] & (1 << (i_isr % 8))) != 0));
188250
i_isr = (i_isr + 1) % NUM_LEDS;
189251
if (arg != nullptr && arg->p_context != nullptr) {
190-
LED_Matrix* _m = (LED_Matrix*)arg->p_context;
191-
if (_m->_interval != 0 && millis() - _m->_last_interval > _m->_interval) {
252+
ArduinoLEDMatrix* _m = (ArduinoLEDMatrix*)arg->p_context;
253+
if (_m->_interval != 0 && millis() - _m->_lastInterval > _m->_interval) {
192254
_m->next();
193-
_m->_last_interval = millis();
255+
_m->_lastInterval = millis();
194256
}
195257
}
196258
}

0 commit comments

Comments
 (0)