112 lines
4.1 KiB
C++
Executable File
112 lines
4.1 KiB
C++
Executable File
/// @file i2c.h
|
|
/// @brief i2c driver
|
|
/// @author Guangzong Chen <chen-gz@outlook.com>
|
|
/// @date 2021-08-06
|
|
/// @copyright Copyright (c) 2023 ggeta. All rights reserved.
|
|
/// @note this only for i2c master mode
|
|
/// @version 0.1 initial version
|
|
/// @version 0.11 replace read_block adn send_block by read_it (interrupt) and send_it (interrupt)
|
|
/// add send, receive for blocking sending mode
|
|
/// new initialization function
|
|
/// @version 0.12 Seperate the file to cpp and h file.
|
|
|
|
#ifndef STM32U5XX_HAL_I2C_H
|
|
#define STM32U5XX_HAL_I2C_H
|
|
|
|
#include "global_variable.h"
|
|
//#include <cstdint>
|
|
|
|
#include "delay.h"
|
|
#include "queue.hpp"
|
|
#include "reg_i2c_gen.h"
|
|
|
|
typedef enum {
|
|
I2C_STATE_WAIT = 1, ///< idle
|
|
I2C_STATE_SENDING, ///< sending data
|
|
I2C_STATE_RECEIVING, ///< receiving data
|
|
I2C_STATE_ERROR, ///< error occur
|
|
} i2c_state_e; ///< i2c state machine
|
|
|
|
typedef struct _i2c_err_t {
|
|
uint32_t buf_overflow : 1; // 0 Buffer overflow (for reception)
|
|
uint32_t buf_underflow : 1; // 1 Buffer underflow (for transmission)
|
|
uint32_t resv0 : 2; // 2
|
|
uint32_t nackf : 1; // 4 Not acknowledge received flag
|
|
uint32_t resv1 : 3; // 7
|
|
uint32_t berr : 1; // 8 Bus error
|
|
uint32_t arlo : 1; // 9 Arbitration lost
|
|
uint32_t ovr : 1; // 10 Overrun/Underrun (slave mode)
|
|
uint32_t pecerr : 1; // 10 PEC Error in reception
|
|
uint32_t timeout : 1; // 10 Timeout or t_low detection flag
|
|
uint32_t alert : 1; // 10 SMBus alert
|
|
uint32_t resv2 : 18; // 14 Reserve
|
|
|
|
void update_error(reg_i2c_isr_t isr) {
|
|
this->arlo = isr.arlo, this->berr = isr.berr, this->ovr = isr.ovr,
|
|
this->pecerr = isr.pecerr, this->timeout = isr.timeout, this->alert = isr.alert;
|
|
}
|
|
|
|
bool has_error() const {
|
|
return this->buf_overflow | this->buf_underflow | this->nackf | this->berr | this->arlo |
|
|
this->ovr | this->pecerr | this->timeout | this->alert;
|
|
}
|
|
|
|
void clean_error() {
|
|
this->buf_overflow = buf_underflow = nackf = berr = arlo = ovr = pecerr = timeout = alert =
|
|
0;
|
|
}
|
|
} i2c_err_t; // this should match with i2c_isr_t
|
|
|
|
class I2c {
|
|
|
|
private:
|
|
I2C_TypeDef *ins = nullptr; ///< i2c register
|
|
reg_i2c_t *reg = nullptr;
|
|
void (*user_tc_cb)() = nullptr; ///< user callback function
|
|
void (*user_err_cb)(i2c_err_t err) = nullptr; ///< user callback function
|
|
i2c_err_t errors = {}; ///< i2c error
|
|
|
|
public:
|
|
queue20u8 send_queue;
|
|
queue20u8 recv_queue;
|
|
i2c_state_e state = I2C_STATE_WAIT; ///< i2c state
|
|
|
|
I2c();
|
|
|
|
void setup(I2C_TypeDef *i2c);
|
|
|
|
void
|
|
init(uint32_t timing = 0x30909DEC, // should be calculated by clock_speed
|
|
ll_state_e autoend = LL_DISABLE, // auto send 'stop' after send/receive
|
|
uint16_t own_address1 = 0x00, ll_state_e own_address1_en = LL_DISABLE, // slave address 1
|
|
uint16_t own_address2 = 0x00, ll_state_e own_address2_en = LL_DISABLE, // slave address 2
|
|
ll_state_e analog_filter = LL_ENABLE, uint32_t digital_filter = 0x00,
|
|
ll_state_e clock_stretching = LL_DISABLE,
|
|
ll_state_e general_call = LL_DISABLE // Address 0b00000000 is NACKed (enable to ACKed).
|
|
);
|
|
|
|
/// \brief send data to slave.
|
|
/// This function will send data, return until all data is sent or error occured.
|
|
/// \param slave_addr
|
|
/// \param data
|
|
/// \param size size of data (should be less than 255)
|
|
/// \return
|
|
hal_status_e send(uint16_t slave_addr, const uint8_t *data, uint32_t len);
|
|
|
|
hal_status_e send_it(uint16_t slave_addr, const uint8_t *data, uint8_t len,
|
|
void (*cmp_cb)() = nullptr, void (*err_cb)(i2c_err_t) = nullptr);
|
|
|
|
hal_status_e read(uint16_t slave_addr, uint8_t *data, uint8_t len);
|
|
|
|
hal_status_e read_it(uint16_t slave_add, uint8_t len, void (*cmp_cb)() = nullptr,
|
|
void (*err_cb)(i2c_err_t) = nullptr);
|
|
|
|
void error_handler();
|
|
|
|
void i2c_ev_irq_handler();
|
|
|
|
void i2c_er_irq_handler();
|
|
};
|
|
|
|
#endif // STM32U5XX_HAL_I2C_H
|