ready to alpha

подготовка к альфа-тестированию
This commit is contained in:
khristolyubov committed 2024-08-19 22:44:04 +07:00
commit e36b851783
164 files changed
+27352

No files matched your search

+318
View File
@@ -0,0 +1,318 @@
extern "C"
{
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "utility/twi.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 --------------------------- //
void TwoWire::begin(void)
{
rxBufferIndex = 0;
rxBufferLength = 0;
txBufferIndex = 0;
txBufferLength = 0;
twi_init(slaveAddress);
twi_attachSlaveTxEvent(onRequestService); // default callback must exist
twi_attachSlaveRxEvent(onReceiveService); // default callback must exist
}
void TwoWire::begin(uint8_t address)
{
slaveAddress = address;
begin();
}
void TwoWire::begin(int address)
{
begin((uint8_t)address);
}
void TwoWire::end(void)
{
flush(); // wait for transmission complete
twi_deinit();
slaveAddress = 0;
}
void TwoWire::setClock(uint32_t clock)
{
if (twi_setFrequency(clock, false) != I2C_OK)
ErrorMsgHandler("Wire.setClock(): invalid frequency or Wire was not begin");
}
// ----------------------------- request ----------------------------- //
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop)
{
if (isize > 0)
{
// send internal register address if needed
beginTransmission(address); // save slave address
// the maximum size of internal address is 3 bytes
if (isize > 3) isize = 3;
// write internal register address - most significant byte first
while (isize-- > 0)
write((uint8_t)(iaddress >> (isize*8))); // write data to txBuf
endTransmission(false); // transmit data without stop generation
}
// clamp to buffer length
if(quantity > BUFFER_LENGTH)
quantity = BUFFER_LENGTH;
// perform blocking read into buffer
uint8_t read = twi_masterReadFrom(address, rxBuffer, quantity, sendStop);
// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = read;
return read;
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)sendStop);
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
}
uint8_t TwoWire::requestFrom(int address, int quantity)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
}
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
}
// ----------------------------- Transmission ----------------------------- //
void TwoWire::beginTransmission(uint8_t address)
{
// indicate that we are transmitting
transmitting = 1;
// set address of targeted slave whithout shift
txAddress = address;
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
}
void TwoWire::beginTransmission(int address)
{
beginTransmission((uint8_t)address);
}
// Calling endTransmission(false) allows a sketch to
// perform a repeated start.
// WARNING: Nothing in the library keeps track of whether
// the bus tenure has been properly ended with a STOP. It
// is very possible to leave the bus in a hung state if
// no call to endTransmission(true) is made. Some I2C
// devices will behave oddly if they do not see a STOP.
uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
uint8_t ret = I2C_ERROR;
if (transmitting)
{
// transmit buffer (blocking)
ret = twi_masterWriteTo(txAddress, txBuffer, txBufferLength, sendStop);
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
// indicate that we are done transmitting
transmitting = 0;
}
return ret;
}
// This provides backwards compatibility with the original
// definition, and expected behaviour, of endTransmission
uint8_t TwoWire::endTransmission(void)
{
return endTransmission((uint8_t)true);
}
// ----------------------------- Write ----------------------------- //
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
size_t TwoWire::write(uint8_t data)
{
size_t ret = 1;
if (transmitting)
{
// in master transmitter mode
// don't bother if buffer is full
if(txBufferLength >= BUFFER_LENGTH)
{
setWriteError();
return 0;
}
// put byte in tx buffer
txBuffer[txBufferIndex] = data;
++txBufferIndex;
// update amount in buffer
txBufferLength = txBufferIndex;
}
else
{
// in slave send mode - reply to master
if (twi_slaveWrite(&data, 1) != I2C_OK)
ret = 0;
}
return ret;
}
/**
* @brief This function must be called in slave Tx event callback or after
* beginTransmission() and before endTransmission().
* @param pdata: pointer to the buffer data
* @param quantity: number of bytes to write
* @retval number of bytes ready to write.
*/
size_t TwoWire::write(const uint8_t *data, size_t quantity)
{
size_t ret = quantity;
if (transmitting)
{
// in master transmitter mode
for(size_t i = 0; i < quantity; ++i)
write(data[i]);
}
else
{
// in slave send mode - reply to master
if (twi_slaveWrite((uint8_t *)data, quantity) != I2C_OK)
ret = 0;
}
return ret;
}
// ----------------------------- Stream func ----------------------------- //
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::available(void)
{
return rxBufferLength - rxBufferIndex;
}
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::read(void)
{
int value = -1;
// get each successive byte on each call
if (rxBufferIndex < rxBufferLength)
{
value = rxBuffer[rxBufferIndex];
++rxBufferIndex;
}
return value;
}
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::peek(void)
{
int value = -1;
if (rxBufferIndex < rxBufferLength)
value = rxBuffer[rxBufferIndex];
return value;
}
void TwoWire::flush(void)
{
// we use blocking transactions, so we won't get here until the reception/transmission is complete
rxBufferIndex = 0;
rxBufferLength = 0;
txBufferIndex = 0;
txBufferLength = 0;
txAddress = 0;
}
// ----------------------------- Events ----------------------------- //
// behind the scenes function that is called when data is received
void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
{
// don't bother if user hasn't registered a callback
if(!user_onReceive)
return;
// copy twi rx buffer into local read buffer
// this enables new reads to happen in parallel
memcpy(rxBuffer, inBytes, numBytes);
// set rx iterator vars
rxBufferIndex = 0;
rxBufferLength = numBytes;
// alert user program
user_onReceive(numBytes);
}
// behind the scenes function that is called when data is requested
void TwoWire::onRequestService(void)
{
// don't bother if user hasn't registered a callback
if(user_onRequest)
user_onRequest(); // alert user program
}
// sets function called on slave write
void TwoWire::onReceive( void (*function)(int) )
{
user_onReceive = function;
}
// sets function called on slave read
void TwoWire::onRequest( void (*function)(void) )
{
user_onRequest = function;
}
// С function for trap handler
extern "C" void wire_handler_wrapper(void)
{
twi_interruptHandler();
}
// ----------------------------- Preinstantiate Objects ----------------------------- //
TwoWire Wire = TwoWire( );
+69
View File
@@ -0,0 +1,69 @@
#ifndef TwoWire_h
#define TwoWire_h
#include "Stream.h"
#include "Arduino.h"
#define BUFFER_LENGTH 32
// WIRE_HAS_END means Wire has end()
#define WIRE_HAS_END 1
class TwoWire : public Stream
{
private:
static uint8_t rxBuffer[];
static uint8_t rxBufferIndex;
static uint8_t rxBufferLength;
static uint8_t txAddress;
static uint8_t txBuffer[];
static uint8_t txBufferIndex;
static uint8_t txBufferLength;
static uint8_t transmitting;
static uint8_t slaveAddress;
static void (*user_onRequest)(void);
static void (*user_onReceive)(int numBytes);
static void onRequestService(void);
static void onReceiveService(uint8_t* inBytes, int numBytes);
public:
TwoWire();
void begin();
void begin(uint8_t);
void begin(int);
void end();
void setClock(uint32_t frequency);
void beginTransmission(uint8_t address);
void beginTransmission(int address);
uint8_t endTransmission(void);
uint8_t endTransmission(uint8_t sendStop);
uint8_t requestFrom(uint8_t address, uint8_t quantity);
uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop);
uint8_t requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop);
uint8_t requestFrom(int address, int quantity);
uint8_t requestFrom(int address, int quantity, int sendStop);
virtual int available(void);
virtual int read(void);
virtual int peek(void);
virtual void flush(void);
virtual size_t write(uint8_t data);
virtual size_t write(const uint8_t * data, size_t quantity);
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
using Print::write;
void onReceive( void (*)(int) );
void onRequest( void (*)(void) );
};
extern TwoWire Wire;
#endif
+384
View File
@@ -0,0 +1,384 @@
#include <stdlib.h>
#include <inttypes.h>
#include "Arduino.h"
#include "twi.h"
#include "mik32_hal_i2c.h"
#include "mik32_hal_irq.h"
#define TIMEOUT_TICKS 1000000
#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
* Desc readys twi pins and sets twi bitrate
* Input slaveAddress - address of Arduino if working in slave mode
* Output none
*/
uint8_t twi_init(uint8_t slaveAddress)
{
// Common settings
uint32_t EPICmask;
#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
hi2c.Init.DigitalFilter = I2C_DIGITALFILTER_2CLOCKCYCLES;
hi2c.Init.AnalogFilter = I2C_ANALOGFILTER_DISABLE;
if (slaveAddress == 0) // if there is no address - master mode
{
hi2c.Init.Mode = HAL_I2C_MODE_MASTER;
hi2c.Init.AutoEnd = I2C_AUTOEND_ENABLE;
}
else
{
// 7-bit address without any additional bits
hi2c.Init.Mode = HAL_I2C_MODE_SLAVE;
hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; // stretch is used
hi2c.Init.OwnAddress1 = slaveAddress;
}
// set the frequency
if (hi2c.Init.Mode == HAL_I2C_MODE_MASTER)
twi_setFrequency(CurrentFrequency, true);
else
twi_setFrequency(0, true);
if (HAL_I2C_Init(&hi2c) != HAL_OK)
return I2C_ERROR;
// enable interrupts for slave mode
if (hi2c.Init.Mode == HAL_I2C_MODE_SLAVE)
{
// enable interrupts for addressing, byte reception and transfer completion
HAL_I2C_InterruptDisable(&hi2c, I2C_INTMASK);
HAL_I2C_InterruptEnable(&hi2c, I2C_CR1_ADDRIE_M | I2C_CR1_RXIE_M | I2C_CR1_STOPIE_M);
// enable interrupt from i2c
HAL_EPIC_MaskLevelSet(EPICmask);
}
twiIsOn = true;
return I2C_OK;
}
/*
* Function twi_deinit
* Desc disables twi pins
* Input none
* Output none
*/
void twi_deinit(void)
{
uint32_t EPICmask;
HAL_I2C_Disable(&hi2c);
// disable clock
#if I2C_NUM == 0
hi2c.Instance = I2C_0;
EPICmask = HAL_EPIC_I2C_0_MASK;
__HAL_PCC_I2C_0_CLK_DISABLE();
#elif I2C_NUM == 1
hi2c.Instance = I2C_1;
EPICmask = HAL_EPIC_I2C_1_MASK;
__HAL_PCC_I2C_1_CLK_DISABLE();
#else
#error "Unsupported I2C_NUM value in pins_arduino.h"
#endif
// for slave mode disable interrupts from i2c
if (hi2c.Init.Mode == HAL_I2C_MODE_SLAVE)
HAL_EPIC_MaskLevelClear(EPICmask);
// reconfigure pins to z state
GPIO_InitTypeDef GPIO_InitStruct;
memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct));
// SDA
GPIO_InitStruct.Pin = (HAL_PinsTypeDef)digitalPinToBitMask(PIN_WIRE_SDA);
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(digitalPinToPort(PIN_WIRE_SDA), &GPIO_InitStruct);
// SCL
GPIO_InitStruct.Pin = (HAL_PinsTypeDef)digitalPinToBitMask(PIN_WIRE_SCL);
HAL_GPIO_Init(digitalPinToPort(PIN_WIRE_SCL), &GPIO_InitStruct);
twiIsOn = false;
}
/*
* Function twi_setClock
* Desc sets twi bit rate
* Input Clock Frequency - 100000 / 400000 / 1000000,
* onInit = true only if function is called from twi_init()
* Output I2C_OK - frequency changed, I2C_ERROR - frequency didn't change
*/
uint8_t twi_setFrequency(uint32_t frequency, bool onInit)
{
uint8_t ret = I2C_OK;
// change the frequency only during or after bus initialization
if (twiIsOn || onInit)
{
// You can change the frequency only when the interface is turned off
HAL_I2C_Disable(&hi2c);
if (frequency == WIRE_FREQ_100K) // 100 kHz
{
hi2c.Clock.PRESC = 2;
hi2c.Clock.SCLDEL = 8;
hi2c.Clock.SDADEL = 2;
hi2c.Clock.SCLH = 49;
hi2c.Clock.SCLL = 49;
CurrentFrequency = WIRE_FREQ_100K;
}
else if (frequency == WIRE_FREQ_400K) // 400 kHz
{
hi2c.Clock.PRESC = 0;
hi2c.Clock.SCLDEL = 3;
hi2c.Clock.SDADEL = 2;
hi2c.Clock.SCLH = 30;
hi2c.Clock.SCLL = 30;
CurrentFrequency = WIRE_FREQ_400K;
}
else if (frequency == WIRE_FREQ_1000K)// 1000 kHz
{
hi2c.Clock.PRESC = 0;
hi2c.Clock.SCLDEL = 1;
hi2c.Clock.SDADEL = 2;
hi2c.Clock.SCLH = 6;
hi2c.Clock.SCLL = 6;
CurrentFrequency = WIRE_FREQ_1000K;
}
else if (frequency == 0) // slave mode
{
hi2c.Clock.PRESC = 0;
hi2c.Clock.SCLDEL = 0;
hi2c.Clock.SDADEL = 2;
hi2c.Clock.SCLH = 0;
hi2c.Clock.SCLL = 0;
}
else
// frequency does not change
ret = I2C_ERROR;
// write the timings to the register if everything is OK
if (ret == I2C_OK)
HAL_I2C_SetClockSpeed(&hi2c);
//turn the interface back only if initialization has already passed
if (twiIsOn)
HAL_I2C_Enable(&hi2c);
}
else
ret = I2C_ERROR;
return ret;
}
/*
* Function twi_masterReadFrom
* Desc attempts to become twi bus master and read a
* series of bytes from a device on the bus
* Input address: 7bit i2c device address
* data: pointer to byte array
* length: number of bytes to read into array
* sendStop: Boolean indicating whether to send a stop at the end
* Output number of bytes read
*/
uint8_t twi_masterReadFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
{
uint8_t ret = 0;
// if there are errors left from previous transactions, you need to restart
// the interface for correct operation
if (hi2c.ErrorCode != I2C_ERROR_NONE)
HAL_I2C_Reset(&hi2c);
if (sendStop) hi2c.Init.AutoEnd = 1;
else hi2c.Init.AutoEnd = 0;
// put the data directly into the external buffer
if (HAL_I2C_Master_Receive(&hi2c, address, data, length, TIMEOUT_TICKS) == HAL_OK)
ret = length;
return ret;
}
/*
* Function twi_masterWriteTo
* Desc attempts to become twi bus master and write a
* series of bytes to a device on the bus
* Input address: 7bit i2c device address
* data: pointer to byte array
* length: number of bytes in array
* sendStop: boolean indicating whether or not to send a stop at the end
* Output 0 .. success
* 1 .. length to long for buffer
* 2 .. address send, NACK received
* 3 .. data send, NACK received
* 4 .. other twi error (lost bus arbitration, bus error, ..)
* 5 .. timeout
*/
uint8_t twi_masterWriteTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
{
uint8_t ret = I2C_OK;
// if there are errors left from previous transactions, you need to restart
// the interface for correct operation
if (hi2c.ErrorCode != I2C_ERROR_NONE)
HAL_I2C_Reset(&hi2c);
if (sendStop) hi2c.Init.AutoEnd = 1;
else hi2c.Init.AutoEnd = 0;
// take data from an external buffer
HAL_I2C_Master_Transmit(&hi2c, address, data, length, TIMEOUT_TICKS);
// parse errors
// check separately, because in hal libraries not all functions look at this
if (hi2c.Instance->ISR & I2C_ISR_NACKF_M)
hi2c.ErrorCode = I2C_ERROR_NACK;
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_OK) ret = I2C_ERROR; // any other error
return ret;
}
/*
* Function twi_slaveWrite
* Desc attempts to become twi bus slave and write a
* series of bytes to a master after it asks
* Input txData: pointer to byte array
* bytesNum: number of bytes in array
* Output 0 .. success
* 5 .. timeout
*/
i2c_status_e twi_slaveWrite(uint8_t *txData, uint8_t bytesNum)
{
if ((hi2c.ErrorCode != I2C_ERROR_NONE))
HAL_I2C_Reset(&hi2c);
// отправка данных
HAL_StatusTypeDef error_code = HAL_OK;
hi2c.Instance->CR2 &= ~I2C_CR2_RELOAD_M;
if (!(hi2c.Instance->CR1 & I2C_CR1_NOSTRETCH_M)) // NOSTRETCH = 0
hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents
hi2c.Instance->TXDR = txData[0]; // The first recording is made in advance
// Запись байта
for (uint32_t tx_count = 1; tx_count < bytesNum; tx_count++)
{
if ((error_code = HAL_I2C_Slave_WaitTXIS(&hi2c, TIMEOUT_TICKS)) != HAL_OK)
{
// неудачная запись
hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents
hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus
HAL_I2C_Reset(&hi2c);
return I2C_TIMEOUT;
}
hi2c.Instance->TXDR = txData[tx_count];
}
if ((error_code = HAL_I2C_WaitBusy(&hi2c, TIMEOUT_TICKS)) != HAL_OK)
{
// неудачное завершение транзакции
HAL_I2C_Reset(&hi2c);
return I2C_TIMEOUT;
}
hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents
hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus
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
* Desc handles an interrupts from twi
* Input none
* Output none
*/
void twi_interruptHandler(void)
{
uint32_t int_mask = hi2c.Instance->CR1 & I2C_INTMASK; // interrupts allowed
uint32_t interrupt_status = hi2c.Instance->ISR; // current flags
// master calls by address, device in slave mode
if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M))
{
// reset ADDR flag
hi2c.Instance->ICR |= I2C_ICR_ADDRCF_M;
// look at the transmission direction and respond to the request
if (interrupt_status & I2C_ISR_DIR_M) // master reads, slave sends
// отправляем данные
twi_onSlaveTransmit();
else // master writes, slave reads
{
twi_rxBufferIndex = 0; // write from the beginning of the buffer
hi2c.State = HAL_I2C_STATE_BUSY;
hi2c.Instance->CR2 &= ~I2C_CR2_RELOAD_M;
// wait for interrupts because of receiving a byte or a stop condition
}
}
// new byte of data received
if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M))
{
// put new byte into buffer
twi_rxBuffer[twi_rxBufferIndex++] = (uint8_t)hi2c.Instance->RXDR;
}
// master sent a STOP to the bus
if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M))
{
hi2c.State = HAL_I2C_STATE_END;
hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents
hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus
// pass the received data to callback function
twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
}
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef __TWI_H__
#define __TWI_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TWI_BUFFER_LENGTH
#define TWI_BUFFER_LENGTH 32
#endif
// I2C state
typedef enum
{
I2C_OK = 0,
I2C_DATA_TOO_LONG = 1,
I2C_NACK_ADDR = 2,
I2C_NACK_DATA = 3,
I2C_ERROR = 4,
I2C_TIMEOUT = 5,
I2C_BUSY = 6
} i2c_status_e;
uint8_t twi_init(uint8_t slaveAddress);
void twi_deinit(void);
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_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));
void twi_attachSlaveTxEvent(void (*function)(void));
void twi_interruptHandler(void);
#ifdef __cplusplus
}
#endif
#endif /* __TWI_H__ */