/****************************************************************************/
/*
 * MODULE              Driver for DKx Matrix buttons
 *
 * COMPONENT           MatrixButton.c
 *
 * VERSION:            R and D Release 6 JAN 2011
 *
 * REVISION:           1.0
 *
 * DATED:              2014/03/28
 *
 * AUTHOR              frobbe
 *
 * DESCRIPTION         Button Controller for DKx board (matrix 42 buttons rf4ce remote control)
 *
 ****************************************************************************
 *
 * This software is owned by Jennic and/or its supplier and is protected
 * under applicable copyright laws. All rights are reserved. We grant You,
 * and any third parties, a license to use this software solely and
 * exclusively on Jennic products. You, and any third parties must reproduce
 * the copyright and warranty notice and any other legend of ownership on each
 * copy or partial copy of the software.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS". JENNIC MAKES NO WARRANTIES, WHETHER
 * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
 * ACCURACY OR LACK OF NEGLIGENCE. JENNIC SHALL NOT, IN ANY CIRCUMSTANCES,
 * BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, SPECIAL,
 * INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON WHATSOEVER.
 *
 * Copyright Jennic Ltd 2010. All rights reserved
 *
 ****************************************************************************/

/****************************************************************************/
/***        Include files                                                 ***/
/****************************************************************************/
#include "jendefs.h"
#include "string.h"
//#include "Printf.h"
#include "AppHardwareApi.h"
#include "MatrixButton.h"
//#include "dbg.h"

/****************************************************************************/
/***        Macro Definitions                                             ***/
/****************************************************************************/

/* maximun BANK count is 8, maximun number of lines is 8 lines per bank*/

#ifdef DEBUG_APP
    #define TRACE_APP   TRUE
#else
    #define TRACE_APP   FALSE
#endif

#define vPrintf DBG_vPrintf

/****************************************************************************/
/***        Type Definitions                                              ***/
/****************************************************************************/

typedef struct {
				uint8 NumButtons;
				uint8 BankCount;
				uint8 FirstBankDIO;
				uint8 LastBankDIO;
				uint8 FirstLineDIO;
				uint32 BankMask;
				uint32 LineMask;
				bool_t MatrixEnabled;
} tsMatrixConfig;

/****************************************************************************/
/***        Local Function Prototypes                                     ***/
/****************************************************************************/

/****************************************************************************/
/***        Exported Variables                                            ***/
/****************************************************************************/

/****************************************************************************/
/***        Local Variables                                               ***/
/****************************************************************************/
tsMatrixConfig tsMatrixConfiguration;

/****************************************************************************/
/***        Exported Functions                                            ***/
/****************************************************************************/

/****************************************************************************
 *
 * NAME: vMatrixButton_Configure
 *
 * DESCRIPTION:
 * Configures the Button matrix.
 * The matrix is defined as n banks of m lines.
 * Both n and m must be less or equal than 8.
 * Inputs are:
 * NumberOfButtons: number of buttons actually present on the matrix
 * MatrixBanksMask: mask for DIO used to select a bank. DIO must be consecutive.
 *                  The mask will be truncated to 8 bits starting from the first lsb set.
 * MatrixLinesMask: mask for DIO used to select a line. DIO must be consecutive.
 *                  The mask will be truncated to 8 bits starting from the first lsb set.
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void vMatrixButton_Configure(uint8 NumberOfButtons, uint32 MatrixBanksMask, uint32 MatrixLinesMask)
{
	uint8 i;

	tsMatrixConfiguration.NumButtons = NumberOfButtons;
	tsMatrixConfiguration.BankMask = MatrixBanksMask;
	tsMatrixConfiguration.LineMask = MatrixLinesMask;


	/* find first Bank DIO*/
	tsMatrixConfiguration.FirstBankDIO = 32;
	tsMatrixConfiguration.LastBankDIO = 0;
	tsMatrixConfiguration.BankCount = 0;
	for (i=0;i<32;i++)
	{
		if (((MatrixBanksMask>>i)&0x1) == 1)
		{
			if (tsMatrixConfiguration.FirstBankDIO == 32) tsMatrixConfiguration.FirstBankDIO = i;
			if (i >= tsMatrixConfiguration.LastBankDIO) tsMatrixConfiguration.LastBankDIO = i;
			tsMatrixConfiguration.BankCount++;
		}
	}


	/* find first Line DIO*/
	tsMatrixConfiguration.FirstLineDIO = 32;
	for (i=0;i<32;i++)
	{
		if (((MatrixLinesMask>>i)&0x1) == 1)
		{
			if (tsMatrixConfiguration.FirstLineDIO == 32) tsMatrixConfiguration.FirstLineDIO = i;
			break;

		}
	}


	/* Set Bank Select Bank DIOs as outputs and Lines DIO as inputs*/
	vAHI_DioSetDirection(tsMatrixConfiguration.LineMask, tsMatrixConfiguration.BankMask);

	/* Enable Matrix */
	tsMatrixConfiguration.MatrixEnabled = TRUE;

}

