From 112e9e681432e4abf74dd4b3191b67e72b9df93d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 23 Mar 2017 22:29:52 +0000 Subject: i2c-master: cleaned up again on l1 now has repeated-start and stop/start support, with the same API as v2 Just to decide whether all of it goes up into the library or not. --- tests/i2c-master/i2c-master.c | 249 ++++++++++++++---------------------------- 1 file changed, 81 insertions(+), 168 deletions(-) (limited to 'tests/i2c-master/i2c-master.c') diff --git a/tests/i2c-master/i2c-master.c b/tests/i2c-master/i2c-master.c index a7308b7..7eb2f6f 100644 --- a/tests/i2c-master/i2c-master.c +++ b/tests/i2c-master/i2c-master.c @@ -105,10 +105,81 @@ static void i2c_set_speed(uint32_t p, enum i2c_speeds speed, uint32_t clock_mega #endif } -// read/write are almost identical! -//static void i2c__transfer_helper(uint32_p, uint8_t addr, uint8_t *buf) + +static void i2c_write7_v1(uint32_t i2c, int addr, uint8_t *data, size_t n) +{ + while ((I2C_SR2(i2c) & I2C_SR2_BUSY)) { + } + + i2c_send_start(i2c); + + /* Wait for master mode selected */ + while (!((I2C_SR1(i2c) & I2C_SR1_SB) + & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); + + i2c_send_7bit_address(i2c, addr, I2C_WRITE); + + /* Waiting for address is transferred. */ + while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); + + /* Cleaning ADDR condition sequence. */ + uint32_t reg32 = I2C_SR2(i2c); + (void) reg32; /* unused */ + + size_t i; + for (i = 0; i < n; i++) { + i2c_send_data(i2c, data[i]); + while (!(I2C_SR1(i2c) & (I2C_SR1_BTF))); + } +} + +static void i2c_read7_v1(uint32_t i2c, int addr, uint8_t *res, int n) +{ + i2c_send_start(i2c); + i2c_enable_ack(i2c); + + /* Wait for master mode selected */ + while (!((I2C_SR1(i2c) & I2C_SR1_SB) + & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); + + i2c_send_7bit_address(i2c, addr, I2C_READ); + + /* Waiting for address is transferred. */ + while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); + /* Clearing ADDR condition sequence. */ + uint32_t reg32 = I2C_SR2(i2c); + (void) reg32; /* unused */ + + int i = 0; + for (i = 0; i < n; ++i) { + if (i == n - 1) { + i2c_disable_ack(i2c); + } + while (!(I2C_SR1(i2c) & I2C_SR1_RxNE)); + res[i] = i2c_get_data(i2c); + } + i2c_send_stop(i2c); + + return; +} + +/* v1 isn't handling stop/start vs repeated start very well yet */ +/* probably good enough to merge, but... maybe not put the v1 in the library.*/ static -void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn) +void i2c_transfer7_v1(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn) { + if (wn) { + i2c_write7_v1(i2c, addr, w, wn); + } + if (rn) { + i2c_read7_v1(i2c, addr, r, rn); + } else { + i2c_send_stop(i2c); + } +} + + +static +void i2c_transfer7_v2(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn) { int wait; size_t i; @@ -160,72 +231,16 @@ void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r } -/** - * Write bytes to a 7bit address - * @param p i2c peripheral of interest - * @param addr 7bit i2c slave address (unshifted) - * @param buf data to send - * @param count how many bytes to send - * @param end true if you wish to send a stop bit. false if you intend to - * continue sending data with a repeated start - */ -static -void i2c_write_bytes7(uint32_t p, uint8_t addr, uint8_t *buf, size_t count, bool end) -{ - bool wait; - size_t i; - /* start transfer */ - i2c_send_start(p); - while (i2c_busy(p) == 1); -// while (i2c_is_start(p) == 1); - /* Setting transfer properties */ - i2c_set_bytes_to_transfer(p, count); - i2c_set_7bit_address(p, addr); - i2c_set_write_transfer_dir(p); - if (end) { - i2c_enable_autoend(p); - } else { - i2c_disable_autoend(p); - } - - for (i = 0; i < count; i++) { - wait = true; - while (wait) { - if (i2c_transmit_int_status(p)) { - wait = false; - } - while (i2c_nack(p)); - } - i2c_send_data(p, buf[i]); - } -} - static -void i2c_read_bytes7(uint32_t p, uint8_t addr, uint8_t *buf, size_t count, bool end) +void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn) { - bool wait; - size_t i; - //while (i2c_busy(p) == 1); // FIXME - repeated start vs not - //while (i2c_is_start(p) == 1); - /* Setting transfer properties */ - i2c_set_bytes_to_transfer(p, 1); - i2c_set_7bit_address(p, addr); - i2c_set_read_transfer_dir(p); - if (end) { - i2c_enable_autoend(p); - } else { - i2c_disable_autoend(p); - } - /* start transfer */ - i2c_send_start(p); - - for (i = 0; i < count; i++) { - while (i2c_received_data(p) == 0); - buf[i] = i2c_get_data(p); - } +#if defined I2C_SR2 + i2c_transfer7_v1(i2c, addr, w, wn, r, rn); +#else + i2c_transfer7_v2(i2c, addr, w, wn, r, rn); +#endif } - // --------------- end of upstream planned section void i2cm_init(void) @@ -239,91 +254,6 @@ void i2cm_init(void) i2c_peripheral_enable(hw_details.periph); } -#if defined I2C_SR2 -static void sht21_send_data(uint32_t i2c, size_t n, uint8_t *data) -{ - while ((I2C_SR2(i2c) & I2C_SR2_BUSY)) { - } - - i2c_send_start(i2c); - - /* Wait for master mode selected */ - while (!((I2C_SR1(i2c) & I2C_SR1_SB) - & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); - - i2c_send_7bit_address(i2c, SENSOR_ADDRESS, I2C_WRITE); - - /* Waiting for address is transferred. */ - while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); - - /* Cleaning ADDR condition sequence. */ - uint32_t reg32 = I2C_SR2(i2c); - (void) reg32; /* unused */ - - size_t i; - for (i = 0; i < n; i++) { - i2c_send_data(i2c, data[i]); - while (!(I2C_SR1(i2c) & (I2C_SR1_BTF))); - } -} - -// FIXME - this is dumb, just need send_data with len==1! -static void sht21_send_cmd(uint32_t i2c, uint8_t cmd) -{ - while ((I2C_SR2(i2c) & I2C_SR2_BUSY)) { - } // wait for not busy! - - i2c_send_start(i2c); - - /* Wait for master mode selected */ - while (!((I2C_SR1(i2c) & I2C_SR1_SB) // waiting for start bit to hav ebeen sent - & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); // and waiting for no longer busy again - - i2c_send_7bit_address(i2c, SENSOR_ADDRESS, I2C_WRITE); - - /* Waiting for address is transferred. */ - while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); - - /* Cleaning ADDR condition sequence. */ - uint32_t reg32 = I2C_SR2(i2c); - (void) reg32; /* unused */ - - i2c_send_data(i2c, cmd); - while (!(I2C_SR1(i2c) & (I2C_SR1_BTF))); -} - -static void sht21_readn(uint32_t i2c, int n, uint8_t *res) -{ - //assert(n > 0); - i2c_send_start(i2c); - - i2c_enable_ack(i2c); - - /* Wait for master mode selected */ - while (!((I2C_SR1(i2c) & I2C_SR1_SB) - & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); - - i2c_send_7bit_address(i2c, SENSOR_ADDRESS, I2C_READ); - - /* Waiting for address is transferred. */ - while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); - /* Cleaning ADDR condition sequence. */ - uint32_t reg32 = I2C_SR2(i2c); - (void) reg32; /* unused */ - - int i = 0; - for (i = 0; i < n; ++i) { - if (i == n - 1) { - i2c_disable_ack(i2c); - } - while (!(I2C_SR1(i2c) & I2C_SR1_RxNE)); - res[i] = i2c_get_data(i2c); - } - i2c_send_stop(i2c); - - return; -} -#endif static float sht21_convert_temp(uint16_t raw) { @@ -344,10 +274,6 @@ static float sht21_convert_humi(uint16_t raw) static float sht21_read_temp_hold(uint32_t i2c) { uint8_t data[3]; -#if 0 - sht21_send_cmd(i2c, SHT21_CMD_TEMP_HOLD); - sht21_readn(i2c, 2, data); -#endif uint8_t cmd = SHT21_CMD_TEMP_HOLD; i2c_transfer7(i2c, SENSOR_ADDRESS, &cmd, 1, data, sizeof(data)); uint8_t crc = data[2]; @@ -360,10 +286,6 @@ static float sht21_read_temp_hold(uint32_t i2c) static float sht21_read_humi_hold(uint32_t i2c) { uint8_t data[3]; -#if 0 - sht21_send_cmd(i2c, SHT21_CMD_HUMIDITY_HOLD); - sht21_readn(i2c, 2, data); -#endif uint8_t cmd = SHT21_CMD_HUMIDITY_HOLD; i2c_transfer7(i2c, SENSOR_ADDRESS, &cmd, 1, data, sizeof(data)); @@ -377,10 +299,6 @@ static float sht21_read_humi_hold(uint32_t i2c) static void sht21_readid(void) { uint8_t raw = 0; -#if defined I2C_SR2 - sht21_send_cmd(I2C1, SHT21_CMD_READ_REG); - sht21_readn(I2C1, 1, &raw); -#else uint8_t cmd = SHT21_CMD_READ_REG; printf("RP..."); i2c_transfer7(hw_details.periph, SENSOR_ADDRESS, &cmd, 1, &raw, 1); @@ -389,7 +307,6 @@ static void sht21_readid(void) i2c_transfer7(hw_details.periph, SENSOR_ADDRESS, &cmd, 1, 0, 0); i2c_transfer7(hw_details.periph, SENSOR_ADDRESS, 0, 0, &raw, 1); -#endif printf("raw user reg = %#x\n", raw); int resolution = ((raw & 0x80) >> 6) | (raw & 1); printf("temp resolution is in %d bits\n", 14 - resolution); @@ -398,13 +315,9 @@ static void sht21_readid(void) uint8_t req1[] = {0xfa, 0x0f}; uint8_t res[8]; -// sht21_send_data(I2C1, 2, req1); -// sht21_readn(I2C1, sizeof(res), res); i2c_transfer7(hw_details.periph, SENSOR_ADDRESS, req1, sizeof(req1), res, 8); uint8_t req2[] = {0xfc, 0xc9}; uint8_t res2[8]; -// sht21_send_data(I2C1, 2, req2); -// sht21_readn(I2C1, sizeof(res), res2); i2c_transfer7(hw_details.periph, SENSOR_ADDRESS, req1, sizeof(req1), res2, 8); printf("Serial = %02x%02x %02x%02x %02x%02x %02x%02x\n", @@ -414,7 +327,7 @@ static void sht21_readid(void) void i2cm_task(void) { static int i = 1; - printf("Starting iteration %d\n", i++); + printf(">>>>Starting iteration %d\n", i++); gpio_set(hw_details.trigger_port, hw_details.trigger_pin); sht21_readid(); float temp = sht21_read_temp_hold(hw_details.periph); -- cgit