/****************************************************************************/
/* Copyright 2003-2011 MBARI												*/
/****************************************************************************/
/* Summary	: SPI I/O Support for BEDS controller							*/
/* Filename : spi.c															*/
/* Author	: Robert Herlien (rah)											*/
/* Project	: Benthic Event Detection System (BEDS)							*/
/* Revision: 1.0															*/
/* Created	: 10/17/2011 from Respirometer spi.c							*/
/*																			*/
/* MBARI provides this documentation and code "as is", with no warranty,	*/
/* express or implied, of its quality or consistency. It is provided without*/
/* support and without obligation on the part of the Monterey Bay Aquarium	*/
/* Research Institute to assist in its use, correction, modification, or	*/
/* enhancement. This information should not be published or distributed to	*/
/* third parties without specific written permission from MBARI.			*/
/*																			*/
/****************************************************************************/
/* Modification History:													*/
/* 10jan2003 rah - created for OASIS3										*/ 
/* 08dec2008 rah - modified for respirometer controller						*/ 
/* 17oct2011 rah - modified for BEDS										*/
/****************************************************************************/

#include <mbariTypes.h>					/* MBARI type definitions			*/
#include <mbariConst.h>					/* MBARI constants					*/
#include <cfxpico.h>					/* Persistor PicoDOS definitions	*/
#include <beds.h>						/* BEDS controller definitions		*/
#include <io.h>							/* BEDS I/O definitions				*/
#include <spi.h>						/* BEDS SPI I/O definitions			*/
#include <file.h>						/* BEDS File I/O Routines			*/
#include <string.h>						/* For memset						*/


/********************************/
/*		Module Local Data		*/
/********************************/

MLocal QPB		*clkQPB;				/* QPB for doing SPI I/O			*/


/* MAX DS3234 SPI Definition */
MLocal QPBDev clkQPBTemplate =
{
	RTCSLOT,					/* qslot - our qspi slot					*/
	"DS3234",					/* Device name (char[16])					*/
	1000000,					/* Max baud rate							*/
	8,							/* Bits Per Transfer						*/
	iaHighSCK,					/* SPI Clock Polarity (iaLowSCK,iaHighSCK)	*/
	captFall,					/* SPI Clock Phase (captLead/captFall)		*/
	true,						/* Continue CS assert between mult xfrs		*/
	true,						/* Auto adjust timing to clock flag			*/
	0,							/* Min. Delay Before SCK (picoSecs)			*/
	0,							/* Min. Delay After Transfer (ps)			*/
	NULL,						/* pointer to received data buffer			*/
								/*	 (filled in by QPBInitSlot)				*/
	2							/* Words transferred						*/
};

MLocal Nat16	spiXmitDataOut[] = 
{  0x3e00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};


/************************************************************************/
/* Function	   : spiInit												*/
/* Purpose	   : Initialize SPI I/O										*/
/* Inputs	   : None													*/
/* Outputs	   : None													*/
/* Comment	   : Configures SPI power on, so no need to call spiPower	*/
/************************************************************************/
Void spiInit(Void)
{
	clkQPB = QPBInitSlot(&clkQPBTemplate);

} /* spiInit() */


/************************************************************************/
/* Function	   : spiReadRTCReg											*/
/* Purpose	   : Read one register from the DS3234 RTC chip				*/
/* Inputs	   : Register address										*/
/* Outputs	   : Register data or ERROR									*/
/************************************************************************/
Int16 spiReadRTCReg(Nat16 addr)
{
	Int16		cmd[2];

	if (addr > 0x19)
		return(ERROR);

	cmd[0] = addr & 0x7f;
	cmd[1] = 0;

	QPBTransact(clkQPB, 0, 2, cmd);

	return(clkQPB->dev->rcvData[1] & 0xff);

} /* spiReadRTCReg() */


/************************************************************************/
/* Function	   : spiWriteRTCReg											*/
/* Purpose	   : Write one register to the DS3234 RTC chip				*/
/* Inputs	   : Register address, data to write						*/
/* Outputs	   : OK or ERROR											*/
/************************************************************************/
Int16 spiWriteRTCReg(Nat16 addr, Nat16 wdat)
{
	Int16		cmd[2];

	if (addr > 0x19)
		return(ERROR);

	cmd[0] = addr | 0x80;
	cmd[1] = wdat & 0xff;

	QPBTransact(clkQPB, 0, 2, cmd);

	return(OK);

} /* spiWriteRTCReg() */


/************************************************************************/
/* Function	   : spiReadMultRTCRegs										*/
/* Purpose	   : Read multiple registers from the DS3234 RTC chip		*/
/* Inputs	   : Starting address, number of registers, ptr for result data*/
/* Outputs	   : OK or ERROR											*/
/************************************************************************/
Int16 spiReadMultRTCRegs(Nat16 addr, Nat16 numRegs, Nat16 *result)
{
	Int16		cmd[16];

	if ((addr + numRegs > 0x1a) || (numRegs > 15))
		return(ERROR);

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = addr & 0x7f;

	QPBTransact(clkQPB, 0, numRegs+1, cmd);

//	  LoopModeMemCopyWords(result, &clkQPB->dev->rcvData[1], numRegs);
	memcpy(result, &clkQPB->dev->rcvData[1], 2*numRegs);

	return(OK);

} /* spiReadMultiRTCRegs() */


/************************************************************************/
/* Function	   : spiWriteMultRTCRegs									*/
/* Purpose	   : Write multiple registers to the DS3234 RTC chip		*/
/* Inputs	   : Starting address, number of registers, ptr to data		*/
/* Outputs	   : OK or ERROR											*/
/************************************************************************/
Int16 spiWriteMultRTCRegs(Nat16 addr, Nat16 numRegs, Nat16 *wdat)
{
	Int16		cmd[16];

	if ((addr + numRegs > 0x1a) || (numRegs > 15))
		return(ERROR);

	cmd[0] = addr | 0x80;
	LoopModeMemCopyWords(&cmd[1], wdat, numRegs);
//	  memcpy(&cmd[1], wdat,2* numRegs);

	QPBTransact(clkQPB, 0, numRegs+1, cmd);

	return(OK);

} /* spiWriteMultiRTCRegs() */
