/*
 * i2c_fram.h
 *
 *  Created on: Aug 5, 2019
 *      Author: tm
 */

#ifndef PHFETSOS_I2C_FRAM_H_
#define PHFETSOS_I2C_FRAM_H_



#include <stdint.h>
#include <stdbool.h>

#include "driverlib/i2c.h"
#include "inc/hw_i2c.h"

//****************************Function prototypes******************************

// init fram and probe id
// returns 1 on success and <= 0 on failure
int fram_init(void);
int fram_apf_store_all(void);

void fram_test(void);
void fram_soak_test(void);
void fram_size_check(void);

// probe id or perform write/read test to b[3..0]
// id or probe val is returned in out_id if non-null
// returns 1 on success and <= 0 on failure
int fram_probe(uint32_t* out_id);

// returns 1 on success and <= 0 on failure
int fram_sys_samp_store(void);
// returns 1 on success and <= 0 on failure
int fram_sys_samp_retrieve(void);
int fram_last_samp_store(void);
int fram_last_samp_retrieve(void);

int fram_apf_vars_store(void);
int fram_apf_vars_retrieve(void);
int fram_apf_vars_refresh(void);

int fram_apfArray_retrieve(void);
int fram_apfArray_store(void);
int fram_apfArray_refresh(void);

//void fram_apf_vars_store(unsigned char *apfBuf, uint32_t byteCnt);
//void fram_apf_vars_retrieve(unsigned char *apfBuf, uint32_t byteCnt);
int fram_apf_dbuf_store(unsigned char *sampBuf, uint32_t byteCnt);              //void fram_apf_dbuf_store(void);
int fram_apf_dbuf_retrieve(unsigned char *sampBuf, uint32_t byteCnt);           //void fram_apf_dbuf_retrieve(void);

// returns 1 on success and <= 0 on failure
int i2c0_fram_write(unsigned char uiSlave_addr, unsigned char *ucData,
        uint16_t uiCount, uint16_t ucStart_addr );                      // was unsigned char ucStart_add

// returns 1 on success and <= 0 on failure
int i2c0_fram_read(unsigned char uiSlave_addr, unsigned char *ucRec_Data,
        uint16_t uiCount, uint16_t ucStart_addr);


//*****************************************************************************

//******************  FRAM Memory Layout:  ***********************************
#define FRAM_PROBESIG_ADDR      0           // fram probe signature, first 4 bytes are for fram_probe signature, then 12 spare
#define FRAM_PROBESIG_BLKSIZE   16

#define FRAM_SPARE1_ADDR        (FRAM_PROBESIG_ADDR + FRAM_PROBESIG_BLKSIZE)   //16
#define FRAM_SPARE1_BLKSIZE     48

#define FRAM_SYSSAMP_ADDR       (FRAM_SPARE1_ADDR + FRAM_SPARE1_BLKSIZE)  //64          // sys_samp struct 15 * 4 = 60, pad to 128 (was 64)
#define FRAM_SYSSAMP_BLKSIZE    128

#define FRAM_LASTSAMP_ADDR      (FRAM_SYSSAMP_ADDR + FRAM_SYSSAMP_BLKSIZE)  //128         // sampl struct size is ~96 pad to 128
#define FRAM_LASTSAMP_BLKSIZE   128

#define FRAM_APFVAR_ADDR        (FRAM_LASTSAMP_ADDR + FRAM_LASTSAMP_BLKSIZE)   //256         // apf_fram struct
#define FRAM_APFVAR_BLKSIZE     1024

#define FRAM_APFARRAY_ADDR      (FRAM_APFVAR_ADDR + FRAM_APFVAR_BLKSIZE)  //1024        // apfArray struct,  20K in size.   pre-initialized arrays when Zcoefs are loaded.
#define FRAM_APFARRAY_BLKSIZE   24576       //8192*3, size of apfArray is ~ 18,856bytes

#define FRAM_APFDBUF_ADDR       (FRAM_APFARRAY_ADDR + FRAM_APFARRAY_BLKSIZE)        // was 8192        // apf_dbuf is 2048 in size
#define FRAM_APFDBUF_BLKSIZE    2048


// defs from https://github.com/sosandroid/FRAM_MB85RC_I2C/blob/master/FRAM_MB85RC_I2C.h

// IDs
//Manufacturers codes
#define FUJITSU_MANUFACT_ID 0x00A
#define CYPRESS_MANUFACT_ID 0x004
#define MANUALMODE_MANUFACT_ID 0xF00
#define MANUALMODE_PRODUCT_ID 0xF00
#define MANUALMODE_DENSITY_ID 0xF00

// The density codes gives the memory's adressing scheme
#define DENSITY_MB85RC04V   0x00     // 4K
#define DENSITY_MB85RC64TA  0x03     // 64K
#define DENSITY_MB85RC256V  0x05     // 256K
#define DENSITY_MB85RC512T  0x06     // 512K
#define DENSITY_MB85RC1MT   0x07     // 1M

#define DENSITY_CY15B128J 0x01      // 128K - FM24V01A also
#define DENSITY_CY15B256J 0x02      // 256K - FM24V02A also
#define DENSITY_FM24V05 0x03        // 512K
#define DENSITY_FM24V10 0x04        // 1024K

// Devices MB85RC16, MB85RC16V, MB85RC64A, MB85RC64V and MB85RC128A do not support Device ID reading
//          FM24W256,FM24CL64B, FM24C64B, FM24C16B, FM24C04B, FM24CL04B

#define MAXADDRESS_04 512
#define MAXADDRESS_16 2048
#define MAXADDRESS_64 8192
#define MAXADDRESS_128 16384
#define MAXADDRESS_256 32768
#define MAXADDRESS_512 65535
#define MAXADDRESS_1024 65535 // 1M devices are in fact managed as 2 512 devices from lib point of view > create 2 instances of the object with each a differnt address

// Adresses
#define MB85RC_ADDRESS_A000   0x50
#define MB85RC_ADDRESS_A001   0x51
#define MB85RC_ADDRESS_A010   0x52
#define MB85RC_ADDRESS_A011   0x53
#define MB85RC_ADDRESS_A100   0x54
#define MB85RC_ADDRESS_A101   0x55
#define MB85RC_ADDRESS_A110   0x56
#define MB85RC_ADDRESS_A111   0x57
#define MB85RC_DEFAULT_ADDRESS   MB85RC_ADDRESS_A000

//Special commands
#define MASTER_CODE 0xF8
#define SLEEP_MODE  0x86 //Cypress codes, not used here
#define HIGH_SPEED  0x08 //Cypress codes, not used here


// Error management
#define ERROR_0 0 // Success
#define ERROR_1 1 // Data too long to fit the transmission buffer on Arduino
#define ERROR_2 2 // received NACK on transmit of address
#define ERROR_3 3 // received NACK on transmit of data
#define ERROR_4 4 // Serial seems not available
#define ERROR_5 5 // Not referenced device ID
#define ERROR_6 6 // Unused
#define ERROR_7 7 // Fram chip unidentified
#define ERROR_8 8 // Number of bytes asked to read null
#define ERROR_9 9 // Bit position out of range
#define ERROR_10 10 // Not permitted opération
#define ERROR_11 11 // Memory address out of range








#endif /* I2C_FRAM_H_ */
