i2c_master: remove TIMEOUT since it makes little sense when sleeping
This commit is contained in:
parent
64c97740e1
commit
d7bc187e37
42
i2c_master.c
42
i2c_master.c
|
@ -15,12 +15,6 @@
|
||||||
#include "stm8s.h" // STM8S definitions
|
#include "stm8s.h" // STM8S definitions
|
||||||
#include "i2c_master.h" // I²C header and definitions
|
#include "i2c_master.h" // I²C header and definitions
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
// timeout for while loops (at least 100 us)
|
|
||||||
#define TIMEOUT 20000U
|
|
||||||
static uint16_t timeout;
|
|
||||||
|
|
||||||
bool i2c_master_setup(uint16_t freq_khz)
|
bool i2c_master_setup(uint16_t freq_khz)
|
||||||
{
|
{
|
||||||
// configure I²C peripheral
|
// configure I²C peripheral
|
||||||
|
@ -98,12 +92,8 @@ enum i2c_master_rc i2c_master_start(void)
|
||||||
// in practice this is not synchronous, and the TRM doesn't document it
|
// in practice this is not synchronous, and the TRM doesn't document it
|
||||||
|
|
||||||
I2C_SR2 = 0; // clear error flags
|
I2C_SR2 = 0; // clear error flags
|
||||||
timeout = TIMEOUT; // start timeout count
|
|
||||||
rim(); // enable interrupts
|
rim(); // enable interrupts
|
||||||
while ((I2C_CR2 & I2C_CR2_START) || !(I2C_SR1 & I2C_SR1_SB) || !(I2C_SR3 & I2C_SR3_MSL)) { // wait until start condition has been accepted, send, and we are in aster mode
|
while ((I2C_CR2 & I2C_CR2_START) || !(I2C_SR1 & I2C_SR1_SB) || !(I2C_SR3 & I2C_SR3_MSL)) { // wait until start condition has been accepted, send, and we are in aster mode
|
||||||
if (0 == timeout--) {
|
|
||||||
return I2C_MASTER_RC_TIMEOUT;
|
|
||||||
}
|
|
||||||
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
||||||
return I2C_MASTER_RC_BUS_ERROR;
|
return I2C_MASTER_RC_BUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -123,17 +113,11 @@ enum i2c_master_rc i2c_master_start(void)
|
||||||
static enum i2c_master_rc i2c_master_wait_stop(void)
|
static enum i2c_master_rc i2c_master_wait_stop(void)
|
||||||
{
|
{
|
||||||
I2C_SR2 = 0; // clear error flags
|
I2C_SR2 = 0; // clear error flags
|
||||||
timeout = TIMEOUT; // start timeout counter
|
|
||||||
rim(); // enable interrupts
|
|
||||||
while (I2C_CR2 & I2C_CR2_STOP) { // wait until stop condition is accepted and cleared
|
while (I2C_CR2 & I2C_CR2_STOP) { // wait until stop condition is accepted and cleared
|
||||||
if (0 == timeout--) {
|
|
||||||
return I2C_MASTER_RC_TIMEOUT;
|
|
||||||
}
|
|
||||||
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
||||||
return I2C_MASTER_RC_BUS_ERROR;
|
return I2C_MASTER_RC_BUS_ERROR;
|
||||||
}
|
}
|
||||||
I2C_ITR = (I2C_ITR_ITEVTEN | I2C_ITR_ITERREN); // enable I²C interrupts
|
// there is no interrupt flag we can use here
|
||||||
wfi(); // got to sleep to prevent EMI causing glitches
|
|
||||||
}
|
}
|
||||||
// this time we can't use I2C_CR2_STOP to check for timeout
|
// this time we can't use I2C_CR2_STOP to check for timeout
|
||||||
if (I2C_SR3 & I2C_SR3_MSL) { // ensure we are not in master mode anymore
|
if (I2C_SR3 & I2C_SR3_MSL) { // ensure we are not in master mode anymore
|
||||||
|
@ -182,12 +166,8 @@ enum i2c_master_rc i2c_master_select_slave(uint16_t slave, bool address_10bit, b
|
||||||
if (!address_10bit) { // 7-bit address
|
if (!address_10bit) { // 7-bit address
|
||||||
I2C_DR = (slave << 1) | (write ? 0 : 1); // select slave, with read/write flag
|
I2C_DR = (slave << 1) | (write ? 0 : 1); // select slave, with read/write flag
|
||||||
I2C_SR2 = 0; // clear error flags
|
I2C_SR2 = 0; // clear error flags
|
||||||
timeout = TIMEOUT; // start timeout counter
|
|
||||||
rim(); // enable interrupts
|
rim(); // enable interrupts
|
||||||
while (!(I2C_SR1 & I2C_SR1_ADDR)) { // wait until address is transmitted (or error)
|
while (!(I2C_SR1 & I2C_SR1_ADDR)) { // wait until address is transmitted (or error)
|
||||||
if (0 == timeout--) {
|
|
||||||
return I2C_MASTER_RC_TIMEOUT;
|
|
||||||
}
|
|
||||||
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
||||||
return I2C_MASTER_RC_BUS_ERROR;
|
return I2C_MASTER_RC_BUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -204,12 +184,8 @@ enum i2c_master_rc i2c_master_select_slave(uint16_t slave, bool address_10bit, b
|
||||||
// send first part of address
|
// send first part of address
|
||||||
I2C_DR = 11110000 | (((slave >> 8 ) & 0x3) << 1); // send first header (11110xx0, where xx are 2 MSb of slave address)
|
I2C_DR = 11110000 | (((slave >> 8 ) & 0x3) << 1); // send first header (11110xx0, where xx are 2 MSb of slave address)
|
||||||
I2C_SR2 = 0; // clear error flags
|
I2C_SR2 = 0; // clear error flags
|
||||||
timeout = TIMEOUT; // start timeout counter
|
|
||||||
rim(); // enable interrupts
|
rim(); // enable interrupts
|
||||||
while (!(I2C_SR1 & I2C_SR1_ADD10)) { // wait until address is transmitted (or error)
|
while (!(I2C_SR1 & I2C_SR1_ADD10)) { // wait until address is transmitted (or error)
|
||||||
if (0 == timeout--) {
|
|
||||||
return I2C_MASTER_RC_TIMEOUT;
|
|
||||||
}
|
|
||||||
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
||||||
return I2C_MASTER_RC_BUS_ERROR;
|
return I2C_MASTER_RC_BUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -226,12 +202,8 @@ enum i2c_master_rc i2c_master_select_slave(uint16_t slave, bool address_10bit, b
|
||||||
I2C_SR2 &= ~(I2C_SR2_AF); // clear acknowledgement failure
|
I2C_SR2 &= ~(I2C_SR2_AF); // clear acknowledgement failure
|
||||||
I2C_DR = (slave & 0xff); // send remaining of address
|
I2C_DR = (slave & 0xff); // send remaining of address
|
||||||
I2C_SR2 = 0; // clear error flags
|
I2C_SR2 = 0; // clear error flags
|
||||||
timeout = TIMEOUT; // start timeout counter
|
|
||||||
rim(); // enable interrupts
|
rim(); // enable interrupts
|
||||||
while (!(I2C_SR1 & I2C_SR1_ADDR)) { // wait until address is transmitted (or error)
|
while (!(I2C_SR1 & I2C_SR1_ADDR)) { // wait until address is transmitted (or error)
|
||||||
if (0 == timeout--) {
|
|
||||||
return I2C_MASTER_RC_TIMEOUT;
|
|
||||||
}
|
|
||||||
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
||||||
return I2C_MASTER_RC_BUS_ERROR;
|
return I2C_MASTER_RC_BUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -254,11 +226,7 @@ enum i2c_master_rc i2c_master_select_slave(uint16_t slave, bool address_10bit, b
|
||||||
I2C_SR2 &= ~(I2C_SR2_AF); // clear acknowledgement failure
|
I2C_SR2 &= ~(I2C_SR2_AF); // clear acknowledgement failure
|
||||||
I2C_DR = 11110001 | (((slave >> 8) & 0x3) << 1); // send header (11110xx1, where xx are 2 MSb of slave address)
|
I2C_DR = 11110001 | (((slave >> 8) & 0x3) << 1); // send header (11110xx1, where xx are 2 MSb of slave address)
|
||||||
I2C_SR2 = 0; // clear error flags
|
I2C_SR2 = 0; // clear error flags
|
||||||
timeout = TIMEOUT; // start timeout counter
|
|
||||||
while (!(I2C_SR1 & I2C_SR1_ADDR)) { // wait until address is transmitted (or error)
|
while (!(I2C_SR1 & I2C_SR1_ADDR)) { // wait until address is transmitted (or error)
|
||||||
if (0 == timeout--) {
|
|
||||||
return I2C_MASTER_RC_TIMEOUT;
|
|
||||||
}
|
|
||||||
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
||||||
return I2C_MASTER_RC_BUS_ERROR;
|
return I2C_MASTER_RC_BUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -308,12 +276,8 @@ enum i2c_master_rc i2c_master_read(uint8_t* data, uint16_t data_size)
|
||||||
I2C_CR2 &= ~(I2C_CR2_ACK); // disable ACK
|
I2C_CR2 &= ~(I2C_CR2_ACK); // disable ACK
|
||||||
I2C_CR2 |= I2C_CR2_STOP; // prepare to send the stop
|
I2C_CR2 |= I2C_CR2_STOP; // prepare to send the stop
|
||||||
}
|
}
|
||||||
timeout = TIMEOUT; // start timeout counter
|
|
||||||
rim(); // enable interrupts
|
rim(); // enable interrupts
|
||||||
while (!(I2C_SR1 & I2C_SR1_RXNE)) { // wait until data is received (or error)
|
while (!(I2C_SR1 & I2C_SR1_RXNE)) { // wait until data is received (or error)
|
||||||
if (0 == timeout--) {
|
|
||||||
return I2C_MASTER_RC_TIMEOUT;
|
|
||||||
}
|
|
||||||
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
||||||
return I2C_MASTER_RC_BUS_ERROR;
|
return I2C_MASTER_RC_BUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -345,13 +309,9 @@ enum i2c_master_rc i2c_master_write(const uint8_t* data, uint16_t data_size)
|
||||||
(void)(I2C_SR1 & I2C_SR1_BTF); // clear BTF (when followed by write) in case the clock is stretched because there was no data to send on the next transmission slot
|
(void)(I2C_SR1 & I2C_SR1_BTF); // clear BTF (when followed by write) in case the clock is stretched because there was no data to send on the next transmission slot
|
||||||
I2C_DR = data[i]; // send byte
|
I2C_DR = data[i]; // send byte
|
||||||
I2C_SR2 = 0; // clear error flags
|
I2C_SR2 = 0; // clear error flags
|
||||||
timeout = TIMEOUT; // start timeout counter
|
|
||||||
rim(); // enable interrupts
|
rim(); // enable interrupts
|
||||||
while (!(I2C_SR1 & I2C_SR1_TXE)) { // wait until byte has been transmitted
|
while (!(I2C_SR1 & I2C_SR1_TXE)) { // wait until byte has been transmitted
|
||||||
IWDG->KR.fields.KEY = IWDG_KR_KEY_REFRESH; // reset watchdog
|
IWDG->KR.fields.KEY = IWDG_KR_KEY_REFRESH; // reset watchdog
|
||||||
if (0 == timeout--) {
|
|
||||||
return I2C_MASTER_RC_NOT_MASTER;
|
|
||||||
}
|
|
||||||
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
if (I2C_SR2 & (I2C_SR2_BERR | I2C_SR2_ARLO)) {
|
||||||
return I2C_MASTER_RC_BUS_ERROR;
|
return I2C_MASTER_RC_BUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue