Skip to content

Conversation

@hathach
Copy link
Member

@hathach hathach commented Sep 13, 2018

It is still work in progress but current code works with 8 MB MX25R6435F on pca10056. The read speed is ok, but the write is painfully slow (will improve later). I would like to have as many review/suggestion as possible.

  • added flash_api directory and move all the flash there
  • flash_api.c implement generic read/write blocks API with page caching along with python glueing.
  • flash_api use flash_hal_erase/read/program which are implemented by internal or qspi flash.
  • flash hal will be dynamic binding later ( e.g switch from qspi to internal should we couldn't read/write to external flash in case of soldering issue etc ..)

#1049

@hathach
Copy link
Member Author

hathach commented Sep 13, 2018

the super slow write speed really need some improvement !! I will try to implement

  • non-blocking API, since the current write caching with erase + write + read is not that good at all.
  • Also we don't really need read if the whole 4KB is written only read data that we are not writing does not increase write speed with testbench.

screenshot from 2018-09-13 18-58-31

@tannewt
Copy link
Member

tannewt commented Sep 13, 2018

Write speed isn't critical to using CircuitPython. Yes, it'd be nice if it was faster but let's ignore it for now and focus on getting all of the APIs going.

I suggest filing a separate issue for it for the full 4.0.0 release milestone and moving onto other tasks for now.

@hathach
Copy link
Member Author

hathach commented Sep 13, 2018

@tannewt phew, I am trying to increase usb msc buffer size to 8KB but it doesn't help as well. probably need to dive deeper into the flash datasheet timing etc ... I will try to wrap it up now.

Update: just check datasheet of the flash on pca10056, we may need to enable high performance mode, will give it a try later.

@dhalbert
Copy link
Collaborator

@hathach We'd like to make this implementation be as similar as possible to the atmel-samd QSPI and external flash implementation, so that we can factor out the common code as much as possible and only implement the lowest level routines in a chip-specific way. For instance, that code has parameterized chip support, and it already has caching logic. Did you try copying that impl? This impl is more different than we thought it would be.

@hathach
Copy link
Member Author

hathach commented Sep 13, 2018

@dhalbert many of the spi std command for flash is handled by nrfx qspi driver. Since nrf52840 has enough memory (4K) to cache the whole page. I just refactor both caching for internal + external flash leaving it to only basic hal erase, read, program. At anywhere you could use block API flash_read_blocks/flash_write_blocks instead of internal/external_flash_write_blocks. The flash_ will use either internal or external depending on the config. Those can be changed to function pointer for concurrent internal + external uses if needed.

@tannewt
Copy link
Member

tannewt commented Sep 13, 2018

There is additional logic in the atmel-samd port that isn't in this one because it wasn't started from a copy. For example, the SPI flash chip is detected rather than hard coded. Ideally this logic would be shared but for now it can be copied if that's easier.

Ideally you'd only need to replace the implementations here but it hasn't been tested yet.

@hathach
Copy link
Member Author

hathach commented Sep 13, 2018

@tannewt ah yeah, I am adding support device lookup table with JEDEC ID. Instead of using 3 bytes response from 0x9F for manufacture id, memory type and capacity, can we use only 2 bytes response from 0x90 command (manufacture id, device id) ?

…f flash device is not one of supported.

change nrf qspi to blocking model
Rename config pin name from QSPI_FLASH_ --> MICROPY_QSPI_
@hathach
Copy link
Member Author

hathach commented Sep 15, 2018

I tried to enable high performance bit but couldn't get it written any faster. It is probably default mode already. Note: nrf52 SCK clock speed is only up to 32 Mhz.
screenshot from 2018-09-16 00-20-58

I post an issue on Nordic devzone to see if there is anyone got more lucky than us.
https://devzone.nordicsemi.com/f/nordic-q-a/38570/write-speed-with-mx25r6435f-on-nrf52840dk

@hathach
Copy link
Member Author

hathach commented Sep 19, 2018

Nordic testing is a bit higher than us for write speed (different tool can be a bit different), but seem like write speed will be somewhat 1/10 of read speed. We may not improve it much with pca10056.

image

@dhalbert
Copy link
Collaborator

dhalbert commented Oct 3, 2018

@hathach can you resolve the conflicts that have arisen? Thanks.

@hathach
Copy link
Member Author

hathach commented Oct 12, 2018

@dhalbert I am making more improvement while porting this for Arduino, I will clean up and update the flash code then resolve the conflict for this a bit later.

@dhalbert
Copy link
Collaborator

@hathach I stumbled on this while looking at the datasheet for something else. It says to use high drive strength to drive the QSPI pins:

[page 267, section 6.19.1]

2. To ensure stable operation, set the GPIO drive strength to “high drive”. See the GPIO — General
purpose input/output on page 141 chapter for details on how to configure GPIO drive strength.

#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 12)
#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 14)
#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 8)
#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 8)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems inconsistent that all other defines in this file use the pin__ objects but for QSPI we use the pin number

nrf_gpio_cfg_input(11, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(12, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(24, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(25, NRF_GPIO_PIN_PULLUP);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like test code that shouldn't be merged.



// Settings for the Gigadevice GD25Q16C 2MiB SPI flash.
// Datasheet: http://www.gigadevice.com/wp-content/uploads/2017/12/DS-00086-GD25Q16C-Rev2.6.pdf
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link returns 404 for me

.status_quad_enable = (1 << 9)\
}

#define MX25R6435F {\
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a datasheet link as well?

@arturo182
Copy link
Collaborator

I'm trying to get this patch working on my board. I use a different flash chip but I added it to flash_devices.h, it seems to get detected properly because I get past the if ( _flash_devices_arr[i].manufacturer_id == mfgr_id && _flash_devices_arr[i].device_id == dev_id ) { check with proper values, however the MSD does not get mounted by the system (Linux Mint), trying to mount it manually gives me an error:

> sudo mount /dev/sdb /media/arturo182/usb
mount: /media/arturo182/usb: wrong fs type, bad option, bad superblock on /dev/sdb, missing codepage or helper program, or other error.

The CDC is properly detected and works just fine, but it also doesn't seem to be aware of the flash storage:

>>> import os
>>> os.listdir('.')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 19] Unsupported operation

Also, the chip i use is 128Mbit/16Mbyte and I specified it as so .total_size = 16*1024*1024, but when I connect the board I get this message sd 4:0:0:0: [sdb] 32768 512-byte logical blocks: (16.8 MB/16.0 MiB), doesn't that mean that the system think there is more space than the chip has so either we might overwrite something or discard it at some boundary check? I think it's possible the total_size units are wrong.

@dhalbert
Copy link
Collaborator

@arturo182 What chip is it, and does it truly have 16MiB (binary megabytes), or is it smaller?

Also 16MB is just at the boundary between FAT12 and FAT16, and it's possible either Linux or FatFS is confused about just where that boundary is: one might be think it's FAT12 and the other might think it's FAT16.

@arturo182
Copy link
Collaborator

Ah yes, I should've written the model, it's IS25LP128F, datasheet available here: http://www.issi.com/WW/pdf/25LP-WP128F.pdf
I also tried setting total_size to 8MB and that didn't work either, but I'm not sure if mismatching like that should work at all.

@hathach
Copy link
Member Author

hathach commented Oct 17, 2018

@aturo182 is the flash wired for quad mode ? If yes, Also please check the status registers mask in device config to make sure it is correct value to put flash device into quad mode.

@arturo182
Copy link
Collaborator

I use (1 << 6) for the quad enable value, I think it's correct according to the datasheet:
image

As for the design, I'm not sure what more is needed for quad mode wiring, I pretty much copied the PCA10056 except with a different chip, most qspi flash ICs seem to be pin compatible.

Datasheet:
image

My design:
image

@ladyada do you think it would be possible to post the nrf52840 feather schematic part with the QSPI flash so I could compare?

@tannewt
Copy link
Member

tannewt commented Oct 17, 2018

@arturo182 I think most of the QSPI testing has been done on the Nordic dev boards. The feather exists but I'm not sure if anyone has tested it at all.

@arturo182
Copy link
Collaborator

I see, I thought @hathach was using some early nRF52840 feather prototypes to test the qspi :D

Looking at the PCA10056 schematic the pinout seems the same, I don't think there is any limit to which pins can be used as QSPI, so maybe I'll double check my soldering, but seems odd that it managed so read the chip id without a problem.
image

@hathach
Copy link
Member Author

hathach commented Oct 18, 2018

@arturo182 I only tested with pca10056, maybe you should start there to see if that works for you first and then moving to your custom board.

@arturo182
Copy link
Collaborator

Good idea, I'll try that :D

@arturo182
Copy link
Collaborator

I tested the code on PCA10056 and it works there so must be something with either the soldering, the chip or my gpio choice.

@tannewt
Copy link
Member

tannewt commented Oct 26, 2018

FYI I'm moving the atmel-samd port to tiny usb and factoring out all of the usb stuff from the ports. This includes MSC so I plan on factoring out the spi flash chip support as well. I'll add support for QSPI on nRF based on this PR (thanks for it!) but will not merge it directly. Expect to see a PR for it next week sometime. Thanks!

@tannewt tannewt closed this Oct 26, 2018
@hathach hathach deleted the nrf52_qspi_flash branch December 17, 2019 03:38
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

Successfully merging this pull request may close these issues.

4 participants