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( );