-
Notifications
You must be signed in to change notification settings - Fork 3k
Add explicit pin-map support for extra targets #11632
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
Changes from all commits
171f9bb
8fd0184
993843b
61ba60b
6e6d597
d3e6b3c
8dc1172
9a9c329
82eb7aa
0f19604
0642808
9b7b4a1
8c10728
7e87cf0
82aefe7
21a9712
e048619
ba95fcf
9813021
d38c7d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,7 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin | |
_qspi_io3 = io3; | ||
_qspi_clk = sclk; | ||
_qspi_cs = ssel; | ||
_explicit_pinmap = NULL; | ||
_inst_width = QSPI_CFG_BUS_SINGLE; | ||
_address_width = QSPI_CFG_BUS_SINGLE; | ||
_address_size = QSPI_CFG_ADDR_SIZE_24; | ||
|
@@ -59,9 +60,36 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin | |
_mode = mode; | ||
_hz = ONE_MHZ; | ||
_initialized = false; | ||
_init_func = &QSPI::_initialize; | ||
|
||
//Go ahead init the device here with the default config | ||
bool success = _initialize(); | ||
bool success = (this->*_init_func)(); | ||
MBED_ASSERT(success); | ||
} | ||
|
||
QSPI::QSPI(const qspi_pinmap_t &pinmap, int mode) : _qspi() | ||
{ | ||
_qspi_io0 = pinmap.data0_pin; | ||
_qspi_io1 = pinmap.data1_pin; | ||
_qspi_io2 = pinmap.data2_pin; | ||
_qspi_io3 = pinmap.data3_pin; | ||
_qspi_clk = pinmap.sclk_pin; | ||
_qspi_cs = pinmap.ssel_pin; | ||
_explicit_pinmap = &pinmap; | ||
_inst_width = QSPI_CFG_BUS_SINGLE; | ||
_address_width = QSPI_CFG_BUS_SINGLE; | ||
_address_size = QSPI_CFG_ADDR_SIZE_24; | ||
_alt_width = QSPI_CFG_BUS_SINGLE; | ||
_alt_size = QSPI_CFG_ALT_SIZE_8; | ||
_data_width = QSPI_CFG_BUS_SINGLE; | ||
_num_dummy_cycles = 0; | ||
_mode = mode; | ||
_hz = ONE_MHZ; | ||
_initialized = false; | ||
_init_func = &QSPI::_initialize_direct; | ||
|
||
//Go ahead init the device here with the default config | ||
bool success = (this->*_init_func)(); | ||
MBED_ASSERT(success); | ||
} | ||
|
||
|
@@ -255,12 +283,30 @@ bool QSPI::_initialize() | |
return _initialized; | ||
} | ||
|
||
// Note: Private helper function to initialize qspi HAL | ||
bool QSPI::_initialize_direct() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
{ | ||
if (_mode != 0 && _mode != 1) { | ||
_initialized = false; | ||
return _initialized; | ||
} | ||
|
||
qspi_status_t ret = qspi_init_direct(&_qspi, _explicit_pinmap, _hz, _mode); | ||
if (QSPI_STATUS_OK == ret) { | ||
_initialized = true; | ||
} else { | ||
_initialized = false; | ||
} | ||
|
||
return _initialized; | ||
} | ||
|
||
// Note: Private function with no locking | ||
bool QSPI::_acquire() | ||
{ | ||
if (_owner != this) { | ||
//This will set freq as well | ||
_initialize(); | ||
(this->*_init_func)(); | ||
_owner = this; | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you requiring the passed-in pinmap object to have lifetime extending beyond the constructor call? That's not specified.
Looking at the code, I don't think you are, so this doesn't have to be a member. You could just pass the pinmap to the(Nope - you should be calling_initialize_direct
. Will save 4 bytes of RAM._initialize_direct
other places)I realise this model comes from the
SPI
code, which does require the pinmap to persist for later re-init. That one does need that specified. Maybe the same should be specified for all classes to allow suspend/resume in future, even if they don't do it now.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pondering the persistence thing - this means that
which I've seen suggested is actually illegal. That would be retaining a pointer to a temporary.
It's unfortunate that the compiler accepts it. You're allowed to pass a temporary
X
to aconst X &
Two suggestions to prevent that here: https://stackoverflow.com/questions/40790126/prevent-passing-temporary-for-const-ref-parameter
SPI(const spi_pinmap_t &&) = delete
SPI(const spi_pinmap_t *)
Not sure it's too worth worrying about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mentioned form
SPI(get_spi_pinmap(A,B,C,D))
is actually not suggested. According to the design doc:I think we should prevent passing of temporary objects. The first option looks more suitable for our case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added
SPI(const spi_pinmap_t &&, PinName) = delete;
And now when
SPI spi(get_spi_pinmap(PA_7, PA_6, PA_5, PA_4));
causes compilation error:This is what we wanted to achieve. The last question is if this solution should be added only to
SPI
andQSPI
classes or to all peripheral constructors (which support explicit pinmap)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the minute, the others do support passing a temporary, I guess, because they copy all the data out in the constructor.
Removing that ability to pass a temporary later (eg if they wanted to implement suspend/resume) would be an API change, so I guess it's probably better to ensure it's blocked now. And it prevents the bad code generation possibility.