From f1b1bacb52777dced4f53563b4a30fc31940ca7d Mon Sep 17 00:00:00 2001 From: r-studio Date: Thu, 22 Apr 2010 13:12:00 +0000 Subject: [PATCH] Fixed a bug in the Software I2C. The first time a start condition was sent the clock pin was not configurated correctly. Also added a low-power pin configuration. --- .../mulle/chips/ds2782/DS2782InternalC.nc | 3 +- .../mulle/chips/ds2782/DS2782InternalP.nc | 10 +- tos/platforms/mulle/hardware.h | 4 + tos/platforms/mulle/pin_configuration.h | 218 ++++++++ .../mulle/softwarei2c/SoftwareI2CPacketC.nc | 529 +++++++++--------- 5 files changed, 492 insertions(+), 272 deletions(-) create mode 100644 tos/platforms/mulle/pin_configuration.h diff --git a/tos/platforms/mulle/chips/ds2782/DS2782InternalC.nc b/tos/platforms/mulle/chips/ds2782/DS2782InternalC.nc index 0041b06f..6c3063c0 100644 --- a/tos/platforms/mulle/chips/ds2782/DS2782InternalC.nc +++ b/tos/platforms/mulle/chips/ds2782/DS2782InternalC.nc @@ -57,7 +57,6 @@ implementation HplDS2782 = Logic; StdControl = Logic; - DS2782InternalP.SDA -> IOs.PortP70; - DS2782InternalP.SCL -> IOs.PortP71; + DS2782InternalP.Pullup -> IOs.PortP75; DS2782InternalP.ResourceDefaultOwner -> I2C; } diff --git a/tos/platforms/mulle/chips/ds2782/DS2782InternalP.nc b/tos/platforms/mulle/chips/ds2782/DS2782InternalP.nc index 5d2b7cbc..6db69919 100644 --- a/tos/platforms/mulle/chips/ds2782/DS2782InternalP.nc +++ b/tos/platforms/mulle/chips/ds2782/DS2782InternalP.nc @@ -44,26 +44,24 @@ module DS2782InternalP { uses interface ResourceDefaultOwner; - uses interface GeneralIO as SDA; - uses interface GeneralIO as SCL; + uses interface GeneralIO as Pullup; } implementation { async event void ResourceDefaultOwner.granted() { - call SDA.clr(); - call SDA.makeOutput(); - call SCL.clr(); - call SCL.makeOutput(); + call Pullup.clr(); } async event void ResourceDefaultOwner.requested() { + call Pullup.set(); call ResourceDefaultOwner.release(); } async event void ResourceDefaultOwner.immediateRequested() { + call Pullup.set(); call ResourceDefaultOwner.release(); } } diff --git a/tos/platforms/mulle/hardware.h b/tos/platforms/mulle/hardware.h index e2c63166..5da8a586 100755 --- a/tos/platforms/mulle/hardware.h +++ b/tos/platforms/mulle/hardware.h @@ -51,6 +51,10 @@ You should not remove this fix unless you are totaly sure of what you are doing! #endif +#ifdef ENABLE_STOP_MODE +#include "pin_configuration.h" +#endif + #include "m16c62phardware.h" // Header file for the MCU #endif // __HARDWARE_H__ diff --git a/tos/platforms/mulle/pin_configuration.h b/tos/platforms/mulle/pin_configuration.h new file mode 100644 index 00000000..8bae1b68 --- /dev/null +++ b/tos/platforms/mulle/pin_configuration.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2009 Communication Group and Eislab at + * Lulea University of Technology + * + * Contact: Laurynas Riliskis, LTU + * Mail: laurynas.riliskis@ltu.se + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * - Neither the name of Communication Group at Lulea University of Technology + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD + * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Inactive pin states on Mulle. + * + * @author Henrik Makitaavola + */ + +#ifndef __PIN_CONFIGURATION_H__ +#define __PIN_CONFIGURATION_H__ + +//P00/D0/AN10 +//P01/D1/AN11 +//P02/D2/AN12 +//P03/D3/AN13 +//P04/D4/AN14 +//P05/D5/AN15 +//P06/D6/AN16 +//P07/D7/AN17 - Radio.SLP_TR +#define PORT_P0_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + +//P10/D8 RADIO.MISO (INPUT) +//P11/D9 RADIO.MOSI +//P12/D10 Accel.SLEEP_MODE +//P13/D11 +//P14/D12 +//P15/D13/INT3 +//P16/D14/INT4 +//P17/D15/INT5 +#define PORT_P1_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + +#define PORT_P2_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + +//P30 Accel.GS1 +//P31 Accel.GS2 +//P32/A10 Flash.EN +//P33/A11 Radio.SCLK +//P34/A12 Ext. LED +//P35/A13 Radio.SEL (HIGH) +//P36/A14 Red LED +//P37/A14 Green LED +#define PORT_P3_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_HIGH,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + +//P40/A16 Flash.SO +//P41/A17 Flash.SI +//P42/A18 Flash.SCK +//P43/A19 Radio.RST (HIGH) +//P44/CS0 Flash.WP +//P45/CS1 Flash.CS +//P46/CS2 Flash.RESET +//P47/CS3 RTC.CLKOE +#define PORT_P4_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + +#define PORT_P5_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_INPUT,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_INPUT,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + + +//P62/RXD0 UART0.TXD +//P63/TXD0 UART0.RXD +//P66/RXD1 UART1.TXD +//P67/TXD1 UART1.RXD +#define PORT_P6_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + +//P70/TXD2/SDA2 UART2.TXD +//P71/RDX2/SCK2 UART2.TXD +//P72/TA1OUT +//P74/TA2OUT +//P75 Vcc for I2C (must be pulled high before the I2C bus can be used) +//P76 Accel VCC +//P77 Radio VCC (HIGH) +#define PORT_P7_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + + +//P80/TA4OUT H1.47 ; IC1.P97/ADTRG +//P81/TA4IN +//P82/INT0 RTC.CLKOUT +//P83/INT1 RADIO.IRQ (INPUT) +//P84/INT2 RTC.INT +//P85/NMI pulled high through resistor +//P87/XCIN RTC.CLKOUT +#define PORT_P8_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_INPUT,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_INPUT,\ + M16C_PIN_INACTIVE_INPUT,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_INPUT) + +//P90/TB0IN RTC.CLKOUT +//P91 +//P92/TB2IN RTC.CLKOUT +//P93/DA0/TB3IN +//P94/DA1/TB4IN +//P95/ANEX0 +//P96/ANEX1 +//P97/ADTRG +#define PORT_P9_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_INPUT,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_INPUT,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_INPUT) + +//P100/AN00 +//P101/AN01 +//P102/AN02 +//P103/AN03 - Accel.Z +//P104/AN04 - Accel.Y +//P105/AN05 - Accel.X +//P106/AN06 +//P107/AN07 +#define PORT_P_10_INACTIVE_STATE M16C_PORT_INACTIVE_STATE(M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW,\ + M16C_PIN_INACTIVE_OUTPUT_LOW) + + + + + + +#endif //__PIN_CONFIGURATION_H__ diff --git a/tos/platforms/mulle/softwarei2c/SoftwareI2CPacketC.nc b/tos/platforms/mulle/softwarei2c/SoftwareI2CPacketC.nc index bb2a9cd9..1a6904ad 100644 --- a/tos/platforms/mulle/softwarei2c/SoftwareI2CPacketC.nc +++ b/tos/platforms/mulle/softwarei2c/SoftwareI2CPacketC.nc @@ -48,282 +48,283 @@ */ generic module SoftwareI2CPacketC(int speed) { - provides interface I2CPacket; - - uses interface GeneralIO as SDA; - uses interface GeneralIO as SCL; - uses interface BusyWait; + provides interface I2CPacket; + + uses interface GeneralIO as SDA; + uses interface GeneralIO as SCL; + uses interface BusyWait; } implementation { - enum + enum + { + S_IDLE, + S_BUSY, + }; + + uint8_t m_state = S_IDLE; + uint16_t m_addr; + uint8_t m_length; + uint8_t* m_data; + error_t m_error; + bool m_read; + + uint8_t READSDA() + { + call SDA.makeInput(); + return call SDA.get(); + } + + uint8_t READSCL() + { + call SCL.makeInput(); + return call SCL.get(); + } + + void CLRSCL() + { + call SCL.clr(); + call SCL.makeOutput(); + } + + void CLRSDA() + { + call SDA.clr(); + call SDA.makeOutput(); + } + + void i2cDelay(uint16_t u) { + call BusyWait.wait(u); + } + + uint8_t i2cReadBit(void) + { + uint8_t bit; + + /* lets the slave drive data */ + READSDA(); + i2cDelay(speed/2); + /* Clock stretching */ + while (READSCL() == 0); + /* SCL is high, now data is valid */ + bit = READSDA(); + i2cDelay(speed/2); + CLRSCL(); + return bit; + } + + error_t i2cWriteBit(bool bit) + { + if (bit) + READSDA(); + else + CLRSDA(); + i2cDelay(speed/2); + /* Clock stretching */ + while (READSCL() == 0); + /* SCL is high, now data is valid */ + /* check that nobody is driving SDA */ + if (bit && READSDA() == 0) + return FAIL; + i2cDelay(speed/2); + CLRSCL(); + return SUCCESS; + } + + error_t i2cStartCond(void) + { + READSCL(); + if (READSDA() == 0) + return FAIL; + /* SCL is high, set SDA from 1 to 0 */ + CLRSDA(); + i2cDelay(speed/2); + CLRSCL(); + return SUCCESS; + } + + error_t i2cStopCond(void) + { + /* set SDA to 0 */ + CLRSDA(); + i2cDelay(speed/2); + /* Clock stretching */ + while (READSCL() == 0); + /* SCL is high, set SDA from 0 to 1 */ + if (READSDA() == 0) + return FAIL; + i2cDelay(speed/2); + return SUCCESS; + } + + error_t i2cTx(uint8_t byte) + { + uint8_t bit; + uint8_t ack; + error_t error = SUCCESS; + + for (bit = 0; bit < 8; bit++) { + error = ecombine(error, i2cWriteBit(byte & 0x80)); + byte <<= 1; + } + + // The ack bit is 0 for success + if (!i2cReadBit()) + { + return ecombine(error, SUCCESS); + } + else + { + return FAIL; + } + } + + uint8_t i2cRx (bool nack) + { + uint8_t byte = 0; + uint8_t bit; + + for (bit = 0; bit < 8; bit++) { + byte <<= 1; + byte |= i2cReadBit(); + } + i2cWriteBit(nack); + return byte; + } + + task void signalTask() + { + uint16_t addr; + uint8_t length; + uint8_t* data; + error_t error; + bool read; + atomic + { + addr = m_addr; + length = m_length; + data = m_data; + error = m_error; + m_state = S_IDLE; + read = m_read; + } + if (read) + { + signal I2CPacket.readDone(error, addr, length, data); + } + else + { + signal I2CPacket.writeDone(error, addr, length, data); + } + } + + async command error_t I2CPacket.read(i2c_flags_t flags, uint16_t addr, uint8_t length, uint8_t* data) + { + uint8_t i; + error_t error = SUCCESS; + + // Both I2C_STOP and I2C_ACK_END flags are not allowed at the same time. + if ((flags & I2C_STOP) && (flags & I2C_ACK_END)) + { + return EINVAL; + } + + atomic { - S_IDLE, - S_BUSY, - }; - - uint8_t m_state = S_IDLE; - uint16_t m_addr; - uint8_t m_length; - uint8_t* m_data; - error_t m_error; - bool m_read; - - uint8_t READSDA() - { - call SDA.makeInput(); - return call SDA.get(); - } - - uint8_t READSCL() - { - call SCL.makeInput(); - return call SCL.get(); - } - - void CLRSCL() - { - call SCL.clr(); - call SCL.makeOutput(); - } - - void CLRSDA() - { - call SDA.clr(); - call SDA.makeOutput(); - } - - void i2cDelay(uint16_t u) { - call BusyWait.wait(u); - } - - uint8_t i2cReadBit(void) - { - uint8_t bit; - - /* lets the slave drive data */ - READSDA(); - i2cDelay(speed/2); - /* Clock stretching */ - while (READSCL() == 0); - /* SCL is high, now data is valid */ - bit = READSDA(); - i2cDelay(speed/2); - CLRSCL(); - return bit; - } - - error_t i2cWriteBit(bool bit) - { - if (bit) - READSDA(); - else - CLRSDA(); - i2cDelay(speed/2); - /* Clock stretching */ - while (READSCL() == 0); - /* SCL is high, now data is valid */ - /* check that nobody is driving SDA */ - if (bit && READSDA() == 0) - return FAIL; - i2cDelay(speed/2); - CLRSCL(); - return SUCCESS; - } - - error_t i2cStartCond(void) - { - if (READSDA() == 0) - return FAIL; - /* SCL is high, set SDA from 1 to 0 */ - CLRSDA(); - i2cDelay(speed/2); - CLRSCL(); - return SUCCESS; - } - - error_t i2cStopCond(void) - { - /* set SDA to 0 */ - CLRSDA(); - i2cDelay(speed/2); - /* Clock stretching */ - while (READSCL() == 0); - /* SCL is high, set SDA from 0 to 1 */ - if (READSDA() == 0) - return FAIL; - i2cDelay(speed/2); - return SUCCESS; - } - - error_t i2cTx(uint8_t byte) - { - uint8_t bit; - uint8_t ack; - error_t error = SUCCESS; - - for (bit = 0; bit < 8; bit++) { - error = ecombine(error, i2cWriteBit(byte & 0x80)); - byte <<= 1; - } - - // The ack bit is 0 for success - if (!i2cReadBit()) - { - return ecombine(error, SUCCESS); - } - else - { - return FAIL; - } - } - - uint8_t i2cRx (bool nack) - { - uint8_t byte = 0; - uint8_t bit; - - for (bit = 0; bit < 8; bit++) { - byte <<= 1; - byte |= i2cReadBit(); - } - i2cWriteBit(nack); - return byte; - } - - task void signalTask() + if (m_state == S_IDLE) + { + m_state = S_BUSY; + } + else + { + return EBUSY; + } + } + atomic { - uint16_t addr; - uint8_t length; - uint8_t* data; - error_t error; - bool read; - atomic + if (flags & I2C_START) + { + error = ecombine(error, i2cStartCond()); + error = ecombine(error, i2cTx(addr+1)); + } + + // Only read data from the device if length is >0. + // TODO(henrik): Should a data length of 0 be a invalid input? + if (length > 0) + { + // Read the data from the device. + for (i = 0; i < length-1; ++i) { - addr = m_addr; - length = m_length; - data = m_data; - error = m_error; - m_state = S_IDLE; - read = m_read; + data[i] = i2cRx(false); } - if (read) + if (flags & I2C_ACK_END) { - signal I2CPacket.readDone(error, addr, length, data); + data[length-1] = i2cRx(false); } else { - signal I2CPacket.writeDone(error, addr, length, data); + data[length-1] = i2cRx(true); } + } + if (flags & I2C_STOP) + { + error = ecombine(error, i2cStopCond()); + } + + m_error = error; + m_addr = addr; + m_length = length; + m_data = data; + m_read = true; } - - async command error_t I2CPacket.read(i2c_flags_t flags, uint16_t addr, uint8_t length, uint8_t* data) - { - uint8_t i; - error_t error = SUCCESS; - - // Both I2C_STOP and I2C_ACK_END flags are not allowed at the same time. - if ((flags & I2C_STOP) && (flags & I2C_ACK_END)) - { - return EINVAL; - } - - atomic - { - if (m_state == S_IDLE) - { - m_state = S_BUSY; - } - else - { - return EBUSY; - } - } - atomic - { - if (flags & I2C_START) - { - error = ecombine(error, i2cStartCond()); - error = ecombine(error, i2cTx(addr+1)); - } - - // Only read data from the device if length is >0. - // TODO(henrik): Should a data length of 0 be a invalid input? - if (length > 0) - { - // Read the data from the device. - for (i = 0; i < length-1; ++i) - { - data[i] = i2cRx(false); - } - if (flags & I2C_ACK_END) - { - data[length-1] = i2cRx(false); - } - else - { - data[length-1] = i2cRx(true); - } - } - if (flags & I2C_STOP) - { - error = ecombine(error, i2cStopCond()); - } - - m_error = error; - m_addr = addr; - m_length = length; - m_data = data; - m_read = true; - } - post signalTask(); + post signalTask(); - return SUCCESS; - } + return SUCCESS; + } - async command error_t I2CPacket.write(i2c_flags_t flags, uint16_t addr, uint8_t length, uint8_t* data) - { - uint8_t i; - error_t error = SUCCESS; - - atomic - { - if (m_state == S_IDLE) - { - m_state = S_BUSY; - } - else - { - return EBUSY; - } - } - atomic - { - if (flags & I2C_START) - { - error = ecombine(error, i2cStartCond()); - } - - i2cTx(addr); - - // Send the data to the device. - for (i = 0; i < length; ++i) - { - error = ecombine(error, i2cTx(data[i])); - } - - if (flags & I2C_STOP) - { - error = ecombine(error, i2cStopCond()); - } - - m_error = error; - m_addr = addr; - m_length = length; - m_data = data; - m_read = false; - } - post signalTask(); - return SUCCESS; - } -} \ No newline at end of file + async command error_t I2CPacket.write(i2c_flags_t flags, uint16_t addr, uint8_t length, uint8_t* data) + { + uint8_t i; + error_t error = SUCCESS; + + atomic + { + if (m_state == S_IDLE) + { + m_state = S_BUSY; + } + else + { + return EBUSY; + } + } + atomic + { + if (flags & I2C_START) + { + error = ecombine(error, i2cStartCond()); + } + + i2cTx(addr); + + // Send the data to the device. + for (i = 0; i < length; ++i) + { + error = ecombine(error, i2cTx(data[i])); + } + + if (flags & I2C_STOP) + { + error = ecombine(error, i2cStopCond()); + } + + m_error = error; + m_addr = addr; + m_length = length; + m_data = data; + m_read = false; + } + post signalTask(); + return SUCCESS; + } +} -- 2.39.2