Skip to content

Commit 42c3a78

Browse files
sgilbert182carlescufi
authored andcommitted
i2c: stm32: Add cache memory support
Add basic cache memory support Signed-off-by: Simon Gilbert <[email protected]>
1 parent 26a8b36 commit 42c3a78

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

drivers/i2c/i2c_ll_stm32_v2.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121
#include <zephyr/pm/device_runtime.h>
2222
#include "i2c_ll_stm32.h"
2323

24+
#ifdef CONFIG_DCACHE
25+
#include <zephyr/cache.h>
26+
#include <zephyr/linker/linker-defs.h>
27+
#include <zephyr/mem_mgmt/mem_attr.h>
28+
#include <zephyr/dt-bindings/memory-attr/memory-attr-arm.h>
29+
#endif /* CONFIG_DCACHE */
30+
2431
#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
2532
#include <zephyr/logging/log.h>
2633
LOG_MODULE_REGISTER(i2c_ll_stm32_v2);
@@ -676,6 +683,35 @@ void stm32_i2c_error_isr(void *arg)
676683
}
677684
#endif
678685

686+
#ifdef CONFIG_DCACHE
687+
static bool buf_in_nocache(uintptr_t buf, size_t len_bytes)
688+
{
689+
bool buf_within_nocache = false;
690+
691+
#ifdef CONFIG_NOCACHE_MEMORY
692+
/* Check if buffer is in nocache region defined by the linker */
693+
buf_within_nocache = (buf >= ((uintptr_t)_nocache_ram_start)) &&
694+
((buf + len_bytes - 1) <= ((uintptr_t)_nocache_ram_end));
695+
if (buf_within_nocache) {
696+
return true;
697+
}
698+
#endif /* CONFIG_NOCACHE_MEMORY */
699+
700+
/* Check if buffer is in nocache memory region defined in DT */
701+
buf_within_nocache = mem_attr_check_buf(
702+
(void *)buf, len_bytes, DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE)) == 0;
703+
if (buf_within_nocache) {
704+
return true;
705+
}
706+
707+
/* Check if buffer is in RO region (Flash..) */
708+
buf_within_nocache = (buf >= ((uintptr_t)__rodata_region_start)) &&
709+
((buf + len_bytes - 1) <= ((uintptr_t)__rodata_region_end));
710+
711+
return buf_within_nocache;
712+
}
713+
#endif /* CONFIG_DCACHE */
714+
679715
static int stm32_i2c_msg_write(const struct device *dev, struct i2c_msg *msg,
680716
uint8_t *next_msg_flags, uint16_t slave)
681717
{
@@ -691,6 +727,14 @@ static int stm32_i2c_msg_write(const struct device *dev, struct i2c_msg *msg,
691727
data->current.is_err = 0U;
692728
data->current.msg = msg;
693729

730+
#ifdef CONFIG_DCACHE
731+
if (!buf_in_nocache((uintptr_t)msg->buf, msg->len)) {
732+
LOG_DBG("Tx buffer at %p (len %zu) is in cached memory; cleaning cache", msg->buf,
733+
msg->len);
734+
sys_cache_data_flush_range((void *)msg->buf, msg->len);
735+
}
736+
#endif /* CONFIG_DCACHE */
737+
694738
msg_init(dev, msg, next_msg_flags, slave, LL_I2C_REQUEST_WRITE);
695739

696740
stm32_i2c_enable_transfer_interrupts(dev);
@@ -762,6 +806,14 @@ static int stm32_i2c_msg_read(const struct device *dev, struct i2c_msg *msg,
762806
is_timeout = true;
763807
}
764808

809+
#ifdef CONFIG_DCACHE
810+
if (!buf_in_nocache((uintptr_t)msg->buf, msg->len)) {
811+
LOG_DBG("Rx buffer at %p (len %zu) is in cached memory; invalidating cache",
812+
msg->buf, msg->len);
813+
sys_cache_data_invd_range((void *)msg->buf, msg->len);
814+
}
815+
#endif /* CONFIG_DCACHE */
816+
765817
if (data->current.is_nack || data->current.is_err ||
766818
data->current.is_arlo || is_timeout) {
767819
goto error;

0 commit comments

Comments
 (0)