Skip to content

WRAM double read is only needed for 32-bit values #17

@dewhisna

Description

@dewhisna

I don't think it's necessary for this vs1053::Mp3ReadWRAM function to read the WRAM value twice. I assume the reason it's being done is because of section 10.11 in the datasheet, which reads:

Notice that reading two-word variables through the SCI_WRAMADDR and SCI_WRAM interface is not protected in any way. The variable can be updated between the read of the low and high parts. The problem arises when both the low and high parts change values. To determine if the value is correct, you should read the value twice and compare the results.

However, that paragraph is talking about reading 32-bit values (i.e. two-word variables), not a single 16-bit value. Their example, even, is illustrating the read of bytesLeft, which is a 32-bit value.

That makes sense, because there's nothing that keeps one 16-bit half of the value from changing while the code is reading the other half, but as I understand from the datasheet, an individual 16-bit value is latched during the read for the transfer to the SPI bus and is sent consistently as a unit, meaning that its upper and lower bytes should be correct paired.

It is possible for a value to change between consecutive reads, but the caller of this function will need to determine if that change affects its reading of a larger 32-bit value or not, and since this function is only for reading a single 16-bit location, I don't think it can determine that since it wouldn't know if the caller is even doing a 32-bit read.

If I'm wrong, please point me to the part of the datasheet that I missed.

/**
* \brief Read a VS10xx WRAM Location
*
* \param[in] addressbyte of the VSdsp's WRAM to be read
* \return result read from the WRAM
*
* Function to communicate to the VSdsp's registers, indirectly accessing the WRAM.
* As per data sheet the result is read back twice to verify. As it is not buffered.
*/
uint16_t vs1053::Mp3ReadWRAM (uint16_t addressbyte){
unsigned short int tmp1,tmp2;
//Set SPI bus for write
spiInit();
SPI.setClockDivider(spi_Read_Rate);
Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
tmp1 = Mp3ReadRegister(SCI_WRAM);
Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
tmp2 = Mp3ReadRegister(SCI_WRAM);
if(tmp1==tmp2) return tmp1;
Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
tmp2 = Mp3ReadRegister(SCI_WRAM);
if(tmp1==tmp2) return tmp1;
Mp3WriteRegister(SCI_WRAMADDR, addressbyte);
tmp2 = Mp3ReadRegister(SCI_WRAM);
if(tmp1==tmp2) return tmp1;
return tmp1;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions