I2C protection
This commit is contained in:
@@ -6,14 +6,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <I2CBB.hpp>
|
#include <I2CBB.hpp>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
#define SCL_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET)
|
#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 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_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_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 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 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() {
|
void I2CBB::init() {
|
||||||
//Set GPIO's to output open drain
|
//Set GPIO's to output open drain
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
@@ -25,6 +27,9 @@ void I2CBB::init() {
|
|||||||
HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct);
|
||||||
SDA_HIGH();
|
SDA_HIGH();
|
||||||
SCL_HIGH();
|
SCL_HIGH();
|
||||||
|
I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer);
|
||||||
|
xSemaphoreGive(I2CSemaphore);
|
||||||
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I2CBB::probe(uint8_t address) {
|
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,
|
bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
|
||||||
uint16_t Size) {
|
uint16_t Size) {
|
||||||
|
if (!lock())
|
||||||
|
return false;
|
||||||
start();
|
start();
|
||||||
bool ack = send(DevAddress | 1);
|
bool ack = send(DevAddress);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ack = send(MemAddress);
|
ack = send(MemAddress);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
start();
|
||||||
|
ack = send(DevAddress | 1);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (Size) {
|
while (Size) {
|
||||||
@@ -53,20 +69,27 @@ bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
|
|||||||
Size--;
|
Size--;
|
||||||
}
|
}
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
|
bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
|
||||||
uint16_t Size) {
|
uint16_t Size) {
|
||||||
|
if (!lock())
|
||||||
|
return false;
|
||||||
start();
|
start();
|
||||||
bool ack = send(DevAddress);
|
bool ack = send(DevAddress);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
asm("bkpt");
|
||||||
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ack = send(MemAddress);
|
ack = send(MemAddress);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
asm("bkpt");
|
||||||
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (Size) {
|
while (Size) {
|
||||||
@@ -74,40 +97,51 @@ bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
|
|||||||
bool ack = send(pData[0]);
|
bool ack = send(pData[0]);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
asm("bkpt");
|
||||||
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pData++;
|
pData++;
|
||||||
Size--;
|
Size--;
|
||||||
}
|
}
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||||
|
if (!lock())
|
||||||
|
return;
|
||||||
start();
|
start();
|
||||||
bool ack = send(DevAddress);
|
bool ack = send(DevAddress);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (Size) {
|
while (Size) {
|
||||||
bool ack = send(pData[0]);
|
bool ack = send(pData[0]);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pData++;
|
pData++;
|
||||||
Size--;
|
Size--;
|
||||||
}
|
}
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||||
|
if (!lock())
|
||||||
|
return;
|
||||||
start();
|
start();
|
||||||
bool ack = send(DevAddress | 1);
|
bool ack = send(DevAddress | 1);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (Size) {
|
while (Size) {
|
||||||
@@ -116,23 +150,28 @@ void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
|||||||
Size--;
|
Size--;
|
||||||
}
|
}
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
|
void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
|
||||||
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
|
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
|
||||||
if (Size_tx == 0 && Size_rx == 0)
|
if (Size_tx == 0 && Size_rx == 0)
|
||||||
return;
|
return;
|
||||||
|
if (lock() == false)
|
||||||
|
return;
|
||||||
if (Size_tx) {
|
if (Size_tx) {
|
||||||
start();
|
start();
|
||||||
bool ack = send(DevAddress);
|
bool ack = send(DevAddress);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (Size_tx) {
|
while (Size_tx) {
|
||||||
bool ack = send(pData_tx[0]);
|
bool ack = send(pData_tx[0]);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pData_tx++;
|
pData_tx++;
|
||||||
@@ -144,6 +183,7 @@ void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
|
|||||||
bool ack = send(DevAddress | 1);
|
bool ack = send(DevAddress | 1);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (Size_rx) {
|
while (Size_rx) {
|
||||||
@@ -153,6 +193,7 @@ void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
stop();
|
stop();
|
||||||
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::start() {
|
void I2CBB::start() {
|
||||||
@@ -220,6 +261,17 @@ uint8_t I2CBB::read_bit() {
|
|||||||
return b;
|
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) {
|
void I2CBB::write_bit(uint8_t val) {
|
||||||
if (val > 0)
|
if (val > 0)
|
||||||
SDA_HIGH();
|
SDA_HIGH();
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "Setup.h"
|
#include "Setup.h"
|
||||||
#include "Pins.h"
|
#include "Pins.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
/*
|
/*
|
||||||
* Simple static I2C bit-bang class used on the TS80P
|
* Simple static I2C bit-bang class used on the TS80P
|
||||||
* SCL = PA5
|
* SCL = PA5
|
||||||
@@ -31,6 +33,10 @@ public:
|
|||||||
static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
|
static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
|
||||||
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx);
|
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx);
|
||||||
private:
|
private:
|
||||||
|
static SemaphoreHandle_t I2CSemaphore;
|
||||||
|
static StaticSemaphore_t xSemaphoreBuffer;
|
||||||
|
static void unlock();
|
||||||
|
static bool lock();
|
||||||
static void start();
|
static void start();
|
||||||
static void stop();
|
static void stop();
|
||||||
static bool send(uint8_t value);
|
static bool send(uint8_t value);
|
||||||
|
|||||||
Reference in New Issue
Block a user