DCF77 Atomic clock using Nokia 6610 colour LCD display. This will continue to run with no signal and shows a graphic bit map display demonstrating the time build. Does not use the Mbed RTC so will run on the LPC11U24. The main signal timing is achieved by using a Ticker ISR that looks at the DCF signal input every 50mS this also produces the seconds on the local clock incase of signal errors or no signal. Many thanks to Lynton Towler for the idea of this part of the code and Wim who helped me convert it from an Arduino program. The Parity code was fromHans program that works.

Dependencies:   mbed

/media/uploads/star297/_scaled_20130306_221042.jpg

Re published due to error in title.

I have also updated the 'Leap' year print code as that was incorrect.

This program works on the both Mbed's (LPC1768 and LPC11U24)

NokiaLCD_X3/MobileLCD.cpp

Committer:
star297
Date:
2013-03-19
Revision:
2:31f5b5d56af6
Parent:
1:cad87f63a115

File content as of revision 2:31f5b5d56af6:

/* mbed Library - Nokia LCD Labelled "X3"
* This is using the Philips PCF8833 controller
 * Copyright (c) 2009 P.R.Green
 */

#include "MobileLCD.h"

#include "mbed.h"

using namespace mbed;

MobileLCD::MobileLCD(PinName mosi, PinName miso, PinName clk, PinName cs, PinName rst)
        : _spi(mosi, miso, clk)
        , _rst(rst)
        , _cs(cs) {
    _row = 0;
    _column = 0;
    _rows = 16;
    _columns = 16;
    _width = 130;
    _height = 130;
    foreground(0xFFFF);
    background(0x0000);
    reset();
}

void MobileLCD::reset() {
    long i;
    _cs = 1;
    _rst = 0;
    _spi.format(9);
    _spi.frequency(5000000);
    wait(0.020);
    _rst = 1;
    wait(0.020);
    _select();
    command(0x11);//SLEEPOUT
    command(0x3A);//COLMOD
    data(0x05);//0x03 = 16bits-per-pixel 5:6:5 mode
    command(0x36);//MADCTL
    data(0x60);// 0x60 = mirror x, vertical RAM write
    command(0x25);//SETCON
    data(0x42);// contrast 0x30
    wait(0.002);
    command(0x29);//DISPON
    command(0x03);//BSTRON

    command(0x2B);//Row Address Set
    data(0);
    data(131);

    command(0x2A);//Column Address Set
    data(0);
    data(131);

    command(0x2C);//RAMWR
    //Clear RAM to black
    for (i=0; i < (132 * 132); i++) {
        data(0);
        data(0);
    }
    _deselect();
}

void MobileLCD::command(int value) {
    _spi.write(value & 0xFF);
}

void MobileLCD::data(int value) {
    _spi.write(value | 0x100);
}

void MobileLCD::_select() {
    _spi.format(9);
    _spi.frequency(5000000);
    _cs = 0;
}

void MobileLCD::_deselect() {
    _cs = 1;
}

void MobileLCD::_window(int x, int y, int width, int height) {
    int x1, x2, y1, y2;
    switch (0) { //_rotation) {
        default:
        case 0:
            x1 = x + 1;
            y1 = y + 1;
            x2 = x1 + width - 1;
            y2 = y1 + height -1 ;
            break;
        case 1:
            x1 = y + 1;
            y1 = x + 1;
            x2 = x1 + height - 1;
            y2 = y1 + width - 1;
            break;
        case 2:
            x1 = x + 1;
            y1 = y + 3;
            x2 = x1 + width - 1;
            y2 = y1 + height - 1;
            break;
        case 3:
            x1 = y + 3;
            y1 = x + 3;
            x2 = x1 + height - 1;
            y2 = y1 + width - 1;
            break;
    }
    command(0x2A); //CASET column
    data(x1);
    data(x2);
    command(0x2B); //PASET page
    data(y1);
    data(y2);
    command(0x2C); //RAMWR start write to ram
}

void MobileLCD::_putp(int colour) {

    data((colour >> 8) & 0xFF);
    data(colour & 0xFF);

}
/*
void MobileLCD::orientation() {
    int m;
    switch (0) { //_rotation) {
        case 0:
        default:
            m = 3;
            break;
        case 2:
            m = 0;
            break;
        case 1:
            m = 5;
            break;
        case 3:
            m = 6;
            break;
    }

    command(0xBC); // data control
    data(m); // scan dirs
    data(1); // RGB
    data(4); // grayscale
}
*/

