Entwurf einer pinconfig.h, die von IOCON_-Sondernamen unabhängig benutzbar ist.
[hackover2013-badge-firmware.git] / core / i2c / i2c.c
index f9df690..292a7f4 100644 (file)
@@ -11,6 +11,9 @@
  *                           Major cleaning and a rewrite of some functions
  *                           - adding ACK/NACK handling to the state machine
  *                           - adding a return result to the I2CEngine()
+ *   2011.02.19  ver 1.20    KTownsend - microBuilder.eu
+ *                           - Added slave mode status values to 
+ *                             I2C_IRQHandler
  *
 *****************************************************************************/
 #include "i2c.h"
 volatile uint32_t I2CMasterState = I2CSTATE_IDLE;
 volatile uint32_t I2CSlaveState = I2CSTATE_IDLE;
 
-volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
-volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
+volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];    // Master Mode
+volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];     // Master Mode
+
+//volatile uint8_t I2CWrBuffer[I2C_BUFSIZE];        // Slave Mode
+//volatile uint8_t I2CRdBuffer[I2C_BUFSIZE];        // Slave Mode
+
 volatile uint32_t I2CReadLength;
 volatile uint32_t I2CWriteLength;
 
-volatile uint32_t RdIndex = 0;
-volatile uint32_t WrIndex = 0;
+volatile uint32_t RdIndex;
+volatile uint32_t WrIndex;
 
+volatile uint32_t _I2cMode;                       // I2CMASTER or I2CSLAVE
 
 /*****************************************************************************
 ** Function name:              I2C_IRQHandler
@@ -204,10 +212,77 @@ void I2C_IRQHandler(void)
                I2C_I2CCONCLR = I2CONCLR_SIC;   /* Clear SI flag */
                break;
 
-       
+        
+        /* Slave Mode */
+
+//      case 0x60:                                     /* An own SLA_W has been received. */
+//     case 0x70:
+//                RdIndex = 0;
+//                I2C_I2CCONSET = I2CONSET_AA;            /* assert ACK after SLV_W is received */
+//                I2C_I2CCONCLR = I2CONCLR_SIC;
+//                I2CSlaveState = I2C_WR_STARTED;
+//                break;
+//     
+//     case 0x80:                                      /*  data receive */
+//     case 0x90:
+//                if ( I2CSlaveState == I2C_WR_STARTED )
+//                {
+//                  I2CRdBuffer[RdIndex++] = I2C_I2CDAT;
+//                  I2C_I2CCONSET = I2CONSET_AA;          /* assert ACK after data is received */
+//                }
+//                else
+//                {
+//                  I2C_I2CCONCLR = I2CONCLR_AAC;         /* assert NACK */
+//                }
+//                // ToDo: Set a flag to indicate data is ready and process it somewhere
+//                I2C_I2CCONCLR = I2CONCLR_SIC;
+//                break;
+//             
+//     case 0xA8:                                      /* An own SLA_R has been received. */
+//     case 0xB0:
+//                // RdIndex = 0;
+//                WrIndex = I2CRdBuffer[0];               /* The 1st byte is the index. */
+//                I2C_I2CDAT = I2CRdBuffer[WrIndex+1];    /* write the same data back to master */
+//                WrIndex++;                           /* Need to skip the index byte in RdBuffer */
+//                I2C_I2CCONSET = I2CONSET_AA;            /* assert ACK after SLV_R is received */
+//                I2C_I2CCONCLR = I2CONCLR_SIC;
+//                I2CSlaveState = I2C_RD_STARTED;
+//                break;
+//     
+//     case 0xB8:                                      /* Data byte has been transmitted */
+//     case 0xC8:
+//                if ( I2CSlaveState == I2C_RD_STARTED )
+//                {
+//                  I2C_I2CDAT = I2CRdBuffer[WrIndex+1];  /* write the same data back to master */
+//                  WrIndex++;                            /* Need to skip the index byte in RdBuffer */
+//                  I2C_I2CCONSET = I2CONSET_AA;          /* assert ACK  */
+//                }
+//                else
+//                {
+//                  I2C_I2CCONCLR = I2CONCLR_AAC;         /* assert NACK  */
+//                }    
+//                I2C_I2CCONCLR = I2CONCLR_SIC;
+//                break;
+//
+//     case 0xC0:                                      /* Data byte has been transmitted, NACK */
+//                I2C_I2CCONCLR = I2CONCLR_AAC;                /* assert NACK  */
+//                I2C_I2CCONCLR = I2CONCLR_SIC;
+//                I2CSlaveState = DATA_NACK;
+//                break;
+//
+//     case 0xA0:                                      /* Stop condition or repeated start has */
+//                I2C_I2CCONSET = I2CONSET_AA;            /* been received, assert ACK.  */
+//                I2C_I2CCONCLR = I2CONCLR_SIC;
+//                I2CSlaveState = I2C_IDLE;
+//                break;
+
        default:
-               I2C_I2CCONCLR = I2CONCLR_SIC;
-       break;
+                I2C_I2CCONCLR = I2CONCLR_SIC;
+//                if (_I2cMode = I2CSLAVE)
+//                {
+//                  I2C_I2CCONSET = I2CONSET_I2EN | I2CONSET_SI;
+//                }
+                break;
   }
   return;
 }
