Skip to content
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

Add SPI Mode Enum to LinuxSpiDriver #2097

Merged
merged 6 commits into from
Jul 10, 2023

Conversation

mohitsingh999
Copy link
Contributor

SPI Modes specify the clock polarity for each transaction. The default Fprime LinuxSpiDriver assumed SPI Mode 0. This should be generalized to account for SPI devices with different clock polarity and phases.

Originating Project/Creator SRH/Mohit Singh
Affected Component Drv::LinuxSpiDriver
Affected Architectures(s) SRH MPPT Tester
Related Issue(s)
Has Unit Tests (y/n) n
Builds Without Errors (y/n) y
Unit Tests Pass (y/n)
Documentation Included (y/n) y

Change Description

Add a SPI Mode Enumeration to the LinuxSpiDriver Component Implementation, and include the SpiMode as a formal parameter in the LinuxSpiDriverComponentImpl::open() function .

Rationale

This allows for SPI devices with a different clock phase and polarity to be properly integrated with F-Prime, without having to modify the component implementation. Previously, the SPI Mode for any SPI device was assumed to be SPI mode 0. This implies a clock phase=0 and a clock polarity=0, which is not always true.

Testing/Review Recommendations

The implementation has been tested with SPI Mode 0 and SPI Mode 1 devices and works correctly.

Future Work

In addition to SPI Modes, the Linux SPI implementations include several additional parameters, such as SPI_CS_HIGH, SPI_LSB_FIRST, and the bits per word for each SPI Transaction. These parameters generally do not change for most SPI devices, but it might make sense to give the user ability to configure these parameters when opening a SPI device in FPrime.

SPI Modes specify the clock polarity for each transaction. The default Fprime LinuxSpiDriver assumed SPI Mode 0. This should be generalized to account for SPI devices with different clock polarity and phases.
@@ -59,7 +77,8 @@ namespace Drv {
//! Open device
bool open(NATIVE_INT_TYPE device,
NATIVE_INT_TYPE select,
SpiFrequency clock);
SpiFrequency clock,
SpiMode spiMode);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we add a default parameter here such that old code still works?

spiMode = SPI_MODE_0

Copy link
Collaborator

@LeStarch LeStarch left a comment

Choose a reason for hiding this comment

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

We should add the default to that parameter to preserve old code.

Copy link
Collaborator

@LeStarch LeStarch left a comment

Choose a reason for hiding this comment

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

Two changes, assert mode is in-range and add a default.

@@ -70,7 +70,8 @@ namespace Drv {

bool LinuxSpiDriverComponentImpl::open(NATIVE_INT_TYPE device,
NATIVE_INT_TYPE select,
SpiFrequency clock) {
SpiFrequency clock,
SpiMode spiMode) {

Copy link
Collaborator

Choose a reason for hiding this comment

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

We should assert that spiMode is in the correct range:

FW_ASSERT(spiMode >= SPI_MODE_0 || spiMode <= SPI_MODE_3);

@LeStarch LeStarch requested a review from timcanham June 26, 2023 18:22
@LeStarch
Copy link
Collaborator

@timcanham want to look at this too?

@LeStarch
Copy link
Collaborator

@mohitsingh999 I think the RPI error will be resolved by adding a default to that argument.

@timcanham
Copy link
Collaborator

@LeStarch Glad to look at it after @mohitsingh999 makes the changes.

@mohitsingh999
Copy link
Contributor Author

@LeStarch @timcanham I just made the changes to 1) Have a default SPI Mode parameter value and 2) Assert that the SPI Device mode is in range. Let me know if anything else needs fixing!

@LeStarch
Copy link
Collaborator

@timcanham I'll leave you to do a final approval and run.

Copy link
Collaborator

@LeStarch LeStarch left a comment

Choose a reason for hiding this comment

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

One minor nit.

mode = SPI_MODE_3;
default:
//Assert if the device SPI Mode is not in the correct range
FW_ASSERT(spiMode >= SpiMode::SPI_MODE_0 || spiMode <= SpiMode::SPI_MODE_3);
Copy link
Collaborator

Choose a reason for hiding this comment

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

You should just assert zero in this case.

FW_ASSERT(0, spiMode);

This will force-fail the assert and print the invalid mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@LeStarch Made the fix

mode = SPI_MODE_1;
break;
case SpiMode::SPI_MODE_2:
mode = SPI_MODE_2;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just noticed! Missing break statements.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! Just added the missing statements

* on the falling clock edge(CPHA = 0) or if data is shifted out on the
* falling clock edge and sampled on the rising clock edge(CPHA=1)
*
* SPI Mode 0: (CPOL = 0, CPHA = 0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would take these SPI comments out and annotate the SpiMode enum with a description of what each means, since the "SPI Mode X" values are now hidden.

U8 mode = SPI_MODE_0; // Mode 0 (CPOL = 0, CPHA = 0)

U8 mode; // Mode Select (CPOL = 0/1, CPHA = 0/1)
switch(spiMode) {

Check warning

Code scanning / CodeQL

Unchecked function argument

This use of parameter spiMode has not been checked.
@LeStarch LeStarch merged commit be4088d into nasa:devel Jul 10, 2023
thomas-bc pushed a commit that referenced this pull request Aug 4, 2023
* Add SPI Mode Enum to LinuxSpiDriver

SPI Modes specify the clock polarity for each transaction. The default Fprime LinuxSpiDriver assumed SPI Mode 0. This should be generalized to account for SPI devices with different clock polarity and phases.

* Add default spiMode parameter value, assert check to ensure SPI Mode is in range

* Use switch statement to set SPI Mode when opening SPI Device

* Force-fail assert and print SPI Mode for invalid SPI modes

* Redefined SpiMode enum variables, added missing break statements

* Update SpiMode enum comments for each variable
thomas-bc added a commit that referenced this pull request Aug 4, 2023
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.

3 participants