Platform/ECM3532/M3/hw/csp/ecm3532/m3/csp/src/eta_csp_i2c.c
/***************************************************************************/
/**
 *
 *  EtaCspI2cProcessIntTxData - Process I2C Interrupt for TX Space Available
 *
 *  @param iNum the I2C number.
 *
 ******************************************************************************/
Process I2C Interrupt for TX Space Available
@param iNum the I2C number.
Process I2C Interrupt for TX Space Available @param iNum the I2C number .
tEtaStatus EtaCspI2cProcessIntTxData (tI2cNum iNum)
{
  uint8_t space_in_fifo;
  if ((g_pEtaCspI2cCmd[iNum]->bCmdActive == 0) || (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 0))
  {
#ifdef ETA_CSP_I2C_DEBUG
    ETA_DIAGS_PRINTF("ERROR: received i2c_int_tx but command is done. bCmdActive=%x  ui32TxLen=%x\r\n", g_pEtaCspI2cCmd[iNum]->bCmdActive, g_pEtaCspI2cCmd[iNum]->ui32TxLen);
#endif
    return eEtaI2cCmdSequenceErr;
  }
  if (ETA_CSP_I2C_EN_GREEDY_INT) 
  {
    space_in_fifo = 16-(MEMIO8(REG_I2C_TX_FIFO_DEBUG_ADDR (iNum)) & BM_I2C_TX_FIFO_DEBUG_ENTRIES);
  }
  else
  {
    space_in_fifo = g_pEtaCspI2cCmd[iNum]->ui8TxIntSize; 
  }
  #ifdef ETA_CSP_I2C_INT_DEBUG
    ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: Space for %d bytes starting with %x\r\n", space_in_fifo, *g_pEtaCspI2cCmd[iNum]->pui8TxData);
  #endif
  do
  {
    if (g_pEtaCspI2cCmd[iNum]->ui32RestartAfterByte != 0)
    {
      if (g_pEtaCspI2cCmd[iNum]->ui32CurrByteCount == g_pEtaCspI2cCmd[iNum]->ui32RestartAfterByte)
      {
        g_pEtaCspI2cCmd[iNum]->ui32RestartAfterByte = 0; 
        MEMIO8(REG_I2C_CMD_FIFO_DATA_ADDR(iNum)) = I2C_CMD_RESTART;
        #ifdef ETA_CSP_I2C_INT_DEBUG
          ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: I2C TX restart\r\n");
        #endif
        break; 
      }
    }
    g_pEtaCspI2cCmd[iNum]->ui32CurrByteCount = g_pEtaCspI2cCmd[iNum]->ui32CurrByteCount + 1;
    if (g_pEtaCspI2cCmd[iNum]->ui32TxLen > 4) 
    {
      #ifdef ETA_CSP_I2C_INT_DEBUG
        ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: Sending: %x txleft: %x part A\r\n", (*g_pEtaCspI2cCmd[iNum]->pui8TxData) & 0xff, g_pEtaCspI2cCmd[iNum]->ui32TxLen-1);
      #endif
      MEMIO8(REG_I2C_TXRX_1BYTE_FIFO_DATA_ADDR(iNum)) = *g_pEtaCspI2cCmd[iNum]->pui8TxData++;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      if (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 0) 
      {
        REG_I2C_INT_EN(iNum).V = BM_I2C_INT_EN_RX_HIT_LEVEL_EN | BM_I2C_INT_EN_UNACK_EN;
        REG_I2C_CONFIG(iNum).BF.RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd[iNum]->ui8RxIntSize;
        #ifdef ETA_CSP_I2C_INT_DEBUG
          ETA_DIAGS_PRINTF("DETAILED_I2C:Last I2C TX data interrupt\r\n");
        #endif
      }
    }
    else if ((g_pEtaCspI2cCmd[iNum]->bRxLenIs0==1) && (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 1))
    {
      MEMIO8(REG_I2C_CMD_FIFO_DATA_ADDR(iNum)) = I2C_CMD_END_WRITE;
      REG_I2C_INT_EN(iNum).V = BM_I2C_INT_EN_CMD_DONE | BM_I2C_INT_EN_UNACK_EN;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      REG_I2C_CONFIG(iNum).BF.RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd[iNum]->ui8RxIntSize;
      #ifdef ETA_CSP_I2C_INT_DEBUG
        ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: rxlen=0,txleft=0\r\n");
      #endif
      break; 
    }
    else if ((g_pEtaCspI2cCmd[iNum]->bRxLenIs1==1) && (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 2))
    {
      MEMIO8(REG_I2C_TXRX_1BYTE_FIFO_DATA_ADDR(iNum)) = 0xff;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      #ifdef ETA_CSP_I2C_INT_DEBUG
       ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: rxlen=1,txleft=1\r\n");
      #endif
    }
    else if ((g_pEtaCspI2cCmd[iNum]->bRxLenIs1==1) && (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 1))
    {
      MEMIO8(REG_I2C_CMD_FIFO_DATA_ADDR(iNum)) = I2C_CMD_BEGIN_READ | I2C_CMD_END_READ;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      REG_I2C_INT_EN(iNum).V = BM_I2C_INT_EN_RX_HIT_LEVEL_EN | BM_I2C_INT_EN_UNACK_EN; 
      REG_I2C_CONFIG(iNum).BF.RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd[iNum]->ui8RxIntSize;
      #ifdef ETA_CSP_I2C_INT_DEBUG
       ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: rxlen=1,txleft=0\r\n");
      #endif
      break; 
    }
    else if ((g_pEtaCspI2cCmd[iNum]->bRxLenIsGt1==1) && (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 4))
    {
      MEMIO8(REG_I2C_TXRX_1BYTE_FIFO_DATA_ADDR(iNum)) = 0xff;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      #ifdef ETA_CSP_I2C_INT_DEBUG
       ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: rxlen>1,txleft=3\r\n");
      #endif
    }
    else if ((g_pEtaCspI2cCmd[iNum]->bRxLenIsGt1==1) && (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 3))
    {
      MEMIO8(REG_I2C_CMD_FIFO_DATA_ADDR(iNum)) = I2C_CMD_BEGIN_READ;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      #ifdef ETA_CSP_I2C_INT_DEBUG
       ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: rxlen>1,txleft=2\r\n");
      #endif
    }
    else if ((g_pEtaCspI2cCmd[iNum]->bRxLenIsGt1==1) && (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 2))
    {
      MEMIO8(REG_I2C_CMD_FIFO_DATA_ADDR(iNum)) = I2C_CMD_DUMMYBYTE;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      #ifdef ETA_CSP_I2C_INT_DEBUG
       ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: rxlen>1,txleft=1\r\n");
      #endif
    }
    else if ((g_pEtaCspI2cCmd[iNum]->bRxLenIsGt1==1) && (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 1))
    {
      MEMIO8(REG_I2C_CMD_FIFO_DATA_ADDR(iNum)) = I2C_CMD_END_READ;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      REG_I2C_INT_EN(iNum).V = BM_I2C_INT_EN_RX_HIT_LEVEL_EN | BM_I2C_INT_EN_UNACK_EN; 
      REG_I2C_CONFIG(iNum).BF.RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd[iNum]->ui8RxIntSize;
      #ifdef ETA_CSP_I2C_INT_DEBUG
       ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: rxlen>1,txleft=0\r\n");
      #endif
      break; 
    }
    else
    {
      #ifdef ETA_CSP_I2C_INT_DEBUG
       ETA_DIAGS_PRINTF("DETAILED_I2C:I2C TX interrupt: Sending: %x txleft: %x part B\r\n", (*g_pEtaCspI2cCmd[iNum]->pui8TxData) & 0xff, g_pEtaCspI2cCmd[iNum]->ui32TxLen-1);
      #endif
      MEMIO8(REG_I2C_TXRX_1BYTE_FIFO_DATA_ADDR(iNum)) = *g_pEtaCspI2cCmd[iNum]->pui8TxData++;
      g_pEtaCspI2cCmd[iNum]->ui32TxLen--;
      if (g_pEtaCspI2cCmd[iNum]->ui32TxLen == 0) 
      {
        REG_I2C_INT_EN(iNum).V = BM_I2C_INT_EN_RX_HIT_LEVEL_EN | BM_I2C_INT_EN_UNACK_EN;
        REG_I2C_CONFIG(iNum).BF.RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd[iNum]->ui8RxIntSize;
        #ifdef ETA_CSP_I2C_INT_DEBUG
         ETA_DIAGS_PRINTF("DETAILED_I2C:Last I2C TX data interrupt\r\n");
        #endif
        break; 
      }
    }
  } while (--space_in_fifo);
  return eEtaSuccess;
}
tEtaStatus EtaCspI2cProcessIntTxData ( tI2cNum iNum ) { uint8_t space_in_fifo ; if ( ( g_pEtaCspI2cCmd [ iNum ] -> bCmdActive == 0 ) || ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 0 ) ) { #ifdef ETA_CSP_I2C_DEBUG ETA_DIAGS_PRINTF ( " \r \n " , g_pEtaCspI2cCmd [ iNum ] -> bCmdActive , g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen ) ; #endif return eEtaI2cCmdSequenceErr ; } if ( ETA_CSP_I2C_EN_GREEDY_INT ) { space_in_fifo = 16 - ( MEMIO8 ( REG_I2C_TX_FIFO_DEBUG_ADDR ( iNum ) ) & BM_I2C_TX_FIFO_DEBUG_ENTRIES ) ; } else { space_in_fifo = g_pEtaCspI2cCmd [ iNum ] -> ui8TxIntSize ; } #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " , space_in_fifo , * g_pEtaCspI2cCmd [ iNum ] -> pui8TxData ) ; #endif do { if ( g_pEtaCspI2cCmd [ iNum ] -> ui32RestartAfterByte != 0 ) { if ( g_pEtaCspI2cCmd [ iNum ] -> ui32CurrByteCount == g_pEtaCspI2cCmd [ iNum ] -> ui32RestartAfterByte ) { g_pEtaCspI2cCmd [ iNum ] -> ui32RestartAfterByte = 0 ; MEMIO8 ( REG_I2C_CMD_FIFO_DATA_ADDR ( iNum ) ) = I2C_CMD_RESTART ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif break ; } } g_pEtaCspI2cCmd [ iNum ] -> ui32CurrByteCount = g_pEtaCspI2cCmd [ iNum ] -> ui32CurrByteCount + 1 ; if ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen > 4 ) { #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " , ( * g_pEtaCspI2cCmd [ iNum ] -> pui8TxData ) & 0xff , g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen - 1 ) ; #endif MEMIO8 ( REG_I2C_TXRX_1BYTE_FIFO_DATA_ADDR ( iNum ) ) = * g_pEtaCspI2cCmd [ iNum ] -> pui8TxData ++ ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; if ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 0 ) { REG_I2C_INT_EN ( iNum ) . V = BM_I2C_INT_EN_RX_HIT_LEVEL_EN | BM_I2C_INT_EN_UNACK_EN ; REG_I2C_CONFIG ( iNum ) . BF . RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd [ iNum ] -> ui8RxIntSize ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif } } else if ( ( g_pEtaCspI2cCmd [ iNum ] -> bRxLenIs0 == 1 ) && ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 1 ) ) { MEMIO8 ( REG_I2C_CMD_FIFO_DATA_ADDR ( iNum ) ) = I2C_CMD_END_WRITE ; REG_I2C_INT_EN ( iNum ) . V = BM_I2C_INT_EN_CMD_DONE | BM_I2C_INT_EN_UNACK_EN ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; REG_I2C_CONFIG ( iNum ) . BF . RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd [ iNum ] -> ui8RxIntSize ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif break ; } else if ( ( g_pEtaCspI2cCmd [ iNum ] -> bRxLenIs1 == 1 ) && ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 2 ) ) { MEMIO8 ( REG_I2C_TXRX_1BYTE_FIFO_DATA_ADDR ( iNum ) ) = 0xff ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif } else if ( ( g_pEtaCspI2cCmd [ iNum ] -> bRxLenIs1 == 1 ) && ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 1 ) ) { MEMIO8 ( REG_I2C_CMD_FIFO_DATA_ADDR ( iNum ) ) = I2C_CMD_BEGIN_READ | I2C_CMD_END_READ ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; REG_I2C_INT_EN ( iNum ) . V = BM_I2C_INT_EN_RX_HIT_LEVEL_EN | BM_I2C_INT_EN_UNACK_EN ; REG_I2C_CONFIG ( iNum ) . BF . RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd [ iNum ] -> ui8RxIntSize ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif break ; } else if ( ( g_pEtaCspI2cCmd [ iNum ] -> bRxLenIsGt1 == 1 ) && ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 4 ) ) { MEMIO8 ( REG_I2C_TXRX_1BYTE_FIFO_DATA_ADDR ( iNum ) ) = 0xff ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif } else if ( ( g_pEtaCspI2cCmd [ iNum ] -> bRxLenIsGt1 == 1 ) && ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 3 ) ) { MEMIO8 ( REG_I2C_CMD_FIFO_DATA_ADDR ( iNum ) ) = I2C_CMD_BEGIN_READ ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif } else if ( ( g_pEtaCspI2cCmd [ iNum ] -> bRxLenIsGt1 == 1 ) && ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 2 ) ) { MEMIO8 ( REG_I2C_CMD_FIFO_DATA_ADDR ( iNum ) ) = I2C_CMD_DUMMYBYTE ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif } else if ( ( g_pEtaCspI2cCmd [ iNum ] -> bRxLenIsGt1 == 1 ) && ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 1 ) ) { MEMIO8 ( REG_I2C_CMD_FIFO_DATA_ADDR ( iNum ) ) = I2C_CMD_END_READ ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; REG_I2C_INT_EN ( iNum ) . V = BM_I2C_INT_EN_RX_HIT_LEVEL_EN | BM_I2C_INT_EN_UNACK_EN ; REG_I2C_CONFIG ( iNum ) . BF . RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd [ iNum ] -> ui8RxIntSize ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif break ; } else { #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " , ( * g_pEtaCspI2cCmd [ iNum ] -> pui8TxData ) & 0xff , g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen - 1 ) ; #endif MEMIO8 ( REG_I2C_TXRX_1BYTE_FIFO_DATA_ADDR ( iNum ) ) = * g_pEtaCspI2cCmd [ iNum ] -> pui8TxData ++ ; g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen -- ; if ( g_pEtaCspI2cCmd [ iNum ] -> ui32TxLen == 0 ) { REG_I2C_INT_EN ( iNum ) . V = BM_I2C_INT_EN_RX_HIT_LEVEL_EN | BM_I2C_INT_EN_UNACK_EN ; REG_I2C_CONFIG ( iNum ) . BF . RX_FIFO_INT_LEVEL = g_pEtaCspI2cCmd [ iNum ] -> ui8RxIntSize ; #ifdef ETA_CSP_I2C_INT_DEBUG ETA_DIAGS_PRINTF ( " \r \n " ) ; #endif break ; } } } while ( -- space_in_fifo ) ; return eEtaSuccess ; }
EtaCspI2cProcessIntTxData - Process I2C Interrupt for TX Space Available
  @param iNum the I2C number.
EtaCspI2cProcessIntTxData - Process I2C Interrupt for TX Space Available @param iNum the I2C number .
// This allows for burst writes, which is more efficient, but not requires an extra read. // Do work that interrupt said we have space for // Deal with restart // First we check if we have a restart, then we check if it is ours. If not, continue with transactions. // This should "disable" restart since 0 is illegal for restart position // Exit loop if we entered here. // This is the more common case, so we'll check this first and only go to the exceptions if this common case is not true. // These are various exceptions // Note, this is the same as the "else" clause at the bottom below. // Just sent last byte. // Case where RX Length == 0 // Exit loop, we're done. // Cases where RX Length == 1 // Go to RX // Exit loop, we're done. // Cases where RX Length >1 // Go to RX // Exit loop, we're done. // Just sent last byte. // Exit loop, we're done.