Skip to content

fram size incorrect with len #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jerryneedell opened this issue Jan 9, 2019 · 15 comments
Closed

fram size incorrect with len #6

jerryneedell opened this issue Jan 9, 2019 · 15 comments
Assignees

Comments

@jerryneedell
Copy link
Contributor

I was experimenting with an SPI FRAM breakout and found that len(fram) only reports the size as 8191 - but I can write to the 8192nd location -- Is this a bug?

Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 4.0.0-alpha.5-82-g0599fbf7d on 2019-01-09; Adafruit Feather nRF52840 Express with nRF52840
>>>
>>> import board
>>> import busio
>>> import digitalio
>>> import adafruit_fram
>>>
>>> ## Create a FRAM object.
>>> spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
>>> cs = digitalio.DigitalInOut(board.D5)
>>> fram = adafruit_fram.FRAM_SPI(spi, cs)
>>> len(fram)
8191
>>> fram[8191]
bytearray(b'\x00')
>>> len(fram)
8191

>>> fram[8191]=1
>>> fram[8191]
bytearray(b'\x01')
>>> 
@jerryneedell
Copy link
Contributor Author

same for an I2C fram


Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 4.0.0-alpha.5-82-g0599fbf7d on 2019-01-09; Adafruit Feather nRF52840 Express with nRF52840
>>> 
>>> import board
>>> import busio
>>> import adafruit_fram
>>> 
>>> ## Create a FRAM object (default address used).
>>> i2c = busio.I2C(board.SCL, board.SDA)
>>> fram = adafruit_fram.FRAM_I2C(i2c)
>>> 
>>> len(fram)
32767
>>> fram[32767]
bytearray(b'\x00')
>>> fram[32767]=1
>>> fram[32767]
bytearray(b'\x01')
>>> 

@jerryneedell
Copy link
Contributor Author

jerryneedell commented Jan 9, 2019

@jerryneedell
Copy link
Contributor Author

The description https://github.com/adafruit/Adafruit_CircuitPython_FRAM/blob/master/adafruit_fram.py#L109 is a little confusing -- for the SPI FRAM there are 8192 locations 0 - 8191 so the maximum "register" location is 8191, but the size of the bytearray is 8192. or am I missing something.

@makermelissa
Copy link
Collaborator

I have the I2C FRAM and will take a look into this.

@makermelissa
Copy link
Collaborator

Confirmed. My FRAM exhibited the same symptoms. Also, just to be sure it was zero-based:

>>> fram[0]
bytearray(b'\x00')
>>> fram[0] = 1
>>> fram[0]
bytearray(b'\x01')

@makermelissa
Copy link
Collaborator

Because of the way that python normally handles arrays:

>>> fruit = ["apple", "banana", "orange"]
>>> len(fruit)
3

I think it makes sense to add 1 to the length and to change the description so that it is less confusing.

@dhalbert
Copy link
Contributor

I totally agree. _max_size right now is a misnomer, so either rename it to _max_address or change the constants to be a power of 2, not the current power of 2 minus -1.

@dhalbert
Copy link
Contributor

I think changing the constants makes more sense, not changing the name. People rarely use constants like 8191.

@jerryneedell
Copy link
Contributor Author

jerryneedell commented Jan 25, 2019

Agreed -- the len(fram) should be the total size -- 8192 or 32768 in these examples. I just wanted someone else to look over ti to make sure "fixing" it would not break something else that depended on the "max_address" value.

@makermelissa
Copy link
Collaborator

Changing the constant would require changing all of the checks to make sure it wasn't writing out of range and adding + 1 to the length only required one code change. Either way is fine, just something to keep in mind.

@makermelissa
Copy link
Collaborator

After thinking about it, I think logically changing all the checks does make a bit more sense. I just need to doublecheck that this doesn't result in an off by one error.

@dhalbert
Copy link
Contributor

Yes, keep the name as _max_size, increment the constants by 1 to be a power of 2, and change the if key > statements to be if key >=. Otherwise we still have technical debt.

@makermelissa
Copy link
Collaborator

Yes, keep the name as _max_size, increment the constants by 1 to be a power of 2, and change the if key > statements to be if key >=. Otherwise we still have technical debt.

Agreed.

@makermelissa
Copy link
Collaborator

makermelissa commented Jan 25, 2019

While testing my code, I found another bug in the code from before I worked on it. With Address Slicing, the addresses are off by one (they don't include the last address and are unable to use the last address by slicing. This is using the original code before my edits:

>>> fram[32767]
bytearray(b'\x01')
>>> fram[32766:32767]
bytearray(b'\x00')
>>> fram[32766:32768]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/lib/adafruit_fram.py", line 150, in __getitem__
ValueError: Register + Length greater than maximum FRAM size. (32767)

I can fix this in my changes, but could also open another issue since it's related to the issue, but also is another issue entirely.

@makermelissa
Copy link
Collaborator

Size issue fixed as well as the slicing issue I found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants