Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TheBubbleWorks_MicroBorg
Fork of NanoBit by
Diff: NanoBitDisplay.cpp
- Revision:
- 1:7a9d736530c8
- Parent:
- 0:b34dc22c2bdd
- Child:
- 2:b45f392b18eb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/NanoBitDisplay.cpp Wed Feb 10 19:06:22 2016 +0000
@@ -0,0 +1,201 @@
+#include <new>
+#include "nrf_gpio.h"
+#include "mbed.h"
+#include "NanoBitDisplay.h"
+
+#define MY_DBG_ENABLED 1
+#include "MyDebug.h"
+
+
+const uint8_t panicFace[MICROBIT_DISPLAY_COLUMN_COUNT] = {0x1B, 0x1B,0x0,0x0E,0x11};
+
+const uint8_t heart[]={
+0, 1, 0, 1, 0,
+1, 1, 1, 1, 1,
+1, 1, 1, 1, 1,
+0, 1, 1, 1, 0,
+0, 0, 1, 0, 0}; // a cute heart
+
+const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
+{
+ {MatrixPoint(0,0),MatrixPoint(4,2),MatrixPoint(2,4)},
+ {MatrixPoint(2,0),MatrixPoint(0,2),MatrixPoint(4,4)},
+ {MatrixPoint(4,0),MatrixPoint(2,2),MatrixPoint(0,4)},
+ {MatrixPoint(4,3),MatrixPoint(1,0),MatrixPoint(0,1)},
+ {MatrixPoint(3,3),MatrixPoint(3,0),MatrixPoint(1,1)},
+ {MatrixPoint(2,3),MatrixPoint(3,4),MatrixPoint(2,1)},
+ {MatrixPoint(1,3),MatrixPoint(1,4),MatrixPoint(3,1)},
+ {MatrixPoint(0,3),MatrixPoint(NO_CONN,NO_CONN),MatrixPoint(4,1)},
+ {MatrixPoint(1,2),MatrixPoint(NO_CONN,NO_CONN),MatrixPoint(3,2)}
+};
+
+/**
+ * Constructor.
+ * Create a representation of a display of a given size.
+ * The display is initially blank.
+ *
+ * @param x the width of the display in pixels.
+ * @param y the height of the display in pixels.
+ *
+ * Example:
+ * @code
+ * MicroBitDisplay display(MICROBIT_ID_DISPLAY, 5, 5),
+ * @endcode
+ */
+MicroBitDisplay::MicroBitDisplay(uint16_t id, uint8_t x, uint8_t y) {
+ //set pins as output
+ nrf_gpio_range_cfg_output(MICROBIT_DISPLAY_COLUMN_START,MICROBIT_DISPLAY_COLUMN_START + MICROBIT_DISPLAY_COLUMN_COUNT + MICROBIT_DISPLAY_ROW_COUNT);
+
+ this->width = x;
+ this->height = y;
+ this->strobeRow = 0;
+ this->strobeBitMsk = 0x20;
+// this->timingCount = 0;
+
+ this->setBrightness(MICROBIT_DEFAULT_BRIGHTNESS);
+ uint8_t defaultBitmap[MICROBIT_DISPLAY_COLUMN_COUNT]= {
+ 0b101010,
+ 0b101010,
+ 0b101010,
+ 0b101010,
+ 0b101010
+ };
+
+ //memcpy(bitmap, panicFace, sizeof(bitmap));
+ memcpy(bitmap, heart, sizeof(bitmap));
+ systemTicker.attach(this, &MicroBitDisplay::systemTick, MICROBIT_DISPLAY_REFRESH_PERIOD);
+
+}
+
+/**
+ * Internal frame update method, used to strobe the display.
+ *
+ * TODO: Write a more efficient, complementary variation of this method for the case where
+ * MICROBIT_DISPLAY_ROW_COUNT > MICROBIT_DISPLAY_COLUMN_COUNT.
+ */
+void MicroBitDisplay::systemTick()
+{
+ // Move on to the next row.
+ strobeBitMsk <<= 1;
+ strobeRow++;
+
+ //reset the row counts and bit mask when we have hit the max.
+ if(strobeRow >= MICROBIT_DISPLAY_ROW_COUNT){
+ strobeRow = 0;
+ strobeBitMsk = 0x20;
+ }
+
+ render();
+}
+
+void MicroBitDisplay::renderFinish()
+{
+ //kept inline to reduce overhead
+ //clear the old bit pattern for this row.
+ //clear port 0 4-7 and retain lower 4 bits
+ nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT0, 0xF0 | nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0) & 0x0F);
+
+ // clear port 1 8-12 for the current row
+ nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, strobeBitMsk | 0x1F);
+}
+
+void MicroBitDisplay::render()
+{
+ if(brightness == 0)
+ return;
+
+ int coldata = 0;
+
+ // Calculate the bitpattern to write.
+ for (int i = 0; i<MICROBIT_DISPLAY_COLUMN_COUNT; i++)
+ {
+ //MY_DBG_PRINTF("%d,%d,", i, strobeRow);
+ int x = matrixMap[i][strobeRow].x;
+ int y = matrixMap[i][strobeRow].y;
+ //MY_DBG_PRINTF("%d,%d => bitmap[%d]\n", x,y, y*(width*2)+x);
+
+ if(bitmap[y*(width)+x]) {
+
+ coldata |= (1 << i);
+ }
+ }
+
+ //write the new bit pattern
+ //set port 0 4-7 and retain lower 4 bits
+ nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT0, ~coldata<<4 & 0xF0 | nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0) & 0x0F);
+
+ //set port 1 8-12 for the current row
+ nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, strobeBitMsk | (~coldata>>4 & 0x1F));
+
+ //timer does not have enough resolution for brightness of 1. 23.53 us
+ if(brightness != MICROBIT_DISPLAY_MAX_BRIGHTNESS && brightness > MICROBIT_DISPLAY_MIN_BRIGHTNESS)
+ renderTimer.attach(this, &MicroBitDisplay::renderFinish, (((float)brightness) / ((float)MICROBIT_DISPLAY_MAX_BRIGHTNESS)) * (float)MICROBIT_DISPLAY_REFRESH_PERIOD);
+
+ //this will take around 23us to execute
+ if(brightness <= MICROBIT_DISPLAY_MIN_BRIGHTNESS)
+ renderFinish();
+}
+
+
+/**
+ * Enables the display, should only be called if the display is disabled.
+ *
+ * Example:
+ * @code
+ * uBit.display.enable(); //reenables the display mechanics
+ * @endcode
+ */
+void MicroBitDisplay::enable()
+{
+ setBrightness(brightness);
+}
+
+/**
+ * Disables the display, should only be called if the display is enabled.
+ * Display must be disabled to avoid MUXing of edge connector pins.
+ *
+ * Example:
+ * @code
+ * uBit.display.disable(); //disables the display
+ * @endcode
+ */
+void MicroBitDisplay::disable()
+{
+}
+
+/**
+ * Clears the current image on the display.
+ * Simplifies the process, you can also use uBit.display.image.clear
+ *
+ * Example:
+ * @code
+ * uBit.display.clear(); //clears the display
+ * @endcode
+ */
+void MicroBitDisplay::clear()
+{
+ memset(bitmap, 0, sizeof(bitmap));
+}
+
+
+/**
+ * Sets the display brightness to the specified level.
+ * @param b The brightness to set the brightness to, in the range 0..255.
+ *
+ * Example:
+ * @code
+ * uBit.display.setBrightness(255); //max brightness
+ * @endcode
+ */
+void MicroBitDisplay::setBrightness(int b)
+{
+ //sanitise the brightness level
+ if(b < 0)
+ b = 0;
+
+ if (b > 255)
+ b = 255;
+
+ this->brightness = b;
+}
+