const unsigned char FONT8x8[97][8] = {
    0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
    0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // !
    0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // "
    0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // #
    0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $
    0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00, // %
    0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00, // &
    0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00, // '
    0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // (
    0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // )
    0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // *
    0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00, // +
    0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // ,
    0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // -
    0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // .
    0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash)
    0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30
    0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1
    0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2
    0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3
    0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00, // 4
    0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00, // 5
    0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00, // 6
    0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00, // 7
    0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00, // 8
    0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00, // 9
    0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // :
    0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ;
    0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00, // <
    0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // =
    0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00, // >
    0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00, // ?
    0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00, // @ 0x40
    0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00, // A
    0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00, // B
    0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00, // C
    0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00, // D
    0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00, // E
    0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00, // F
    0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00, // G
    0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00, // H
    0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I
    0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // J
    0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00, // K
    0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00, // L
    0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00, // M
    0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00, // N
    0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00, // O
    0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00, // P 0x50
    0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00, // Q
    0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00, // R
    0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00, // S
    0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00, // T
    0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, // U
    0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00, // V
    0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, // W
    0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00, // X
    0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y
    0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00, // Z
    0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [
    0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // \ (back slash)
    0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ]
    0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, // ^
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _
    0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ` 0x60
    0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00, // a
    0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00, // b
    0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00, // c
    0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00, // d
    0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, // e
    0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00, // f
    0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C, // g
    0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00, // h
    0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i
    0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j
    0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00, // k
    0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l
    0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, // m
    0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00, // n
    0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, // o
    0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78, // p
    0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F, // q
    0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00, // r
    0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, // s
    0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00, // t
    0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00, // u
    0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00, // v
    0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00, // w
    0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00, // x
    0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C, // y
    0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z
    0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // {
    0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // |
    0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // }
    0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~
    0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00
}; // DEL

void MobileLCD::locate(int column, int row) {
    _row = row;
    _column = column;
}

void MobileLCD::newline() {
    _column = 0;
    _row++;
    if (_row >= _rows) {
        _row = 0;
    }
}

int MobileLCD::_putc(int value) {
    int x = _column * 8;  // FIXME: Char sizes
    int y = _row * 8;
    bitblit(x , y , 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));

    _column++;

    if (_column >= _columns) {
        _row++;
        _column = 0;
    }

    if (_row >= _rows) {
        _row = 0;
    }

    return value;
}

void MobileLCD::cls() {
    fill(0, 0, _width, _height, _background);
    _row = 0;
    _column = 0;
}

int MobileLCD::width() {
    return _width;
}

int MobileLCD::height() {
    return _height;
}

int MobileLCD::columns() {
    return _columns;
}

int MobileLCD::rows() {
    return _rows;
}

void MobileLCD::window(int x, int y, int width, int height) {
    _select();
    _window(x, y, width, height);
    _deselect();
}

void MobileLCD::putp(int colour) {
    _select();
    _putp(colour);
    _deselect();
}

void MobileLCD::pixel(int x, int y, int colour) {
    _select();
    _window(x, y, 1, 1);
    _putp(colour);
    _deselect();
}

void MobileLCD::fill(int x, int y, int width, int height, int colour) {
    _select();
    _window(x, y, width, height);
    for (int i=0; i<width*height; i++) {
        _putp(colour);
    }
    _window(0, 0, _width, _height);
    _deselect();
}


void MobileLCD::blit(int x, int y, int width, int height, const int* colour) {
    _select();
    _window(x, y, width, height);
    for (int i=0; i<width*height; i++) {
        _putp(colour[i]);
    }
    _window(0, 0, _width, _height);
    _deselect();
}

void MobileLCD::foreground(int v) {
    _foreground = v;
}

void MobileLCD::background(int v) {
    _background = v;
}

void MobileLCD::bitblit(int x, int y, int width, int height, const char* bitstream) {
    _select();
    _window(x, y, width, height);

    for (int i=0; i<height*width; i++) {
        unsigned char byte = i / 8;
        unsigned char bit = i % 8;
        int colour = (((bitstream[byte] << bit) & 0x80) ? _foreground : _background);
        _putp(colour);
    }
    _window(0, 0, _width, _height);
    _deselect();
}