ready to alpha
подготовка к альфа-тестированию
This commit is contained in:
commit
e36b851783
164 files changed
+27352
No files matched your search
@@ -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( );
|
||||
Reference in new issue
Block a user