Files
Cnomicon/src/libPIC/fram.c
2021-01-22 10:16:20 -05:00

261 lines
6.1 KiB
C

/*****************************************************************************
* Copyright (C) 2008
* ProbeStar Telematics, LLC
* All Rights Reserved. Proprietary and Confidential.
*============================================================================
* FRAM Chip Driver
*----------------------------------------------------------------------------
* Details
*****************************************************************************/
/*****************************************************************************
* includes
*****************************************************************************/
#include "system.h"
#include "delay.h"
#include "fram.h"
#include "types.h"
/*****************************************************************************
* defines
*****************************************************************************/
#if defined(FRAM_MODULE) || defined(__linux__)
#ifdef __linux__
#define FRAM_SIZE 8192
#undef FRAM_SCL
// Linux I2C driver?
#define MEMORY_EMUL
#endif
#ifdef FRAM_SIZE
#define MEMORY_SIZE FRAM_SIZE
#endif
#define MEMORY_FILE "fram.pic"
#define MEMORY_NAME "Fram"
#ifdef MEMORY_DEBUG
#define MEMORY_ERROR // track errors
#define READ_PROTECT
#define WRITE_PROTECT
#endif
#include "memio.h"
#ifdef FRAM_SCL
// internalize the module for I2C bit banged I/O
#define I2C_INTERNAL
#define I2C_MODULE
#endif
#ifdef I2C_INTERNAL
// port definitions from project.h
#define SCL FRAM_SCL
#define SCL_DIR FRAM_SCL_DIR
#define SDA FRAM_SDA
#define SDA_DIR FRAM_SDA_DIR
// include the C modules directly
// adjusted timings
#define I2C_TM_PUT_FUDGE 0
#define I2C_TM_START_SU 1
#define I2C_TM_START_HD 1
#define I2C_TM_SCL_LOW 0
#define I2C_TM_SCL_HIGH 0
#define I2C_TM_DATA_SU 0
#define I2C_TM_DATA_HD 0
#define I2C_TM_SCL_TO_DATA 0 // SCL low to data valid
#define I2C_TM_STOP_SU 1
#define I2C_TM_STOP_HD 0
#define I2C_TM_BUS_FREE 1
#define I2C_TM_SCL_TMO 0 // clock time out
#include "i2c_master.h"
#include "i2c_bitbang.c"
#else
//#include "i2c_master.h"
#endif
/*****************************************************************************
* macros
*****************************************************************************/
#ifndef MEMORY_EMUL
#define DevStopRead() i2c_StopRead()
#define DevStopWrite() i2c_StopWrite()
#endif
/*****************************************************************************
* structs & typedefs
*****************************************************************************/
/*****************************************************************************
* global constants
*****************************************************************************/
/*****************************************************************************
* global variables
*****************************************************************************/
/*****************************************************************************
* static constants
*****************************************************************************/
/*****************************************************************************
* static variables
*****************************************************************************/
/*****************************************************************************
* static prototypes
*****************************************************************************/
/*****************************************************************************
* C functions
*****************************************************************************/
// templated
#include "memio.c"
/* Init *****************************************************************/
// special functions
DWORD FramSize( void )
{
#ifdef FRAM_SIZE
return FRAM_SIZE;
#else
BYTE byZero, byTest, byCount;
WORD wAddr;
// already sized?
if ( MemGetSize() )
return MemGetSize();
wAddr = 0; // establish test byte addr
byZero = FramReadByte(wAddr); // store test byte
FramWriteByte(wAddr, 0); // establish test byte value
byCount=0;
while (FramReadByte(0) == 0)
{
if (++byCount > 1)
FramWriteByte(wAddr, byTest); // restore real byte
wAddr += 8192; // increment address 8K
byTest = FramReadByte(wAddr); // store real byte
FramWriteByte(wAddr, byCount); // write real/test byte
}
FramWriteByte(0, byZero); // restore test byte
return (DWORD)wAddr;
#endif
}
/* I/O ******************************************************************/
#ifndef MEMORY_EMUL
// device functions
static BYTE FramWriteAddr( WORD wAddr )
{
// setup up for write
BYTE byCtl = ROM | ((wAddr & 0x8000) >> 14);
i2c_WriteTo( byCtl );
i2c_PutByte( wAddr >> 8 );
i2c_PutByte( wAddr );
return byCtl;
}
static void DevInit( void )
{
#ifdef I2C_INTERNAL
I2C_init();
#endif
MemSetSize( FramSize() );
}
static BYTE DevStartRead( WORD wAddr, WORD nBytes )
{
i2c_ReadFrom( FramWriteAddr( wAddr ) );
return 1;
}
static BYTE DevReadByte( WORD wAddr )
{
return i2c_GetByte( MemGetLen() > 0 ? I2C_MORE : I2C_LAST );
}
static BYTE DevStartWrite( WORD wAddr, WORD nBytes )
{
FramWriteAddr( wAddr );
return 1;
}
static void DevWriteByte( WORD wAddr, BYTE byData )
{
i2c_PutByte( byData );
}
#endif
// desired functions
MT_Init(Fram)
MT_GetChecksum(Fram)
MT_GetError(Fram)
MT_ReadBlock(Fram)
MT_ReadNext(Fram)
MT_ReadBytes(Fram)
MT_WriteBlock(Fram)
MT_WriteNext(Fram)
MT_WriteBytes(Fram)
MT_ReadData(Fram)
MT_WriteData(Fram)
MT_ReadCSData(Fram)
MT_WriteCSData(Fram)
MT_SkipNext(Fram)
MT_WriteFill(Fram)
// additional functions
#ifdef FRAM_DIRECT
BYTE FramReadByte( WORD wAddr )
{
BYTE byData = 0;
FramReadData( wAddr, &byData, sizeof(BYTE) );
return byData;
}
WORD FramReadWord( WORD wAddr )
{
WORD wData = 0;
FramReadData( wAddr, (BYTE*)&wData, sizeof(WORD) );
return wData;
}
DWORD FramReadDword( WORD wAddr )
{
DWORD dwData = 0;
FramReadData( wAddr, (BYTE*)&dwData, sizeof(DWORD) );
return dwData;
}
void FramWriteByte( WORD wAddr, BYTE byData )
{
FramWriteData( wAddr, (const BYTE *)&byData, sizeof(BYTE) );
}
void FramWriteWord( WORD wAddr, WORD wData )
{
FramWriteData( wAddr, (const BYTE *)&wData, sizeof(WORD) );
}
void FramWriteDword( WORD wAddr, DWORD dwData )
{
FramWriteData( wAddr, (const BYTE *)&dwData, sizeof(DWORD) );
}
#endif
#endif