0
\$\begingroup\$

I am trying to store "long int" values to memory (SM28VLT32) via SPI communication. I am using IAR compiler. Memory is 16 bit read or write access. I would like to store bigger than 16 bit value like "3245672341" and some times float values. ex: "5008.456". I can convert float to int then the integer will be bigger than 16 bit value. I have to store an array of [6] "long int"values every minit to memory. I can not store long integer value to memory as it has 16 bit read and write access.

I am thinking to convert "long int" to "string"! Any suggestions on how can i store those values and should use less memory?

Presently i am able to store 16 bit integer value using the below coode.

unsigned int sampledata[5]= {34586, 43877,53780, 64879,1}; 
FlashPointer = 2;

int StoreToFlash(unsigned int sampledata[], int StartAddress);  // Strore Sample to flash

StoreToFlash(sampledata, FlashPointer);   //function calling

int StoreToFlash(long int sampledata[], int StartAddress)
{   
int iCtr;
int ErrorCode = 0;
int address = StartAddress;

// Write to flash
for(iCtr=0;iCtr<5;iCtr++)
{   
    ErrorCode = Flash_Write(address++, sampledata[iCtr]);
    if((ErrorCode &0x45)!= 0)
    {
      Flash_ClearError();          
    }
}
return ErrorCode;
}

int Flash_Write(int Address, long int Data)   //Flash wirte function
{ 
int error ;
int data0 = 0;

// Make chip select Low
Flash_Set_CS_Status(0);

// Send Command ID 0x17
data0 = Flash_SPI_SendByte(0x17);

// Send Address Byte 3
data0 = Flash_SPI_SendByte((Address & 0xFF0000) >> 16);    

// Send Address Byte 2
data0 = Flash_SPI_SendByte((Address & 0xFF00) >> 8);

// Send Address Byte 1
data0 = Flash_SPI_SendByte(Address & 0xFF);

// Send Data Byte MSB
data0 = Flash_SPI_SendByte((Data & 0xFF00) >> 8);

// Send Data Byte LSB
data0 = Flash_SPI_SendByte(Data & 0xFF);

// Send Dummy Byte
data0 = Flash_SPI_SendByte(0);

// Make Chip select high
Flash_Set_CS_Status(1);  
}

How can i store sampledata[5]= {3456782676, 3890.345, 5035.675, 1, 64534}?
\$\endgroup\$
6
  • 3
    \$\begingroup\$ Just cast to an array of bytes and save/load whatever you like. As long as you save the correct number of bytes, it doesn't matter what the internal format is. \$\endgroup\$ Sep 3, 2015 at 14:35
  • \$\begingroup\$ how large is a 'float' value? 2 bytes? \$\endgroup\$ Sep 4, 2015 at 16:42
  • \$\begingroup\$ The posted code does not even come close to compiling. Please correct that and re-post the code \$\endgroup\$ Sep 4, 2015 at 16:43
  • \$\begingroup\$ the SPI interface to the flash, per the posted code, can handle 24 bit address and 16 bit data. What does the final 0x00 byte of data do? Is that 0x00 byte being stored in the flash or is it some control value? \$\endgroup\$ Sep 4, 2015 at 16:54
  • \$\begingroup\$ for data values greater than 2 bytes, have 2 calls to the Flash_Write() function, something like: Flash_Write( Address, (data&0xFFFF0000)>>16 ); Flash_Write( Address+2, (data&ox0000FFFF) ); \$\endgroup\$ Sep 4, 2015 at 16:58

1 Answer 1

1
\$\begingroup\$

So the flash you are using only supports writes to a 16-bit word at a time and cannot be accessed in another way (that is a bit odd). Because of that you will have to do some manual address management, but the flash luckily comes with an address auto-increment write.

So as you can transfer just a byte via SPI anyways (there are some 16-bit variants but let's forget about them for a minute, although it would be most fitting here), the most natural way to interface with it is with byte arrays.

So I'd change the Flash_Write like so:

long int Start_Flash_Write(int StartAddress, unsigned char* Data, long int Datacount, const unsigned char FINISH_BYTE)
{
    long int dataSent = 0;
    // Make chip select Low
    Flash_Set_CS_Status(0);

    // Send Command ID 0x17
    data0 = Flash_SPI_SendByte(0x17);

    // Send Address Byte 3
    data0 = Flash_SPI_SendByte((StartAddress & 0xFF0000) >> 16);    

    // Send Address Byte 2
    data0 = Flash_SPI_SendByte((StartAddress & 0xFF00) >> 8);

    // Send Address Byte 1
    data0 = Flash_SPI_SendByte(StartAddress & 0xFF);

    // Send first two DataBytes
    data0 = Flash_SPI_SendByte(Data[dataSent++]);
    if (dataSent < (Datacount))
    {
        data0 = Flash_SPI_SendByte(Data[dataSent++]);
    }
    else
    {
        data0 = Flash_SPI_SendByte(FINISH_BYTE);
    }
    // Send Dummy Byte
    data0 = Flash_SPI_SendByte(0);

    // Make Chip select high
    Flash_Set_CS_Status(1);

    return dataSent;

}

int Flash_Write(int StartAddress, unsigned char* Data, long int Datacount)   //Flash wirte function
{ 
    int error ;
    int data0 = 0;
    long int dataSent;
    const unsigned char FINISH_BYTE  = 0xFF;

    if (Datacount == 0)
    {
        return 0; // writing nothing is easy
    }

    // First Write sets StartAddress
    dataSent = Start_Flash_Write(StartAddress, Data, Datacount, FINISH_BYTE);

    while (dataSent < (Datacount))
    {
        // Make chip select Low
        Flash_Set_CS_Status(0);

        // Send Command ID 0x18 (auto increment write)
        data0 = Flash_SPI_SendByte(0x18);

        // Send first two DataBytes
        data0 = Flash_SPI_SendByte(Data[dataSent++]);
        if (dataSent < (Datacount))
        {
            data0 = Flash_SPI_SendByte(Data[dataSent++]);
        }
        else
        {
            data0 = Flash_SPI_SendByte(FINISH_BYTE);
        }

        // Send Dummy Byte
        data0 = Flash_SPI_SendByte(0);

        // Make Chip select high
        Flash_Set_CS_Status(1); 
    }
}

And you would then call it like this:

Flash_Write(0x1234, (unsigned char*)(sampledata), sizeof(sampledata))

How it works:

It starts with writing the StartAddress and the first two bytes to the flash. Afterwards it writes the bytes as a pair to the next address using the auto increment mode of the flash.

As the byte count of data might not be even, I check if the data count has been reached after each byte is written. If that is the case, a constant FINISH_BYTE is used to end the transfer in a normal way.

Notes:

I'd strongly advice against the use of integral data types directly as no one can tell how big they really are (is an int 16 or 32 bit wide?).

The datacount has to be passed to the function as information on the size of the array gets lost when it is cast to a pointer and out of scope.

The function does not return something, that should be fixed. Error is unused.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.