A ferroelectric random access memory or F-RAM is nonvolatile and performs reads and writes similar to a RAM.

Dependents:   Memoria

FM24V10.cpp

Committer:
yangcq88517
Date:
2016-03-08
Revision:
1:b9f6d029c760
Parent:
0:e4b7a2f63736

File content as of revision 1:b9f6d029c760:

#include "FM24V10.h"

// A1 pin ground == false
// A2 pin ground == false

FM24V10::FM24V10(PinName sda, PinName scl, bool A1, bool A2, SPEED_MODE speed): _i2c_bus(sda,scl)
{
    switch (speed) {
        case STANDARD:
            _speed = FREQUENCY_STANDARD;
            break;
        case FULL:
            _speed = FREQUENCY_FULL;
            break;
        case FAST:
            _speed = FREQUENCY_FAST;
            break;
        case HIGH:
            _speed = FREQUENCY_HIGH;
            break;
    }
    Init(A1, A2);
}

void FM24V10::Init(bool A1, bool A2)
{
    _i2c_bus.frequency(_speed);

    _addr = 0xA0;

    if (A1)
        _addr |= 0x04;

    if (A2)
        _addr |= 0x08;
}

void FM24V10::GetSlaveAddress(int position)
{
    if ((position >> 16) == 0x01)
        _addr |= 0x02;
    else _addr &= 0xFD;
}

void FM24V10::WriteShort(int position, int value, bool Hs_mode)
{
    WriteShort(position, &value, 1, Hs_mode);
}

// position from 0x000000 to 0x01FFFF
void FM24V10::WriteShort(int position, int * value, int size, bool Hs_mode)
{
    GetSlaveAddress(position);

    if (Hs_mode)
        StartHS();

    _i2c_bus.start();

    _i2c_bus.write(_addr);
    _i2c_bus.write(position >> 8);
    _i2c_bus.write(position);

    for (int i = 0 ; i< size; i++) {
        _i2c_bus.write(*(value + i) >> 8);
        _i2c_bus.write(*(value + i));
    }

    _i2c_bus.stop();

    if (Hs_mode)
        StopHS();
}

int FM24V10::ReadShort(int position, bool Hs_mode)
{
    ReadShort(position, &result, 1,Hs_mode);
    return result;
}

// position from 0x000000 to 0x01FFFF
void FM24V10::ReadShort(int position, int * value, int size, bool Hs_mode)
{
    GetSlaveAddress(position);

    if (Hs_mode)
        StartHS();

    _i2c_bus.start();
    _i2c_bus.write(_addr);
    _i2c_bus.write(position >> 8);
    _i2c_bus.write(position);

    _i2c_bus.start();
    _i2c_bus.write(_addr | 0x01);

    for (int i = 0; i< size; i++) {
        *(value + i) = _i2c_bus.read(1) << 8;

        if (i == size - 1)
            *(value + i) |= _i2c_bus.read(0);
        else
            *(value + i) |= _i2c_bus.read(1);
    }

    _i2c_bus.stop();

    if (Hs_mode)
        StopHS();
}

void FM24V10::StartHS()
{
    _i2c_bus.start();
    _i2c_bus.write(HS_COMMAND);
    _i2c_bus.frequency(FREQUENCY_HIGH);
}

void FM24V10::StopHS()
{
    _i2c_bus.frequency(_speed);
}