mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #5722 from scartmell-arm/bug-spi-abort-deep-sleep
Fix bug allowing SPI::abort_transfer to incorrectly unlock deep sleep modepull/5744/merge
						commit
						f14ddd1708
					
				| 
						 | 
					@ -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