@@ -216,8 +291,8 @@ void I2C_IRQHandler(void)
 ** Function name:      I2CStart
 **
 ** Descriptions:       Create I2C start condition, a timeout
-**                                     value is set if the I2C never gets started,
-**                                     and timed out. It's a fatal error.
+**                     value is set if the I2C never gets started,
+**                     and timed out. It's a fatal error.
 **
 ** parameters:         None
 ** Returned value:     true or false, return false if timed out
@@ -225,17 +300,17 @@ void I2C_IRQHandler(void)
 *****************************************************************************/
 static uint32_t I2CStart( void )
 {
-       uint32_t timeout = 0;
-
-       /*--- Issue a start condition ---*/
-       I2C_I2CCONSET = I2CONSET_STA;   /* Set Start flag */
-    
-       while((I2CMasterState != I2CSTATE_PENDING) && (timeout < MAX_TIMEOUT))
-       {
-               timeout++;
-       }
-
-       return (timeout < MAX_TIMEOUT);
+  uint32_t timeout = 0;
+  
+  /*--- Issue a start condition ---*/
+  I2C_I2CCONSET = I2CONSET_STA;        /* Set Start flag */
+  
+  while((I2CMasterState != I2CSTATE_PENDING) && (timeout < MAX_TIMEOUT))
+  {
+    timeout++;
+  }
+  
+  return (timeout < MAX_TIMEOUT);
 }
 
 /*****************************************************************************
@@ -249,17 +324,17 @@ static uint32_t I2CStart( void )
 *****************************************************************************/
 static uint32_t I2CStop( void )
 {
-       uint32_t timeout = 0;
-
-       I2C_I2CCONSET = I2CONSET_STO;      /* Set Stop flag */
-       I2C_I2CCONCLR = I2CONCLR_SIC;  /* Clear SI flag */
-
-       /*--- Wait for STOP detected ---*/
-       while((I2C_I2CCONSET & I2CONSET_STO) && (timeout < MAX_TIMEOUT))
-       {
-               timeout++;
-       }
-       return (timeout >= MAX_TIMEOUT);
+  uint32_t timeout = 0;
+  
+  I2C_I2CCONSET = I2CONSET_STO;      /* Set Stop flag */
+  I2C_I2CCONCLR = I2CONCLR_SIC;  /* Clear SI flag */
+  
+  /*--- Wait for STOP detected ---*/
+  while((I2C_I2CCONSET & I2CONSET_STO) && (timeout < MAX_TIMEOUT))
+  {
+    timeout++;
+  }
+  return (timeout >= MAX_TIMEOUT);
 }
 
 /*****************************************************************************
@@ -269,12 +344,14 @@ static uint32_t I2CStop( void )
 **
 ** parameters:         I2c mode is either MASTER or SLAVE
 ** Returned value:     true or false, return false if the I2C
-**                                     interrupt handler was not installed correctly
+**                     interrupt handler was not installed correctly
 ** 
 *****************************************************************************/
 uint32_t i2cInit( uint32_t I2cMode ) 
 {
-       SCB_PRESETCTRL |= (0x1<<1);
+  _I2cMode = I2cMode;
+
+  SCB_PRESETCTRL |= (0x1<<1);
 
   // Enable I2C clock
   SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_I2C);
@@ -304,14 +381,22 @@ uint32_t i2cInit( uint32_t I2cMode )
   I2C_I2CSCLH   = I2SCLH_SCLH;
 #endif
 
-  if ( I2cMode == I2CSLAVE )
+  if ( _I2cMode == I2CSLAVE )
   {
     I2C_I2CADR0 = SLAVE_ADDR;
-  }    
+    I2CSlaveState = I2C_IDLE;
+  }
 
   /* Enable the I2C Interrupt */
   NVIC_EnableIRQ(I2C_IRQn);
-  I2C_I2CCONSET = I2C_I2CCONSET_I2EN;
+  if ( _I2cMode == I2CMASTER )
+  {
+    I2C_I2CCONSET = I2C_I2CCONSET_I2EN;
+  }
+//  else
+//  {
+//    I2C_I2CCONSET = I2C_I2CCONSET_I2EN | I2C_I2CCONSET_SI;
+//  }
 
   return( TRUE );
 }
@@ -320,11 +405,11 @@ uint32_t i2cInit( uint32_t I2cMode )
 ** Function name:      I2CEngine
 **
 ** Descriptions:       The routine to complete a I2C transaction
-**                                     from start to stop. All the intermitten
-**                                     steps are handled in the interrupt handler.
-**                                     Before this routine is called, the read
-**                                     length, write length and I2C master buffer
-**                                     need to be filled.
+**                     from start to stop. All the intermitten
+**                     steps are handled in the interrupt handler.
+**                     Before this routine is called, the read
+**                     length, write length and I2C master buffer
+**                     need to be filled.
 **
 ** parameters:         None
 ** Returned value:     Any of the I2CSTATE_... values. See i2c.h
This page took 0.026259 seconds and 4 git commands to generate.