Skip to content

feature-qspi: QSPI HAL addition #5429

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

Merged
merged 5 commits into from
Nov 14, 2017
Merged

Conversation

0xc0170
Copy link
Contributor

@0xc0170 0xc0170 commented Nov 3, 2017

Destination branch: feature-qspi

Adding new QSPI HAL header file. This should help to use memory-maped devices
as memories, graphical displays.

The API consist of few functions, most important are read/write/write_command functions.

The command format is:

----------------------------------------------
| Instruction | Address | Alt | Dummy | Data |
----------------------------------------------

We define only synch API at the moment. This patch contains only a header file.

We will provide an implementation for a target.

@jeromecoutant @LMESTM @kl-cruz @stevew817 @mmahadevan108 @Archcady @TomoYamanaka @jessexm @jacobjohnson-ON please have a look, might be interested in this, any feedback welcome!

cc @maclobdell @screamerbg @MarceloSalazar @ashok-rao

Adding new QSPI HAL header file. This should help to use memory-maped devices
as memories, graphical displays.

The API consist of few functions, most important are read/write/write_command functions.

The command format is:

```
----------------------------------------------
| Instruction | Address | Alt | Dummy | Data |
----------------------------------------------
```

We define only synch API at the moment.
@0xc0170 0xc0170 changed the base branch from master to feature-qspi November 3, 2017 14:18
@stevew817
Copy link
Contributor

How does this fit in with #4229 ?

@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 3, 2017

How does this fit in with #4229 ?

The API proposed there is slighty different (more oriented to a file system like, program/erase). You can view the file for hal API here https://github.com/kl-cruz/mbed-os/blob/61a510a15af9b780d260b24fea33920229074144/hal/qspi_api.h. #4229 (comment) - I left there a comment regarding HAL. We can continue discussion around it here.

@stevew817 you got any driver for QSPI or even an example for any target that I can have a look at? I could not find any in the codebase, but recall there was one of GG targets that should have QSPI peripheral.

@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 3, 2017

For a reader it might help some references that are out there and worth looking at (I forgot to pinned this in the first comment !)

References:

@stevew817
Copy link
Contributor

stevew817 commented Nov 6, 2017

@0xc0170 Our QSPI HAL doc lives ere: http://devtools.silabs.com/dl/documentation/doxygen/5.3.2/efm32gg11/html/group__QSPI.html
QSPI is being introduced on EFM32GG11, for which support is getting staged here: https://github.com/SiliconLabs/mbed-os/tree/feature/EFM32GG11

@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 6, 2017

@0xc0170 Our QSPI HAL doc lives ere: http://devtools.silabs.com/dl/documentation/doxygen/5.3.2/efm32gg11/html/group__QSPI.html

Thanks Steve, I checked the docs. The API there is similar to the one here, found some diferencies but mostly as it is structured differently (read/write data and config). The write/read config maps to our qspi_command_t, read/write plus read/write configs should be straight-forward to port to this HAL.

@LMESTM
Copy link
Contributor

LMESTM commented Nov 6, 2017

cc @adustm @bcostm

Fixing by adding NONE values for both
@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 7, 2017

Updated (see 2 commits for details)

hal/qspi_api.h Outdated
* @param obj QSPI object
* @param command QSPI command
* @param data TX buffer
* @param[in,out] in - length TX buffer length in bytes, out - number of bites written
Copy link
Contributor

Choose a reason for hiding this comment

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

bites->bytes

hal/qspi_api.h Outdated
* @param obj QSPI object
* @param command QSPI command
* @param data RX buffer
* @param[in,out] in - length RX buffer length in bytes, out - number of bites read
Copy link
Contributor

Choose a reason for hiding this comment

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

bites->bytes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will fix asap

@bentcooke
Copy link
Contributor

Looks good other than the two minor corrections of bites->bytes in the comments.

This provides a way to return how many bytes have been written/read (as status codes
are returned via func ret value)
Copy link
Contributor

@bentcooke bentcooke left a comment

Choose a reason for hiding this comment

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

Looks good!

hal/qspi_api.h Outdated
* @param sclk The clock pin
* @param ssel The chip select pin
* @param hz The bus frequency
* @param mode SPI mode
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this just the master/slave mode or are we referring to SPI modes 0,1,2,3? Would be nice to add a 1 line comment if it's either.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will add Clock polarity and phase mode (0 - 3)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

QSPI_STATUS_ERROR = -1, /**< Generic error >*/
QSPI_STATUS_INVALID_PARAMETER = -2, /**< The parameter is invalid >*/
QSPI_STATUS_OK = 0, /**< Function executed sucessfully >*/
} qspi_status_t;
Copy link
Contributor

Choose a reason for hiding this comment

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

How about some specific error codes like peripheral init fail, read/write fail along with generic error and maybe we can add more as it matures (buffer issues, bus error etc)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would expect this might get more errors once we get some implementations. As this error is per function, I find it sufficient for cases like peripheral fail (if init returns ERROR) init phase failed. Or if write() returns error, write failed. If we got something like transfer(read+write) then write/read error would make sense.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @0xc0170 . OK with me!

SPI mode means Clock polarity and phase mode (0 - 3)
@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 10, 2017

/morph build

@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 10, 2017

I triggered CI build to move forward with this.

This goes to feature branch feature-qspi, feedback is still open anytime even if this gets integrated to the branch.

@mbed-ci
Copy link

mbed-ci commented Nov 10, 2017

Build : SUCCESS

Build number : 493
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/5429/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build

