|
|
@@ -1,26 +1,28 @@
|
|
|
#include "i2csniffer.h"
|
|
|
|
|
|
-void clearSnifferBuffers(i2csniffer* sniffer) {
|
|
|
+void clear_sniffer_buffers(i2cSniffer* i2c_sniffer) {
|
|
|
+ furi_assert(i2c_sniffer);
|
|
|
for(uint8_t i = 0; i < MAX_RECORDS; i++) {
|
|
|
for(uint8_t j = 0; j < MAX_MESSAGE_SIZE; j++) {
|
|
|
- sniffer->frames[i].ack[j] = false;
|
|
|
- sniffer->frames[i].data[j] = 0;
|
|
|
+ i2c_sniffer->frames[i].ack[j] = false;
|
|
|
+ i2c_sniffer->frames[i].data[j] = 0;
|
|
|
}
|
|
|
- sniffer->frames[i].bit_index = 0;
|
|
|
- sniffer->frames[i].data_index = 0;
|
|
|
+ i2c_sniffer->frames[i].bit_index = 0;
|
|
|
+ i2c_sniffer->frames[i].data_index = 0;
|
|
|
}
|
|
|
- sniffer->frame_index = 0;
|
|
|
- sniffer->state = I2C_BUS_FREE;
|
|
|
- sniffer->first = true;
|
|
|
+ i2c_sniffer->frame_index = 0;
|
|
|
+ i2c_sniffer->state = I2C_BUS_FREE;
|
|
|
+ i2c_sniffer->first = true;
|
|
|
}
|
|
|
|
|
|
-void start_interrupts(i2csniffer* sniffer) {
|
|
|
+void start_interrupts(i2cSniffer* i2c_sniffer) {
|
|
|
+ furi_assert(i2c_sniffer);
|
|
|
furi_hal_gpio_init(pinSCL, GpioModeInterruptRise, GpioPullNo, GpioSpeedHigh);
|
|
|
- furi_hal_gpio_add_int_callback(pinSCL, SCLcallback, sniffer);
|
|
|
+ furi_hal_gpio_add_int_callback(pinSCL, SCLcallback, i2c_sniffer);
|
|
|
|
|
|
// Add Rise and Fall Interrupt on SDA pin
|
|
|
furi_hal_gpio_init(pinSDA, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedHigh);
|
|
|
- furi_hal_gpio_add_int_callback(pinSDA, SDAcallback, sniffer);
|
|
|
+ furi_hal_gpio_add_int_callback(pinSDA, SDAcallback, i2c_sniffer);
|
|
|
}
|
|
|
|
|
|
void stop_interrupts() {
|
|
|
@@ -30,28 +32,28 @@ void stop_interrupts() {
|
|
|
|
|
|
// Called on Fallin/Rising SDA
|
|
|
// Used to monitor i2c bus state
|
|
|
-void SDAcallback(void* _sniffer) {
|
|
|
- i2csniffer* sniffer = _sniffer;
|
|
|
+void SDAcallback(void* _i2c_sniffer) {
|
|
|
+ i2cSniffer* i2c_sniffer = _i2c_sniffer;
|
|
|
// SCL is low maybe cclock strecching
|
|
|
if(furi_hal_gpio_read(pinSCL) == false) {
|
|
|
return;
|
|
|
}
|
|
|
// Check for stop condition: SDA rising while SCL is High
|
|
|
- if(sniffer->state == I2C_BUS_STARTED) {
|
|
|
+ if(i2c_sniffer->state == I2C_BUS_STARTED) {
|
|
|
if(furi_hal_gpio_read(pinSDA) == true) {
|
|
|
- sniffer->state = I2C_BUS_FREE;
|
|
|
+ i2c_sniffer->state = I2C_BUS_FREE;
|
|
|
}
|
|
|
}
|
|
|
// Check for start condition: SDA falling while SCL is high
|
|
|
else if(furi_hal_gpio_read(pinSDA) == false) {
|
|
|
- sniffer->state = I2C_BUS_STARTED;
|
|
|
- if(sniffer->first) {
|
|
|
- sniffer->first = false;
|
|
|
+ i2c_sniffer->state = I2C_BUS_STARTED;
|
|
|
+ if(i2c_sniffer->first) {
|
|
|
+ i2c_sniffer->first = false;
|
|
|
return;
|
|
|
}
|
|
|
- sniffer->frame_index++;
|
|
|
- if(sniffer->frame_index >= MAX_RECORDS) {
|
|
|
- clearSnifferBuffers(sniffer);
|
|
|
+ i2c_sniffer->frame_index++;
|
|
|
+ if(i2c_sniffer->frame_index >= MAX_RECORDS) {
|
|
|
+ clear_sniffer_buffers(i2c_sniffer);
|
|
|
}
|
|
|
}
|
|
|
return;
|
|
|
@@ -59,21 +61,34 @@ void SDAcallback(void* _sniffer) {
|
|
|
|
|
|
// Called on Rising SCL
|
|
|
// Used to read bus datas
|
|
|
-void SCLcallback(void* _sniffer) {
|
|
|
- i2csniffer* sniffer = _sniffer;
|
|
|
- if(sniffer->state == I2C_BUS_FREE) {
|
|
|
+void SCLcallback(void* _i2c_sniffer) {
|
|
|
+ i2cSniffer* i2c_sniffer = _i2c_sniffer;
|
|
|
+ if(i2c_sniffer->state == I2C_BUS_FREE) {
|
|
|
return;
|
|
|
}
|
|
|
- uint8_t frame = sniffer->frame_index;
|
|
|
- uint8_t bit = sniffer->frames[frame].bit_index;
|
|
|
- uint8_t data_idx = sniffer->frames[frame].data_index;
|
|
|
+ uint8_t frame = i2c_sniffer->frame_index;
|
|
|
+ uint8_t bit = i2c_sniffer->frames[frame].bit_index;
|
|
|
+ uint8_t data_idx = i2c_sniffer->frames[frame].data_index;
|
|
|
if(bit < 8) {
|
|
|
- sniffer->frames[frame].data[data_idx] <<= 1;
|
|
|
- sniffer->frames[frame].data[data_idx] |= (int)furi_hal_gpio_read(pinSDA);
|
|
|
- sniffer->frames[frame].bit_index++;
|
|
|
+ i2c_sniffer->frames[frame].data[data_idx] <<= 1;
|
|
|
+ i2c_sniffer->frames[frame].data[data_idx] |= (int)furi_hal_gpio_read(pinSDA);
|
|
|
+ i2c_sniffer->frames[frame].bit_index++;
|
|
|
} else {
|
|
|
- sniffer->frames[frame].ack[data_idx] = !furi_hal_gpio_read(pinSDA);
|
|
|
- sniffer->frames[frame].data_index++;
|
|
|
- sniffer->frames[frame].bit_index = 0;
|
|
|
+ i2c_sniffer->frames[frame].ack[data_idx] = !furi_hal_gpio_read(pinSDA);
|
|
|
+ i2c_sniffer->frames[frame].data_index++;
|
|
|
+ i2c_sniffer->frames[frame].bit_index = 0;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+i2cSniffer* i2c_sniffer_alloc() {
|
|
|
+ i2cSniffer* i2c_sniffer = malloc(sizeof(i2cSniffer));
|
|
|
+ i2c_sniffer->started = false;
|
|
|
+ clear_sniffer_buffers(i2c_sniffer);
|
|
|
+ return i2c_sniffer;
|
|
|
+}
|
|
|
+
|
|
|
+void i2c_sniffer_free(i2cSniffer* i2c_sniffer) {
|
|
|
+ furi_assert(i2c_sniffer);
|
|
|
+ furi_check(i2c_sniffer->started == false);
|
|
|
+ free(i2c_sniffer);
|
|
|
+}
|