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.
This commit is contained in:
parent
dcd8f459b1
commit
112e9e6814
1 changed files with 81 additions and 168 deletions
|
|
@ -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)
|
||||
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;
|
||||
/* 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]);
|
||||
}
|
||||
#if defined I2C_SR2
|
||||
i2c_transfer7_v1(i2c, addr, w, wn, r, rn);
|
||||
#else
|
||||
i2c_transfer7_v2(i2c, addr, w, wn, r, rn);
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
void i2c_read_bytes7(uint32_t p, uint8_t addr, uint8_t *buf, size_t count, bool end)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------- 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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue