/* ------------------------------------------------------------------------------------------------ */
/* FILE :		Demo_6_BB_LPC1343_IAR.c																*/
/*																									*/
/* CONTENTS :																						*/
/*				Demo for the NGX Technologies BlueBoard LPC1343 evaluation board					*/
/*				The ADC converts the value set by the trimmer										*/
/*				The value read is displayed on the serial port and LCD								*/
/*				Serial port settings:																*/
/*							Baud Rate: 115200														*/
/*							Data bits:      8														*/
/*							Stop bits:		1														*/
/*							Parity:      none														*/
/*							Flow Ctrl:   none														*/
/*																									*/
/*																									*/
/* Copyright (c) 2012, Code-Time Technologies Inc. All rights reserved.								*/
/*																									*/
/* Code-Time Technologies retains all right, title, and interest in and to this work				*/
/*																									*/
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS							*/
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF										*/
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 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.																	*/
/*																									*/
/*																									*/
/*	$Revision: 1.1 $																				*/
/*	$Date: 2012/06/28 15:19:55 $																	*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

#if OS_DEMO != 6
	#error "Wrong OS_DEMO value" 
#endif

#include <stdio.h>
#include <ctype.h>
#include <Abassi.h>

/* ------------------------------------------------ */

#include "LPC13xx.h"
#include "system_LPC13xx.h"
#include "adc.h"
#include "glcd_api.h"
#include "uart.h"

#define BAUDRATE	115200							/* Serial port baud rate						*/
#define SYS_FREQ	SystemCoreClock					/* Processor clock frequency					*/

extern void lcd_write_data(unsigned char data);
extern void SystemInit(void);
extern void UARTInit(uint32_t BaudRate);

extern volatile uint32_t ADCValue[ADC_NUM];
extern volatile uint8_t  UARTBuffer[BUFSIZE];
extern volatile uint32_t UARTCount;

#define LCD_LINE(_Pos,_Txt) do{init_xy_axis(PAGE0+_Pos,COL0);lcd_display_string((unsigned char *)_Txt);}while(0)

/* ------------------------------------------------ */

MBX_t *MbxADC;										/* Mailbox the ISR put thre ADC value in		*/
MBX_t *MbxTime;										/* Mailbox the ISR put the RTC valeu in			*/

TSK_t *A_E;

/* ------------------------------------------------ */

void ADChandler(void);

/* ------------------------------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------------------------------ */

int main()
{
unsigned int ADCval;								/* ADC value received from the mailbox			*/
int          ii;									/* General purpose								*/
int          jj;									/* General purpose								*/
intptr_t     Msg;									/* Message received from a mailbox				*/
int          Prio = 0;								/* SysTick interrupt priority					*/
unsigned int Time;									/* Running time value, received from ISR		*/
int          Tdigits[4];							/* To print the RTC								*/
int         *TimerBase;								/* SysTick register base address				*/

static char  Str[64];								/* String to print the update on serial port	*/

/* ------------------------------------------------ */
/* 	Processor clock set-up							*/

	SystemInit();

/* ------------------------------------------------ */
/* 	Start the RTOS									*/

	OSstart();

	A_E = TSKmyID();

/* ------------------------------------------------ */
/* SysTick Set-up									*/

	TimerBase = (int *)0xE000E000;
	((volatile int *)0xE000Ed20)[0] = (((volatile int *)0xE000Ed20)[0] & 0x1FFFFFFF)
	                                |   ((Prio & 7) << 29);
	OSisrInstall(-1, TIMtick);						/* Install the OS timer tick function			*/
	TimerBase[5] = (((SYS_FREQ/100000) * OS_TIMER_US)/10)-1;
	TimerBase[4] = 0x7;								/* internal clock / int & enable				*/

/* ------------------------------------------------ */
/* UART set-up										*/

	OSisrInstall(46, UART_IRQHandler);				/* NGX BSP uses the UART interrupts				*/
	UARTInit(BAUDRATE);

/* ------------------------------------------------ */
/* Init the LCD										*/

	init_glcd();
	glcd_clear();
	init_xy_axis(PAGE0,COL0);
	back_light_on();

/* ------------------------------------------------ */
/* ADC & set-up										*/

	OSisrInstall(49, ADChandler);					/* NGX DSP uses the ADC interrupts				*/
	ADCInit(ADC_CLK);

/* ------------------------------------------------ */
/* Application set-up								*/

	MbxADC  = MBXopen("ADC", 5);
	MbxTime = MBXopen("Time", 5);

/* ------------------------------------------------ */
/* Interrupts ON, the application runs				*/

	OSeint(1);

	puts("\n\n");									/* Welcome banner								*/
	puts("\n       Abassi Demo 6\n");
	puts("\n       NGX BB LPC1343\n");
	puts("\n      Use the trimmer\n\n");

	LCD_LINE(0, "        Abassi Demo 6   ");
	LCD_LINE(2, "       Use the trimmer  ");


	ADCval = 0;

	Tdigits[0] = 0;
	Tdigits[1] = 0;
	Tdigits[2] = 0;
	Tdigits[3] = 0;

	Str[0]     = ' ';
	Str[1]     = ' ';
	Str[2]     = ' ';

	for (;;) {
		EVTwait(0x0000, 0xFFFF, -1);				/* A&E Waiting for a new time or ADC value		*/
		while (0 == MBXget(MbxTime, &Msg, 0)) {		/* Empty the mailbox with the running time		*/
			Time = (unsigned int)Msg;				/* The ISR limits the time to < 3600			*/
			Tdigits[0] = Time       / 600;			/* Minutes MS digit								*/
			Time      -= Tdigits[0] * 600; 
			Tdigits[1] = Time       / 60;			/* Minutes LS digit								*/
			Time      -= Tdigits[1] * 60; 
			Tdigits[2] = Time       / 10;			/* Seconds MS digit								*/
			Time      -= Tdigits[2] * 10; 
			Tdigits[3] = Time;						/* Seconds LS digit								*/
		}
			
		while(0 == MBXget(MbxADC, &Msg, 0)) {		/* Always completely empty the mailbox			*/
			ADCval = (unsigned int)Msg;				/* Memo the ADC value 							*/
		}

		ii = (int)(((double)ADCval)/10.24);

		printf("[%d%d:%d%d] ADC:%u%%       \r", Tdigits[0], Tdigits[1], Tdigits[2], Tdigits[3], ii);

		sprintf(&Str[3], "  %d%d:%d%d     ADC:%u%%       ", Tdigits[0], Tdigits[1], Tdigits[2], Tdigits[3],
		        ii);
		LCD_LINE(5, (unsigned char *)&Str[0]);

		ii = ADCval>>3;								/* Display witdh = 128, max ADC value 1023		*/
		init_xy_axis(PAGE0+7,COL0);					/* Display the BAR								*/
		for (jj=0 ; jj<ii ; jj++) {
			lcd_write_data(0xFF);
		}
		for (     ; jj<128 ; jj++) {
			lcd_write_data(0x00);
		}
	}
}