@marcuschangarm
Copy link
Contributor

@0xc0170 this seems like a very manual API. Are there any plans for enabling memory mapped QSPI devices? For example, it would be useful to have an API for setting up an external QSPI flash chip as memory mapped internal flash.

struct {
qspi_bus_width_t bus_width; /**< Bus width for the address >*/
qspi_address_size_t size; /**< Address size >*/
uint32_t value; /**< Address value >*/
Copy link
Contributor

Choose a reason for hiding this comment

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

For memory mapped flash devices, do we only use the "value" element from the command structure?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you elaborate ? provide more details ?

Note: This so far does not support memory mapped QSPI. I am about to add a proposal below for it.

@mbed-ci
Copy link

mbed-ci commented Nov 10, 2017

@mbed-ci
Copy link

mbed-ci commented Nov 10, 2017

@bcostm
Copy link
Contributor

bcostm commented Nov 13, 2017

It looks good. But I looked in the ST HAL QSPI driver and there are other parameters that are used during QSPI peripheral initialization and I think not covered in this API.

  uint32_t FifoThreshold;      /* Specifies the threshold number of bytes in the FIFO (used only in indirect mode)
                                  This parameter can be a value between 1 and 32 */

  uint32_t SampleShifting;     /* Specifies the Sample Shift. The data is sampled 1/2 clock cycle delay later to 
                                  take in account external signal delays. (It should be QSPI_SAMPLE_SHIFTING_NONE in DDR mode)
                                  This parameter can be a value of @ref QSPI_SampleShifting */

  uint32_t FlashSize;          /* Specifies the Flash Size. FlashSize+1 is effectively the number of address bits 
                                  required to address the flash memory. The flash capacity can be up to 4GB 
                                  (addressed using 32 bits) in indirect mode, but the addressable space in 
                                  memory-mapped mode is limited to 256MB
                                  This parameter can be a number between 0 and 31 */

  uint32_t ChipSelectHighTime; /* Specifies the Chip Select High Time. ChipSelectHighTime+1 defines the minimum number 
                                  of clock cycles which the chip select must remain high between commands.
                                  This parameter can be a value of @ref QSPI_ChipSelectHighTime */ 

  uint32_t ClockMode;          /* Specifies the Clock Mode. It indicates the level that clock takes between commands.
                                  This parameter can be a value of @ref QSPI_ClockMode */

  uint32_t FlashID;            /* Specifies the Flash which will be used,
                                  This parameter can be a value of @ref QSPI_Flash_Select */

  uint32_t DualFlash;          /* Specifies the Dual Flash Mode State
                                  This parameter can be a value of @ref QSPI_DualFlash_Mode */

So, how are we going to set them ? Add other parameters in the qspi_init function or create additional methods ?

Same thing for the qspi command. We have many other parameters and I don't know how to manage them with the actual API:

uint32_t DdrMode;            // Two values: Disabled or Enabled
uint32_t DdrHoldHalfCycle;   // Two values: Analog delay or half clock delay
uint32_t SIOOMode;          // Two values: every command or only first command

uint32_t TimeOutPeriod;      // Specifies the number of clock to wait when the FIFO is full before to release the chip select. Range 0..0xFFFF
uint32_t TimeOutActivation;  // Specifies if the time out counter is enabled to release the chip select. 

@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 13, 2017

@0xc0170 this seems like a very manual API. Are there any plans for enabling memory mapped QSPI devices? For example, it would be useful to have an API for setting up an external QSPI flash chip as memory mapped internal flash.

@marcuschangarm Currently looking at memory mapped mode support (execute in place - XIP mode). There could be two methods that would enable/disable memory mapped mode. I'll propose a change via separate comment and what implications they have.

It looks good. But I looked in the ST HAL QSPI driver and there are other parameters that are used during QSPI peripheral initialization and I think not covered in this API.

@bcostm Thanks for the review.
These configurations are target specific, what we are capturing here is generic QSPI definitions. From the above, they are very peripheral specific and should be set to default values in HAL (if tuning required, then use direct SDK drivers API). If you find any that are common, let us know. I'll recheck them and we can have a look at their portability.

@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 13, 2017

The proposal for extending this to cover memory mapped QSPI (execute code in place - XIP) in HAL.

From a driver perspective, all it needs to do is enable/disable memory-mapped mode. This is usually a register in QSPI peripheral that controls this. Based on this, plus QSPI section, it would use QSPI peripheral for read if its within the defined section and it's active.

/** Enable memory-mapped mode
 *
 * Each target defines own memory section
 * that is mapped for this.
 * If a peripheral is in memory-mapped mode, it provides limited set of features. Write is not allowed, only read.
 */
qspi_status_t qspi_enable_xip(qspi_t *obj);

/** Disable memory-mapped mode
 *
 */
 qspi_status_t qspi_disable_xip(qspi_t *obj);

Each target defines QSPI specific memory section. QSPI would be used if an access is done within this defined section and memory-mapped is active.

Based on this proposal it can come as separate addition to this feature branch, or I'll add it here. Waiting for review!

@0xc0170 0xc0170 removed the needs: CI label Nov 14, 2017
@0xc0170
Copy link
Contributor Author

0xc0170 commented Nov 14, 2017

I'll send a new pull request with memory mapped support (the latest comment above).

This is ready for merge to the feature-branch (comments are always appreciated)

@0xc0170 0xc0170 merged this pull request into ARMmbed:feature-qspi Nov 14, 2017
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.

9 participants