|
2 | 2 |
|
3 | 3 | #include "i2c.h" |
4 | 4 |
|
5 | | -#ifndef I2C_POLL_TIMEOUT |
6 | | -#define I2C_POLL_TIMEOUT 2000 |
7 | | -#endif |
| 5 | +/* Private function declarations */ |
| 6 | +static void clear_i2c_buffers(void); |
| 7 | +static w_status_t check_i2c_state(void); |
| 8 | +static w_status_t wait_for_idle(void); |
| 9 | +static w_status_t i2c_write(uint8_t address, const uint8_t *data, uint8_t len); |
| 10 | +static w_status_t i2c_read(uint8_t address, uint8_t *data, uint8_t len); |
| 11 | + |
| 12 | +/* |
| 13 | + * Clear I2C buffers and ensure they're in a known state |
| 14 | + */ |
| 15 | +static void clear_i2c_buffers(void) { |
| 16 | + // Clear the buffer flag and flush any pending data |
| 17 | + I2C1STAT1bits.CLRBF = 1; |
| 18 | + while (I2C1STAT1bits.RXBF) { |
| 19 | + (void)I2C1RXB; // Read and discard any data |
| 20 | + } |
| 21 | +} |
| 22 | + |
| 23 | +/* |
| 24 | + * Check the current state of the I2C module |
| 25 | + * Verifies module is enabled and no errors are present |
| 26 | + */ |
| 27 | +static w_status_t check_i2c_state(void) { |
| 28 | + if (!I2C1CON0bits.EN) { |
| 29 | + return W_IO_ERROR; // Module not enabled |
| 30 | + } |
| 31 | + |
| 32 | + // Check for any error conditions |
| 33 | + if (I2C1ERRbits.BCLIF || // Bus collision |
| 34 | + I2C1ERRbits.BTOIF || // Bus timeout |
| 35 | + I2C1ERRbits.NACKIF) { // Not acknowledged |
| 36 | + |
| 37 | + I2C1ERR = 0; // Clear error flags |
| 38 | + return W_IO_ERROR; |
| 39 | + } |
| 40 | + |
| 41 | + return W_SUCCESS; |
| 42 | +} |
| 43 | + |
| 44 | +/* |
| 45 | + * Wait for the I2C bus to become idle |
| 46 | + * Monitors the Bus Free bit with timeout protection |
| 47 | + */ |
| 48 | +static w_status_t wait_for_idle(void) { |
| 49 | + unsigned int timeout = 0; |
| 50 | + while (!I2C1STAT0bits.BFRE) { |
| 51 | + if (timeout++ >= I2C_POLL_TIMEOUT) { |
| 52 | + return W_IO_TIMEOUT; |
| 53 | + } |
| 54 | + } |
| 55 | + return W_SUCCESS; |
| 56 | +} |
8 | 57 |
|
9 | 58 | w_status_t i2c_init(uint8_t clkdiv) { |
10 | 59 | // CSTR Enable clocking; S Cleared by hardware after Start; MODE 7-bit address; EN enabled; RSEN |
|
0 commit comments