From b24866225a6301d3a663f874725e83c012dc25d3 Mon Sep 17 00:00:00 2001 From: Florent Duchon Date: Wed, 26 Dec 2012 17:36:00 +0100 Subject: digital/beacon: add bitcloud stack into common directory digital/zigbit --- .../Components/HAL/avr/common/src/i2cPacket.c | 371 +++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c (limited to 'digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c') diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c new file mode 100644 index 00000000..340981e1 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c @@ -0,0 +1,371 @@ +/**************************************************************************//** + \file i2cPacket.c + + \brief Provides the functionality for the writing and the reading \n + of packets through the TWI. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 5/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +/* states of the i2c transaction */ +#define I2C_CLOSE 0 +#define I2C_IDLE 1 +#define I2C_WRITE_IADDR_WRITE_DATA 2 +#define I2C_WRITE_IADDR_READ_DATA 3 +#define I2C_WRITE_DATA 4 +#define I2C_READ_DATA 5 +#define I2C_TRANSAC_SUCCESS 6 +#define I2C_TRANSAC_FAIL 7 + +/****************************************************************************** + Types section +******************************************************************************/ +typedef struct +{ + volatile uint8_t* data; // bytes to write to the i2c bus + volatile uint8_t length; // length in bytes of the request + volatile uint8_t index; // current index of read/write byte + volatile uint8_t addr; // destination address + volatile uint32_t intAddress; // internal address inner i2c device + void (*done)(bool result); // callback +} HalI2cPacketControl_t; + +/****************************************************************************** + Global variables section +******************************************************************************/ +// current state of the i2c request +volatile uint8_t halI2cPacketState = I2C_CLOSE; +HalI2cPacketControl_t halI2cPacketControl; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +Resets TWI bus and i2c HAL. +******************************************************************************/ +void halI2cBusReset(void) +{ + halI2cPacketState = I2C_TRANSAC_FAIL; + halResetI2c(); + halPostTask4(HAL_TWI); +} + +/****************************************************************************** +Opens resource. +Parameters: + i2cMode - pointer to clock rate structure. +Returns: + Returns: + -1 - resource was opened or pointer is NULL + 0 - success. +******************************************************************************/ +int HAL_OpenI2cPacket(HAL_i2cMode_t *i2cMode) +{ + if (NULL == i2cMode) + return -1; + if (I2C_CLOSE == halI2cPacketState) + { + halInitI2c(i2cMode); + halI2cPacketState = I2C_IDLE; + halI2cPacketControl.index = 0; + return 0; + } + return -1; +} + +/****************************************************************************** +Closes resource. +Returns: + -1 - resource was not opened. + 0 - success. +******************************************************************************/ +int HAL_CloseI2cPacket(void) +{ + if (I2C_CLOSE != halI2cPacketState) + { + halI2cPacketControl.done = NULL; + halI2cPacketState = I2C_CLOSE; + return 0; + } + return -1; +} + +/****************************************************************************** +Writes the series of bytes out to the TWI bus. +Parameters: + param - pointer to HAL_I2cParams_t structure +Returns: + 0 - the bus is free and the request is accepted. + -1 - other case. +******************************************************************************/ +int HAL_WriteI2cPacket(HAL_I2cParams_t *param) +{ + if ((I2C_IDLE == halI2cPacketState) && param) + { + halI2cPacketControl.addr = param->id; + halI2cPacketControl.data = param->data; + halI2cPacketControl.index = param->lengthAddr; + halI2cPacketControl.length = param->length; + halI2cPacketControl.done = param->f; + halI2cPacketControl.intAddress = param->internalAddr; + } + else + { + return -1; + } + + if (HAL_NO_INTERNAL_ADDRESS == halI2cPacketControl.index) + halI2cPacketState = I2C_WRITE_DATA; + else + halI2cPacketState = I2C_WRITE_IADDR_WRITE_DATA; + halSendStartI2c(); + return 0; +} + +/****************************************************************************** +Reads the series of bytes out to the TWI bus. +Parameters: + param - pointer to HAL_I2cParams_t structure +Returns: + 0 - the bus is free and the request is accepted. + -1 - other case. +******************************************************************************/ +int HAL_ReadI2cPacket(HAL_I2cParams_t *param) +{ + if ((I2C_IDLE == halI2cPacketState) && param) + { + halI2cPacketControl.addr = param->id; + halI2cPacketControl.index = param->lengthAddr; + halI2cPacketControl.length = param->length; + halI2cPacketControl.data = param->data; + halI2cPacketControl.done = param->f; + halI2cPacketControl.intAddress = param->internalAddr; + } + else + { + return -1; + } + + if (HAL_NO_INTERNAL_ADDRESS == halI2cPacketControl.index) + halI2cPacketState = I2C_READ_DATA; + else + halI2cPacketState = I2C_WRITE_IADDR_READ_DATA; + halSendStartI2c(); + return 0; +} + +/****************************************************************************** +Notification about the start condition was sent. +Parameters: + none. +Returns: + none. +******************************************************************************/ +void halSendStartDoneI2c(void) +{ + if ((I2C_WRITE_IADDR_WRITE_DATA == halI2cPacketState) || + (I2C_WRITE_IADDR_READ_DATA == halI2cPacketState) || + (I2C_WRITE_DATA == halI2cPacketState)) + { + halWriteI2c(((halI2cPacketControl.addr << 1) + 0)); + } + else if (I2C_READ_DATA == halI2cPacketState) + { + halWriteI2c(((halI2cPacketControl.addr << 1) + 1)); + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Sending data to i2c bus. If last byte then send stop condition and post task. +Parameters: + none. +Returns: + none. +******************************************************************************/ +void halWriteData(void) +{ + if (halI2cPacketControl.index < halI2cPacketControl.length) + { + halWriteI2c(halI2cPacketControl.data[halI2cPacketControl.index++]); + } + else + { + halI2cPacketState = I2C_TRANSAC_SUCCESS; + halSendStopI2c(); + halPostTask4(HAL_TWI); + } +} + +/****************************************************************************** +Sending internal device address to i2c bus. If address is sent then switch i2c +hal state. +Parameters: + none. +Returns: + none. +******************************************************************************/ +void halWriteInternalAddress(void) +{ + uint8_t data; + + data = (uint8_t)(halI2cPacketControl.intAddress >> --halI2cPacketControl.index * 8); + halWriteI2c(data); + + if (0 == halI2cPacketControl.index) + { + if (I2C_WRITE_IADDR_WRITE_DATA == halI2cPacketState) + halI2cPacketState = I2C_WRITE_DATA; + else + halI2cPacketState = I2C_READ_DATA; + } +} + +/****************************************************************************** +Notification that byte was written to the TWI. +Parameters: + result - contains result of previous operation. +Returns: + none. +******************************************************************************/ +void halWriteDoneI2c(void) +{ + if (I2C_WRITE_DATA == halI2cPacketState) + { + halWriteData(); + } + else if ((I2C_WRITE_IADDR_WRITE_DATA == halI2cPacketState) || (I2C_WRITE_IADDR_READ_DATA == halI2cPacketState)) + { + halWriteInternalAddress(); + } + else if (I2C_READ_DATA == halI2cPacketState) + { + halSendStartI2c(); + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Notification that address byte was written to the TWI and was read ACK. +Starts reading data. +Parameters: + none. +Returns: + none. +******************************************************************************/ +void halMasterReadWriteAddressAckI2c(void) +{ + if (I2C_READ_DATA == halI2cPacketState) + { + if (1 == halI2cPacketControl.length) + halReadI2c(false); // send nack + else + halReadI2c(true); // send ack + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Notification that byte was read from the TWI. +Parameters: + data - contains byte that was read. +Returns: + none. +******************************************************************************/ +void halReadDoneI2c(uint8_t data) +{ + if (I2C_READ_DATA == halI2cPacketState) + { + halI2cPacketControl.data[halI2cPacketControl.index++] = data; + if (halI2cPacketControl.index < (halI2cPacketControl.length - 1)) + halReadI2c(true); // send ACK + else + halReadI2c(false); // send NACK + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Notification that last byte was read from the TWI. Needs send STOP condition +on bus. +Parameters: + data - contains byte that was read. +Returns: + none. +******************************************************************************/ +void halReadLastByteDoneI2c(uint8_t data) +{ + if (I2C_READ_DATA == halI2cPacketState) + { + halI2cPacketControl.data[halI2cPacketControl.index++] = data; + halI2cPacketState = I2C_TRANSAC_SUCCESS; + halSendStopI2c(); + halPostTask4(HAL_TWI); + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Waits for end of sending and calls user's callback +******************************************************************************/ +void halSig2WireSerialHandler(void) +{ + if (halI2cPacketControl.done) + { + if (I2C_TRANSAC_SUCCESS == halI2cPacketState) + { + halWaitEndOfStopStation(); + halI2cPacketState = I2C_IDLE; + halI2cPacketControl.done(true); + } + else + { + halI2cPacketState = I2C_IDLE; + halI2cPacketControl.done(false); + } + } + else + { + halI2cPacketState = I2C_IDLE; + } +} +// eof i2cPacket.c -- cgit v1.2.3