/****************************************************************************/
/* 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() */
