CI: Build on Arch (bleeding-ege) and Ubuntu (stable) AVR-GCC toolchains.
[pub/USBasp.git] / LUFA / Drivers / Peripheral / XMEGA / TWI_XMEGA.c
index c4204e2..2265dfc 100644 (file)
@@ -1,13 +1,13 @@
 /*
              LUFA Library
-     Copyright (C) Dean Camera, 2013.
+     Copyright (C) Dean Camera, 2018.
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
-  Copyright 2013  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2018  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
 #define  __INCLUDE_FROM_TWI_C
 #include "../TWI.h"
 
-uint8_t TWI_StartTransmission(TWI_t *twi,
+uint8_t TWI_StartTransmission(TWI_t* const TWI,
                               const uint8_t SlaveAddress,
                               const uint8_t TimeoutMS)
 {
-  uint16_t TimeoutRemaining;
-
-  twi->MASTER.ADDR = SlaveAddress;
-
-  TimeoutRemaining = (TimeoutMS * 100);
-  while (TimeoutRemaining)
-  {
-    if (twi->MASTER.STATUS & (TWI_MASTER_WIF_bm | TWI_MASTER_ARBLOST_bm)) 
-    {
-      // Case 1: Arbitration lost.  Try again. (or error)
-      twi->MASTER.ADDR = SlaveAddress;
-    }
-    else if (twi->STATUS & (TWI_MASTER_WIF_bm | TWI_MASTER_RXACK_bm))
-    {
-      // Case 2: No response from slave.
-      return TWI_ERROR_SlaveResponseTimeout;
-    }
-    else if (twi->STATUS & (TWI_MASTER_WIF_bm))
-    {
-      // Case 3: Slave ACK the Write. Ready!
-      return TWI_ERROR_NoError;
-    }
-    else if (twi->STATUS & (TWI_MASTER_RIF_bm))
-    {
-      // Case 4: Slave ACK the Read. Ready! (a byte will be read)
-      return TWI_ERROR_NoError;
-    }
-    // Still waiting..
-    _delay_us(10);
-    TimeoutRemaining--;
-  }
-
-  if (!(TimeoutRemaining)) {
-    if (twi->MASTER.STATUS & TWI_MASTER_CLKHOLD_bm) {
-      // Release the bus if we're holding it.
-      twi->CTRLC = TWI_MASTER_CMD_STOP_gc;
-    }
-    return TWI_ERROR_BusCaptureTimeout;
-  }
+       uint16_t TimeoutRemaining;
+
+       TWI->MASTER.ADDR = SlaveAddress;
+
+       TimeoutRemaining = (TimeoutMS * 100);
+       while (TimeoutRemaining)
+       {
+               uint8_t status = TWI->MASTER.STATUS;
+
+               if ((status & (TWI_MASTER_WIF_bm | TWI_MASTER_ARBLOST_bm)) == (TWI_MASTER_WIF_bm | TWI_MASTER_ARBLOST_bm))
+               {
+                       TWI->MASTER.ADDR = SlaveAddress;
+               }
+               else if ((status & (TWI_MASTER_WIF_bm | TWI_MASTER_RXACK_bm)) == (TWI_MASTER_WIF_bm | TWI_MASTER_RXACK_bm))
+               {
+                       TWI_StopTransmission(TWI);
+                       return TWI_ERROR_SlaveResponseTimeout;
+               }
+               else if (status & (TWI_MASTER_WIF_bm | TWI_MASTER_RIF_bm))
+               {
+                       return TWI_ERROR_NoError;
+               }
+
+               _delay_us(10);
+               TimeoutRemaining--;
+       }
+
+       if (!(TimeoutRemaining)) {
+               if (TWI->MASTER.STATUS & TWI_MASTER_CLKHOLD_bm) {
+                       TWI_StopTransmission(TWI);
+               }
+       }
+
+       return TWI_ERROR_BusCaptureTimeout;
 }
 
-bool TWI_SendByte(TWI_t *twi, const uint8_t Byte)
+bool TWI_SendByte(TWI_t* const TWI,
+                  const uint8_t Byte)
 {
-  // We assume we're ready to write!
-  twi->MASTER.DATA = Byte;
-  while (!(twi->MASTER.STATUS & TWI_MASTER_WIF_bm));
-  return (twi->MASTER.STATUS & TWI_MASTER_WIF_bm) & !(twi->MASTER.STATUS & TWI_MASTER_RXACK_bm);
+       TWI->MASTER.DATA = Byte;
+
+       while (!(TWI->MASTER.STATUS & TWI_MASTER_WIF_bm));
+
+       return (TWI->MASTER.STATUS & TWI_MASTER_WIF_bm) && !(TWI->MASTER.STATUS & TWI_MASTER_RXACK_bm);
 }
 
-bool TWI_ReceiveByte(uint8_t* const Byte,
-                                        const bool LastByte)
+bool TWI_ReceiveByte(TWI_t* const TWI,
+                     uint8_t* const Byte,
+                     const bool LastByte)
 {
-  // If we're here, we should already be reading.  Wait if we haven't read yet.
-  if (twi->MASTER.STATUS & (TWI_MASTER_BUSERR_bm | TWI_MASTER_ARBLOST_bm)) {
-    return false;
-  }
-  while (!(twi->MASTER.STATUS & TWI_MASTER_RIF_bm));
-  *byte = twi->MASTER.DATA;
-  if (LastByte)
-    twi->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_RECVTRANS_gc;
-  else
-    twi->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
-  return true;
+       if ((TWI->MASTER.STATUS & (TWI_MASTER_BUSERR_bm | TWI_MASTER_ARBLOST_bm)) == (TWI_MASTER_BUSERR_bm | TWI_MASTER_ARBLOST_bm)) {
+               return false;
+       }
+
+       while (!(TWI->MASTER.STATUS & TWI_MASTER_RIF_bm));
+
+       *Byte = TWI->MASTER.DATA;
+
+       if (LastByte)
+         TWI->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc;
+       else
+         TWI->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
+
+       return true;
 }
 
-uint8_t TWI_ReadPacket(TWI_t *twi,
+uint8_t TWI_ReadPacket(TWI_t* const TWI,
                        const uint8_t SlaveAddress,
                        const uint8_t TimeoutMS,
                        const uint8_t* InternalAddress,
                        uint8_t InternalAddressLen,
                        uint8_t* Buffer,
-                       uint8_t Length)
+                       uint16_t Length)
 {
        uint8_t ErrorCode;
 
-       if ((ErrorCode = TWI_StartTransmission(twi, (SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE,
+       if ((ErrorCode = TWI_StartTransmission(TWI, (SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE,
                                               TimeoutMS)) == TWI_ERROR_NoError)
        {
                while (InternalAddressLen--)
                {
-                       if (!(TWI_SendByte(twi, *(InternalAddress++))))
+                       if (!(TWI_SendByte(TWI, *(InternalAddress++))))
                        {
                                ErrorCode = TWI_ERROR_SlaveNAK;
                                break;
                        }
                }
 
-               if ((ErrorCode = TWI_StartTransmission(twi, (SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_READ,
-                                                                                          TimeoutMS)) == TWI_ERROR_NoError)
+               if ((ErrorCode = TWI_StartTransmission(TWI, (SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_READ,
+                                                      TimeoutMS)) == TWI_ERROR_NoError)
                {
                        while (Length--)
                        {
-                               if (!(TWI_ReceiveByte(twi, Buffer++, (Length == 0))))
+                               if (!(TWI_ReceiveByte(TWI, Buffer++, (Length == 0))))
                                {
                                        ErrorCode = TWI_ERROR_SlaveNAK;
                                        break;
                                }
                        }
-
-                       TWI_StopTransmission(twi);
                }
+
+               TWI_StopTransmission(TWI);
        }
 
        return ErrorCode;
 }
 
-uint8_t TWI_WritePacket(TWI_t *twi,
+uint8_t TWI_WritePacket(TWI_t* const TWI,
                         const uint8_t SlaveAddress,
                         const uint8_t TimeoutMS,
                         const uint8_t* InternalAddress,
                         uint8_t InternalAddressLen,
                         const uint8_t* Buffer,
-                        uint8_t Length)
+                        uint16_t Length)
 {
        uint8_t ErrorCode;
 
-       if ((ErrorCode = TWI_StartTransmission(twi, (SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE,
+       if ((ErrorCode = TWI_StartTransmission(TWI, (SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE,
                                               TimeoutMS)) == TWI_ERROR_NoError)
        {
                while (InternalAddressLen--)
                {
-                       if (!(TWI_SendByte(twi, *(InternalAddress++))))
+                       if (!(TWI_SendByte(TWI, *(InternalAddress++))))
                        {
                                ErrorCode = TWI_ERROR_SlaveNAK;
                                break;
@@ -168,14 +169,14 @@ uint8_t TWI_WritePacket(TWI_t *twi,
 
                while (Length--)
                {
-                       if (!(TWI_SendByte(twi, *(Buffer++))))
+                       if (!(TWI_SendByte(TWI, *(Buffer++))))
                        {
                                ErrorCode = TWI_ERROR_SlaveNAK;
                                break;
                        }
                }
 
-               TWI_StopTransmission(twi);
+               TWI_StopTransmission(TWI);
        }
 
        return ErrorCode;