From b4689cb3f1f28b6edc4fe81aa91e4d1ad3c315a7 Mon Sep 17 00:00:00 2001 From: Evan Lojewski Date: Mon, 18 May 2020 18:57:10 -0600 Subject: [PATCH] i2c: Reduce __data usage by switching i2c routines to use the stack. By default with the large memory mode, sdcc places temp data in DSEG (__data) and parameters in XSEG (__xdata). This causes both to be placed on the stack instead. Previously, the temperary variables were using up to ox69 bytes in DSEG. After the change, temperary variables now end at 0x5D (12 bytes less). The i2c routines were using the following XSEG bytes: - 0x03 - 0x0b (i2c_recv - 8 bytes now on the stack) - 0x0c - 0x14 (i2c_send - 8 bytes now on the stack) - 0x15 - 0x1e (i2c_get - 9 bytes now on the stack) - 0x1f - 0x2c (i2c_set - 13 bytes now on the stack) - 0x1e2 - 0x1e5 (i2c_reset - 4 bytes now on the stack) - 0x1e6 - ? (i2c_start - ? bytes now on the stack) --- src/common/i2c.c | 8 ++++---- src/common/include/common/i2c.h | 16 ++++++++-------- src/ec/it5570e/i2c.c | 6 +++--- src/ec/it8587e/i2c.c | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/common/i2c.c b/src/common/i2c.c index d1ccd69..5fb0eef 100644 --- a/src/common/i2c.c +++ b/src/common/i2c.c @@ -2,7 +2,7 @@ #include -int i2c_recv(struct I2C * i2c, uint8_t addr, uint8_t* data, int length) { +int i2c_recv(struct I2C * i2c, uint8_t addr, uint8_t* data, int length) __reentrant { int res = 0; res = i2c_start(i2c, addr, true); @@ -16,7 +16,7 @@ int i2c_recv(struct I2C * i2c, uint8_t addr, uint8_t* data, int length) { return res; } -int i2c_send(struct I2C * i2c, uint8_t addr, uint8_t* data, int length) { +int i2c_send(struct I2C * i2c, uint8_t addr, uint8_t* data, int length) __reentrant { int res = 0; res = i2c_start(i2c, addr, false); @@ -30,7 +30,7 @@ int i2c_send(struct I2C * i2c, uint8_t addr, uint8_t* data, int length) { return res; } -int i2c_get(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int length) { +int i2c_get(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int length) __reentrant { int res = 0; res = i2c_start(i2c, addr, false); @@ -42,7 +42,7 @@ int i2c_get(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int leng return i2c_recv(i2c, addr, data, length); } -int i2c_set(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int length) { +int i2c_set(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int length) __reentrant { int res = 0; res = i2c_start(i2c, addr, false); diff --git a/src/common/include/common/i2c.h b/src/common/include/common/i2c.h index e89951f..ca7cfc6 100644 --- a/src/common/include/common/i2c.h +++ b/src/common/include/common/i2c.h @@ -11,30 +11,30 @@ struct I2C; // Start i2c transaction // Must be defined by arch, board, or ec -int i2c_start(struct I2C * i2c, uint8_t addr, bool read); +int i2c_start(struct I2C * i2c, uint8_t addr, bool read) __reentrant; // Stop i2c transaction // Must be defined by arch, board, or ec -void i2c_stop(struct I2C * i2c); +void i2c_stop(struct I2C * i2c) __reentrant; // Send a byte on i2c bus // Must be defined by arch, board, or ec -int i2c_write(struct I2C * i2c, uint8_t * data, int length); +int i2c_write(struct I2C * i2c, uint8_t * data, int length) __reentrant; // Read bytes from bus // Must be defined by arch, board, or ec -int i2c_read(struct I2C * i2c, uint8_t * data, int length); +int i2c_read(struct I2C * i2c, uint8_t * data, int length) __reentrant; // Read multiple bytes from address in one transaction -int i2c_recv(struct I2C * i2c, uint8_t addr, uint8_t* data, int length); +int i2c_recv(struct I2C * i2c, uint8_t addr, uint8_t* data, int length) __reentrant; // Write multiple bytes to address in one transaction -int i2c_send(struct I2C * i2c, uint8_t addr, uint8_t* data, int length); +int i2c_send(struct I2C * i2c, uint8_t addr, uint8_t* data, int length) __reentrant; // Read multiple bytes from a register in one transaction -int i2c_get(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int length); +int i2c_get(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int length) __reentrant; // Write multiple bytes to a register in one transaction -int i2c_set(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int length); +int i2c_set(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, int length) __reentrant; #endif // _COMMON_I2C_H diff --git a/src/ec/it5570e/i2c.c b/src/ec/it5570e/i2c.c index 1ee8813..58be800 100644 --- a/src/ec/it5570e/i2c.c +++ b/src/ec/it5570e/i2c.c @@ -55,7 +55,7 @@ void i2c_reset(struct I2C * i2c, bool kill) { *(i2c->hoctl2) = 0; } -int i2c_start(struct I2C * i2c, uint8_t addr, bool read) { +int i2c_start(struct I2C * i2c, uint8_t addr, bool read) __reentrant { // If we are already in a transaction if (*(i2c->hosta) & HOSTA_BYTE_DONE) { // If we are switching direction @@ -151,10 +151,10 @@ static int i2c_transaction(struct I2C * i2c, uint8_t * data, int length, bool re return i; } -int i2c_read(struct I2C * i2c, uint8_t * data, int length) { +int i2c_read(struct I2C * i2c, uint8_t * data, int length) __reentrant { return i2c_transaction(i2c, data, length, true); } -int i2c_write(struct I2C * i2c, uint8_t * data, int length) { +int i2c_write(struct I2C * i2c, uint8_t * data, int length) __reentrant { return i2c_transaction(i2c, data, length, false); } diff --git a/src/ec/it8587e/i2c.c b/src/ec/it8587e/i2c.c index ebbad06..a403940 100644 --- a/src/ec/it8587e/i2c.c +++ b/src/ec/it8587e/i2c.c @@ -47,7 +47,7 @@ void i2c_reset(struct I2C * i2c, bool kill) { *(i2c->hoctl2) = 0; } -int i2c_start(struct I2C * i2c, uint8_t addr, bool read) { +int i2c_start(struct I2C * i2c, uint8_t addr, bool read) __reentrant { // If we are already in a transaction if (*(i2c->hosta) & HOSTA_BYTE_DONE) { // If we are switching direction @@ -143,10 +143,10 @@ static int i2c_transaction(struct I2C * i2c, uint8_t * data, int length, bool re return i; } -int i2c_read(struct I2C * i2c, uint8_t * data, int length) { +int i2c_read(struct I2C * i2c, uint8_t * data, int length) __reentrant { return i2c_transaction(i2c, data, length, true); } -int i2c_write(struct I2C * i2c, uint8_t * data, int length) { +int i2c_write(struct I2C * i2c, uint8_t * data, int length) __reentrant { return i2c_transaction(i2c, data, length, false); }