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.
156 lines
2.9 KiB
156 lines
2.9 KiB
#pragma once |
|
|
|
#include <stdbool.h> |
|
#include <stm32f4xx.h> |
|
#include <hal.h> |
|
#include "systick.h" |
|
#include "Scheduler.h" |
|
#include "timer.h" |
|
|
|
//#define SI2C_DEBUG 1 |
|
//#define SI2C_PROF 1 |
|
|
|
|
|
|
|
class Soft_I2C { |
|
public: |
|
|
|
typedef enum STATE { |
|
START, |
|
// address |
|
A_0L, |
|
A_0H, |
|
A_1L, |
|
A_1H, |
|
A_2L, |
|
A_2H, |
|
A_3L, |
|
A_3H, |
|
A_4L, |
|
A_4H, |
|
A_5L, |
|
A_5H, |
|
A_6L, |
|
A_6H, |
|
A_7L, |
|
A_7H, |
|
A_AL, |
|
A_AH, |
|
// byte write |
|
W_0L, |
|
W_0H, |
|
W_1L, |
|
W_1H, |
|
W_2L, |
|
W_2H, |
|
W_3L, |
|
W_3H, |
|
W_4L, |
|
W_4H, |
|
W_5L, |
|
W_5H, |
|
W_6L, |
|
W_6H, |
|
W_7L, |
|
W_7H, |
|
W_AL, |
|
W_AH, |
|
|
|
STOP, |
|
STOP2, |
|
RESTART, |
|
RESTART2, // 2nd stage |
|
DUMMY, |
|
// byte read after restart |
|
R_0L, |
|
R_0H, |
|
R_1L, |
|
R_1H, |
|
R_2L, |
|
R_2H, |
|
R_3L, |
|
R_3H, |
|
R_4L, |
|
R_4H, |
|
R_5L, |
|
R_5H, |
|
R_6L, |
|
R_6H, |
|
R_7L, |
|
R_7H, |
|
R_AL, |
|
R_AH, |
|
} State; |
|
|
|
#ifdef SI2C_DEBUG |
|
typedef struct SI2C_STATE { |
|
uint32_t time; |
|
State state; |
|
unsigned int sda; |
|
unsigned int f_sda; |
|
} SI2C_State; |
|
#endif |
|
|
|
|
|
|
|
Soft_I2C(); |
|
|
|
void init(); |
|
void init_hw( const gpio_dev *scl_dev, uint8_t scl_bit, const gpio_dev *sda_dev, uint8_t sda_bit, const timer_dev *tim); |
|
|
|
uint8_t writeBuffer( uint8_t addr_, uint8_t len_, const uint8_t *data); |
|
uint8_t read( uint8_t addr_, uint8_t reg, uint8_t len, uint8_t* buf); |
|
uint8_t transfer(uint8_t addr, uint8_t send_len, const uint8_t *send, uint8_t len, uint8_t *buf); |
|
|
|
bool bus_reset(void); |
|
|
|
void set_low_speed(bool s) { } |
|
|
|
|
|
private: |
|
void tick(); // ISR |
|
|
|
bool _start(void); |
|
uint8_t wait_done(); |
|
|
|
const gpio_dev *_scl_dev; |
|
uint8_t _scl_bit; |
|
const gpio_dev *_sda_dev; |
|
uint8_t _sda_bit; |
|
const timer_dev * _timer; |
|
|
|
volatile GPIO_TypeDef *scl_port; // for quick direct access to hardware |
|
uint16_t scl_pin; |
|
volatile GPIO_TypeDef *sda_port; |
|
uint16_t sda_pin; |
|
|
|
volatile bool done; |
|
volatile uint8_t result; |
|
volatile State state; |
|
bool f_sda; // what line we touch |
|
bool wait_scl; // flag - we wait for SCL stretching |
|
bool was_restart; |
|
|
|
uint8_t data; // data byte to output / from input |
|
|
|
const uint8_t *send; |
|
uint8_t send_len; |
|
uint8_t *recv; |
|
uint8_t recv_len; |
|
uint8_t _addr; |
|
|
|
uint16_t bit_time; |
|
|
|
#ifdef SI2C_DEBUG |
|
#define SI2C_LOG_SIZE 199 |
|
static SI2C_State log[SI2C_LOG_SIZE]; |
|
static uint16_t log_ptr; |
|
#endif |
|
|
|
#ifdef SI2C_PROF |
|
static uint64_t full_time; |
|
static uint32_t int_count; |
|
#endif |
|
|
|
}; |
|
|
|
|