Louis Mayencourt
/
NRFBOY
MBED NRF51 Arduboy port
arduboy.hpp@0:649b2fe69f16, 2017-01-05 (annotated)
- Committer:
- lmayencou
- Date:
- Thu Jan 05 18:37:50 2017 +0000
- Revision:
- 0:649b2fe69f16
- Child:
- 1:c53e766082b4
I2C screen
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lmayencou | 0:649b2fe69f16 | 1 | #include "Adafruit_SSD1306.h" |
lmayencou | 0:649b2fe69f16 | 2 | |
lmayencou | 0:649b2fe69f16 | 3 | #define WIDTH 128 |
lmayencou | 0:649b2fe69f16 | 4 | #define HEIGHT 32 |
lmayencou | 0:649b2fe69f16 | 5 | |
lmayencou | 0:649b2fe69f16 | 6 | class Arduboy : public Adafruit_SSD1306_I2c |
lmayencou | 0:649b2fe69f16 | 7 | { |
lmayencou | 0:649b2fe69f16 | 8 | public: |
lmayencou | 0:649b2fe69f16 | 9 | Arduboy(I2C i2c) : |
lmayencou | 0:649b2fe69f16 | 10 | Adafruit_SSD1306_I2c(i2c) |
lmayencou | 0:649b2fe69f16 | 11 | { |
lmayencou | 0:649b2fe69f16 | 12 | // frame management |
lmayencou | 0:649b2fe69f16 | 13 | setFrameRate(60); |
lmayencou | 0:649b2fe69f16 | 14 | frameCount = 0; |
lmayencou | 0:649b2fe69f16 | 15 | nextFrameStart = 0; |
lmayencou | 0:649b2fe69f16 | 16 | post_render = false; |
lmayencou | 0:649b2fe69f16 | 17 | } |
lmayencou | 0:649b2fe69f16 | 18 | |
lmayencou | 0:649b2fe69f16 | 19 | void begin() |
lmayencou | 0:649b2fe69f16 | 20 | { |
lmayencou | 0:649b2fe69f16 | 21 | clearDisplay(); |
lmayencou | 0:649b2fe69f16 | 22 | writeChar('h'); |
lmayencou | 0:649b2fe69f16 | 23 | writeChar('e'); |
lmayencou | 0:649b2fe69f16 | 24 | writeChar('l'); |
lmayencou | 0:649b2fe69f16 | 25 | writeChar('l'); |
lmayencou | 0:649b2fe69f16 | 26 | writeChar('o'); |
lmayencou | 0:649b2fe69f16 | 27 | display(); |
lmayencou | 0:649b2fe69f16 | 28 | } |
lmayencou | 0:649b2fe69f16 | 29 | |
lmayencou | 0:649b2fe69f16 | 30 | void idle() |
lmayencou | 0:649b2fe69f16 | 31 | {} |
lmayencou | 0:649b2fe69f16 | 32 | |
lmayencou | 0:649b2fe69f16 | 33 | /* Frame management */ |
lmayencou | 0:649b2fe69f16 | 34 | |
lmayencou | 0:649b2fe69f16 | 35 | void setFrameRate(uint8_t rate) |
lmayencou | 0:649b2fe69f16 | 36 | { |
lmayencou | 0:649b2fe69f16 | 37 | frameRate = rate; |
lmayencou | 0:649b2fe69f16 | 38 | eachFrameMillis = 1000/rate; |
lmayencou | 0:649b2fe69f16 | 39 | } |
lmayencou | 0:649b2fe69f16 | 40 | |
lmayencou | 0:649b2fe69f16 | 41 | bool everyXFrames(uint8_t frames) |
lmayencou | 0:649b2fe69f16 | 42 | { |
lmayencou | 0:649b2fe69f16 | 43 | return frameCount % frames == 0; |
lmayencou | 0:649b2fe69f16 | 44 | } |
lmayencou | 0:649b2fe69f16 | 45 | |
lmayencou | 0:649b2fe69f16 | 46 | bool newFrame() |
lmayencou | 0:649b2fe69f16 | 47 | { |
lmayencou | 0:649b2fe69f16 | 48 | long now = time(NULL); |
lmayencou | 0:649b2fe69f16 | 49 | uint8_t remaining; |
lmayencou | 0:649b2fe69f16 | 50 | |
lmayencou | 0:649b2fe69f16 | 51 | // post render |
lmayencou | 0:649b2fe69f16 | 52 | if (post_render) |
lmayencou | 0:649b2fe69f16 | 53 | { |
lmayencou | 0:649b2fe69f16 | 54 | lastFrameDurationMs = now - lastFrameStart; |
lmayencou | 0:649b2fe69f16 | 55 | frameCount++; |
lmayencou | 0:649b2fe69f16 | 56 | post_render = false; |
lmayencou | 0:649b2fe69f16 | 57 | } |
lmayencou | 0:649b2fe69f16 | 58 | |
lmayencou | 0:649b2fe69f16 | 59 | // if it's not time for the next frame yet |
lmayencou | 0:649b2fe69f16 | 60 | if (now < nextFrameStart) |
lmayencou | 0:649b2fe69f16 | 61 | { |
lmayencou | 0:649b2fe69f16 | 62 | remaining = nextFrameStart - now; |
lmayencou | 0:649b2fe69f16 | 63 | // if we have more than 1ms to spare, lets sleep |
lmayencou | 0:649b2fe69f16 | 64 | // we should be woken up by timer0 every 1ms, so this should be ok |
lmayencou | 0:649b2fe69f16 | 65 | if (remaining > 1) |
lmayencou | 0:649b2fe69f16 | 66 | idle(); |
lmayencou | 0:649b2fe69f16 | 67 | return false; |
lmayencou | 0:649b2fe69f16 | 68 | } |
lmayencou | 0:649b2fe69f16 | 69 | |
lmayencou | 0:649b2fe69f16 | 70 | // pre-render |
lmayencou | 0:649b2fe69f16 | 71 | |
lmayencou | 0:649b2fe69f16 | 72 | // next frame should start from last frame start + frame duration |
lmayencou | 0:649b2fe69f16 | 73 | nextFrameStart = lastFrameStart + eachFrameMillis; |
lmayencou | 0:649b2fe69f16 | 74 | // If we're running CPU at 100%+ (too slow to complete each loop within |
lmayencou | 0:649b2fe69f16 | 75 | // the frame duration) then it's possible that we get "behind"... Say we |
lmayencou | 0:649b2fe69f16 | 76 | // took 5ms too long, resulting in nextFrameStart being 5ms in the PAST. |
lmayencou | 0:649b2fe69f16 | 77 | // In that case we simply schedule the next frame to start immediately. |
lmayencou | 0:649b2fe69f16 | 78 | // |
lmayencou | 0:649b2fe69f16 | 79 | // If we were to let the nextFrameStart slide further and further into |
lmayencou | 0:649b2fe69f16 | 80 | // the past AND eventually the CPU usage dropped then frame management |
lmayencou | 0:649b2fe69f16 | 81 | // would try to "catch up" (by speeding up the game) to make up for all |
lmayencou | 0:649b2fe69f16 | 82 | // that lost time. That would not be good. We allow frames to take too |
lmayencou | 0:649b2fe69f16 | 83 | // long (what choice do we have?), but we do not allow super-fast frames |
lmayencou | 0:649b2fe69f16 | 84 | // to make up for slow frames in the past. |
lmayencou | 0:649b2fe69f16 | 85 | if (nextFrameStart < now) |
lmayencou | 0:649b2fe69f16 | 86 | nextFrameStart = now; |
lmayencou | 0:649b2fe69f16 | 87 | |
lmayencou | 0:649b2fe69f16 | 88 | lastFrameStart = now; |
lmayencou | 0:649b2fe69f16 | 89 | |
lmayencou | 0:649b2fe69f16 | 90 | post_render = true; |
lmayencou | 0:649b2fe69f16 | 91 | return post_render; |
lmayencou | 0:649b2fe69f16 | 92 | } |
lmayencou | 0:649b2fe69f16 | 93 | |
lmayencou | 0:649b2fe69f16 | 94 | // This function is deprecated. |
lmayencou | 0:649b2fe69f16 | 95 | // It should remain as is for backwards compatibility. |
lmayencou | 0:649b2fe69f16 | 96 | // New code should use newFrame(). |
lmayencou | 0:649b2fe69f16 | 97 | bool nextFrame() |
lmayencou | 0:649b2fe69f16 | 98 | { |
lmayencou | 0:649b2fe69f16 | 99 | long now = time(NULL); |
lmayencou | 0:649b2fe69f16 | 100 | uint8_t remaining; |
lmayencou | 0:649b2fe69f16 | 101 | |
lmayencou | 0:649b2fe69f16 | 102 | if (post_render) { |
lmayencou | 0:649b2fe69f16 | 103 | lastFrameDurationMs = now - lastFrameStart; |
lmayencou | 0:649b2fe69f16 | 104 | frameCount++; |
lmayencou | 0:649b2fe69f16 | 105 | post_render = false; |
lmayencou | 0:649b2fe69f16 | 106 | } |
lmayencou | 0:649b2fe69f16 | 107 | |
lmayencou | 0:649b2fe69f16 | 108 | if (now < nextFrameStart) { |
lmayencou | 0:649b2fe69f16 | 109 | remaining = nextFrameStart - now; |
lmayencou | 0:649b2fe69f16 | 110 | if (remaining > 1) |
lmayencou | 0:649b2fe69f16 | 111 | idle(); |
lmayencou | 0:649b2fe69f16 | 112 | return false; |
lmayencou | 0:649b2fe69f16 | 113 | } |
lmayencou | 0:649b2fe69f16 | 114 | |
lmayencou | 0:649b2fe69f16 | 115 | nextFrameStart = now + eachFrameMillis; |
lmayencou | 0:649b2fe69f16 | 116 | lastFrameStart = now; |
lmayencou | 0:649b2fe69f16 | 117 | post_render = true; |
lmayencou | 0:649b2fe69f16 | 118 | return post_render; |
lmayencou | 0:649b2fe69f16 | 119 | } |
lmayencou | 0:649b2fe69f16 | 120 | |
lmayencou | 0:649b2fe69f16 | 121 | void clear() |
lmayencou | 0:649b2fe69f16 | 122 | { |
lmayencou | 0:649b2fe69f16 | 123 | clearDisplay(); |
lmayencou | 0:649b2fe69f16 | 124 | } |
lmayencou | 0:649b2fe69f16 | 125 | |
lmayencou | 0:649b2fe69f16 | 126 | void setCursor(int16_t x, int16_t y) |
lmayencou | 0:649b2fe69f16 | 127 | { |
lmayencou | 0:649b2fe69f16 | 128 | setTextCursor(x,y); |
lmayencou | 0:649b2fe69f16 | 129 | } |
lmayencou | 0:649b2fe69f16 | 130 | |
lmayencou | 0:649b2fe69f16 | 131 | uint8_t frameRate; |
lmayencou | 0:649b2fe69f16 | 132 | uint16_t frameCount; |
lmayencou | 0:649b2fe69f16 | 133 | uint8_t eachFrameMillis; |
lmayencou | 0:649b2fe69f16 | 134 | long lastFrameStart; |
lmayencou | 0:649b2fe69f16 | 135 | long nextFrameStart; |
lmayencou | 0:649b2fe69f16 | 136 | bool post_render; |
lmayencou | 0:649b2fe69f16 | 137 | uint8_t lastFrameDurationMs; |
lmayencou | 0:649b2fe69f16 | 138 | |
lmayencou | 0:649b2fe69f16 | 139 | protected: |
lmayencou | 0:649b2fe69f16 | 140 | unsigned char sBuffer[(HEIGHT*WIDTH)/8]; |
lmayencou | 0:649b2fe69f16 | 141 | }; |