Cutdown and discrete versions of the official MicroBit libraries.
Dependents: TheBubbleWorks_MicroBorg
Fork of NanoBit by
NanoBitDisplay.cpp@4:117f7dca8b81, 2016-03-14 (annotated)
- Committer:
- waynek
- Date:
- Mon Mar 14 09:13:31 2016 +0000
- Revision:
- 4:117f7dca8b81
- Parent:
- 3:388d7fc71320
remove debug image
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
waynek | 0:b34dc22c2bdd | 1 | #include <new> |
waynek | 0:b34dc22c2bdd | 2 | #include "nrf_gpio.h" |
waynek | 0:b34dc22c2bdd | 3 | #include "mbed.h" |
waynek | 2:b45f392b18eb | 4 | #include "NanoBitPins.h" |
waynek | 1:7a9d736530c8 | 5 | #include "NanoBitDisplay.h" |
waynek | 0:b34dc22c2bdd | 6 | |
waynek | 0:b34dc22c2bdd | 7 | #include "MyDebug.h" |
waynek | 0:b34dc22c2bdd | 8 | |
waynek | 3:388d7fc71320 | 9 | /* |
waynek | 0:b34dc22c2bdd | 10 | const uint8_t panicFace[MICROBIT_DISPLAY_COLUMN_COUNT] = {0x1B, 0x1B,0x0,0x0E,0x11}; |
waynek | 2:b45f392b18eb | 11 | const uint8_t defaultBitmap[MICROBIT_DISPLAY_COLUMN_COUNT]= { |
waynek | 2:b45f392b18eb | 12 | 0b10101, |
waynek | 2:b45f392b18eb | 13 | 0b10101, |
waynek | 2:b45f392b18eb | 14 | 0b10101, |
waynek | 2:b45f392b18eb | 15 | 0b10101, |
waynek | 2:b45f392b18eb | 16 | 0b10101 |
waynek | 2:b45f392b18eb | 17 | }; |
waynek | 4:117f7dca8b81 | 18 | |
waynek | 0:b34dc22c2bdd | 19 | const uint8_t heart[]={ |
waynek | 0:b34dc22c2bdd | 20 | 0, 1, 0, 1, 0, |
waynek | 0:b34dc22c2bdd | 21 | 1, 1, 1, 1, 1, |
waynek | 0:b34dc22c2bdd | 22 | 1, 1, 1, 1, 1, |
waynek | 0:b34dc22c2bdd | 23 | 0, 1, 1, 1, 0, |
waynek | 0:b34dc22c2bdd | 24 | 0, 0, 1, 0, 0}; // a cute heart |
waynek | 4:117f7dca8b81 | 25 | */ |
waynek | 3:388d7fc71320 | 26 | |
waynek | 0:b34dc22c2bdd | 27 | const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] = |
waynek | 0:b34dc22c2bdd | 28 | { |
waynek | 0:b34dc22c2bdd | 29 | {MatrixPoint(0,0),MatrixPoint(4,2),MatrixPoint(2,4)}, |
waynek | 0:b34dc22c2bdd | 30 | {MatrixPoint(2,0),MatrixPoint(0,2),MatrixPoint(4,4)}, |
waynek | 0:b34dc22c2bdd | 31 | {MatrixPoint(4,0),MatrixPoint(2,2),MatrixPoint(0,4)}, |
waynek | 0:b34dc22c2bdd | 32 | {MatrixPoint(4,3),MatrixPoint(1,0),MatrixPoint(0,1)}, |
waynek | 0:b34dc22c2bdd | 33 | {MatrixPoint(3,3),MatrixPoint(3,0),MatrixPoint(1,1)}, |
waynek | 0:b34dc22c2bdd | 34 | {MatrixPoint(2,3),MatrixPoint(3,4),MatrixPoint(2,1)}, |
waynek | 0:b34dc22c2bdd | 35 | {MatrixPoint(1,3),MatrixPoint(1,4),MatrixPoint(3,1)}, |
waynek | 0:b34dc22c2bdd | 36 | {MatrixPoint(0,3),MatrixPoint(NO_CONN,NO_CONN),MatrixPoint(4,1)}, |
waynek | 0:b34dc22c2bdd | 37 | {MatrixPoint(1,2),MatrixPoint(NO_CONN,NO_CONN),MatrixPoint(3,2)} |
waynek | 0:b34dc22c2bdd | 38 | }; |
waynek | 0:b34dc22c2bdd | 39 | |
waynek | 0:b34dc22c2bdd | 40 | /** |
waynek | 0:b34dc22c2bdd | 41 | * Constructor. |
waynek | 0:b34dc22c2bdd | 42 | * Create a representation of a display of a given size. |
waynek | 0:b34dc22c2bdd | 43 | * The display is initially blank. |
waynek | 0:b34dc22c2bdd | 44 | * |
waynek | 0:b34dc22c2bdd | 45 | * @param x the width of the display in pixels. |
waynek | 0:b34dc22c2bdd | 46 | * @param y the height of the display in pixels. |
waynek | 0:b34dc22c2bdd | 47 | * |
waynek | 0:b34dc22c2bdd | 48 | * Example: |
waynek | 0:b34dc22c2bdd | 49 | * @code |
waynek | 0:b34dc22c2bdd | 50 | * MicroBitDisplay display(MICROBIT_ID_DISPLAY, 5, 5), |
waynek | 0:b34dc22c2bdd | 51 | * @endcode |
waynek | 0:b34dc22c2bdd | 52 | */ |
waynek | 0:b34dc22c2bdd | 53 | MicroBitDisplay::MicroBitDisplay(uint16_t id, uint8_t x, uint8_t y) { |
waynek | 0:b34dc22c2bdd | 54 | //set pins as output |
waynek | 0:b34dc22c2bdd | 55 | nrf_gpio_range_cfg_output(MICROBIT_DISPLAY_COLUMN_START,MICROBIT_DISPLAY_COLUMN_START + MICROBIT_DISPLAY_COLUMN_COUNT + MICROBIT_DISPLAY_ROW_COUNT); |
waynek | 0:b34dc22c2bdd | 56 | |
waynek | 0:b34dc22c2bdd | 57 | this->width = x; |
waynek | 0:b34dc22c2bdd | 58 | this->height = y; |
waynek | 0:b34dc22c2bdd | 59 | this->strobeRow = 0; |
waynek | 0:b34dc22c2bdd | 60 | this->strobeBitMsk = 0x20; |
waynek | 0:b34dc22c2bdd | 61 | // this->timingCount = 0; |
waynek | 0:b34dc22c2bdd | 62 | |
waynek | 0:b34dc22c2bdd | 63 | this->setBrightness(MICROBIT_DEFAULT_BRIGHTNESS); |
waynek | 2:b45f392b18eb | 64 | |
waynek | 0:b34dc22c2bdd | 65 | |
waynek | 0:b34dc22c2bdd | 66 | //memcpy(bitmap, panicFace, sizeof(bitmap)); |
waynek | 3:388d7fc71320 | 67 | //memcpy(bitmap, heart, sizeof(bitmap)); |
waynek | 0:b34dc22c2bdd | 68 | systemTicker.attach(this, &MicroBitDisplay::systemTick, MICROBIT_DISPLAY_REFRESH_PERIOD); |
waynek | 0:b34dc22c2bdd | 69 | |
waynek | 0:b34dc22c2bdd | 70 | } |
waynek | 0:b34dc22c2bdd | 71 | |
waynek | 0:b34dc22c2bdd | 72 | /** |
waynek | 0:b34dc22c2bdd | 73 | * Internal frame update method, used to strobe the display. |
waynek | 0:b34dc22c2bdd | 74 | * |
waynek | 0:b34dc22c2bdd | 75 | * TODO: Write a more efficient, complementary variation of this method for the case where |
waynek | 0:b34dc22c2bdd | 76 | * MICROBIT_DISPLAY_ROW_COUNT > MICROBIT_DISPLAY_COLUMN_COUNT. |
waynek | 0:b34dc22c2bdd | 77 | */ |
waynek | 0:b34dc22c2bdd | 78 | void MicroBitDisplay::systemTick() |
waynek | 0:b34dc22c2bdd | 79 | { |
waynek | 0:b34dc22c2bdd | 80 | // Move on to the next row. |
waynek | 0:b34dc22c2bdd | 81 | strobeBitMsk <<= 1; |
waynek | 0:b34dc22c2bdd | 82 | strobeRow++; |
waynek | 0:b34dc22c2bdd | 83 | |
waynek | 0:b34dc22c2bdd | 84 | //reset the row counts and bit mask when we have hit the max. |
waynek | 0:b34dc22c2bdd | 85 | if(strobeRow >= MICROBIT_DISPLAY_ROW_COUNT){ |
waynek | 0:b34dc22c2bdd | 86 | strobeRow = 0; |
waynek | 0:b34dc22c2bdd | 87 | strobeBitMsk = 0x20; |
waynek | 0:b34dc22c2bdd | 88 | } |
waynek | 0:b34dc22c2bdd | 89 | |
waynek | 0:b34dc22c2bdd | 90 | render(); |
waynek | 0:b34dc22c2bdd | 91 | } |
waynek | 0:b34dc22c2bdd | 92 | |
waynek | 0:b34dc22c2bdd | 93 | void MicroBitDisplay::renderFinish() |
waynek | 0:b34dc22c2bdd | 94 | { |
waynek | 0:b34dc22c2bdd | 95 | //kept inline to reduce overhead |
waynek | 0:b34dc22c2bdd | 96 | //clear the old bit pattern for this row. |
waynek | 0:b34dc22c2bdd | 97 | //clear port 0 4-7 and retain lower 4 bits |
waynek | 0:b34dc22c2bdd | 98 | nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT0, 0xF0 | nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0) & 0x0F); |
waynek | 0:b34dc22c2bdd | 99 | |
waynek | 0:b34dc22c2bdd | 100 | // clear port 1 8-12 for the current row |
waynek | 0:b34dc22c2bdd | 101 | nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, strobeBitMsk | 0x1F); |
waynek | 0:b34dc22c2bdd | 102 | } |
waynek | 0:b34dc22c2bdd | 103 | |
waynek | 0:b34dc22c2bdd | 104 | void MicroBitDisplay::render() |
waynek | 0:b34dc22c2bdd | 105 | { |
waynek | 0:b34dc22c2bdd | 106 | if(brightness == 0) |
waynek | 0:b34dc22c2bdd | 107 | return; |
waynek | 0:b34dc22c2bdd | 108 | |
waynek | 0:b34dc22c2bdd | 109 | int coldata = 0; |
waynek | 0:b34dc22c2bdd | 110 | |
waynek | 0:b34dc22c2bdd | 111 | // Calculate the bitpattern to write. |
waynek | 0:b34dc22c2bdd | 112 | for (int i = 0; i<MICROBIT_DISPLAY_COLUMN_COUNT; i++) |
waynek | 0:b34dc22c2bdd | 113 | { |
waynek | 0:b34dc22c2bdd | 114 | //MY_DBG_PRINTF("%d,%d,", i, strobeRow); |
waynek | 0:b34dc22c2bdd | 115 | int x = matrixMap[i][strobeRow].x; |
waynek | 0:b34dc22c2bdd | 116 | int y = matrixMap[i][strobeRow].y; |
waynek | 0:b34dc22c2bdd | 117 | //MY_DBG_PRINTF("%d,%d => bitmap[%d]\n", x,y, y*(width*2)+x); |
waynek | 0:b34dc22c2bdd | 118 | |
waynek | 0:b34dc22c2bdd | 119 | if(bitmap[y*(width)+x]) { |
waynek | 0:b34dc22c2bdd | 120 | coldata |= (1 << i); |
waynek | 0:b34dc22c2bdd | 121 | } |
waynek | 0:b34dc22c2bdd | 122 | } |
waynek | 0:b34dc22c2bdd | 123 | |
waynek | 0:b34dc22c2bdd | 124 | //write the new bit pattern |
waynek | 0:b34dc22c2bdd | 125 | //set port 0 4-7 and retain lower 4 bits |
waynek | 0:b34dc22c2bdd | 126 | nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT0, ~coldata<<4 & 0xF0 | nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0) & 0x0F); |
waynek | 0:b34dc22c2bdd | 127 | |
waynek | 0:b34dc22c2bdd | 128 | //set port 1 8-12 for the current row |
waynek | 0:b34dc22c2bdd | 129 | nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, strobeBitMsk | (~coldata>>4 & 0x1F)); |
waynek | 0:b34dc22c2bdd | 130 | |
waynek | 0:b34dc22c2bdd | 131 | //timer does not have enough resolution for brightness of 1. 23.53 us |
waynek | 0:b34dc22c2bdd | 132 | if(brightness != MICROBIT_DISPLAY_MAX_BRIGHTNESS && brightness > MICROBIT_DISPLAY_MIN_BRIGHTNESS) |
waynek | 0:b34dc22c2bdd | 133 | renderTimer.attach(this, &MicroBitDisplay::renderFinish, (((float)brightness) / ((float)MICROBIT_DISPLAY_MAX_BRIGHTNESS)) * (float)MICROBIT_DISPLAY_REFRESH_PERIOD); |
waynek | 0:b34dc22c2bdd | 134 | |
waynek | 0:b34dc22c2bdd | 135 | //this will take around 23us to execute |
waynek | 0:b34dc22c2bdd | 136 | if(brightness <= MICROBIT_DISPLAY_MIN_BRIGHTNESS) |
waynek | 0:b34dc22c2bdd | 137 | renderFinish(); |
waynek | 0:b34dc22c2bdd | 138 | } |
waynek | 0:b34dc22c2bdd | 139 | |
waynek | 0:b34dc22c2bdd | 140 | |
waynek | 0:b34dc22c2bdd | 141 | /** |
waynek | 0:b34dc22c2bdd | 142 | * Enables the display, should only be called if the display is disabled. |
waynek | 0:b34dc22c2bdd | 143 | * |
waynek | 0:b34dc22c2bdd | 144 | * Example: |
waynek | 0:b34dc22c2bdd | 145 | * @code |
waynek | 0:b34dc22c2bdd | 146 | * uBit.display.enable(); //reenables the display mechanics |
waynek | 0:b34dc22c2bdd | 147 | * @endcode |
waynek | 0:b34dc22c2bdd | 148 | */ |
waynek | 0:b34dc22c2bdd | 149 | void MicroBitDisplay::enable() |
waynek | 0:b34dc22c2bdd | 150 | { |
waynek | 0:b34dc22c2bdd | 151 | setBrightness(brightness); |
waynek | 0:b34dc22c2bdd | 152 | } |
waynek | 0:b34dc22c2bdd | 153 | |
waynek | 0:b34dc22c2bdd | 154 | /** |
waynek | 0:b34dc22c2bdd | 155 | * Disables the display, should only be called if the display is enabled. |
waynek | 0:b34dc22c2bdd | 156 | * Display must be disabled to avoid MUXing of edge connector pins. |
waynek | 0:b34dc22c2bdd | 157 | * |
waynek | 0:b34dc22c2bdd | 158 | * Example: |
waynek | 0:b34dc22c2bdd | 159 | * @code |
waynek | 0:b34dc22c2bdd | 160 | * uBit.display.disable(); //disables the display |
waynek | 0:b34dc22c2bdd | 161 | * @endcode |
waynek | 0:b34dc22c2bdd | 162 | */ |
waynek | 0:b34dc22c2bdd | 163 | void MicroBitDisplay::disable() |
waynek | 0:b34dc22c2bdd | 164 | { |
waynek | 0:b34dc22c2bdd | 165 | } |
waynek | 0:b34dc22c2bdd | 166 | |
waynek | 0:b34dc22c2bdd | 167 | /** |
waynek | 0:b34dc22c2bdd | 168 | * Clears the current image on the display. |
waynek | 0:b34dc22c2bdd | 169 | * Simplifies the process, you can also use uBit.display.image.clear |
waynek | 0:b34dc22c2bdd | 170 | * |
waynek | 0:b34dc22c2bdd | 171 | * Example: |
waynek | 0:b34dc22c2bdd | 172 | * @code |
waynek | 0:b34dc22c2bdd | 173 | * uBit.display.clear(); //clears the display |
waynek | 0:b34dc22c2bdd | 174 | * @endcode |
waynek | 0:b34dc22c2bdd | 175 | */ |
waynek | 0:b34dc22c2bdd | 176 | void MicroBitDisplay::clear() |
waynek | 0:b34dc22c2bdd | 177 | { |
waynek | 0:b34dc22c2bdd | 178 | memset(bitmap, 0, sizeof(bitmap)); |
waynek | 0:b34dc22c2bdd | 179 | } |
waynek | 0:b34dc22c2bdd | 180 | |
waynek | 0:b34dc22c2bdd | 181 | |
waynek | 0:b34dc22c2bdd | 182 | /** |
waynek | 0:b34dc22c2bdd | 183 | * Sets the display brightness to the specified level. |
waynek | 0:b34dc22c2bdd | 184 | * @param b The brightness to set the brightness to, in the range 0..255. |
waynek | 0:b34dc22c2bdd | 185 | * |
waynek | 0:b34dc22c2bdd | 186 | * Example: |
waynek | 0:b34dc22c2bdd | 187 | * @code |
waynek | 0:b34dc22c2bdd | 188 | * uBit.display.setBrightness(255); //max brightness |
waynek | 0:b34dc22c2bdd | 189 | * @endcode |
waynek | 0:b34dc22c2bdd | 190 | */ |
waynek | 0:b34dc22c2bdd | 191 | void MicroBitDisplay::setBrightness(int b) |
waynek | 0:b34dc22c2bdd | 192 | { |
waynek | 0:b34dc22c2bdd | 193 | //sanitise the brightness level |
waynek | 0:b34dc22c2bdd | 194 | if(b < 0) |
waynek | 0:b34dc22c2bdd | 195 | b = 0; |
waynek | 0:b34dc22c2bdd | 196 | |
waynek | 0:b34dc22c2bdd | 197 | if (b > 255) |
waynek | 0:b34dc22c2bdd | 198 | b = 255; |
waynek | 0:b34dc22c2bdd | 199 | |
waynek | 0:b34dc22c2bdd | 200 | this->brightness = b; |
waynek | 0:b34dc22c2bdd | 201 | } |
waynek | 0:b34dc22c2bdd | 202 |