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
NanoBitDisplay.cpp
- Committer:
- waynek
- Date:
- 2016-02-10
- Revision:
- 1:7a9d736530c8
- Parent:
- BBL_MicroBit_Display.cpp@ 0:b34dc22c2bdd
- Child:
- 2:b45f392b18eb
File content as of revision 1:7a9d736530c8:
#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;
}
