Disabled interrupts during an I2C transaction to make them atomic

This commit is contained in:
Th3maz1ng 2023-01-07 10:00:14 +01:00
parent f53ec9b5db
commit af85b9b594

View File

@ -15,11 +15,22 @@ bool i2c_write(uint8_t address, uint8_t reg, const uint8_t *const data, size_t l
{ {
if(!data) return false; if(!data) return false;
__disable_irq();
//First we send the address followed by the register from where we want to start writing: //First we send the address followed by the register from where we want to start writing:
tls_i2c_write_byte(address << 1, true); tls_i2c_write_byte(address << 1, true);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
tls_i2c_write_byte(reg, false); tls_i2c_write_byte(reg, false);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
for(size_t i = 0; i < length; i++) for(size_t i = 0; i < length; i++)
{ {
@ -27,25 +38,45 @@ bool i2c_write(uint8_t address, uint8_t reg, const uint8_t *const data, size_t l
if(tls_i2c_wait_ack() != WM_SUCCESS) if(tls_i2c_wait_ack() != WM_SUCCESS)
{ {
tls_i2c_stop(); tls_i2c_stop();
__enable_irq();
return false; return false;
} }
} }
tls_i2c_stop(); tls_i2c_stop();
__enable_irq();
return true; return true;
} }
bool i2c_write_reg(uint8_t address, uint8_t reg, uint8_t data) bool i2c_write_reg(uint8_t address, uint8_t reg, uint8_t data)
{ {
__disable_irq();
//First we send the address followed by the register we want to write to: //First we send the address followed by the register we want to write to:
tls_i2c_write_byte(address << 1, true); tls_i2c_write_byte(address << 1, true);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
tls_i2c_write_byte(reg, false); tls_i2c_write_byte(reg, false);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
tls_i2c_write_byte(data, false); tls_i2c_write_byte(data, false);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
tls_i2c_stop(); tls_i2c_stop();
__enable_irq();
return true; return true;
} }
@ -54,14 +85,29 @@ bool i2c_read(uint8_t address, uint8_t reg, uint8_t * const data, size_t length)
{ {
if(!data)return false; if(!data)return false;
__disable_irq();
//First we send the address followed by the register from where we want to start reading: //First we send the address followed by the register from where we want to start reading:
tls_i2c_write_byte(address << 1, true); tls_i2c_write_byte(address << 1, true);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
tls_i2c_write_byte(reg, false); tls_i2c_write_byte(reg, false);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
tls_i2c_write_byte((address << 1) | 1, true); tls_i2c_write_byte((address << 1) | 1, true);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
for(size_t i = 0; i < length - 1; i++ ) for(size_t i = 0; i < length - 1; i++ )
{ {
@ -70,21 +116,41 @@ bool i2c_read(uint8_t address, uint8_t reg, uint8_t * const data, size_t length)
data[length - 1] = tls_i2c_read_byte(false, true); data[length - 1] = tls_i2c_read_byte(false, true);
__enable_irq();
return true; return true;
} }
bool i2c_read_reg(uint8_t address, uint8_t reg, uint8_t * const data) bool i2c_read_reg(uint8_t address, uint8_t reg, uint8_t * const data)
{ {
__disable_irq();
//First we send the address followed by the register we want to read from: //First we send the address followed by the register we want to read from:
tls_i2c_write_byte(address << 1, true); tls_i2c_write_byte(address << 1, true);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
tls_i2c_write_byte(reg, false); {
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; __enable_irq();
return false;
}
tls_i2c_write_byte((address << 1) | 1, true); tls_i2c_write_byte(reg, false);
if(tls_i2c_wait_ack() != WM_SUCCESS) return false; if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
tls_i2c_write_byte(address << 1 | 1, true);
if(tls_i2c_wait_ack() != WM_SUCCESS)
{
__enable_irq();
return false;
}
uint8_t val = tls_i2c_read_byte(false, true); uint8_t val = tls_i2c_read_byte(false, true);
__enable_irq();
if(data) *data = val; if(data) *data = val;
return true; return true;