Merge branch 'master' of https://github.com/microsoft/jacdac-tiny
This commit is contained in:
Коммит
7c545178a7
35
stm32/i2c.c
35
stm32/i2c.c
|
@ -10,6 +10,14 @@
|
|||
#endif
|
||||
|
||||
#ifdef STM32F0
|
||||
#if 1
|
||||
// 22.4.10 I2C_TIMINGR register configuration examples
|
||||
#if I2C_FAST_MODE
|
||||
#define I2C_TIMING 0x00310309
|
||||
#else
|
||||
#define I2C_TIMING 0x00420F13
|
||||
#endif
|
||||
#else
|
||||
// rise 100ns, fall 10ns
|
||||
#if I2C_FAST_MODE
|
||||
#define I2C_TIMING 0x0010020A
|
||||
|
@ -17,6 +25,7 @@
|
|||
#define I2C_TIMING 0x00201D2B
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void setup_pin(uint8_t pin) {
|
||||
pin_setup_output_af(pin, I2C_AF);
|
||||
|
@ -53,13 +62,17 @@ int i2c_write_reg_buf(uint8_t addr, uint8_t reg, const void *src, unsigned len)
|
|||
return -1;
|
||||
|
||||
const uint8_t *p = src - 1;
|
||||
while (!LL_I2C_IsActiveFlag_STOP(I2Cx)) {
|
||||
const uint8_t *end = (const uint8_t *)src + len;
|
||||
while (p < end) {
|
||||
if (LL_I2C_IsActiveFlag_TXIS(I2Cx)) {
|
||||
LL_I2C_TransmitData8(I2Cx, p == src - 1 ? reg : *p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
while (!LL_I2C_IsActiveFlag_STOP(I2Cx))
|
||||
;
|
||||
|
||||
LL_I2C_ClearFlag_STOP(I2Cx);
|
||||
|
||||
return 0;
|
||||
|
@ -70,6 +83,8 @@ int i2c_write_buf(uint8_t addr, const void *src, unsigned len) {
|
|||
return i2c_write_reg_buf(addr, *p, p + 1, len - 1);
|
||||
}
|
||||
|
||||
#define MAXREP 10000
|
||||
|
||||
int i2c_read_buf(uint8_t addr, uint8_t reg, void *dst, unsigned len) {
|
||||
addr <<= 1;
|
||||
LL_I2C_HandleTransfer(I2Cx, addr, LL_I2C_ADDRSLAVE_7BIT, 1, LL_I2C_MODE_SOFTEND,
|
||||
|
@ -86,11 +101,21 @@ int i2c_read_buf(uint8_t addr, uint8_t reg, void *dst, unsigned len) {
|
|||
LL_I2C_HandleTransfer(I2Cx, addr, LL_I2C_ADDRSLAVE_7BIT, len, LL_I2C_MODE_AUTOEND,
|
||||
LL_I2C_GENERATE_RESTART_7BIT_READ);
|
||||
uint8_t *p = dst;
|
||||
while (!LL_I2C_IsActiveFlag_STOP(I2Cx)) {
|
||||
if (LL_I2C_IsActiveFlag_RXNE(I2Cx)) {
|
||||
*p++ = LL_I2C_ReceiveData8(I2Cx);
|
||||
}
|
||||
uint8_t *end = p + len;
|
||||
while (p < end) {
|
||||
unsigned i;
|
||||
for (i = 0; i < MAXREP; ++i)
|
||||
if (LL_I2C_IsActiveFlag_RXNE(I2Cx))
|
||||
break;
|
||||
|
||||
if (i >= MAXREP)
|
||||
return -1;
|
||||
|
||||
*p++ = LL_I2C_ReceiveData8(I2Cx);
|
||||
}
|
||||
|
||||
while (!LL_I2C_IsActiveFlag_STOP(I2Cx))
|
||||
;
|
||||
LL_I2C_ClearFlag_STOP(I2Cx);
|
||||
|
||||
return 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче