The Bubbleworks / NanoBit

Dependents:   TheBubbleWorks_MicroBorg

Fork of NanoBit by Wayne Keenan

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;
+}
+