Vetinari's Clock

LPC810 Vetinari's Clock

Vetinari's Clock

/media/uploads/okini3939/_scaled_img_0661.jpg

Schematic

Schematic

	            LPC810
	           +--__--+
	RESET------|1    8|---[120]---coil2
	coil1------|2    7|-----------GND
	SWCLK------|3    6|---+-------+3V
	SWDIO------|4    5|---|--+
	           +------+   |  |                     +--+
	                      |  |          coil1------|  |
	       +--------------+  |                     |  |
	       |   SG-3030JC  |  |          coil2------|  |
	       |   +------+   |  |                     +--+
	       +---|1    4|---+  |                 Quartz Movement
	           |      |      |
	     GND---|2    3|------+
	           +------+
	           32.768KHz

Program

system_LPC81x.c

#define CLOCK_SETUP           1
#define SYSOSCCTRL_Val        0x00000000              // Reset: 0x000
#define WDTOSCCTRL_Val        0x00000000              // Reset: 0x000
#define SYSPLLCTRL_Val        0x00000000              // Reset: 0x000
#define SYSPLLCLKSEL_Val      0x00000003 // CLKIN             // Reset: 0x000
#define MAINCLKSEL_Val        0x00000001 // PLL in             // Reset: 0x000
#define SYSAHBCLKDIV_Val      0x00000001              // Reset: 0x001

main.c

#include "LPC8xx.h"

volatile int time = 0, timeout = 0, count = 0;

void SwitchMatrix_Init (void);

unsigned long xor128 () { 
	static unsigned long x = 123456789, y = 362436069, z = 521288629, w = 88675123; 
	unsigned long t; 
	t = (x^(x<<11));
	x=y; y=z; z=w;
	return (w = (w^(w>>19))^(t^(t>>8))); 
} 

unsigned int rand (int n) {
	unsigned long r;
	r = xor128() >> 16;
	r = r * n / 0xffff;
	return r;
}

void sleep () {
	LPC_PMU->PCON &= ~(7<<0);
	SCB->SCR &= ~(1<<2);
	__WFI();
}

void MRT_IRQHandler () {
	static int n = 0;

	LPC_GPIO_PORT->CLR0 = ((1<<4)|(1<<0));
	LPC_MRT->Channel[0].STAT = (1<<0);

	n ++;
	if (n >= 32) {
		n = 0;
		time ++;
	}
	if (timeout) timeout --;
}

int main(void) {

	SwitchMatrix_Init();

	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
	LPC_GPIO_PORT->DIR0 = (1<<4)|(1<<0);

	LPC_SYSCON->PDRUNCFG |= (1<<7)|(1<<6)|(1<<5)|(1<<1)|(1<<0); // stop SYSPLL, WDTOSC, SYSOSC, IRC

	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // MRT
	LPC_SYSCON->PRESETCTRL &= ~(1<<7);
	LPC_SYSCON->PRESETCTRL |= (1<<7);
	LPC_MRT->Channel[0].INTVAL = 32768 / 32;
	LPC_MRT->Channel[0].INTVAL |= (1UL<<31);
	LPC_MRT->Channel[0].CTRL = (1<<0);
	LPC_MRT->Channel[0].STAT = (1<<1);
	NVIC_EnableIRQ(MRT_IRQn);
	__enable_irq();

	for (;;) {
		if (time < 50) {
			timeout = 10 + rand(45);
		} else {
			if (time < count) {
				// fast
				timeout = 32 + rand(20);
			} else
			if (time >= count) {
				// slow
				timeout = 32 - rand(25);
			}
		}

		if (time < 59) {
			while (timeout) sleep();
		} else {
			while (time < 59) sleep();
		}

		count ++;
		if (count >= 60) {
			time -= 60;
			count -= 60;
		}

		if (count & 1) {
			LPC_GPIO_PORT->SET0 = (1<<0);
		} else {
			LPC_GPIO_PORT->SET0 = (1<<4);
		}
	}
}

swm.c

#include "LPC8xx.h"    /* LPC8xx Peripheral Registers */
#include "type.h"

void SwitchMatrix_Init()
{
    /* Enable SWM clock */
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);

    /* Pin Assign 8 bit Configuration */
    /* none */

    /* Pin Assign 1 bit Configuration */
    /* SWCLK */
    /* SWDIO */
    /* CLKIN */
    LPC_SWM->PINENABLE0 = 0xffffff73UL;
}


2 comments on Vetinari's Clock:

25 Nov 2013

Are you running C in mbed compiler?

25 Nov 2013

It seems you are using Keil + LPCXpresso for LPC810.

Please log in to post comments.