переделала библиотеку с заготовкой на то, чтобы добавить второй i2c
This commit is contained in:
parent
f45ef1de67
commit
ba668a984e
@ -4,31 +4,9 @@ extern "C"
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "utility/twi.h"
|
|
||||||
}
|
}
|
||||||
#include "Wire.h"
|
#include "Wire.h"
|
||||||
|
|
||||||
// Initialize Class Variables
|
|
||||||
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
|
|
||||||
uint8_t TwoWire::rxBufferIndex = 0;
|
|
||||||
uint8_t TwoWire::rxBufferLength = 0;
|
|
||||||
|
|
||||||
uint8_t TwoWire::txAddress = 0; // 7 bits without shift
|
|
||||||
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
|
|
||||||
uint8_t TwoWire::txBufferIndex = 0;
|
|
||||||
uint8_t TwoWire::txBufferLength = 0;
|
|
||||||
|
|
||||||
uint8_t TwoWire::transmitting = 0;
|
|
||||||
uint8_t TwoWire::slaveAddress = 0; // 7 bits without shift in slave mode
|
|
||||||
|
|
||||||
void (*TwoWire::user_onRequest)(void);
|
|
||||||
void (*TwoWire::user_onReceive)(int);
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
TwoWire::TwoWire()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------- Public Methods --------------------------- //
|
// --------------------------- Public Methods --------------------------- //
|
||||||
void TwoWire::begin(void)
|
void TwoWire::begin(void)
|
||||||
{
|
{
|
||||||
@ -36,10 +14,7 @@ void TwoWire::begin(void)
|
|||||||
rxBufferLength = 0;
|
rxBufferLength = 0;
|
||||||
txBufferIndex = 0;
|
txBufferIndex = 0;
|
||||||
txBufferLength = 0;
|
txBufferLength = 0;
|
||||||
twi_init(slaveAddress);
|
twi_init(&wireHandler, slaveAddress);
|
||||||
|
|
||||||
twi_attachSlaveTxEvent(onRequestService); // default callback must exist
|
|
||||||
twi_attachSlaveRxEvent(onReceiveService); // default callback must exist
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoWire::begin(uint8_t address)
|
void TwoWire::begin(uint8_t address)
|
||||||
@ -56,13 +31,13 @@ void TwoWire::begin(int address)
|
|||||||
void TwoWire::end(void)
|
void TwoWire::end(void)
|
||||||
{
|
{
|
||||||
flush(); // wait for transmission complete
|
flush(); // wait for transmission complete
|
||||||
twi_deinit();
|
twi_deinit(&wireHandler);
|
||||||
slaveAddress = 0;
|
slaveAddress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoWire::setClock(uint32_t clock)
|
void TwoWire::setClock(uint32_t clock)
|
||||||
{
|
{
|
||||||
if (twi_setFrequency(clock, false) != I2C_OK)
|
if (twi_setFrequency(&wireHandler, clock, false) != I2C_OK)
|
||||||
ErrorMsgHandler("Wire.setClock(): invalid frequency or Wire was not begin");
|
ErrorMsgHandler("Wire.setClock(): invalid frequency or Wire was not begin");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +63,7 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres
|
|||||||
quantity = BUFFER_LENGTH;
|
quantity = BUFFER_LENGTH;
|
||||||
|
|
||||||
// perform blocking read into buffer
|
// perform blocking read into buffer
|
||||||
uint8_t read = twi_masterReadFrom(address, rxBuffer, quantity, sendStop);
|
uint8_t read = twi_masterReadFrom(&(wireHandler.i2c_param), address, rxBuffer, quantity, sendStop);
|
||||||
|
|
||||||
// set rx buffer iterator vars
|
// set rx buffer iterator vars
|
||||||
rxBufferIndex = 0;
|
rxBufferIndex = 0;
|
||||||
@ -147,7 +122,7 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
|
|||||||
if (transmitting)
|
if (transmitting)
|
||||||
{
|
{
|
||||||
// transmit buffer (blocking)
|
// transmit buffer (blocking)
|
||||||
ret = twi_masterWriteTo(txAddress, txBuffer, txBufferLength, sendStop);
|
ret = twi_masterWriteTo(&(wireHandler.i2c_param), txAddress, txBuffer, txBufferLength, sendStop);
|
||||||
// reset tx buffer iterator vars
|
// reset tx buffer iterator vars
|
||||||
txBufferIndex = 0;
|
txBufferIndex = 0;
|
||||||
txBufferLength = 0;
|
txBufferLength = 0;
|
||||||
@ -189,7 +164,7 @@ size_t TwoWire::write(uint8_t data)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// in slave send mode - reply to master
|
// in slave send mode - reply to master
|
||||||
if (twi_slaveWrite(&data, 1) != I2C_OK)
|
if (twi_slaveWrite(&(wireHandler.i2c_param), &data, 1) != I2C_OK)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -215,7 +190,7 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// in slave send mode - reply to master
|
// in slave send mode - reply to master
|
||||||
if (twi_slaveWrite((uint8_t *)data, quantity) != I2C_OK)
|
if (twi_slaveWrite(&(wireHandler.i2c_param), (uint8_t *)data, quantity) != I2C_OK)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -309,10 +284,18 @@ void TwoWire::onRequest( void (*function)(void) )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// С function for trap handler
|
// С function for trap handler
|
||||||
extern "C" void __attribute__((optimize("O3"))) wire_interrupt_handler(void)
|
extern "C" void __attribute__((optimize("O3"))) wire_interrupt_handler(uint8_t num)
|
||||||
{
|
{
|
||||||
twi_interruptHandler();
|
if (num == 1)
|
||||||
|
twi_interruptHandler(Wire.getHandler());
|
||||||
|
#if I2C_COMMON_QTY>1
|
||||||
|
else if (num == 0)
|
||||||
|
twi_interruptHandler(Wire1.getHandler());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------- Preinstantiate Objects ----------------------------- //
|
// ----------------------------- Preinstantiate Objects ----------------------------- //
|
||||||
TwoWire Wire = TwoWire( );
|
TwoWire Wire = TwoWire(1);
|
||||||
|
#if I2C_COMMON_QTY>1
|
||||||
|
TwoWire Wire1 = TwoWire(0);
|
||||||
|
#endif
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include "utility/twi.h"
|
||||||
|
}
|
||||||
|
|
||||||
#define BUFFER_LENGTH 32
|
#define BUFFER_LENGTH 32
|
||||||
|
|
||||||
@ -13,23 +17,45 @@
|
|||||||
class TwoWire : public Stream
|
class TwoWire : public Stream
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static uint8_t rxBuffer[];
|
WireHandler_TypeDef wireHandler;
|
||||||
static uint8_t rxBufferIndex;
|
|
||||||
static uint8_t rxBufferLength;
|
|
||||||
|
|
||||||
static uint8_t txAddress;
|
uint8_t rxBuffer[BUFFER_LENGTH];
|
||||||
static uint8_t txBuffer[];
|
uint8_t rxBufferIndex = 0;
|
||||||
static uint8_t txBufferIndex;
|
uint8_t rxBufferLength = 0;
|
||||||
static uint8_t txBufferLength;
|
|
||||||
|
|
||||||
static uint8_t transmitting;
|
uint8_t txAddress = 0; // 7 bits without shift
|
||||||
static uint8_t slaveAddress;
|
uint8_t txBuffer[BUFFER_LENGTH];
|
||||||
static void (*user_onRequest)(void);
|
uint8_t txBufferIndex = 0;
|
||||||
static void (*user_onReceive)(int numBytes);
|
uint8_t txBufferLength = 0;
|
||||||
static void onRequestService(void);
|
|
||||||
static void onReceiveService(uint8_t* inBytes, int numBytes);
|
uint8_t transmitting = 0;
|
||||||
|
uint8_t slaveAddress = 0;
|
||||||
|
void (*user_onRequest)(void);
|
||||||
|
void (*user_onReceive)(int numBytes);
|
||||||
|
void onRequestService(void);
|
||||||
|
void onReceiveService(uint8_t* inBytes, int numBytes);
|
||||||
|
static inline void staticOnRequestService(void* instance)
|
||||||
|
{
|
||||||
|
// cast pointer to TwoWire type and call method
|
||||||
|
static_cast<TwoWire*>(instance)->onRequestService();
|
||||||
|
}
|
||||||
|
static inline void staticOnReceiveService(void* instance, uint8_t* inBytes, int numBytes)
|
||||||
|
{
|
||||||
|
static_cast<TwoWire*>(instance)->onReceiveService(inBytes, numBytes);
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
TwoWire();
|
inline TwoWire(uint8_t num)
|
||||||
|
{
|
||||||
|
wireHandler.i2c_num = (num < I2C_COMMON_QTY) ? num : 1; // I2C1 by default
|
||||||
|
wireHandler.instance = this;
|
||||||
|
// save pointers to static functions to wire handler
|
||||||
|
wireHandler.onSlaveTransmit = &TwoWire::staticOnRequestService;
|
||||||
|
wireHandler.onSlaveReceive = &TwoWire::staticOnReceiveService;
|
||||||
|
}
|
||||||
|
WireHandler_TypeDef* getHandler()
|
||||||
|
{
|
||||||
|
return &wireHandler;
|
||||||
|
}
|
||||||
void begin();
|
void begin();
|
||||||
void begin(uint8_t);
|
void begin(uint8_t);
|
||||||
void begin(int);
|
void begin(int);
|
||||||
@ -65,5 +91,8 @@ class TwoWire : public Stream
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern TwoWire Wire;
|
extern TwoWire Wire;
|
||||||
|
#if I2C_COMMON_QTY>1
|
||||||
|
extern TwoWire Wire1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -2,162 +2,149 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "twi.h"
|
#include "twi.h"
|
||||||
#include "mik32_hal_i2c.h"
|
|
||||||
#include "mik32_hal_irq.h"
|
#include "mik32_hal_irq.h"
|
||||||
|
|
||||||
#define TIMEOUT_TICKS 1000000
|
#define TIMEOUT_TICKS 1000000
|
||||||
#define TWI_FREQ_DEF WIRE_FREQ_100K // default is 100 kHz
|
#define TWI_FREQ_DEF WIRE_FREQ_100K // default is 100 kHz
|
||||||
|
|
||||||
static void (*twi_onSlaveTransmit)(void);
|
|
||||||
static void (*twi_onSlaveReceive)(uint8_t*, int);
|
|
||||||
|
|
||||||
static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
|
|
||||||
static volatile uint8_t twi_rxBufferIndex;
|
|
||||||
|
|
||||||
I2C_HandleTypeDef hi2c;
|
|
||||||
static uint32_t CurrentFrequency = TWI_FREQ_DEF;
|
|
||||||
static bool twiIsOn = false;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------- //
|
// ---------------------------------------------------------------- //
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function twi_init
|
* Function twi_init
|
||||||
* Desc readys twi pins and sets twi bitrate
|
* Desc readys twi pins and sets twi bitrate
|
||||||
* Input slaveAddress - address of Arduino if working in slave mode
|
* Input handler - pointer to wire common handler,
|
||||||
|
* slaveAddress - address of Arduino if working in slave mode
|
||||||
* Output none
|
* Output none
|
||||||
*/
|
*/
|
||||||
uint8_t twi_init(uint8_t slaveAddress)
|
uint8_t twi_init(WireHandler_TypeDef* handler, uint8_t slaveAddress)
|
||||||
{
|
{
|
||||||
// Common settings
|
// Common settings
|
||||||
uint32_t EPICmask;
|
uint32_t EPICmask;
|
||||||
|
|
||||||
#if I2C_NUM == 0
|
if (handler->i2c_num == 0)
|
||||||
hi2c.Instance = I2C_0;
|
{
|
||||||
EPICmask = HAL_EPIC_I2C_0_MASK;
|
handler->i2c_param.Instance = I2C_0;
|
||||||
#elif I2C_NUM == 1
|
EPICmask = HAL_EPIC_I2C_0_MASK;
|
||||||
hi2c.Instance = I2C_1;
|
}
|
||||||
EPICmask = HAL_EPIC_I2C_1_MASK;
|
else if (handler->i2c_num == 1)
|
||||||
#else
|
{
|
||||||
#error "Unsupported I2C_NUM value in pins_arduino.h"
|
handler->i2c_param.Instance = I2C_1;
|
||||||
#endif
|
EPICmask = HAL_EPIC_I2C_1_MASK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return I2C_ERROR;
|
||||||
|
|
||||||
hi2c.Init.DigitalFilter = I2C_DIGITALFILTER_2CLOCKCYCLES;
|
handler->i2c_param.Init.DigitalFilter = I2C_DIGITALFILTER_2CLOCKCYCLES;
|
||||||
hi2c.Init.AnalogFilter = I2C_ANALOGFILTER_DISABLE;
|
handler->i2c_param.Init.AnalogFilter = I2C_ANALOGFILTER_DISABLE;
|
||||||
if (slaveAddress == 0) // if there is no address - master mode
|
if (slaveAddress == 0) // if there is no address - master mode
|
||||||
{
|
{
|
||||||
hi2c.Init.Mode = HAL_I2C_MODE_MASTER;
|
handler->i2c_param.Init.Mode = HAL_I2C_MODE_MASTER;
|
||||||
hi2c.Init.AutoEnd = I2C_AUTOEND_ENABLE;
|
handler->i2c_param.Init.AutoEnd = I2C_AUTOEND_ENABLE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 7-bit address without any additional bits
|
// 7-bit address without any additional bits
|
||||||
hi2c.Init.Mode = HAL_I2C_MODE_SLAVE;
|
handler->i2c_param.Init.Mode = HAL_I2C_MODE_SLAVE;
|
||||||
hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; // stretch is used
|
handler->i2c_param.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; // stretch is used
|
||||||
hi2c.Init.OwnAddress1 = slaveAddress;
|
handler->i2c_param.Init.OwnAddress1 = slaveAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the frequency
|
// set the frequency
|
||||||
if (hi2c.Init.Mode == HAL_I2C_MODE_MASTER)
|
if (handler->i2c_param.Init.Mode == HAL_I2C_MODE_MASTER)
|
||||||
twi_setFrequency(CurrentFrequency, true);
|
twi_setFrequency(handler, TWI_FREQ_DEF, true);
|
||||||
else
|
else
|
||||||
twi_setFrequency(0, true);
|
twi_setFrequency(handler, 0, true);
|
||||||
|
|
||||||
if (HAL_I2C_Init(&hi2c) != HAL_OK)
|
if (HAL_I2C_Init(&(handler->i2c_param)) != HAL_OK)
|
||||||
return I2C_ERROR;
|
return I2C_ERROR;
|
||||||
|
|
||||||
// enable interrupts for slave mode
|
// enable interrupts for slave mode
|
||||||
if (hi2c.Init.Mode == HAL_I2C_MODE_SLAVE)
|
if (handler->i2c_param.Init.Mode == HAL_I2C_MODE_SLAVE)
|
||||||
{
|
{
|
||||||
// enable interrupts for addressing, byte reception and transfer completion
|
// enable interrupts for addressing, byte reception and transfer completion
|
||||||
HAL_I2C_InterruptDisable(&hi2c, I2C_INTMASK);
|
HAL_I2C_InterruptDisable(&(handler->i2c_param), I2C_INTMASK);
|
||||||
HAL_I2C_InterruptEnable(&hi2c, I2C_CR1_ADDRIE_M | I2C_CR1_RXIE_M | I2C_CR1_STOPIE_M);
|
HAL_I2C_InterruptEnable(&(handler->i2c_param), I2C_CR1_ADDRIE_M | I2C_CR1_RXIE_M | I2C_CR1_STOPIE_M);
|
||||||
// enable interrupt from i2c
|
// enable interrupt from i2c
|
||||||
HAL_EPIC_MaskLevelSet(EPICmask);
|
HAL_EPIC_MaskLevelSet(EPICmask);
|
||||||
}
|
}
|
||||||
twiIsOn = true;
|
handler->isInited = true;
|
||||||
return I2C_OK;
|
return I2C_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function twi_deinit
|
* Function twi_deinit
|
||||||
* Desc disables twi pins
|
* Desc disables twi pins
|
||||||
* Input none
|
* Input handler - pointer to wire common handler
|
||||||
* Output none
|
* Output none
|
||||||
*/
|
*/
|
||||||
void twi_deinit(void)
|
void twi_deinit(WireHandler_TypeDef* handler)
|
||||||
{
|
{
|
||||||
uint32_t EPICmask;
|
HAL_I2C_Deinit(&(handler->i2c_param));
|
||||||
|
|
||||||
#if I2C_NUM == 0
|
|
||||||
hi2c.Instance = I2C_0;
|
|
||||||
EPICmask = HAL_EPIC_I2C_0_MASK;
|
|
||||||
#elif I2C_NUM == 1
|
|
||||||
hi2c.Instance = I2C_1;
|
|
||||||
EPICmask = HAL_EPIC_I2C_1_MASK;
|
|
||||||
#else
|
|
||||||
#error "Unsupported I2C_NUM value in pins_arduino.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HAL_I2C_Deinit(&hi2c);
|
|
||||||
|
|
||||||
// for slave mode disable interrupts from i2c
|
// for slave mode disable interrupts from i2c
|
||||||
if (hi2c.Init.Mode == HAL_I2C_MODE_SLAVE)
|
if (handler->i2c_param.Init.Mode == HAL_I2C_MODE_SLAVE)
|
||||||
HAL_EPIC_MaskLevelClear(EPICmask);
|
{
|
||||||
|
if (handler->i2c_num == 0)
|
||||||
|
HAL_EPIC_MaskLevelClear(HAL_EPIC_I2C_0_MASK);
|
||||||
|
else
|
||||||
|
HAL_EPIC_MaskLevelClear(HAL_EPIC_I2C_1_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
twiIsOn = false;
|
handler->isInited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function twi_setClock
|
* Function twi_setClock
|
||||||
* Desc sets twi bit rate
|
* Desc sets twi bit rate
|
||||||
* Input Clock Frequency - 100000 / 400000 / 1000000,
|
* Input handler - pointer to wire common handler
|
||||||
|
* Clock Frequency - 100000 / 400000 / 1000000,
|
||||||
* onInit = true only if function is called from twi_init()
|
* onInit = true only if function is called from twi_init()
|
||||||
* Output I2C_OK - frequency changed, I2C_ERROR - frequency didn't change
|
* Output I2C_OK - frequency changed, I2C_ERROR - frequency didn't change
|
||||||
*/
|
*/
|
||||||
uint8_t twi_setFrequency(uint32_t frequency, bool onInit)
|
uint8_t twi_setFrequency(WireHandler_TypeDef* handler, uint32_t frequency, bool onInit)
|
||||||
{
|
{
|
||||||
uint8_t ret = I2C_OK;
|
uint8_t ret = I2C_OK;
|
||||||
|
|
||||||
// change the frequency only during or after bus initialization
|
// change the frequency only during or after bus initialization
|
||||||
if (twiIsOn || onInit)
|
if (handler->isInited || onInit)
|
||||||
{
|
{
|
||||||
// You can change the frequency only when the interface is turned off
|
// You can change the frequency only when the interface is turned off
|
||||||
HAL_I2C_Disable(&hi2c);
|
HAL_I2C_Disable(&(handler->i2c_param));
|
||||||
|
|
||||||
if (frequency == WIRE_FREQ_100K) // 100 kHz
|
if (frequency == WIRE_FREQ_100K) // 100 kHz
|
||||||
{
|
{
|
||||||
hi2c.Clock.PRESC = 2;
|
handler->i2c_param.Clock.PRESC = 2;
|
||||||
hi2c.Clock.SCLDEL = 8;
|
handler->i2c_param.Clock.SCLDEL = 8;
|
||||||
hi2c.Clock.SDADEL = 2;
|
handler->i2c_param.Clock.SDADEL = 2;
|
||||||
hi2c.Clock.SCLH = 49;
|
handler->i2c_param.Clock.SCLH = 49;
|
||||||
hi2c.Clock.SCLL = 49;
|
handler->i2c_param.Clock.SCLL = 49;
|
||||||
CurrentFrequency = WIRE_FREQ_100K;
|
// CurrentFrequency = WIRE_FREQ_100K;
|
||||||
}
|
}
|
||||||
else if (frequency == WIRE_FREQ_400K) // 400 kHz
|
else if (frequency == WIRE_FREQ_400K) // 400 kHz
|
||||||
{
|
{
|
||||||
hi2c.Clock.PRESC = 0;
|
handler->i2c_param.Clock.PRESC = 0;
|
||||||
hi2c.Clock.SCLDEL = 3;
|
handler->i2c_param.Clock.SCLDEL = 3;
|
||||||
hi2c.Clock.SDADEL = 2;
|
handler->i2c_param.Clock.SDADEL = 2;
|
||||||
hi2c.Clock.SCLH = 30;
|
handler->i2c_param.Clock.SCLH = 30;
|
||||||
hi2c.Clock.SCLL = 30;
|
handler->i2c_param.Clock.SCLL = 30;
|
||||||
CurrentFrequency = WIRE_FREQ_400K;
|
// CurrentFrequency = WIRE_FREQ_400K;
|
||||||
}
|
}
|
||||||
else if (frequency == WIRE_FREQ_1000K)// 1000 kHz
|
else if (frequency == WIRE_FREQ_1000K)// 1000 kHz
|
||||||
{
|
{
|
||||||
hi2c.Clock.PRESC = 0;
|
handler->i2c_param.Clock.PRESC = 0;
|
||||||
hi2c.Clock.SCLDEL = 1;
|
handler->i2c_param.Clock.SCLDEL = 1;
|
||||||
hi2c.Clock.SDADEL = 2;
|
handler->i2c_param.Clock.SDADEL = 2;
|
||||||
hi2c.Clock.SCLH = 6;
|
handler->i2c_param.Clock.SCLH = 6;
|
||||||
hi2c.Clock.SCLL = 6;
|
handler->i2c_param.Clock.SCLL = 6;
|
||||||
CurrentFrequency = WIRE_FREQ_1000K;
|
// CurrentFrequency = WIRE_FREQ_1000K;
|
||||||
}
|
}
|
||||||
else if (frequency == 0) // slave mode
|
else if (frequency == 0) // slave mode
|
||||||
{
|
{
|
||||||
hi2c.Clock.PRESC = 0;
|
handler->i2c_param.Clock.PRESC = 0;
|
||||||
hi2c.Clock.SCLDEL = 0;
|
handler->i2c_param.Clock.SCLDEL = 0;
|
||||||
hi2c.Clock.SDADEL = 2;
|
handler->i2c_param.Clock.SDADEL = 2;
|
||||||
hi2c.Clock.SCLH = 0;
|
handler->i2c_param.Clock.SCLH = 0;
|
||||||
hi2c.Clock.SCLL = 0;
|
handler->i2c_param.Clock.SCLL = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// frequency does not change
|
// frequency does not change
|
||||||
@ -165,11 +152,11 @@ uint8_t twi_setFrequency(uint32_t frequency, bool onInit)
|
|||||||
|
|
||||||
// write the timings to the register if everything is OK
|
// write the timings to the register if everything is OK
|
||||||
if (ret == I2C_OK)
|
if (ret == I2C_OK)
|
||||||
HAL_I2C_SetClockSpeed(&hi2c);
|
HAL_I2C_SetClockSpeed(&(handler->i2c_param));
|
||||||
|
|
||||||
//turn the interface back only if initialization has already passed
|
//turn the interface back only if initialization has already passed
|
||||||
if (twiIsOn)
|
if (handler->isInited)
|
||||||
HAL_I2C_Enable(&hi2c);
|
HAL_I2C_Enable(&(handler->i2c_param));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = I2C_ERROR;
|
ret = I2C_ERROR;
|
||||||
@ -181,26 +168,27 @@ uint8_t twi_setFrequency(uint32_t frequency, bool onInit)
|
|||||||
* Function twi_masterReadFrom
|
* Function twi_masterReadFrom
|
||||||
* Desc attempts to become twi bus master and read a
|
* Desc attempts to become twi bus master and read a
|
||||||
* series of bytes from a device on the bus
|
* series of bytes from a device on the bus
|
||||||
* Input address: 7bit i2c device address
|
* Input hi2c: pointer to hardware i2c handler
|
||||||
|
* address: 7bit i2c device address
|
||||||
* data: pointer to byte array
|
* data: pointer to byte array
|
||||||
* length: number of bytes to read into array
|
* length: number of bytes to read into array
|
||||||
* sendStop: Boolean indicating whether to send a stop at the end
|
* sendStop: Boolean indicating whether to send a stop at the end
|
||||||
* Output number of bytes read
|
* Output number of bytes read
|
||||||
*/
|
*/
|
||||||
uint8_t twi_masterReadFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
|
uint8_t twi_masterReadFrom(I2C_HandleTypeDef* hi2c, uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
|
||||||
{
|
{
|
||||||
uint8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
|
|
||||||
// if there are errors left from previous transactions, you need to restart
|
// if there are errors left from previous transactions, you need to restart
|
||||||
// the interface for correct operation
|
// the interface for correct operation
|
||||||
if (hi2c.ErrorCode != I2C_ERROR_NONE)
|
if (hi2c->ErrorCode != I2C_ERROR_NONE)
|
||||||
HAL_I2C_Reset(&hi2c);
|
HAL_I2C_Reset(hi2c);
|
||||||
|
|
||||||
if (sendStop) hi2c.Init.AutoEnd = 1;
|
if (sendStop) hi2c->Init.AutoEnd = 1;
|
||||||
else hi2c.Init.AutoEnd = 0;
|
else hi2c->Init.AutoEnd = 0;
|
||||||
|
|
||||||
// put the data directly into the external buffer
|
// put the data directly into the external buffer
|
||||||
if (HAL_I2C_Master_Receive(&hi2c, address, data, length, TIMEOUT_TICKS) == HAL_OK)
|
if (HAL_I2C_Master_Receive(hi2c, address, data, length, TIMEOUT_TICKS) == HAL_OK)
|
||||||
ret = length;
|
ret = length;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -210,7 +198,8 @@ uint8_t twi_masterReadFrom(uint8_t address, uint8_t* data, uint8_t length, uint8
|
|||||||
* Function twi_masterWriteTo
|
* Function twi_masterWriteTo
|
||||||
* Desc attempts to become twi bus master and write a
|
* Desc attempts to become twi bus master and write a
|
||||||
* series of bytes to a device on the bus
|
* series of bytes to a device on the bus
|
||||||
* Input address: 7bit i2c device address
|
* Input hi2c: pointer to hardware i2c handler
|
||||||
|
* address: 7bit i2c device address
|
||||||
* data: pointer to byte array
|
* data: pointer to byte array
|
||||||
* length: number of bytes in array
|
* length: number of bytes in array
|
||||||
* sendStop: boolean indicating whether or not to send a stop at the end
|
* sendStop: boolean indicating whether or not to send a stop at the end
|
||||||
@ -221,28 +210,28 @@ uint8_t twi_masterReadFrom(uint8_t address, uint8_t* data, uint8_t length, uint8
|
|||||||
* 4 .. other twi error (lost bus arbitration, bus error, ..)
|
* 4 .. other twi error (lost bus arbitration, bus error, ..)
|
||||||
* 5 .. timeout
|
* 5 .. timeout
|
||||||
*/
|
*/
|
||||||
uint8_t twi_masterWriteTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
|
uint8_t twi_masterWriteTo(I2C_HandleTypeDef* hi2c, uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
|
||||||
{
|
{
|
||||||
uint8_t ret = I2C_OK;
|
uint8_t ret = I2C_OK;
|
||||||
|
|
||||||
// if there are errors left from previous transactions, you need to restart
|
// if there are errors left from previous transactions, you need to restart
|
||||||
// the interface for correct operation
|
// the interface for correct operation
|
||||||
if (hi2c.ErrorCode != I2C_ERROR_NONE)
|
if (hi2c->ErrorCode != I2C_ERROR_NONE)
|
||||||
HAL_I2C_Reset(&hi2c);
|
HAL_I2C_Reset(hi2c);
|
||||||
|
|
||||||
if (sendStop) hi2c.Init.AutoEnd = 1;
|
if (sendStop) hi2c->Init.AutoEnd = 1;
|
||||||
else hi2c.Init.AutoEnd = 0;
|
else hi2c->Init.AutoEnd = 0;
|
||||||
|
|
||||||
// take data from an external buffer
|
// take data from an external buffer
|
||||||
HAL_I2C_Master_Transmit(&hi2c, address, data, length, TIMEOUT_TICKS);
|
HAL_I2C_Master_Transmit(hi2c, address, data, length, TIMEOUT_TICKS);
|
||||||
|
|
||||||
// parse errors
|
// parse errors
|
||||||
// check separately, because in hal libraries not all functions look at this
|
// check separately, because in hal libraries not all functions look at this
|
||||||
if (HAL_I2C_Get_Interrupts_Status(&hi2c) & I2C_ISR_NACKF_M)
|
if (HAL_I2C_Get_Interrupts_Status(hi2c) & I2C_ISR_NACKF_M)
|
||||||
hi2c.ErrorCode = I2C_ERROR_NACK;
|
hi2c->ErrorCode = I2C_ERROR_NACK;
|
||||||
if (hi2c.ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_TIMEOUT) ret = I2C_TIMEOUT; // timeout
|
if (hi2c->ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_TIMEOUT) ret = I2C_TIMEOUT; // timeout
|
||||||
else if (hi2c.ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_NACK) ret = I2C_NACK_DATA; // didn't receive ACK
|
else if (hi2c->ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_NACK) ret = I2C_NACK_DATA; // didn't receive ACK
|
||||||
else if (hi2c.ErrorCode != (HAL_I2C_ErrorTypeDef)I2C_OK) ret = I2C_ERROR; // any other error
|
else if (hi2c->ErrorCode != (HAL_I2C_ErrorTypeDef)I2C_OK) ret = I2C_ERROR; // any other error
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -251,97 +240,79 @@ uint8_t twi_masterWriteTo(uint8_t address, uint8_t* data, uint8_t length, uint8_
|
|||||||
* Function twi_slaveWrite
|
* Function twi_slaveWrite
|
||||||
* Desc attempts to become twi bus slave and write a
|
* Desc attempts to become twi bus slave and write a
|
||||||
* series of bytes to a master after it asks
|
* series of bytes to a master after it asks
|
||||||
* Input txData: pointer to byte array
|
* Input hi2c: pointer to hardware i2c handler
|
||||||
|
* txData: pointer to byte array
|
||||||
* bytesNum: number of bytes in array
|
* bytesNum: number of bytes in array
|
||||||
* Output 0 .. success
|
* Output 0 .. success
|
||||||
* 5 .. timeout
|
* 5 .. timeout
|
||||||
*/
|
*/
|
||||||
i2c_status_e twi_slaveWrite(uint8_t *txData, uint8_t bytesNum)
|
i2c_status_e twi_slaveWrite(I2C_HandleTypeDef* hi2c, uint8_t *txData, uint8_t bytesNum)
|
||||||
{
|
{
|
||||||
if ((hi2c.ErrorCode != I2C_ERROR_NONE))
|
if ((hi2c->ErrorCode != I2C_ERROR_NONE))
|
||||||
HAL_I2C_Reset(&hi2c);
|
HAL_I2C_Reset(hi2c);
|
||||||
|
|
||||||
// send data
|
// send data
|
||||||
HAL_StatusTypeDef error_code = HAL_OK;
|
HAL_StatusTypeDef error_code = HAL_OK;
|
||||||
HAL_I2C_Clear_Reload(&hi2c);
|
HAL_I2C_Clear_Reload(hi2c);
|
||||||
if (!(HAL_I2C_Get_CR1_Content(&hi2c) & I2C_CR1_NOSTRETCH_M)) // NOSTRETCH = 0
|
if (!(HAL_I2C_Get_CR1_Content(hi2c) & I2C_CR1_NOSTRETCH_M)) // NOSTRETCH = 0
|
||||||
HAL_I2C_Reset_TXDR_Content(&hi2c);
|
HAL_I2C_Reset_TXDR_Content(hi2c);
|
||||||
HAL_I2C_Write_TXDR(&hi2c, txData[0]); // first recording is made in advance
|
HAL_I2C_Write_TXDR(hi2c, txData[0]); // first recording is made in advance
|
||||||
|
|
||||||
// write byte
|
// write byte
|
||||||
for (uint32_t tx_count = 1; tx_count < bytesNum; tx_count++)
|
for (uint32_t tx_count = 1; tx_count < bytesNum; tx_count++)
|
||||||
{
|
{
|
||||||
if ((error_code = HAL_I2C_Slave_WaitTXIS(&hi2c, TIMEOUT_TICKS)) != HAL_OK)
|
if ((error_code = HAL_I2C_Slave_WaitTXIS(hi2c, TIMEOUT_TICKS)) != HAL_OK)
|
||||||
{
|
{
|
||||||
// failed to write
|
// failed to write
|
||||||
HAL_I2C_Reset_TXDR_Content(&hi2c);
|
HAL_I2C_Reset_TXDR_Content(hi2c);
|
||||||
HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
HAL_I2C_Reset_Interrupt_Flag(hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
||||||
HAL_I2C_Reset(&hi2c);
|
HAL_I2C_Reset(hi2c);
|
||||||
return I2C_TIMEOUT;
|
return I2C_TIMEOUT;
|
||||||
}
|
}
|
||||||
HAL_I2C_Write_TXDR(&hi2c, txData[tx_count]);
|
HAL_I2C_Write_TXDR(hi2c, txData[tx_count]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error_code = HAL_I2C_WaitBusy(&hi2c, TIMEOUT_TICKS)) != HAL_OK)
|
if ((error_code = HAL_I2C_WaitBusy(hi2c, TIMEOUT_TICKS)) != HAL_OK)
|
||||||
{
|
{
|
||||||
// failed to complete transaction
|
// failed to complete transaction
|
||||||
HAL_I2C_Reset(&hi2c);
|
HAL_I2C_Reset(hi2c);
|
||||||
return I2C_TIMEOUT;
|
return I2C_TIMEOUT;
|
||||||
}
|
}
|
||||||
HAL_I2C_Reset_TXDR_Content(&hi2c);
|
HAL_I2C_Reset_TXDR_Content(hi2c);
|
||||||
HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
HAL_I2C_Reset_Interrupt_Flag(hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
||||||
|
|
||||||
return I2C_OK;
|
return I2C_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Function twi_attachSlaveRxEvent
|
|
||||||
* Desc sets function called before a slave read operation
|
|
||||||
* Input function: callback function to use
|
|
||||||
* Output none
|
|
||||||
*/
|
|
||||||
void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) )
|
|
||||||
{
|
|
||||||
twi_onSlaveReceive = function;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function twi_attachSlaveTxEvent
|
|
||||||
* Desc sets function called before a slave write operation
|
|
||||||
* Input function: callback function to use
|
|
||||||
* Output none
|
|
||||||
*/
|
|
||||||
void twi_attachSlaveTxEvent( void (*function)(void) )
|
|
||||||
{
|
|
||||||
twi_onSlaveTransmit = function;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function twi_interruptHandler
|
* Function twi_interruptHandler
|
||||||
* Desc handles an interrupts from twi
|
* Desc handles an interrupts from twi
|
||||||
* Input none
|
* Input handler - pointer to wire common handler
|
||||||
* Output none
|
* Output none
|
||||||
*/
|
*/
|
||||||
void __attribute__((optimize("O3"))) twi_interruptHandler(void)
|
void __attribute__((optimize("O3"))) twi_interruptHandler(WireHandler_TypeDef* handler)
|
||||||
{
|
{
|
||||||
uint32_t int_mask = HAL_I2C_Get_CR1_Content(&hi2c) & I2C_INTMASK; // interrupts allowed
|
uint32_t int_mask = HAL_I2C_Get_CR1_Content(&(handler->i2c_param)) & I2C_INTMASK; // interrupts allowed
|
||||||
uint32_t interrupt_status = HAL_I2C_Get_Interrupts_Status(&hi2c); // current flags
|
uint32_t interrupt_status = HAL_I2C_Get_Interrupts_Status(&(handler->i2c_param)); // current flags
|
||||||
|
|
||||||
// master calls by address, device in slave mode
|
// master calls by address, device in slave mode
|
||||||
if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M))
|
if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M))
|
||||||
{
|
{
|
||||||
// reset ADDR flag
|
// reset ADDR flag
|
||||||
HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_ADDRCF_M);
|
HAL_I2C_Reset_Interrupt_Flag(&(handler->i2c_param), I2C_ICR_ADDRCF_M);
|
||||||
|
|
||||||
// look at the transmission direction and respond to the request
|
// look at the transmission direction and respond to the request
|
||||||
if (interrupt_status & I2C_ISR_DIR_M) // master reads, slave sends
|
if (interrupt_status & I2C_ISR_DIR_M) // master reads, slave sends
|
||||||
twi_onSlaveTransmit(); // slave send data
|
{
|
||||||
|
// twi_onSlaveTransmit(); // slave send data
|
||||||
|
if (handler->onSlaveTransmit)
|
||||||
|
handler->onSlaveTransmit(handler->instance);
|
||||||
|
}
|
||||||
else // master writes, slave reads
|
else // master writes, slave reads
|
||||||
{
|
{
|
||||||
twi_rxBufferIndex = 0; // write from the beginning of the buffer
|
handler->rxBufferIndex = 0; // write from the beginning of the buffer
|
||||||
hi2c.State = HAL_I2C_STATE_BUSY;
|
handler->i2c_param.State = HAL_I2C_STATE_BUSY;
|
||||||
HAL_I2C_Clear_Reload(&hi2c);
|
HAL_I2C_Clear_Reload(&(handler->i2c_param));
|
||||||
// wait for interrupts by receiving a byte or a stop condition
|
// wait for interrupts by receiving a byte or a stop condition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,16 +321,16 @@ void __attribute__((optimize("O3"))) twi_interruptHandler(void)
|
|||||||
if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M))
|
if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M))
|
||||||
{
|
{
|
||||||
// put new byte into buffer
|
// put new byte into buffer
|
||||||
twi_rxBuffer[twi_rxBufferIndex++] = HAL_I2C_Get_RXDR(&hi2c);
|
handler->rxBuffer[handler->rxBufferIndex++] = HAL_I2C_Get_RXDR(&(handler->i2c_param));
|
||||||
}
|
}
|
||||||
|
|
||||||
// master sent a STOP to the bus
|
// master sent a STOP to the bus
|
||||||
if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M))
|
if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M))
|
||||||
{
|
{
|
||||||
hi2c.State = HAL_I2C_STATE_END;
|
handler->i2c_param.State = HAL_I2C_STATE_END;
|
||||||
HAL_I2C_Reset_TXDR_Content(&hi2c);
|
HAL_I2C_Reset_TXDR_Content(&(handler->i2c_param));
|
||||||
HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
HAL_I2C_Reset_Interrupt_Flag(&(handler->i2c_param), I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
||||||
// pass the received data to callback function
|
// pass the received data to callback function
|
||||||
twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
|
handler->onSlaveReceive(handler->instance, handler->rxBuffer, handler->rxBufferIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,10 +5,24 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "mik32_hal_i2c.h"
|
||||||
|
|
||||||
#ifndef TWI_BUFFER_LENGTH
|
#ifndef TWI_BUFFER_LENGTH
|
||||||
#define TWI_BUFFER_LENGTH 32
|
#define TWI_BUFFER_LENGTH 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
I2C_HandleTypeDef i2c_param;
|
||||||
|
uint8_t i2c_num;
|
||||||
|
bool isInited;
|
||||||
|
uint8_t rxBuffer[TWI_BUFFER_LENGTH];
|
||||||
|
volatile uint8_t rxBufferIndex;
|
||||||
|
void (*onSlaveTransmit)(void*);
|
||||||
|
void (*onSlaveReceive) (void*, uint8_t*, int);
|
||||||
|
void *instance;
|
||||||
|
}WireHandler_TypeDef;
|
||||||
|
|
||||||
// I2C state
|
// I2C state
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -21,17 +35,16 @@ typedef enum
|
|||||||
I2C_BUSY = 6
|
I2C_BUSY = 6
|
||||||
} i2c_status_e;
|
} i2c_status_e;
|
||||||
|
|
||||||
uint8_t twi_init(uint8_t slaveAddress);
|
uint8_t twi_init (WireHandler_TypeDef* handler, uint8_t slaveAddress);
|
||||||
void twi_deinit(void);
|
void twi_deinit(WireHandler_TypeDef* handler);
|
||||||
uint8_t twi_setFrequency(uint32_t frequency, bool onInit);
|
|
||||||
|
|
||||||
uint8_t twi_masterReadFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop);
|
uint8_t twi_setFrequency(WireHandler_TypeDef* handler, uint32_t frequency, bool onInit);
|
||||||
uint8_t twi_masterWriteTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop);
|
|
||||||
i2c_status_e twi_slaveWrite(uint8_t *txData, uint8_t bytesNum);
|
|
||||||
|
|
||||||
void twi_attachSlaveRxEvent(void (*function)(uint8_t*, int));
|
uint8_t twi_masterReadFrom (I2C_HandleTypeDef* hi2c, uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop);
|
||||||
void twi_attachSlaveTxEvent(void (*function)(void));
|
uint8_t twi_masterWriteTo (I2C_HandleTypeDef* hi2c, uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop);
|
||||||
void twi_interruptHandler(void);
|
i2c_status_e twi_slaveWrite (I2C_HandleTypeDef* hi2c, uint8_t *txData, uint8_t bytesNum);
|
||||||
|
|
||||||
|
void twi_interruptHandler(WireHandler_TypeDef* handler);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user