`cdelay` function is not a proper thing to count time.
It wouldn't count SoC clocks, but CPU clocks.
But even then, there are multiple instructions in `cdelay`:
- NOP
- decrement
- branch with compare
Assuming each instruction takes exactly 1 CPU cycle it is still wrong,
as we wait 3 time longer than requested.
But they don't take exactly 1 CPU cycle.
CPUs have caches, branch predictors, are out-of-order and so on.
So a much better way to count this time would be `busy_wait_us`.
I performed some test using vexriscv and Saleae Logic Analyzer:
vexriscv variant | requested I2C speed | actual (cdelay) | actual (busy_wait_us)
-----------------+---------------------+-----------------+----------------------
minimal | 50 kHz | 4 kHz | 38 kHz
minimal | 200 kHz | 15 kHz | 96 kHz
minimal | 400 kHz | 28 kHz | 137 kHz
-----------------+---------------------+-----------------+----------------------
lite | 50 kHz | 12 kHz | 40 kHz
lite | 200 kHz | 43 kHz | 115 kHz
lite | 400 kHz | 74 kHz | 180 kHz
-----------------+---------------------+-----------------+----------------------
standard | 50 kHz | 12 kHz | 45 kHz
standard | 200 kHz | 48 kHz | 159 kHz
standard | 400 kHz | 84 kHz | 311 kHz
Signed-off-by: Michal Sieron <msieron@antmicro.com>
Instead of enabling pull-up after every sent bit, enable it only after
sending all 8 bits.
This prevents some glitches from happening, where transition between
bits 0 to 0, produces a short spike.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
Change made in 1989d85 was supposed to poll I2C devices using both
writes and reads.
Here is a sequence that was supposed to happen:
- I2C start
- start I2C write
- start I2C read
- I2C stop
Unfortunately, the change worked differently:
- I2C start
- start I2C write
- write byte of (slave_addr << 1 | 1)
- I2C stop
This way, not only did the read not happen, but a potentially harmful
write was happening.
This commit makes it so following sequence takes place:
- I2C start
- start I2C write
- if (I2C write returned NACK)
- start I2C read
- if (I2C read returned ACK)
- read 1 byte and NACK it
- I2C stop
An additional 1 byte read is happening, as some devices may be unable
to process I2C stop after initiating I2C read.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
This commit fixes invalid type warning in the `get_i2c_devs` function:
```
/some/path/litex/litex/soc/software/libbase/i2c.c: In function 'get_i2c_devs':
/some/path/litex/litex/soc/software/libbase/i2c.c:21:45: warning: returning 'struct i2c_dev (*)[1]' from a function with incompatible return type 'struct i2c_dev *' [-Wincompatible-pointer-types]
21 | struct i2c_dev *get_i2c_devs(void) { return &i2c_devs; }
| ^~~~~~~~~
```
Signed-off-by: Michal Sieron <msieron@antmicro.com>
Use format constants for fixed width integer types to make it work on
both 32-bit and 64-bit CPUs without warnings.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
Use format constants for fixed width integer types to make it work on
both 32-bit and 64-bit CPUs without warnings.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
When using x4 modules, their response makes up only half a byte.
We need to extract the nibble and then test it.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
It allows to perform a memtest (similar to `sdram_test`), but using DMAs
and bypassing system bus. This way, one can test ranges such above 4 GiB,
which was the limit with `sdram_test` due to address_width being limited
to 32 bits.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
`SDRAM_TEST_DATA_BYTES` definition was incorrect as it treated size
specified in CSR subregisters as if it was a byte count.
Correct way to calculate that is to use definitions from `sdram_phy.h`.
```
#define SDRAM_TEST_DATA_BYTES (SDRAM_PHY_DFI_DATABITS / 8 * SDRAM_PHY_PHASES)
```
Also:
- extracted code to `sdram_bist_[write|read]` functions
- made global variables static
- fixed formatting
Signed-off-by: Michal Sieron <msieron@antmicro.com>
Always print MAIN-RAM and optionally print SDRAM.
This is caused by the fact, that SDRAM size can be bigger than
RAM declared in the memory map.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
Add `get_supported_memory` function that reads SPD to calculate
supported memory from the SDRAM.
When it's not possible to read from the SPD (no I2C) or there are errors
with the readout, it defaults to `SDRAM_PHY_SUPPORTED_MEMORY` defined in
`generated/sdram_phy.h` by `litedram/init.py`.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
Right now there are only `print_size` and `print_progress` functions
from memtest.c, but changed to use uint64_t.
Signed-off-by: Michal Sieron <msieron@antmicro.com>