mirror of https://github.com/ARMmbed/mbed-os.git
Fix bug allowing SPI::abort_transfer to incorrectly unlock deep sleep mode
- Add flag to SPI class to track if the SPI instance has locked deep sleep mode. - Wrap call to sleep_manager_lock_deep_sleep to only be called if SPI instance hasn't already locked deep sleep. - Wrap call to sleep_manager_unlock_deep_sleep to only be called if SPI has currently locked deep sleep mode.pull/5722/head
parent
c832515274
commit
c2670870dc
|
|
@ -33,6 +33,7 @@ SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) :
|
||||||
#if DEVICE_SPI_ASYNCH
|
#if DEVICE_SPI_ASYNCH
|
||||||
_irq(this),
|
_irq(this),
|
||||||
_usage(DMA_USAGE_NEVER),
|
_usage(DMA_USAGE_NEVER),
|
||||||
|
_deep_sleep_locked(false),
|
||||||
#endif
|
#endif
|
||||||
_bits(8),
|
_bits(8),
|
||||||
_mode(0),
|
_mode(0),
|
||||||
|
|
@ -140,7 +141,7 @@ int SPI::transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_
|
||||||
void SPI::abort_transfer()
|
void SPI::abort_transfer()
|
||||||
{
|
{
|
||||||
spi_abort_asynch(&_spi);
|
spi_abort_asynch(&_spi);
|
||||||
sleep_manager_unlock_deep_sleep();
|
unlock_deep_sleep();
|
||||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||||
dequeue_transaction();
|
dequeue_transaction();
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -200,13 +201,29 @@ int SPI::queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, i
|
||||||
|
|
||||||
void SPI::start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event)
|
void SPI::start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event)
|
||||||
{
|
{
|
||||||
sleep_manager_lock_deep_sleep();
|
lock_deep_sleep();
|
||||||
_acquire();
|
_acquire();
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
_irq.callback(&SPI::irq_handler_asynch);
|
_irq.callback(&SPI::irq_handler_asynch);
|
||||||
spi_master_transfer(&_spi, tx_buffer, tx_length, rx_buffer, rx_length, bit_width, _irq.entry(), event , _usage);
|
spi_master_transfer(&_spi, tx_buffer, tx_length, rx_buffer, rx_length, bit_width, _irq.entry(), event , _usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SPI::lock_deep_sleep()
|
||||||
|
{
|
||||||
|
if (_deep_sleep_locked == false) {
|
||||||
|
sleep_manager_lock_deep_sleep();
|
||||||
|
_deep_sleep_locked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPI::unlock_deep_sleep()
|
||||||
|
{
|
||||||
|
if (_deep_sleep_locked == true) {
|
||||||
|
sleep_manager_unlock_deep_sleep();
|
||||||
|
_deep_sleep_locked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||||
|
|
||||||
void SPI::start_transaction(transaction_t *data)
|
void SPI::start_transaction(transaction_t *data)
|
||||||
|
|
@ -230,7 +247,7 @@ void SPI::irq_handler_asynch(void)
|
||||||
{
|
{
|
||||||
int event = spi_irq_handler_asynch(&_spi);
|
int event = spi_irq_handler_asynch(&_spi);
|
||||||
if (_callback && (event & SPI_EVENT_ALL)) {
|
if (_callback && (event & SPI_EVENT_ALL)) {
|
||||||
sleep_manager_unlock_deep_sleep();
|
unlock_deep_sleep();
|
||||||
_callback.call(event & SPI_EVENT_ALL);
|
_callback.call(event & SPI_EVENT_ALL);
|
||||||
}
|
}
|
||||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,14 @@ protected:
|
||||||
*/
|
*/
|
||||||
void start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event);
|
void start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Lock deep sleep only if it is not yet locked */
|
||||||
|
void lock_deep_sleep();
|
||||||
|
|
||||||
|
/** Unlock deep sleep in case it is locked */
|
||||||
|
void unlock_deep_sleep();
|
||||||
|
|
||||||
|
|
||||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||||
|
|
||||||
/** Start a new transaction
|
/** Start a new transaction
|
||||||
|
|
@ -274,6 +282,7 @@ protected:
|
||||||
CThunk<SPI> _irq;
|
CThunk<SPI> _irq;
|
||||||
event_callback_t _callback;
|
event_callback_t _callback;
|
||||||
DMAUsage _usage;
|
DMAUsage _usage;
|
||||||
|
bool _deep_sleep_locked;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void aquire(void);
|
void aquire(void);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue