1

See: https://github.com/adafruit/Adafruit_FRAM_SPI/blob/master/Adafruit_FRAM_SPI.cpp The following method reads and converts the input to 8 bit. I have several questions concerning its function.

Using addr = 0xFFFF as an example, the method converts the variable to 0xFF. I understand that bits are removed from the end, but surely 65535 != 255. Perhaps relatively, to their max size, but how is this a useful conversion? I might be missing something about bitwise here..

uint8_t Adafruit_FRAM_SPI::read8 (uint16_t addr)
{
 digitalWrite(_cs, LOW);
 SPItransfer(OPCODE_READ); //read memory from fram array (2-byte)
 SPItransfer((uint8_t)(addr >> 8));
 SPItransfer((uint8_t)(addr & 0xFF));
 uint8_t x = SPItransfer(0);
 digitalWrite(_cs, HIGH);
 return x;
}

Correct me if I'm wrong, the casting is to keep sign extension from occurring.

The masking I understand in theory, but do not at all understand its application here.

Finally, it always returns the same value x = 0, why?

I also see there's a write method but no read method. Only read8. Reasoning?

  • Think about what happens to the numbers and then plug those into 4 SPI transfers and think about what actually then happens on the SPI bus. – Majenko Mar 16 '16 at 18:36
  • The code above first send the highest 8 bits of the address (addr>>8), and then the lowest 8 bits. Not sure why they do both masking and casting. After that it sends 8 zero bits. During the sending of those bits the FRAM send the value in the address to the arduinos MISO pin. The 8-bit value is stored in the `x variable. Note that SPI is bi-directional, and you can send and receive data at the same time. – Gerben Mar 16 '16 at 20:15
3

Let's assume addr is 0xbeef. Then, if we break down each operation:

expression             │ value
───────────────────────┼───────
addr                   │ 0xbeef
addr >> 8              │ 0x00be
(uint8_t)(addr >> 8)   │   0xbe
addr & 0xFF            │ 0x00ef
(uint8_t)(addr & 0xFF) │   0xef

So this is essentially breaking down the address into two 8-bit chunks, and transmitting those chunks individually. It's done like this because SPI only transmits bytes.

the casting is to keep sign extension from occurring.

Non, sign extension cannot occur, since addr is an unsigned number. The casting really serves no useful purpose, other than documenting the code. It would be done implicitly simply because SPItransfer() takes an uint8_t argument. The casting could be useful if SPItransfer() was overloaded with a 16-bit version.

Finally, it always returns the same value x = 0, why?

No, it returns whatever the call to SPItransfer(0); returns, i.e. the data sent by the FRAM module.

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.