andrewm@268: /* andrewm@268: * render.cpp andrewm@268: * andrewm@268: * Created on: Oct 24, 2014 andrewm@268: * Author: parallels andrewm@268: */ andrewm@268: andrewm@268: giuliomoro@301: #include andrewm@268: #include andrewm@268: andrewm@268: #define NUM_PINS 12 andrewm@268: andrewm@268: // Breadboard wiring layout: andrewm@268: // 11 10 12 9 8 7 andrewm@268: // [ LED DISP ] andrewm@268: // 1 2 3 6 4 5 andrewm@268: andrewm@268: // Organised by display segments: andrewm@268: // e d . X c g b X X X f a andrewm@268: const int kPins[NUM_PINS] = {P8_07, P8_08, P8_09, P8_10, P8_11, P8_12, andrewm@268: P8_15, P8_16, P8_27, P8_28, P8_29, P8_30}; andrewm@268: andrewm@268: // Indices into the above array: pins 12, 9, 8, 6 andrewm@268: const int kDigits[4] = {9, 8, 7, 3}; andrewm@268: andrewm@268: int gCurrentlyDisplayingDigit = 0; andrewm@268: int gDigitDisplayTime = 0; andrewm@268: const int kDigitMaxDisplayTime = 44; andrewm@268: andrewm@268: int gState = 0; andrewm@268: int gStateCounter = 0; andrewm@268: const int kMaxState = 25; andrewm@268: andrewm@268: // . g f e d c b a andrewm@268: //const unsigned char kBELA[4] = {0x7C, 0x79, 0x38, 0x77}; andrewm@268: const unsigned char kBELA[4] = {0x7C, 0x7B, 0x38, 0x5F}; andrewm@268: const unsigned char kPerimeter[6] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20}; andrewm@268: andrewm@268: int gCharacterToDisplay[4] = {0, 0, 0, 0}; andrewm@268: andrewm@268: // setup() is called once before the audio rendering starts. andrewm@268: // Use it to perform any initialisation and allocation which is dependent andrewm@268: // on the period size or sample rate. andrewm@268: // andrewm@268: // userData holds an opaque pointer to a data structure that was passed andrewm@268: // in from the call to initAudio(). andrewm@268: // andrewm@268: // Return true on success; returning false halts the program. andrewm@268: giuliomoro@301: bool setup(BelaContext *context, void *userData) andrewm@268: { andrewm@268: // This project makes the assumption that the audio and digital andrewm@268: // sample rates are the same. But check it to be sure! andrewm@268: if(context->audioFrames != context->digitalFrames) { andrewm@268: rt_printf("Error: this project needs the audio and digital sample rates to be the same.\n"); andrewm@268: return false; andrewm@268: } andrewm@268: andrewm@268: for(int i = 0; i < NUM_PINS; i++) { andrewm@310: pinMode(context, 0, kPins[i], OUTPUT); andrewm@268: } andrewm@268: andrewm@268: return true; andrewm@268: } andrewm@268: andrewm@268: // render() is called regularly at the highest priority by the audio engine. andrewm@268: // Input and output are given from the audio hardware and the other andrewm@268: // ADCs and DACs (if available). If only audio is available, numMatrixFrames andrewm@268: // will be 0. andrewm@268: giuliomoro@301: void render(BelaContext *context, void *userData) andrewm@268: { andrewm@268: for(unsigned int n = 0; n < context->audioFrames; n++) { andrewm@268: // Check for rotation between digits andrewm@268: if(--gDigitDisplayTime <= 0) { andrewm@268: gCurrentlyDisplayingDigit = (gCurrentlyDisplayingDigit + 1) % 4; andrewm@268: gDigitDisplayTime = kDigitMaxDisplayTime; andrewm@268: } andrewm@268: andrewm@268: // Write the currently displaying digit low and the rest high andrewm@268: for(int i = 0; i < 4; i++) andrewm@308: digitalWriteOnce(context, n, kPins[kDigits[i]], HIGH); andrewm@308: digitalWriteOnce(context, n, kPins[kDigits[gCurrentlyDisplayingDigit]], LOW); andrewm@268: andrewm@268: // Write the digit to the other outputs andrewm@308: digitalWriteOnce(context, n, kPins[11], andrewm@268: gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x01); // a andrewm@308: digitalWriteOnce(context, n, kPins[6], andrewm@268: gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x02); // b andrewm@308: digitalWriteOnce(context, n, kPins[4], andrewm@268: gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x04); // c andrewm@308: digitalWriteOnce(context, n, kPins[1], andrewm@268: gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x08); // d andrewm@308: digitalWriteOnce(context, n, kPins[0], andrewm@268: gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x10); // e andrewm@308: digitalWriteOnce(context, n, kPins[10], andrewm@268: gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x20); // f andrewm@308: digitalWriteOnce(context, n, kPins[5], andrewm@268: gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x40); // g andrewm@308: digitalWriteOnce(context, n, kPins[2], andrewm@268: gCharacterToDisplay[gCurrentlyDisplayingDigit] & 0x80); // . andrewm@268: andrewm@268: // Check for changing state andrewm@268: if(--gStateCounter <= 0) { andrewm@268: gState = (gState + 1) % kMaxState; andrewm@268: if(gState != (kMaxState - 1)) { andrewm@268: for(int i = 0; i < 4; i++) andrewm@268: gCharacterToDisplay[i] = 1 << (gState % 6); andrewm@268: gStateCounter = 2000; andrewm@268: } andrewm@268: else { andrewm@268: for(int i = 0; i < 4; i++) andrewm@268: gCharacterToDisplay[i] = kBELA[i]; andrewm@268: gStateCounter = 50000; andrewm@268: } andrewm@268: } andrewm@268: } andrewm@268: } andrewm@268: andrewm@268: // cleanup() is called once at the end, after the audio has stopped. andrewm@268: // Release any resources that were allocated in setup(). andrewm@268: giuliomoro@301: void cleanup(BelaContext *context, void *userData) andrewm@268: { andrewm@268: andrewm@268: }