Merge pull request #5721 from scartmell-arm/bug-i2c-abort-deep-sleep

Fix bug allowing I2C::abort_transfer to incorrectly unlock deep sleep mode
pull/5744/merge
Cruz Monrreal 2018-01-11 10:30:53 -06:00 committed by GitHub
commit 31f59b9fb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 6 deletions

View File

@ -28,9 +28,10 @@ SingletonPtr<PlatformMutex> I2C::_mutex;
I2C::I2C(PinName sda, PinName scl) :
#if DEVICE_I2C_ASYNCH
_irq(this), _usage(DMA_USAGE_NEVER),
_irq(this), _usage(DMA_USAGE_NEVER), _deep_sleep_locked(false),
#endif
_i2c(), _hz(100000) {
_i2c(), _hz(100000)
{
// No lock needed in the constructor
// The init function also set the frequency to 100000
@ -133,7 +134,7 @@ int I2C::transfer(int address, const char *tx_buffer, int tx_length, char *rx_bu
unlock();
return -1; // transaction ongoing
}
sleep_manager_lock_deep_sleep();
lock_deep_sleep();
aquire();
_callback = callback;
@ -148,7 +149,7 @@ void I2C::abort_transfer(void)
{
lock();
i2c_abort_asynch(&_i2c);
sleep_manager_unlock_deep_sleep();
unlock_deep_sleep();
unlock();
}
@ -159,11 +160,26 @@ void I2C::irq_handler_asynch(void)
_callback.call(event);
}
if (event) {
sleep_manager_unlock_deep_sleep();
unlock_deep_sleep();
}
}
void I2C::lock_deep_sleep()
{
if (_deep_sleep_locked == false) {
sleep_manager_lock_deep_sleep();
_deep_sleep_locked = true;
}
}
void I2C::unlock_deep_sleep()
{
if (_deep_sleep_locked == true) {
sleep_manager_unlock_deep_sleep();
_deep_sleep_locked = false;
}
}
#endif

View File

@ -176,11 +176,19 @@ public:
/** Abort the on-going I2C transfer
*/
void abort_transfer();
protected:
protected:
/** Lock deep sleep only if it is not yet locked */
void lock_deep_sleep();
/** Unlock deep sleep only if it has been locked */
void unlock_deep_sleep();
void irq_handler_asynch(void);
event_callback_t _callback;
CThunk<I2C> _irq;
DMAUsage _usage;
bool _deep_sleep_locked;
#endif
protected: