1
0
forked from me/IronOS

I2C protection

This commit is contained in:
Ben V. Brown
2020-06-16 20:19:06 +10:00
parent 9ea92a3c17
commit 54a8aa7ac6
2 changed files with 61 additions and 3 deletions

View File

@@ -6,14 +6,16 @@
*/
#include <I2CBB.hpp>
#include "FreeRTOS.h"
#define SCL_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET)
#define SCL_LOW() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_RESET)
#define SDA_HIGH() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_SET)
#define SDA_LOW() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_RESET)
#define SDA_READ() (HAL_GPIO_ReadPin(SDA2_GPIO_Port,SDA2_Pin)==GPIO_PIN_SET?1:0)
#define SCL_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port,SCL2_Pin)==GPIO_PIN_SET?1:0)
#define I2C_DELAY() {for(int xx=0;xx<100;xx++){asm("nop");}}
#define I2C_DELAY() {for(int xx=0;xx<700;xx++){asm("nop");}}
SemaphoreHandle_t I2CBB::I2CSemaphore = NULL;
StaticSemaphore_t I2CBB::xSemaphoreBuffer;
void I2CBB::init() {
//Set GPIO's to output open drain
GPIO_InitTypeDef GPIO_InitStruct;
@@ -25,6 +27,9 @@ void I2CBB::init() {
HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct);
SDA_HIGH();
SCL_HIGH();
I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer);
xSemaphoreGive(I2CSemaphore);
unlock();
}
bool I2CBB::probe(uint8_t address) {
@@ -36,15 +41,26 @@ bool I2CBB::probe(uint8_t address) {
bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
uint16_t Size) {
if (!lock())
return false;
start();
bool ack = send(DevAddress | 1);
bool ack = send(DevAddress);
if (!ack) {
stop();
unlock();
return false;
}
ack = send(MemAddress);
if (!ack) {
stop();
unlock();
return false;
}
start();
ack = send(DevAddress | 1);
if (!ack) {
stop();
unlock();
return false;
}
while (Size) {
@@ -53,20 +69,27 @@ bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
Size--;
}
stop();
unlock();
return true;
}
bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
uint16_t Size) {
if (!lock())
return false;
start();
bool ack = send(DevAddress);
if (!ack) {
stop();
asm("bkpt");
unlock();
return false;
}
ack = send(MemAddress);
if (!ack) {
stop();
asm("bkpt");
unlock();
return false;
}
while (Size) {
@@ -74,40 +97,51 @@ bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
bool ack = send(pData[0]);
if (!ack) {
stop();
asm("bkpt");
unlock();
return false;
}
pData++;
Size--;
}
stop();
unlock();
return true;
}
void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
if (!lock())
return;
start();
bool ack = send(DevAddress);
if (!ack) {
stop();
unlock();
return;
}
while (Size) {
bool ack = send(pData[0]);
if (!ack) {
stop();
unlock();
return;
}
pData++;
Size--;
}
stop();
unlock();
}
void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
if (!lock())
return;
start();
bool ack = send(DevAddress | 1);
if (!ack) {
stop();
unlock();
return;
}
while (Size) {
@@ -116,23 +150,28 @@ void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
Size--;
}
stop();
unlock();
}
void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
if (Size_tx == 0 && Size_rx == 0)
return;
if (lock() == false)
return;
if (Size_tx) {
start();
bool ack = send(DevAddress);
if (!ack) {
stop();
unlock();
return;
}
while (Size_tx) {
bool ack = send(pData_tx[0]);
if (!ack) {
stop();
unlock();
return;
}
pData_tx++;
@@ -144,6 +183,7 @@ void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
bool ack = send(DevAddress | 1);
if (!ack) {
stop();
unlock();
return;
}
while (Size_rx) {
@@ -153,6 +193,7 @@ void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
}
}
stop();
unlock();
}
void I2CBB::start() {
@@ -220,6 +261,17 @@ uint8_t I2CBB::read_bit() {
return b;
}
void I2CBB::unlock() {
xSemaphoreGive(I2CSemaphore);
}
bool I2CBB::lock() {
if (I2CSemaphore == NULL) {
asm("bkpt");
}
return xSemaphoreTake(I2CSemaphore, (TickType_t) 50) == pdTRUE;
}
void I2CBB::write_bit(uint8_t val) {
if (val > 0)
SDA_HIGH();

View File

@@ -10,6 +10,8 @@
#include "BSP.h"
#include "Setup.h"
#include "Pins.h"
#include "FreeRTOS.h"
#include "semphr.h"
/*
* Simple static I2C bit-bang class used on the TS80P
* SCL = PA5
@@ -31,6 +33,10 @@ public:
static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx);
private:
static SemaphoreHandle_t I2CSemaphore;
static StaticSemaphore_t xSemaphoreBuffer;
static void unlock();
static bool lock();
static void start();
static void stop();
static bool send(uint8_t value);