3# yang_alex
/********************** Interrupt Service Routines
**************************/
void i2c1_evt_isr()
{
uint32_t lastevent= I2C_GetLastEvent(I2C1);
switch (lastevent)
{
/************************** Master Invoke**************************************/
case I2C_EVENT_MASTER_MODE_SELECT: /* EV5 */
// MSL SB BUSY 30001
if(!check_begin)
i2c_comm_state = COMM_IN_PROCESS;
if (MasterDirection == Receiver)
{
if (!OffsetDone)
#if (EE_ADDRESS_NUM>1)
I2C_Send7bitAddress(I2C1,SlaveADDR,I2C_Direction_Transmitter);
#else
I2C_Send7bitAddress(I2C1,((DeviceOffset & 0x0700) >>7) | SlaveADDR,
I2C_Direction_Transmitter);
#endif
else
{
/* Send slave Address for read */
#if (EE_ADDRESS_NUM>1)
I2C_Send7bitAddress(I2C1, SlaveADDR, I2C_Direction_Receiver);
#else
I2C_Send7bitAddress(I2C1, ((DeviceOffset & 0x0700) >>7) | SlaveADDR, I2C_Direction_Receiver);
#endif
OffsetDone = FALSE;
}
}
else
{
/* Send slave Address for write */
#if (EE_ADDRESS_NUM>1)
I2C_Send7bitAddress(I2C1, SlaveADDR, I2C_Direction_Transmitter);
#else
I2C_Send7bitAddress(I2C1, ((DeviceOffset & 0x0700) >>7) | SlaveADDR, I2C_Direction_Transmitter);
#endif
}
I2C_ITConfig(I2C1, I2C_IT_BUF , ENABLE);//also TxE int allowed
break;
/********************** Master Receiver events ********************************/
case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: /* EV6 */
// MSL BUSY ADDR 0x30002
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
//without it, no NAK signal on bus after last Data
//I2C data line would be hold low
I2C_DMALastTransferCmd(I2C1, ENABLE);
I2C_DMACmd(I2C1, ENABLE);
DMA_Cmd(DMA1_Channel7, ENABLE);
break;
case I2C_EVENT_MASTER_BYTE_RECEIVED: /* EV7 */
// MSL BUSY RXNE 0x30040
break;
/************************* Master Transmitter events **************************/
case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: /* EV8 just after EV6 */
//BUSY, MSL, ADDR, TXE and TRA 0x70082
if (check_begin)
{
check_begin = FALSE;
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF |I2C_IT_ERR, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
//!! write over
I2C_EE_WriteOnePageCompleted();
if(I2C_NumByteToWrite>0)
{
I2C_EE_WriteOnePage(I2C_pBuffer,I2C_WriteAddr,I2C_NumByteToWrite);
}
else
{
WriteComplete = 1;
i2c_comm_state = COMM_DONE;
PV_flag_1 = 0;
}
break;
}
#if (EE_ADDRESS_NUM>1)
EE_Addr_Count++;
if (EE_Addr_Count < (EE_ADDRESS_NUM))
{
I2C_SendData(I2C1, DeviceOffset>>8);
}
//
else
//
{
//
I2C_SendData(I2C1, DeviceOffset);
//
}
#else
I2C_SendData(I2C1, DeviceOffset);
OffsetDone = TRUE;
#endif
break;
case I2C_EVENT_MASTER_BYTE_TRANSMITTING: /* EV8 I2C_EVENT_MASTER_BYTE_TRANSMITTING*/
#if (EE_ADDRESS_NUM>1)
if(!OffsetDone)
{
if (EE_Addr_Count < (EE_ADDRESS_NUM))
{
//while ((I2C1->CR1 & 0x200) == 0x200);
//I2C_GenerateSTART(I2C1, ENABLE);
I2C_SendData(I2C1, DeviceOffset);
EE_Addr_Count++;
}
else
{
EE_Addr_Count = 0;
OffsetDone = TRUE;
}
break;
}
#endif
if (MasterDirection == Receiver)
{
I2C_ITConfig(I2C1, I2C_IT_BUF , DISABLE);
while ((I2C1->CR1 & 0x200) == 0x200);
I2C_GenerateSTART(I2C1, ENABLE);
break;
}
else
{
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
I2C_DMACmd(I2C1, ENABLE);
DMA_Cmd(DMA1_Channel6, ENABLE);
break;
}
case I2C_EVENT_MASTER_BYTE_TRANSMITTED: /* EV8-2 */
//TRA, BUSY, MSL, TXE and BTF 0x70084
break;
}
}
void i2c1_err_isr()
{
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF))
{
if (check_begin)
I2C_GenerateSTART(I2C1, ENABLE);
else if (I2C1->SR2 &0x01)
{
//!! receive over
I2C_GenerateSTOP(I2C1, ENABLE);
i2c_comm_state = COMM_EXIT;
PV_flag_1 = 0;
}
I2C_ClearFlag(I2C1, I2C_FLAG_AF);
}
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_BERR))
{
if (I2C1->SR2 &0x01)
{
I2C_GenerateSTOP(I2C1, ENABLE);
i2c_comm_state = COMM_EXIT;
PV_flag_1 = 0;
}
I2C_ClearFlag(I2C1, I2C_FLAG_BERR);
}
}
void i2c1_send_dma_isr()
{
if (DMA_GetFlagStatus(DMA1_FLAG_TC6))
{
if (I2C1->SR2 & 0x01) // master send DMA finish, check process later
{
// DMA1-6 (I2C1 Tx DMA)transfer complete ISR
I2C_DMACmd(I2C1, DISABLE);
DMA_Cmd(DMA1_Channel6, DISABLE);
// wait until BTF
while (!(I2C1->SR1 & 0x04));
I2C_GenerateSTOP(I2C1, ENABLE);
// wait until BUSY clear
while (I2C1->SR2 & 0x02);
MasterTransitionComplete=1;
i2c_comm_state = COMM_IN_PROCESS;
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); // use interrupt to handle check process
check_begin = TRUE;
if(I2C1->CR1 & 0x200)
I2C1->CR1 &= 0xFDFF;
I2C_GenerateSTART(I2C1, ENABLE);
}
else // slave send DMA finish
{
}
DMA_ClearFlag(DMA1_FLAG_TC6);
}
if (DMA_GetFlagStatus(DMA1_FLAG_GL6))
{
DMA_ClearFlag( DMA1_FLAG_GL6);
}
if (DMA_GetFlagStatus(DMA1_FLAG_HT6))
{
DMA_ClearFlag( DMA1_FLAG_HT6);
}
}
void i2c1_receive_dma_isr()
{
if (DMA_GetFlagStatus(DMA1_FLAG_TC7))
{
if (I2C1->SR2 & 0x01) // master receive DMA finish
{
I2C_DMACmd(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
i2c_comm_state = COMM_DONE;
MasterReceptionComplete = 1;
PV_flag_1 =0;
}
else // slave receive DMA finish
{
}
DMA_ClearFlag(DMA1_FLAG_TC7);
}
if (DMA_GetFlagStatus(DMA1_FLAG_GL7))
{
DMA_ClearFlag( DMA1_FLAG_GL7);
}
if (DMA_GetFlagStatus(DMA1_FLAG_HT7))
{
DMA_ClearFlag( DMA1_FLAG_HT7);
}
}
/*******************************************************************************
* Function Name : DMA1_Channel6_IRQHandler
* Description : This function handles DMA1 Channel 6 interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void DMA1_Channel6_IRQHandler(void)
{
i2c1_send_dma_isr();
}
/*******************************************************************************
* Function Name : DMA1_Channel7_IRQHandler
* Description : This function handles DMA1 Channel 7 interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void DMA1_Channel7_IRQHandler(void)
{
i2c1_receive_dma_isr();
}
/*******************************************************************************
* Function Name : I2C1_EV_IRQHandler
* Description : This function handles I2C1 Event interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void I2C1_EV_IRQHandler(void)
{
i2c1_evt_isr();
}
/*******************************************************************************
* Function Name : I2C1_ER_IRQHandler
* Description : This function handles I2C1 Error interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void I2C1_ER_IRQHandler(void)
{
i2c1_err_isr();
} |