From ec28fcd9f905358759eea98161f451567135d17e Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 27 Aug 2023 22:31:09 +0200 Subject: new driver blinkenlights --- driver_fw/i2c.c | 236 -------------------------------------------------------- 1 file changed, 236 deletions(-) delete mode 100644 driver_fw/i2c.c (limited to 'driver_fw/i2c.c') diff --git a/driver_fw/i2c.c b/driver_fw/i2c.c deleted file mode 100644 index bab1a16..0000000 --- a/driver_fw/i2c.c +++ /dev/null @@ -1,236 +0,0 @@ -// Inter-integrated circuit (I2C) management - - -#include "i2c.h" - - -// I2C timeout, about 2ms -#define I2C_TIMEOUT 200U - -// Maximum NBYTES value -#define I2C_NBYTES_MAX 255U - - -// Count rough delay for timeouts -static uint32_t i2c_calc_delay(uint32_t delay) { - uint32_t cnt; - - if (SystemCoreClock > 1000000U) { - cnt = (delay * ((SystemCoreClock / 1000000U) + 1U)); - } else { - cnt = (((delay / 100U) + 1U) * ((SystemCoreClock / 10000U) + 1U)); - } - - return cnt; -} - -// Check if target device is ready for communication -// input: -// I2Cx - pointer to the I2C peripheral (I2C1, etc.) -// devAddr - target device address -// trials - number of trials (must not be zero) -// return: -// I2C_ERROR if there was a timeout during I2C operations, I2C_SUCCESS otherwise -I2CSTATUS i2c_is_device_ready(I2C_TypeDef* I2Cx, uint8_t devAddr, uint32_t trials) { - volatile uint32_t wait; - uint32_t delay_val = i2c_calc_delay(I2C_TIMEOUT); - uint32_t reg; - - while (trials--) { - // Clear all flags - I2Cx->ICR = I2C_ICR_ALL; - - // Generate START - i2c_genstart(I2Cx, devAddr); - - // Wait for STOP, NACK or BERR - wait = delay_val; - while (!((reg = I2Cx->ISR) & (I2C_ISR_STOPF | I2C_ISR_NACKF | I2C_ISR_BERR)) && --wait); - if (wait == 0) { return I2C_ERROR; } - - // Wait while STOP flag is reset - wait = delay_val; - while (!(I2Cx->ISR & I2C_ISR_STOPF) && --wait); - if (wait == 0) { return I2C_ERROR; } - - // Clear the NACK, STOP and BERR flags - I2Cx->ICR = I2C_ICR_STOPCF | I2C_ICR_NACKCF | I2C_ICR_BERRCF; - - // Check for BERR flag - if (reg & I2C_ISR_BERR) { - // Misplaced START/STOP? Perform a software reset of I2C - i2c_disable(I2Cx); - i2c_enable(I2Cx); - } else { - // Device responded if NACK flag is not set - if (!(reg & I2C_ISR_NACKF)) { return I2C_SUCCESS; } - } - } - - return I2C_ERROR; -} - -// Transmit an amount of data in master mode -// input: -// I2Cx - pointer to the I2C peripheral (I2C1, etc.) -// pBbuf - pointer to the data buffer -// nbytes - number of bytes to transmit -// devAddr - address of target device -// flags - options for transmission, combination of I2C_TX_xx values: -// I2C_TX_NOSTART - don't generate START condition -// I2C_TX_NOSTOP - don't generate STOP condition -// I2C_TX_CONT - this flag indicates that transmission will be continued -// e.g. by calling this function again with NOSTART flag -// zero value - generate both START and STOP conditions -// return: -// I2C_ERROR if there was a timeout during I2C operations, I2C_SUCCESS otherwise -I2CSTATUS i2c_transmit(I2C_TypeDef* I2Cx, const uint8_t *pBuf, uint32_t nbytes, uint8_t devAddr, uint32_t flags) { - uint32_t reg; - uint32_t tx_count; - uint32_t delay_val = i2c_calc_delay(I2C_TIMEOUT); - volatile uint32_t wait; - - // Clear all flags - I2Cx->ICR = I2C_ICR_ALL; - - // Everything regarding to the transmission is in the CR2 register - reg = I2Cx->CR2; - reg &= ~I2C_CR2_ALL; - - // Slave device address - reg |= (devAddr & I2C_CR2_SADD); - - // Whether it need to generate START condition - if (!(flags & I2C_TX_NOSTART)) { reg |= I2C_CR2_START; } - - // Whether it need to generate STOP condition - if ((flags & I2C_TX_CONT) || (nbytes > I2C_NBYTES_MAX)) { - reg |= I2C_CR2_RELOAD; - } else { - if (!(flags & I2C_TX_NOSTOP)) { reg |= I2C_CR2_AUTOEND; } - } - - // Transfer length - tx_count = (nbytes > I2C_NBYTES_MAX) ? I2C_NBYTES_MAX : nbytes; - nbytes -= tx_count; - reg |= tx_count << I2C_CR2_NBYTES_Pos; - - // Write a composed value to the I2C register - I2Cx->CR2 = reg; - - // Transmit data - while (tx_count) { - // Wait until either TXIS or NACK flag is set - wait = delay_val; - while (!((reg = I2Cx->ISR) & (I2C_ISR_TXIS | I2C_ISR_NACKF)) && --wait); - if ((reg & I2C_ISR_NACKF) || (wait == 0)) { return I2C_ERROR; } - - // Transmit byte - I2Cx->TXDR = *pBuf++; - tx_count--; - - if ((tx_count == 0) && (nbytes != 0)) { - // Wait until TCR flag is set (Transfer Complete Reload) - wait = delay_val; - while (!(I2Cx->ISR & I2C_ISR_TCR) && --wait); - if (wait == 0) { return I2C_ERROR; } - - // Configure next (or last) portion transfer - reg = I2Cx->CR2; - reg &= ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND); - if ((flags & I2C_TX_CONT) || (nbytes > I2C_NBYTES_MAX)) { - reg |= I2C_CR2_RELOAD; - } else { - if (!(flags & I2C_TX_NOSTOP)) { reg |= I2C_CR2_AUTOEND; } - } - tx_count = (nbytes > I2C_NBYTES_MAX) ? I2C_NBYTES_MAX : nbytes; - nbytes -= tx_count; - reg |= tx_count << I2C_CR2_NBYTES_Pos; - I2Cx->CR2 = reg; - } - } - - // End of transmission - wait = delay_val; - while (!(I2Cx->ISR & (I2C_ISR_TC | I2C_ISR_TCR | I2C_ISR_STOPF)) && --wait); - - return (wait) ? I2C_SUCCESS : I2C_ERROR; -} - -// Receive an amount of data in master mode -// input: -// I2Cx - pointer to the I2C peripheral (I2C1, etc.) -// buf - pointer to the data buffer -// nbytes - number of bytes to receive -// devAddr - address of target device -// return: -// I2C_ERROR if there was a timeout during I2C operations, I2C_SUCCESS otherwise -I2CSTATUS i2c_receive(I2C_TypeDef* I2Cx, uint8_t *pBuf, uint32_t nbytes, uint8_t devAddr) { - uint32_t reg; - uint32_t rx_count; - uint32_t delay_val = i2c_calc_delay(I2C_TIMEOUT); - volatile uint32_t wait; - - // Clear all flags - I2Cx->ICR = I2C_ICR_ALL; - - // Everything regarding to the transmission is in the CR2 register - reg = I2Cx->CR2; - reg &= ~I2C_CR2_ALL; - - // Configure slave device address, enable START condition and set direction to READ - reg |= (devAddr & I2C_CR2_SADD) | I2C_CR2_START | I2C_CR2_RD_WRN; - - // Transfer length - if (nbytes > I2C_NBYTES_MAX) { - rx_count = I2C_NBYTES_MAX; - reg |= I2C_CR2_RELOAD; - } else { - rx_count = nbytes; - reg |= I2C_CR2_AUTOEND; - } - reg |= rx_count << I2C_CR2_NBYTES_Pos; - nbytes -= rx_count; - - // Write a composed value to the I2C register - I2Cx->CR2 = reg; - - // Receive data - while (rx_count) { - // Wait until either RXNE or NACK flag is set - wait = delay_val; - while (!((reg = I2Cx->ISR) & (I2C_ISR_RXNE | I2C_ISR_NACKF)) && --wait); - if ((reg & I2C_ISR_NACKF) || (wait == 0)) { return I2C_ERROR; } - - // Read received data - *pBuf++ = I2Cx->RXDR; - rx_count--; - - if ((rx_count == 0) && (nbytes != 0)) { - // Wait until TCR flag is set (Transfer Complete Reload) - wait = delay_val; - while (!(I2Cx->ISR & I2C_ISR_TCR) && --wait); - if (wait == 0) { return I2C_ERROR; } - - // Configure next (or last) portion transfer - reg = I2Cx->CR2; - reg &= ~(I2C_CR2_NBYTES | I2C_CR2_AUTOEND | I2C_CR2_RELOAD); - if (nbytes > I2C_NBYTES_MAX) { - rx_count = I2C_NBYTES_MAX; - reg |= I2C_CR2_RELOAD; - } else { - rx_count = nbytes; - reg |= I2C_CR2_AUTOEND; - } - reg |= rx_count << I2C_CR2_NBYTES_Pos; - nbytes -= rx_count; - I2Cx->CR2 = reg; - } - } - - // Wait for the STOP flag - wait = delay_val; - while (!(I2Cx->ISR & I2C_ISR_STOPF) && --wait); - - return (wait) ? I2C_SUCCESS : I2C_ERROR; -} -- cgit