/* ------------------------------------------------------------------------------------------------ */
/*																									*/
/* Idle Task																						*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

void IdleTask(void)
{
	for(;;);										/* Idle is a do nothing task					*/
}

/* ------------------------------------------------------------------------------------------------ */
/*																									*/
/* RTOS Timer call back function																	*/
/*																									*/
/* Here we use the macro OS_TICK_PER_SEC to get the XXX led to toggle once every second				*/
/* The LED is not toggle here; instead FctHI gets awaken by posting SemRed							*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

void TIMcallBack(void)
{
static int SecCnt  = 0;								/* Conter to incrm Seconds once per second		*/
static int Seconds = 0;								/* RTC cumulative seconds						*/

	SecCnt++;
	if (SecCnt >= OS_TICK_PER_SEC) {				/* Time to add one more second					*/
		Seconds++;
		if (Seconds >= 3600) {						/* The maximum display value is 59:59			*/
			Seconds = 0;
		}
		SecCnt = 0;
		MBXput(MbxTime, (intptr_t)Seconds, 0);		/* Send to the ADC task the new time in seconds	*/
		EVTset(A_E, 0x1);
	}

	ADCRead(0);										/* Trigger an AD conversion						*/
	return;
}

/* ------------------------------------------------------------------------------------------------ */
/*																									*/
/* ADC interrupt handler																			*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

void ADChandler(void)
{
static unsigned int  ADCavg = 0;
static int           ADCcnt = 0;


	ADC_IRQHandler();								/* NGX BSP for the ADC							*/

	ADCavg += (unsigned int)ADCValue[0];
	ADCcnt++;
	if (ADCcnt >= 16) {								/* Averaging 16 times							*/
		ADCavg = (ADCavg+8) >> 4;					/* Rounding and /16								*/
		MBXput(MbxADC, (intptr_t)ADCavg, 0);		/* Send ADC value to the A&E thriugh a mailbox	*/
		EVTset(A_E, 0x1);							/* Inform A&E there is soemting in one mailbox	*/
		ADCavg = 0;									/* Restart the averaging						*/
		ADCcnt = 0;
	}

	return;
}

/* ------------------------------------------------------------------------------------------------ */
/*																									*/
/* UART functions needed by the Peripheral library to access the UART								*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

size_t __write(int Handle, const unsigned char * Buf, size_t Bufsize)
{
size_t nChars = 0;
static const char rrr = '\r';

	for (/*Empty */; Bufsize > 0; --Bufsize) {
		if (*Buf == '\n') {
			UARTSend( (uint8_t *)&rrr, 1);
		}
		UARTSend((uint8_t *)Buf++, 1);
		++nChars;
	}
	return(nChars);
}

/* ------------------------------------------------------------------------------------------------ */

size_t __read(int handle, unsigned char * buffer, size_t size)
{
int nChars = 0;

	for ( ; size > 0; ) {
		if  (UARTCount != 0) {
			*buffer++ = UARTBuffer[0];
			UARTCount = 0;
			++nChars;
			size--;
		}
	}

	return(nChars);
}

/* ------------------------------------------------------------------------------------------------ */

int GetKey(void)
{
int RetVal;

	RetVal = 0;
	if (UARTCount != 0) {
		RetVal = UARTBuffer[0];
		UARTCount = 0;
	}

	return(RetVal);
}

/* EOF */