/****************************************************************************
 *
 * NAME: vMatrixButton_UnConfigure
 *
 * DESCRIPTION:
 * Disable access to matrix update.
 * Release DIO used by the Button matrix.
 * RAZ pressed, time_pressed and time_released of the Button structure.
  * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void vMatrixButton_UnConfigure(volatile tsButtonDesc* Button)
{
	uint8 i;

	/* disable Matrix */
	tsMatrixConfiguration.MatrixEnabled = FALSE;

	/* Set Bank Select Bank DIOs and Lines DIO as inputs*/
	vAHI_DioSetDirection((tsMatrixConfiguration.LineMask & tsMatrixConfiguration.BankMask), 0);

	/* RAZ pressed, time_pressed and time_released fields */
	for (i=0; i<tsMatrixConfiguration.NumButtons; i++)
	{
		Button[i].pressed == FALSE;
		Button[i].time_pressed = 0;
		Button[i].time_released = 0;
	}
}

/****************************************************************************
 *
 * NAME: tsMatrixButton_Update
 *
 * DESCRIPTION:
 * Reads the matrix and update Button structure array in accordance
 * Input:
 * Button: pointer to an array of tsButtonDesc type
 * Output:
 * Button array updated.
 *
 * RETURNS:
 * Input pointer
 *
 ****************************************************************************/
PUBLIC volatile tsButtonDesc* tsMatrixButton_Update(volatile tsButtonDesc* Button)
{
	uint8 u8Bank = 0;
	uint8 u8BankIndex = 0;
	uint8 i;
	uint16 u16ButtonBank[8];
	uint32 u32BankMask = 0;
	static bool_t bLock = FALSE;

	if ((tsMatrixConfiguration.MatrixEnabled) && (bLock == FALSE))
	{
		/* lock matrix scan access */
		bLock = TRUE;

		/* Read inputs configured as buttons */
		for (u8Bank = tsMatrixConfiguration.FirstBankDIO; u8Bank <= tsMatrixConfiguration.LastBankDIO; u8Bank++) /* Loop, or could do one bank per timer */
		{
			u32BankMask = 0x01 << u8Bank;

			if (u32BankMask & tsMatrixConfiguration.BankMask)
			{
				/* Turn on one of the bank select lines */
				vAHI_DioSetOutput(((~u32BankMask) & tsMatrixConfiguration.BankMask), ((u32BankMask) & tsMatrixConfiguration.BankMask));

				/* May need a pause here */
				for (i = 0; i < 100; i++);

				/* Read the bank into botton bits */
				u16ButtonBank[u8BankIndex] = ((~u32AHI_DioReadInput()) & tsMatrixConfiguration.LineMask) >> tsMatrixConfiguration.FirstLineDIO;
				u8BankIndex++;
			}
		}

		/* update button status */


		for (i=0; i<tsMatrixConfiguration.NumButtons; i++)
		{
			if ((u16ButtonBank[Button[i].bank] & Button[i].line) && (Button[i].type != eDisabled))
			{
				if (Button[i].pressed == FALSE)
					{
						Button[i].time_pressed = 0;
						//vPrintf(TRACE_APP,"\nButton pressed bank %d line(s) read %x\n", Button[i].bank, u16ButtonBank[Button[i].bank]);
						//vPrintf(TRACE_APP,"\nv");
					}
				Button[i].pressed = TRUE;
				if (Button[i].time_pressed<65535) Button[i].time_pressed++;
			}
			else
			{
				if (Button[i].pressed == TRUE)
					{
						Button[i].time_released = 0;
						//vPrintf(TRACE_APP,"Button released\n");
						//vPrintf(TRACE_APP,"^\n");
					}
				Button[i].pressed = FALSE;
				if (Button[i].time_released<65535) Button[i].time_released++;
			}
		}
		/* unlock matrix scan access */
		bLock = FALSE;
	} /* if (tsMatrixConfiguration.MatrixEnabled)*/
	return (Button);
}

/****************************************************************************/
/***        END OF FILE                                                   ***/
/****************************************************************************/
