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.
Fork of sharp_mlcd by
sharp_mlcd.cpp
- Committer:
- noripyon
- Date:
- 2018-03-20
- Revision:
- 2:9898a647e88b
- Parent:
- 1:f8ba3b236d12
File content as of revision 2:9898a647e88b:
/*
* mbed library for the Sharp memory LCD LS027BDH01 / LS013B4DN04
* derived from C12832_lcd
* Copyright (c) 2014 Masato YAMANISHI
* Released under the MIT License: http://mbed.org/license/mit
*/
/* mbed library for the mbed Lab Board 128*32 pixel LCD
* use C12832 controller
* Copyright (c) 2012 Peter Drescher - DC2PD
* Released under the MIT License: http://mbed.org/license/mit
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// 13.10.12 initial design
// 25.10.12 add autorefresh of screen
// 25.10.12 add standart font
// 20.12.12 add bitmap graphics
// optional defines :
// #define debug_lcd 1
// #include "mbed.h"
#include "sharp_mlcd.h"
#include "stdio.h"
#include "Small_7.h"
sharp_mlcd::sharp_mlcd(const char* name)
: _spi(D11,NC,D13),_EXTCOM(D9),_DISP(D8),_CS(D10), GraphicsDisplay(name) // for nucleo L152RE or other
{
draw_mode = NORMAL;
char_x = 0;
lcd_reset();
}
int sharp_mlcd::width()
{
return WIDTH;
}
int sharp_mlcd::height()
{
return HEIGHT; // 32;
}
// write command to lcd controller
// reset and init the lcd controller
void sharp_mlcd::lcd_reset()
{
_CS = 0;
_spi.format(8, 0); // 8 bit spi mode 0
_spi.frequency(2000000); // 2 Mhz SPI clock
_DISP = 1;
flip = 0;
set_reverse_mode(0);
// timer.attach(attime, 0.5); // 1KHz
_CS = 1;
wait_us(4);
_spi.write(0x20); // 0x20:clear 0x00:run
_spi.write(0); // dummy
wait_us(2);
_CS = 0;
// clear and update LCD
cls();
// memset(buffer,0xff,BUFFER_SIZE); // clear display buffer
// copy_to_lcd();
auto_up = 1; // switch on auto update
// dont do this by default. Make the user call
//claim(stdout); // redirekt printf to lcd
locate(0,0);
set_font((unsigned char*)Small_7); // standart font
}
void sharp_mlcd::set_reverse_mode(unsigned int r = 0)
{
reverse = r;
}
// set one pixel in buffer
void sharp_mlcd::pixel(int x, int y, int color)
{
// first check parameter
if(x > WIDTH || y > HEIGHT || x < 0 || y < 0) return;
if(draw_mode == NORMAL) {
if(color != reverse)
buffer[x/8 + (y*WIDTH/8)] &= ~(1 << (7-(x%8))); // set pixel
else
buffer[x/8 + (y*WIDTH/8)] |= (1 << (7-(x%8))); // erase pixel
} else { // XOR mode
if(color != reverse)
buffer[x/8 + (y*WIDTH/8)] ^= (1 << (7-(x%8))); // xor pixel
}
}
// update lcd
void sharp_mlcd::attime() {
flip = !flip;
_EXTCOM = flip;
}
unsigned char sharp_mlcd::bit_reverse(unsigned char c) {
unsigned char u=0; // c = TESTVALUE;
int i;
for (i=0 ; i<4 ; i++)
u |= ((c & (1 << i)) << (7-2*i)) | ((c & (1 << 7-i)) >> (7-2*i));
return u;
}
void sharp_mlcd::copy_to_lcd(void)
{
const int start = 0;
int x, y;
unsigned char *p = (unsigned char*)buffer; // image;
_CS = 1;
wait_us(4); // min 3us
//
for (y = 0; y < HEIGHT; y++) {
_spi.write(0x80); // update mode (multi line)
_spi.write(bit_reverse((y + 1 + start) % HEIGHT)); // set gate line address
for (x = 0; x < (WIDTH / 8); x++) {
_spi.write(*p++); // (((y / 8) + x + mode) % 2)? 0xff: 0);
}
}
//
wait_us(2); // min 1us
_CS = 0;
}
void sharp_mlcd::cls(void)
{
memset(buffer, reverse? 0x00: 0xff, BUFFER_SIZE); // clear display buffer
copy_to_lcd();
}
void sharp_mlcd::line(int x0, int y0, int x1, int y1, int color)
{
int dx = 0, dy = 0;
int dx_sym = 0, dy_sym = 0;
int dx_x2 = 0, dy_x2 = 0;
int di = 0;
dx = x1-x0;
dy = y1-y0;
// if (dx == 0) { /* vertical line */
// if (y1 > y0) vline(x0,y0,y1,color);
// else vline(x0,y1,y0,color);
// return;
// }
if (dx > 0) {
dx_sym = 1;
} else {
dx_sym = -1;
}
// if (dy == 0) { /* horizontal line */
// if (x1 > x0) hline(x0,x1,y0,color);
// else hline(x1,x0,y0,color);
// return;
// }
if (dy > 0) {
dy_sym = 1;
} else {
dy_sym = -1;
}
dx = dx_sym*dx;
dy = dy_sym*dy;
dx_x2 = dx*2;
dy_x2 = dy*2;
if (dx >= dy) {
di = dy_x2 - dx;
while (x0 != x1) {
pixel(x0, y0, color);
x0 += dx_sym;
if (di<0) {
di += dy_x2;
} else {
di += dy_x2 - dx_x2;
y0 += dy_sym;
}
}
pixel(x0, y0, color);
} else {
di = dx_x2 - dy;
while (y0 != y1) {
pixel(x0, y0, color);
y0 += dy_sym;
if (di < 0) {
di += dx_x2;
} else {
di += dx_x2 - dy_x2;
x0 += dx_sym;
}
}
pixel(x0, y0, color);
}
if(auto_up) copy_to_lcd();
}
void sharp_mlcd::rect(int x0, int y0, int x1, int y1, int color)
{
if (x1 > x0) line(x0,y0,x1,y0,color);
else line(x1,y0,x0,y0,color);
if (y1 > y0) line(x0,y0,x0,y1,color);
else line(x0,y1,x0,y0,color);
if (x1 > x0) line(x0,y1,x1,y1,color);
else line(x1,y1,x0,y1,color);
if (y1 > y0) line(x1,y0,x1,y1,color);
else line(x1,y1,x1,y0,color);
if(auto_up) copy_to_lcd();
}
void sharp_mlcd::fillrect(int x0, int y0, int x1, int y1, int color)
{
int l,c,i;
if(x0 > x1) {
i = x0;
x0 = x1;
x1 = i;
}
if(y0 > y1) {
i = y0;
y0 = y1;
y1 = i;
}
for(l = x0; l<= x1; l ++) {
for(c = y0; c<= y1; c++) {
pixel(l,c,color);
}
}
if(auto_up) copy_to_lcd();
}
void sharp_mlcd::circle(int x0, int y0, int r, int color)
{
int draw_x0, draw_y0;
int draw_x1, draw_y1;
int draw_x2, draw_y2;
int draw_x3, draw_y3;
int draw_x4, draw_y4;
int draw_x5, draw_y5;
int draw_x6, draw_y6;
int draw_x7, draw_y7;
int xx, yy;
int di;
//WindowMax();
if (r == 0) { /* no radius */
return;
}
draw_x0 = draw_x1 = x0;
draw_y0 = draw_y1 = y0 + r;
if (draw_y0 < height()) {
pixel(draw_x0, draw_y0, color); /* 90 degree */
}
draw_x2 = draw_x3 = x0;
draw_y2 = draw_y3 = y0 - r;
if (draw_y2 >= 0) {
pixel(draw_x2, draw_y2, color); /* 270 degree */
}
draw_x4 = draw_x6 = x0 + r;
draw_y4 = draw_y6 = y0;
if (draw_x4 < width()) {
pixel(draw_x4, draw_y4, color); /* 0 degree */
}
draw_x5 = draw_x7 = x0 - r;
draw_y5 = draw_y7 = y0;
if (draw_x5>=0) {
pixel(draw_x5, draw_y5, color); /* 180 degree */
}
if (r == 1) {
return;
}
di = 3 - 2*r;
xx = 0;
yy = r;
while (xx < yy) {
if (di < 0) {
di += 4*xx + 6;
} else {
di += 4*(xx - yy) + 10;
yy--;
draw_y0--;
draw_y1--;
draw_y2++;
draw_y3++;
draw_x4--;
draw_x5++;
draw_x6--;
draw_x7++;
}
xx++;
draw_x0++;
draw_x1--;
draw_x2++;
draw_x3--;
draw_y4++;
draw_y5++;
draw_y6--;
draw_y7--;
if ( (draw_x0 <= width()) && (draw_y0>=0) ) {
pixel(draw_x0, draw_y0, color);
}
if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) {
pixel(draw_x1, draw_y1, color);
}
if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) {
pixel(draw_x2, draw_y2, color);
}
if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) {
pixel(draw_x3, draw_y3, color);
}
if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) {
pixel(draw_x4, draw_y4, color);
}
if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) {
pixel(draw_x5, draw_y5, color);
}
if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) {
pixel(draw_x6, draw_y6, color);
}
if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) {
pixel(draw_x7, draw_y7, color);
}
}
if(auto_up) copy_to_lcd();
}
void sharp_mlcd::fillcircle(int x, int y, int r, int color)
{
int i,up;
up = auto_up;
auto_up = 0; // off
for (i = 0; i <= r; i++)
circle(x,y,i,color);
auto_up = up;
if(auto_up) copy_to_lcd();
}
void sharp_mlcd::setmode(int mode)
{
draw_mode = mode;
}
void sharp_mlcd::locate(int x, int y)
{
char_x = x;
char_y = y;
}
int sharp_mlcd::columns()
{
return width() / font[1];
}
int sharp_mlcd::rows()
{
return height() / font[2];
}
int sharp_mlcd::_putc(int value)
{
if (value == '\n') { // new line
char_x = 0;
char_y = char_y + font[2];
if (char_y >= height() - font[2]) {
char_y = 0;
}
} else {
character(char_x, char_y, value);
if(auto_up) copy_to_lcd();
}
return value;
}
void sharp_mlcd::character(int x, int y, int c)
{
unsigned int hor,vert,offset,bpl,j,i,b;
unsigned char* zeichen;
unsigned char z,w;
if ((c < 31) || (c > 127)) return; // test char range
// read font parameter from start of array
// offset = font[0]; // bytes / char
offset = (font[4]<<8) + font[0]; // bytes / char
hor = font[1]; // get hor size of font
vert = font[2]; // get vert size of font
bpl = font[3]; // bytes per line
if (char_x + hor > width()) {
char_x = 0;
char_y = char_y + vert;
if (char_y >= height() - font[2]) {
char_y = 0;
}
}
// zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
zeichen = &font[((c -32) * offset) + 5]; // start of char bitmap
w = zeichen[0]; // width of actual char
// construct the char into the buffer
for (j=0; j<vert; j++) { // vert line
for (i=0; i<hor; i++) { // horz line
z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
b = 1 << (j & 0x07);
if (( z & b ) == 0x00) {
pixel(x+i,y+j,0);
} else {
pixel(x+i,y+j,1);
}
}
}
char_x += w;
}
void sharp_mlcd::set_font(unsigned char* f)
{
font = f;
}
void sharp_mlcd::set_auto_up(unsigned int up)
{
if(up ) auto_up = 1;
else auto_up = 0;
}
unsigned int sharp_mlcd::get_auto_up(void)
{
return (auto_up);
}
void sharp_mlcd::print_bm(Bitmap bm, int x, int y, int color = 1)
{
int h,v,b;
char d;
for(v=0; v < bm.ySize; v++) { // lines
for(h=0; h < bm.xSize; h++) { // pixel
if(h + x > WIDTH-1) break;
if(v + y > HEIGHT-1) break;
d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)];
b = 0x80 >> (h & 0x07);
if((d & b) == 0) {
pixel(x+h,y+v,!color);
} else {
pixel(x+h,y+v,color);
}
}
}
}
