You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
5.0 KiB
167 lines
5.0 KiB
#ifndef _I2C_H |
|
#define _I2C_H |
|
|
|
#include <hal_types.h> |
|
#include <hal.h> |
|
#include "dma.h" |
|
|
|
#define I2C_50KHz_SPEED 50000 |
|
#define I2C_75KHz_SPEED 75000 |
|
#define I2C_100KHz_SPEED 100000 |
|
#define I2C_250KHz_SPEED 250000 |
|
#define I2C_400KHz_SPEED 400000 |
|
|
|
|
|
#define I2C_BIT_MASK ((uint32_t)0x00FFFFFF) |
|
|
|
// SR1 bits |
|
#define I2C_BIT_SMBALERT ((uint32_t)0x0008000) |
|
#define I2C_BIT_TIMEOUT ((uint32_t)0x4000) |
|
#define I2C_BIT_PECERR ((uint32_t)0x1000) |
|
#define I2C_BIT_OVR ((uint32_t)0x0800) |
|
#define I2C_BIT_AF ((uint32_t)0x0400) |
|
#define I2C_BIT_ARLO ((uint32_t)0x0200) |
|
#define I2C_BIT_BERR ((uint32_t)0x0100) |
|
#define I2C_BIT_TXE ((uint32_t)0x0080) |
|
#define I2C_BIT_RXNE ((uint32_t)0x0040) |
|
#define I2C_BIT_STOPF ((uint32_t)0x0010) |
|
#define I2C_BIT_ADD10 ((uint32_t)0x0008) |
|
#define I2C_BIT_BTF ((uint32_t)0x0004) |
|
#define I2C_BIT_ADDR ((uint32_t)0x0002) |
|
#define I2C_BIT_SB ((uint32_t)0x0001) |
|
|
|
// interrupt enable bits |
|
#define I2C_IE_BUF ((uint16_t)0x0400) |
|
#define I2C_IE_EVT ((uint16_t)0x0200) |
|
#define I2C_IE_ERR ((uint16_t)0x0100) |
|
|
|
//SR2 bits |
|
#define I2C_BIT_DUALF ((uint32_t)0x0080) |
|
#define I2C_BIT_SMBHOST ((uint32_t)0x0040) |
|
#define I2C_BIT_SMBDEFAULT ((uint32_t)0x0020) |
|
#define I2C_BIT_GENCALL ((uint32_t)0x0010) |
|
#define I2C_BIT_TRA ((uint32_t)0x0004) |
|
#define I2C_BIT_BUSY ((uint32_t)0x0002) |
|
#define I2C_BIT_MSL ((uint32_t)0x0001) |
|
|
|
|
|
#define I2C_NACKPosition_Next ((uint16_t)0x0800) |
|
#define I2C_NACKPosition_Current ((uint16_t)0xF7FF) |
|
|
|
#define I2C_Direction_Transmitter ((uint8_t)0x00) |
|
#define I2C_Direction_Receiver ((uint8_t)0x01) |
|
|
|
/* Maximum Timeout values for events waiting loops */ |
|
|
|
#undef I2C_TIMEOUT |
|
#define I2C_TIMEOUT (300)// in uS - wait for byte transfer: 10us per bit (100kHz) * 9 bits |
|
#define I2C_SMALL_TIMEOUT (50) // in uS - wait for bit |
|
|
|
|
|
#define I2C_OK 0 |
|
#define I2C_NO_DEVICE 1 |
|
#define I2C_ERROR 2 |
|
#define I2C_BUS_BUSY 2 |
|
#define I2C_ERR_WRITE 6 |
|
#define I2C_NO_REGISTER 8 // 8 Acknolege Failed - not "no device"! this happens when we try to read non-existent register from chip |
|
#define I2C_BUS_ERR 99 |
|
#define I2C_ERR_STOP 98 |
|
#define I2C_STOP_BERR 97 |
|
#define I2C_STOP_BUSY 96 |
|
#define I2C_ERR_TIMEOUT 95 |
|
#define I2C_ERR_REGISTER 94 |
|
#define I2C_ERR_OVERRUN 93 |
|
#define I2C_DMA_BUSY 103 |
|
#define I2C_PENDING 255 |
|
#define I2C_DMA_ERROR 100 |
|
|
|
|
|
#define DMA_BUFSIZE 8 // we read just 6 bytes from compass |
|
|
|
typedef struct I2C_DMA { |
|
uint32_t channel; |
|
dma_stream stream_rx; |
|
dma_stream stream_tx; |
|
} I2C_dma; |
|
|
|
|
|
typedef struct I2c_state { |
|
Handler handler; |
|
volatile bool busy; |
|
} i2c_state; |
|
|
|
|
|
extern uint32_t i2c_bit_time; |
|
|
|
/** |
|
* @brief I2C device type. |
|
*/ |
|
typedef struct i2c_dev { |
|
I2C_TypeDef* I2Cx; |
|
const gpio_dev *gpio_port; |
|
uint8_t sda_pin; |
|
uint8_t scl_pin; |
|
uint32_t clk; |
|
uint8_t gpio_af; |
|
IRQn_Type ev_nvic_line; /* Event IRQ number */ |
|
IRQn_Type er_nvic_line; /* Error IRQ number */ |
|
// I2C_dma dma; |
|
i2c_state *state; |
|
} i2c_dev; |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
|
|
void i2c_init(const i2c_dev *dev, uint16_t address, uint32_t speed); |
|
void i2c_deinit(const i2c_dev *dev); |
|
|
|
uint32_t i2c_write(const i2c_dev *dev, uint8_t addr, const uint8_t *tx_buff, uint8_t txlen); |
|
uint32_t i2c_read (const i2c_dev *dev, uint8_t addr, const uint8_t *tx_buff, uint8_t txlen, uint8_t *rx_buff, uint8_t rxlen); |
|
|
|
void i2c_lowLevel_deinit(const i2c_dev *dev); |
|
|
|
void i2c_master_release_bus(const i2c_dev *dev); |
|
bool i2c_bus_reset(const i2c_dev *dev); |
|
|
|
static inline void i2c_set_isr_handler(const i2c_dev *dev, Handler h){ |
|
IRQn_Type irq; |
|
dev->state->handler = h; |
|
|
|
irq=dev->er_nvic_line; |
|
enable_nvic_irq(irq, I2C_INT_PRIORITY); // 8 bits * 4uS = 32uS max reaction time |
|
|
|
irq=dev->ev_nvic_line; |
|
|
|
enable_nvic_irq(irq, I2C_INT_PRIORITY); |
|
} |
|
|
|
static inline void i2c_clear_isr_handler(const i2c_dev *dev){ |
|
dev->state->handler=0; |
|
} |
|
|
|
|
|
static inline void i2c_send_address(const i2c_dev *dev, uint8_t address, uint8_t direction) |
|
{ |
|
/* Test on the direction to set/reset the read/write bit */ |
|
if (direction != I2C_Direction_Transmitter) { |
|
dev->I2Cx->DR = address | I2C_OAR1_ADD0; /* Set the address bit0 for read */ |
|
} else { |
|
dev->I2Cx->DR = address & (uint8_t)~((uint8_t)I2C_OAR1_ADD0); /* Reset the address bit0 for write */ |
|
} |
|
} |
|
|
|
#ifdef I2C_DEBUG |
|
uint32_t i2c_get_operation_time(uint8_t *psr1); |
|
#endif |
|
|
|
extern const i2c_dev* const _I2C1; |
|
extern const i2c_dev* const _I2C2; |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
|
|
#endif
|
|
|