コード例 #1
0
/**
  * @brief  Enables or disables the LM75.
  * @param  NewState: specifies the LM75 new status. This parameter can be ENABLE
  *         or DISABLE.  
  * @retval None
  */
uint8_t LM75_ShutDown(FunctionalState NewState)
{   
  uint8_t LM75_BufferRX[2] ={0,0};
  uint8_t LM75_BufferTX = 0;
  __IO uint8_t RegValue = 0;    
  
  /* Test on BUSY Flag */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  LM75_DMA_Config(LM75_DMA_RX, (uint8_t*)LM75_BufferRX, 2);  
  
  /* Enable DMA NACK automatic generation */
  I2C_DMALastTransferCmd(LM75_I2C, ENABLE);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(LM75_I2C, ENABLE);
  
  /* Test on SB Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send device address for write */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send the device's internal address to write to */
  I2C_SendData(LM75_I2C, LM75_REG_CONF);  
  
  /* Test on TXE FLag (data sent) */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF)))  
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send START condition a second time */  
  I2C_GenerateSTART(LM75_I2C, ENABLE);
  
  /* Test on SB Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send LM75 address for read */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver);
  
  /* Test on ADDR Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(LM75_I2C,ENABLE);
  
  /* Enable DMA RX Channel */
  DMA_Cmd(LM75_DMA_RX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(LM75_DMA_RX_TCFLAG))
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }        
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);
  
  /* Disable DMA RX Channel */
  DMA_Cmd(LM75_DMA_RX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(LM75_I2C,DISABLE);
  
  /* Clear DMA RX Transfer Complete Flag */
  DMA_ClearFlag(LM75_DMA_RX_TCFLAG);
  
  /*!< Get received data */
  RegValue = (uint8_t)LM75_BufferRX[0];
  
  /*---------------------------- Transmission Phase ---------------------------*/
  
  /*!< Enable or disable SD bit */
  if (NewState != DISABLE)
  {
    /*!< Enable LM75 */
    LM75_BufferTX = RegValue & LM75_SD_RESET;
  }
  else
  {
    /*!< Disable LM75 */
    LM75_BufferTX = RegValue | LM75_SD_SET;
  }  
  
  /* Test on BUSY Flag */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  LM75_DMA_Config(LM75_DMA_TX, (uint8_t*)(&LM75_BufferTX), 1);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(LM75_I2C, ENABLE);
  
  /* Test on SB Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB) == RESET) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Transmit the first address for r/w operations */
  I2C_SendData(LM75_I2C, LM75_REG_CONF);
  
  /* Test on TXE FLag (data sent) */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF)))  
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(LM75_I2C,ENABLE);
  
  /* Enable DMA TX Channel */
  DMA_Cmd(LM75_DMA_TX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(LM75_DMA_TX_TCFLAG))
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }  
  
  /* Wait until BTF Flag is set before generating STOP */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF)))  
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);
  
  /* Disable DMA TX Channel */
  DMA_Cmd(LM75_DMA_TX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(LM75_I2C,DISABLE);
  
  /* Clear DMA TX Transfer Complete Flag */
  DMA_ClearFlag(LM75_DMA_TX_TCFLAG);  
  
  return LM75_OK;
}
コード例 #2
0
ファイル: i2c.c プロジェクト: pandc/unitek
int I2C_RandRead(uint8_t slave,uint16_t addr,uint8_t addrsize,void *pbuffer,uint16_t len)
{
struct i2c_job_st i2c_jobs[2];
uint8_t buf_offset[2];

	xSemaphoreTake(xSemaphoreI2C_Mutex,portMAX_DELAY);

	if (I2C_isBusy())
	{
		i2c_error_flags = I2C_SR1_SB;
		xSemaphoreGive(xSemaphoreI2C_Mutex);
		return FALSE;
	}

	i2c_cntr = 0;
	i2c_oper = I2C_Direction_Transmitter;
	job = i2c_jobs;
	i2c_addr = slave << 1;
	memset(i2c_jobs,0,sizeof(i2c_jobs));
	if (addrsize == 1)
		buf_offset[0] = (uint8_t)addr;
	else
	{
		buf_offset[0] = (uint8_t)(addr >> 8);
		buf_offset[1] = (uint8_t)(addr & 0xff);
	}

	i2c_jobs[0].buf = buf_offset;
	i2c_jobs[0].len = addrsize;
	i2c_jobs[0].dir = I2C_Direction_Transmitter;

	i2c_jobs[1].buf = (uint8_t *)pbuffer;
	i2c_jobs[1].len = len;
	i2c_jobs[1].dir = I2C_Direction_Receiver;
	i2c_jobs[1].last = TRUE;

	i2c_error_flags = 0;
	i2c_done = i2c_err = FALSE;

	// clear the semaphore
	while (xSemaphoreTake(xSemaphoreI2C_Work,0));

	I2C_AcknowledgeConfig(I2Cx,ENABLE);
	I2C_NACKPositionConfig(I2Cx,I2C_NACKPosition_Current);
	I2C_ITConfig(I2Cx,I2C_IT_BUF | I2C_IT_ERR | I2C_IT_EVT,ENABLE);

	/* Send START condition */
	I2C_GenerateSTART(I2Cx, ENABLE);

	while (!i2c_done && !i2c_err)
	{
		if (!xSemaphoreTake(xSemaphoreI2C_Work,SEMA_DELAY))
		{
			I2C_Open(0);
			i2c_err = TRUE;
			break;
		}
	}

	I2C_ITConfig(I2Cx,I2C_IT_BUF | I2C_IT_ERR | I2C_IT_EVT,DISABLE);

	xSemaphoreGive(xSemaphoreI2C_Mutex);
	return !i2c_err;
}
コード例 #3
0
/**
  * @brief  Read the specified register from the LM75.
  * @param  RegName: specifies the LM75 register to be read.
  *              This member can be one of the following values:  
  *                  - LM75_REG_TEMP: temperature register
  *                  - LM75_REG_TOS: Over-limit temperature register
  *                  - LM75_REG_THYS: Hysteresis temperature register
  * @retval LM75 register value.
  */
uint16_t LM75_ReadReg(uint8_t RegName)
{   
  uint8_t LM75_BufferRX[2] ={0,0};
  uint16_t tmp = 0;    
  
   /* Test on BUSY Flag */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  LM75_DMA_Config(LM75_DMA_RX, (uint8_t*)LM75_BufferRX, 2);  
  
  /* Enable DMA NACK automatic generation */
  I2C_DMALastTransferCmd(LM75_I2C, ENABLE);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(LM75_I2C, ENABLE);
  
  /* Test on SB Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send device address for write */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send the device's internal address to write to */
  I2C_SendData(LM75_I2C, RegName);  
  
  /* Test on TXE FLag (data sent) */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF)))  
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send START condition a second time */  
  I2C_GenerateSTART(LM75_I2C, ENABLE);
  
  /* Test on SB Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send LM75 address for read */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver);
  
  /* Test on ADDR Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(LM75_I2C,ENABLE);
  
  /* Enable DMA RX Channel */
  DMA_Cmd(LM75_DMA_RX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(LM75_DMA_RX_TCFLAG))
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }        
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);
  
  /* Disable DMA RX Channel */
  DMA_Cmd(LM75_DMA_RX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(LM75_I2C,DISABLE);
  
  /* Clear DMA RX Transfer Complete Flag */
  DMA_ClearFlag(LM75_DMA_RX_TCFLAG);
  
  /*!< Store LM75_I2C received data */
  tmp = (uint16_t)(LM75_BufferRX[0] << 8);
  tmp |= LM75_BufferRX[1];
  
  /* return a Reg value */
  return (uint16_t)tmp;  
}
コード例 #4
0
ファイル: drv_i2c.c プロジェクト: 363546178/baseflight
void i2c_ev_handler(void)
{
    static uint8_t subaddress_sent, final_stop;                         // flag to indicate if subaddess sent, flag to indicate final bus condition
    static int8_t index;                                                // index is signed -1 == send the subaddress
    uint8_t SReg_1 = I2Cx->SR1;                                         // read the status register here

    if (SReg_1 & 0x0001) {                                              // we just sent a start - EV5 in ref manual
        I2Cx->CR1 &= ~0x0800;                                           // reset the POS bit so ACK/NACK applied to the current byte
        I2C_AcknowledgeConfig(I2Cx, ENABLE);                            // make sure ACK is on
        index = 0;                                                      // reset the index
        if (reading && (subaddress_sent || 0xFF == reg)) {              // we have sent the subaddr
            subaddress_sent = 1;                                        // make sure this is set in case of no subaddress, so following code runs correctly
            if (bytes == 2)
                I2Cx->CR1 |= 0x0800;                                    // set the POS bit so NACK applied to the final byte in the two byte read
            I2C_Send7bitAddress(I2Cx, addr, I2C_Direction_Receiver);    // send the address and set hardware mode
        } else {                                                        // direction is Tx, or we havent sent the sub and rep start
            I2C_Send7bitAddress(I2Cx, addr, I2C_Direction_Transmitter); // send the address and set hardware mode
            if (reg != 0xFF)                                            // 0xFF as subaddress means it will be ignored, in Tx or Rx mode
                index = -1;                                             // send a subaddress
        }
    } else if (SReg_1 & 0x0002) {                                       // we just sent the address - EV6 in ref manual
        // Read SR1,2 to clear ADDR
        __DMB();                                                        // memory fence to control hardware
        if (bytes == 1 && reading && subaddress_sent) {                 // we are receiving 1 byte - EV6_3
            I2C_AcknowledgeConfig(I2Cx, DISABLE);                       // turn off ACK
            __DMB();
            (void)I2Cx->SR2;                                            // clear ADDR after ACK is turned off
            I2C_GenerateSTOP(I2Cx, ENABLE);                             // program the stop
            final_stop = 1;
            I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE);                     // allow us to have an EV7
        } else {                                                        // EV6 and EV6_1
            (void)I2Cx->SR2;                                            // clear the ADDR here
            __DMB();
            if (bytes == 2 && reading && subaddress_sent) {             // rx 2 bytes - EV6_1
                I2C_AcknowledgeConfig(I2Cx, DISABLE);                   // turn off ACK
                I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE);                // disable TXE to allow the buffer to fill
            } else if (bytes == 3 && reading && subaddress_sent)        // rx 3 bytes
                I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE);                // make sure RXNE disabled so we get a BTF in two bytes time
            else                                                        // receiving greater than three bytes, sending subaddress, or transmitting
                I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE);
        }
    } else if (SReg_1 & 0x004) {                                        // Byte transfer finished - EV7_2, EV7_3 or EV8_2
        final_stop = 1;
        if (reading && subaddress_sent) {                               // EV7_2, EV7_3
            if (bytes > 2) {                                            // EV7_2
                I2C_AcknowledgeConfig(I2Cx, DISABLE);                   // turn off ACK
                read_p[index++] = (uint8_t)I2Cx->DR;                    // read data N-2
                I2C_GenerateSTOP(I2Cx, ENABLE);                         // program the Stop
                final_stop = 1;                                         // required to fix hardware
                read_p[index++] = (uint8_t)I2Cx->DR;                    // read data N - 1
                I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE);                 // enable TXE to allow the final EV7
            } else {                                                    // EV7_3
                if (final_stop)
                    I2C_GenerateSTOP(I2Cx, ENABLE);                     // program the Stop
                else
                    I2C_GenerateSTART(I2Cx, ENABLE);                    // program a rep start
                read_p[index++] = (uint8_t)I2Cx->DR;                    // read data N - 1
                read_p[index++] = (uint8_t)I2Cx->DR;                    // read data N
                index++;                                                // to show job completed
            }
        } else {                                                        // EV8_2, which may be due to a subaddress sent or a write completion
            if (subaddress_sent || (writing)) {
                if (final_stop)
                    I2C_GenerateSTOP(I2Cx, ENABLE);                     // program the Stop
                else
                    I2C_GenerateSTART(I2Cx, ENABLE);                    // program a rep start
                index++;                                                // to show that the job is complete
            } else {                                                    // We need to send a subaddress
                I2C_GenerateSTART(I2Cx, ENABLE);                        // program the repeated Start
                subaddress_sent = 1;                                    // this is set back to zero upon completion of the current task
            }
        }
        // we must wait for the start to clear, otherwise we get constant BTF
        while (I2Cx->CR1 & 0x0100) {
            ;
        }
    } else if (SReg_1 & 0x0040) {                                       // Byte received - EV7
        read_p[index++] = (uint8_t)I2Cx->DR;
        if (bytes == (index + 3))
            I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE);                    // disable TXE to allow the buffer to flush so we can get an EV7_2
        if (bytes == index)                                             // We have completed a final EV7
            index++;                                                    // to show job is complete
    } else if (SReg_1 & 0x0080) {                                       // Byte transmitted EV8 / EV8_1
        if (index != -1) {                                              // we dont have a subaddress to send
            I2Cx->DR = write_p[index++];
            if (bytes == index)                                         // we have sent all the data
                I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE);                // disable TXE to allow the buffer to flush
        } else {
            index++;
            I2Cx->DR = reg;                                             // send the subaddress
            if (reading || !bytes)                                      // if receiving or sending 0 bytes, flush now
                I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE);                // disable TXE to allow the buffer to flush
        }
    }
    if (index == bytes + 1) {                                           // we have completed the current job
        subaddress_sent = 0;                                            // reset this here
        if (final_stop)                                                 // If there is a final stop and no more jobs, bus is inactive, disable interrupts to prevent BTF
            I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE);       // Disable EVT and ERR interrupts while bus inactive
        busy = 0;
    }
}
コード例 #5
0
ファイル: I2C.c プロジェクト: luciengou/FinderV2
ErrorStatus I2C_ByteRead(uint8_t I2C_Addrs,uint8_t ReadAddr,uint8_t Data_Buffer[],uint8_t Number_Bytes_to_Read)
{
	uint8_t i=0;
	ErrorStatus	status=ERROR;

	while(i<=7)
	{
		switch(i)
		{
			case 0:
			  	i++;		//Pass
				I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base
				while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY))	//Line busy
#else
				while(I2C->SR3 & 0x02)						//等待總線空閒 檢測i2c-SR3 busy位
#endif
					if(!(I2C_Time_Out_Counter--))			//Timeout Detect
				  	{
						//UART1_Printf("Byte Read case 0: Line Busy!! \n");
						i=7;
						break;
					}

				break;

			case 1:
				i++;		//Pass
				I2C_GenerateSTART(ENABLE);

				I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base
				while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT))	//EV5
#else
				while(!(I2C->SR1 & 0x01))  //等待START發送完 EV5
#endif
					if(!(I2C_Time_Out_Counter--))		//Timeout Detect
				  	{
						//UART1_Printf("Byte Read case 1: EV5 Error!! \n");
						i=7;
						break;
					}

	  			break;

			case 2:
				i++;		//Pass
				I2C_Send7bitAddress(I2C_Addrs, I2C_DIRECTION_TX);

				I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base
				//while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))	//EV6
				while(!(I2C->SR1 & 0x02))  //等特7位器件地址?送完并且收到ack,ADDR置1
					if(!(I2C_Time_Out_Counter--))		//Timeout Detect
				  	{
						//UART1_Printf("Byte Read case 2: EV6 Error!! \n");
						i=7;
						break;
				  	}

				//I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
				I2C_Clear_ADDRESSSENTMATCHED_Flag();
#else
				while(!(I2C->SR1 & 0x02))  //等特7位器件地址?送完并且收到ack,ADDR置1
					if(!(I2C_Time_Out_Counter--))		//Timeout Detect
				  	{
						//UART1_Printf("Byte Read case 2: EV6 Error!! \n");
						i=7;
						break;
					}

				I2C_Clear_ADDRESSSENTMATCHED_Flag();
#endif
	  			break;

			case 3:
				i++;
				I2C_SendData((uint8_t) (ReadAddr));	//Send Read Data Address

				I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base
				while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))	//EV8
#else
				//EV8_2 TxE=1 ,BTF=1,產生停止條件時由硬件清除。
  				while(!(I2C->SR1 & 0x84))	//檢測SR1 TXE1 BTF位置(只有當stm8收到ack,TxE才會置1,其實這句相當于判斷收到ack沒有?)
    										//在發送地址和清除ADDR 之后,I2C接口進入主設備接收模式。以下見stm8s中文數据手冊P252(圖97主設備接收模式接收序列圖)
#endif
					if(!(I2C_Time_Out_Counter--))		//Timeout Detect
				  	{
						//UART1_Printf("Byte Read case 3: EV8 Error!! \n");
						i=7;
						break;
				  	}

	  			break;

			case 4:
				i++;
				I2C_GenerateSTART(ENABLE);

				I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base
				while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT))	//EV5
#else
				while(!(I2C->SR1 & 0x01))  //等待START發送完 EV5
#endif
					if(!(I2C_Time_Out_Counter--))		//Timeout Detect
				  	{
						//UART1_Printf("Byte Read case 4: EV5 Error!! \n");
						i=7;
						break;
				  	}

	  			break;

			case 5:
				i++;
				I2C_Send7bitAddress(I2C_Addrs, I2C_DIRECTION_RX);

				I2C_Time_Out_Counter=I2C_Time_Out;

#ifdef	I2C_By_Function_Base
				//while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))	//EV6
				while(!(I2C->SR1 & 0x02))  //等特7位器件地址?送完并且收到ack,ADDR置1
					if(!(I2C_Time_Out_Counter--))		//Timeout Detect
				  	{
						//UART1_Printf("Byte Read case 5: EV6 Error!! \n");
						i=7;
						break;
				  	}

				//I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
				I2C_Clear_ADDRESSSENTMATCHED_Flag();
#else
				while(!(I2C->SR1 & 0x02))	//等特7位器件地址?送完并且收到ack,ADDR置1
			  		if(!(I2C_Time_Out_Counter--))		//Timeout Detect
				  	{
						//UART1_Printf("Byte Read case 5: EV6 Error!! \n");
						i=7;
						break;
				  	}

				I2C_Clear_ADDRESSSENTMATCHED_Flag();
#endif
	  			break;

			case 6:
				i=0xFF;	//I2C no error
				status=SUCCESS;

				I2C_Time_Out_Counter=I2C_Time_Out;

				while(Number_Bytes_to_Read>0)
				{
					if(!(I2C_Time_Out_Counter--))		//Timeout Detect
					{
						//UART1_Printf("Byte Read case 6: Data Reading Error!! \n");
						i=7;
						break;
					}

					if(Number_Bytes_to_Read==1)
					{
		  				I2C_AcknowledgeConfig(I2C_ACK_NONE);
						I2C_GenerateSTOP(ENABLE);
					}

					if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
					{
		 				*Data_Buffer=I2C_ReceiveData();
						Data_Buffer++;
						Number_Bytes_to_Read--;
					}
				}

				if(i==0xFF) I2C_AcknowledgeConfig(I2C_ACK_CURR);

				break;

			case 7:
				i=0xFD;	//Time Out Error
				status=ERROR;
				break;
		}
	}

	return status;
}
コード例 #6
0
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
        system_tick_t _millis;

	// clamp to buffer length
	if(quantity > BUFFER_LENGTH){
		quantity = BUFFER_LENGTH;
	}

	/* Send START condition */
	I2C_GenerateSTART(I2C1, ENABLE);

	_millis = millis();
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
	{
		if(EVENT_TIMEOUT < (millis() - _millis)) return 0;
	}

	/* Send Slave address for read */
	I2C_Send7bitAddress(I2C1, address, I2C_Direction_Receiver);

	_millis = millis();
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
	{
		if(EVENT_TIMEOUT < (millis() - _millis)) return 0;
	}

	/* perform blocking read into buffer */
	uint8_t *pBuffer = rxBuffer;
	uint8_t numByteToRead = quantity;
	uint8_t bytesRead = 0;

	/* While there is data to be read */
	while(numByteToRead)
	{
		if(numByteToRead == 1 && sendStop == true)
		{
			/* Disable Acknowledgement */
			I2C_AcknowledgeConfig(I2C1, DISABLE);

			/* Send STOP Condition */
			I2C_GenerateSTOP(I2C1, ENABLE);
		}

		if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
		{
			/* Read a byte from the Slave */
			*pBuffer = I2C_ReceiveData(I2C1);

			bytesRead++;

			/* Point to the next location where the byte read will be saved */
			pBuffer++;

			/* Decrement the read bytes counter */
			numByteToRead--;
		}
	}

	/* Enable Acknowledgement to be ready for another reception */
	I2C_AcknowledgeConfig(I2C1, ENABLE);

	// set rx buffer iterator vars
	rxBufferIndex = 0;
	rxBufferLength = bytesRead;

	return bytesRead;
}
コード例 #7
0
ファイル: stm32_eval_i2c_ee.c プロジェクト: Axis-Labs/STM32
/**
  * @brief  Writes more than one byte to the EEPROM with a single WRITE cycle.
  *
  * @note   The number of bytes (combined to write start address) must not 
  *         cross the EEPROM page boundary. This function can only write into
  *         the boundaries of an EEPROM page.
  *         This function doesn't check on boundaries condition (in this driver 
  *         the function sEE_WriteBuffer() which calls sEE_WritePage() is 
  *         responsible of checking on Page boundaries).
  * 
  * @param  pBuffer : pointer to the buffer containing the data to be written to 
  *         the EEPROM.
  * @param  WriteAddr : EEPROM's internal address to write to.
  * @param  NumByteToWrite : pointer to the variable holding number of bytes to 
  *         be written into the EEPROM. 
  * 
  *        @note The variable pointed by NumByteToWrite is reset to 0 when all the 
  *              data are written to the EEPROM. Application should monitor this 
  *              variable in order know when the transfer is complete.
  * 
  * @note This function just configure the communication and enable the DMA 
  *       channel to transfer data. Meanwhile, the user application may perform 
  *       other tasks in parallel.
  * 
  * @retval sEE_OK (0) if operation is correctly performed, else return value 
  *         different from sEE_OK (0) or the timeout user callback.
  */
uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
{ 
  /* Set the pointer to the Number of data to be written. This pointer will be used 
      by the DMA Transfer Completer interrupt Handler in order to reset the 
      variable to 0. User should check on this variable in order to know if the 
      DMA transfer has been complete or not. */
  sEEDataWritePointer = NumByteToWrite;  
  
  /*!< While the bus is busy */
  sEETimeout = sEE_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send START condition */
  I2C_GenerateSTART(sEE_I2C, ENABLE);
  
  /*!< Test on EV5 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send EEPROM address for write */
  sEETimeout = sEE_FLAG_TIMEOUT;
  I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);

  /*!< Test on EV6 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }

#ifdef sEE_M24C08
  
  /*!< Send the EEPROM's internal address to write to : only one byte Address */
  I2C_SendData(sEE_I2C, WriteAddr);
  
#elif defined(sEE_M24C64_32)
  
  /*!< Send the EEPROM's internal address to write to : MSB of the address first */
  I2C_SendData(sEE_I2C, (uint8_t)((WriteAddr & 0xFF00) >> 8));

  /*!< Test on EV8 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;  
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }  
  
  /*!< Send the EEPROM's internal address to write to : LSB of the address */
  I2C_SendData(sEE_I2C, (uint8_t)(WriteAddr & 0x00FF));
  
#endif /*!< sEE_M24C08 */  
  
  /*!< Test on EV8 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT; 
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }  
  
  /* Configure the DMA Tx Channel with the buffer address and the buffer size */
  sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint8_t)(*NumByteToWrite), sEE_DIRECTION_TX);
    
  /* Enable the DMA Tx Channel */
  DMA_Cmd(sEE_I2C_DMA_CHANNEL_TX, ENABLE);
  
  /* If all operations OK, return sEE_OK (0) */
  return sEE_OK;
}
コード例 #8
0
/**
  * @brief  Writes a value in a register of the device through I2C.
  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR
  *         or IOE_2_ADDR. 
  * @param  RegisterAddr: The target register address
  * @param  RegisterValue: The target register value to be written 
  * @retval IOE_OK: if all operations are OK. Other value if error.
  */
uint8_t I2C_WriteDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t RegisterValue)
{
  uint8_t read_verif = 0;
  uint8_t IOE_BufferTX = 0;
  
  /* Get Value to be written */
  IOE_BufferTX = RegisterValue;
  
  /* Configure DMA Peripheral */
  IOE_DMA_Config(IOE_DMA_TX, (uint8_t*)(&IOE_BufferTX));
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(IOE_I2C, ENABLE);
  
  /* Test on SB Flag */
  IOE_TimeOut = TIMEOUT_MAX;
  while (I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB) == RESET) 
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  IOE_TimeOut = TIMEOUT_MAX;
  while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }
  
  /* Transmit the first address for r/w operations */
  I2C_SendData(IOE_I2C, RegisterAddr);
  
  /* Test on TXE FLag (data dent) */
  IOE_TimeOut = TIMEOUT_MAX;
  while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(IOE_I2C,ENABLE);
  
  /* Enable DMA TX Channel */
  DMA_Cmd(IOE_DMA_TX_STREAM, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  IOE_TimeOut = TIMEOUT_MAX;
  while (!DMA_GetFlagStatus(IOE_DMA_TX_STREAM,IOE_DMA_TX_TCFLAG))
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }  
  
  /* Wait until BTF Flag is set before generating STOP */
  IOE_TimeOut = 2 * TIMEOUT_MAX;
  while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
  {
  }
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(IOE_I2C, ENABLE);
  
  /* Disable DMA TX Channel */
  DMA_Cmd(IOE_DMA_TX_STREAM, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(IOE_I2C,DISABLE);
  
  /* Clear DMA TX Transfer Complete Flag */
  DMA_ClearFlag(IOE_DMA_TX_STREAM,IOE_DMA_TX_TCFLAG);
  
#ifdef VERIFY_WRITTENDATA
  /* Verify (if needed) that the loaded data is correct  */
  
  /* Read the just written register*/
  read_verif = I2C_ReadDeviceRegister(DeviceAddr, RegisterAddr);
  /* Load the register and verify its value  */
  if (read_verif != RegisterValue)
  {
    /* Control data wrongly transfered */
    read_verif = IOE_FAILURE;
  }
  else
  {
    /* Control data correctly transfered */
    read_verif = 0;
  }
#endif
  
  /* Return the verifying value: 0 (Passed) or 1 (Failed) */
  return (read_verif);
}
コード例 #9
0
/**
  * @brief Writes a Byte to a given register into the audio codec through the 
           control interface (I2C)
  * @param RegisterAddr: The address (location) of the register to be written.
  * @param RegisterValue: the Byte value to be written into destination register.
  * @retval o if correct communication, else wrong communication
  */
static uint32_t Codec_WriteRegister(uint32_t RegisterAddr, uint32_t RegisterValue)
{
  uint32_t result = 0;

  /*!< While the bus is busy */
  CODECTimeout = CODEC_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /* Start the config sequence */
  I2C_GenerateSTART(CODEC_I2C, ENABLE);

  /* Test on EV5 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }

  /* Transmit the first address for write operation */
  I2C_SendData(CODEC_I2C, RegisterAddr);

  /* Test on EV8 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }

  /* Disable the interrupts mechanism to prevent the I2C communication from corruption */
  __disable_irq();
  
  /* Prepare the register value to be sent */
  I2C_SendData(CODEC_I2C, RegisterValue);
  
  /*!< Wait till all data have been physically transferred on the bus */
  CODECTimeout = CODEC_LONG_TIMEOUT;
  while(!I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BTF))
  {
    if((CODECTimeout--) == 0) Codec_TIMEOUT_UserCallback();
  }
  
  /* End the configuration sequence */
  I2C_GenerateSTOP(CODEC_I2C, ENABLE);  
  
#ifdef VERIFY_WRITTENDATA
  /* Verify that the data has been correctly written */  
  result = (Codec_ReadRegister(RegisterAddr) == RegisterValue)? 0:1;
#endif /* VERIFY_WRITTENDATA */
  
  /* Re-enable the interrupt mechanism */
  __enable_irq();
  
  /* Return the verifying value: 0 (Passed) or 1 (Failed) */
  return result;  
}
コード例 #10
0
ファイル: stm32l1xx_it.c プロジェクト: Amna2013/stm32-test
/**
  * @brief  This function handles I2Cx event interrupt request.
  * @param  None
  * @retval None
  */
void I2Cx_EV_IRQHandler(void)
{
#if defined (I2C_SLAVE)
  /* Get Last I2C Event */
  Event = I2C_GetLastEvent(I2Cx);
  switch (Event)
  { 
    /*****************************************************************************/
    /*                          Slave Transmitter Events                         */
    /*                                                                           */
    /* ***************************************************************************/  
    
    /* Check on EV1 */
  case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:  
      I2C_SendData(I2Cx, TxBuffer[Tx_Idx++]);
      /* Enable I2C event interrupt */
      I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE);
    break;
    
    /* Check on EV3 */
  case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:  
  case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:  
    if (Tx_Idx < NbrOfDataToSend)
      I2C_SendData(I2Cx, TxBuffer[Tx_Idx++]);
    else
      /* Disable I2C event interrupt */
      I2C_ITConfig(I2Cx, I2C_IT_EVT  | I2C_IT_BUF, DISABLE);
    break;
 
  default:
    break;  
  }
#endif /* I2C_SLAVE*/
  
#if defined (I2C_MASTER)
/*****************************************************************************/
/*                               Master Receiver                             */
/*                                                                           */
/* ***************************************************************************/  
#ifdef I2C_10BITS_ADDRESS  
  /* Check on SB Flag and clear it */
  if(I2C_GetITStatus(I2Cx, I2C_IT_SB)== SET)
  {
    if (Send_HeaderStatus == 0x00) 
    {
      /* Send Header to Slave for write */
      I2C_SendData(I2Cx, HEADER_ADDRESS_Write);
      Send_HeaderStatus = 0x01;
      GenerateStartStatus = 0x01;
    }
    else
    {
      /* Send Header to Slave for Read */
      I2C_SendData(I2Cx, HEADER_ADDRESS_Read);
      Send_HeaderStatus = 0x00;
      if (NumberOfByteToReceive == 0x03)
      {
        /* Disable buffer Interrupts */
        I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE);
      }
      else
      {
        /* Enable buffer Interrupts */
        I2C_ITConfig(I2Cx, I2C_IT_BUF , ENABLE);
      }
    }
  }
  /* Check on ADD10 Flag */
  else if(I2C_GetITStatus(I2Cx, I2C_IT_ADD10)== SET)
  {
    /* Send slave Address */
    I2C_Send7bitAddress(I2Cx, (uint8_t)SLAVE_ADDRESS, I2C_Direction_Transmitter);   
  }   
  
#else /* I2C_7BITS_ADDRESS */
  
  /* Check on EV5 */
  if(I2C_GetITStatus(I2Cx, I2C_IT_SB)== SET)
  {
    /* Send slave Address for read */
    I2C_Send7bitAddress(I2Cx, SLAVE_ADDRESS, I2C_Direction_Receiver);
    if (NumberOfByteToReceive == 0x03)
    {
      /* Disable buffer Interrupts */
      I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE);
    }
    else
    {
      /* Enable buffer Interrupts */
      I2C_ITConfig(I2Cx, I2C_IT_BUF , ENABLE);
    }
  }  
#endif /* I2C_10BITS_ADDRESS */
  
  else if(I2C_GetITStatus(I2Cx, I2C_IT_ADDR)== SET)
  {
    if (NumberOfByteToReceive == 1)
    {
      I2C_AcknowledgeConfig(I2Cx, DISABLE);
    }
    
    /* Clear ADDR Register */
    (void)(I2Cx->SR1);
    (void)(I2Cx->SR2);  
    if (GenerateStartStatus == 0x00)
    { 
      if (NumberOfByteToReceive == 1)
      {
         I2C_GenerateSTOP(I2Cx, ENABLE);  
      }  
      
      if (NumberOfByteToReceive == 2)
      {
        I2C_AcknowledgeConfig(I2Cx, DISABLE);
        I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next);
        /* Disable buffer Interrupts */
        I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE);
      }
    }
    
#ifdef I2C_10BITS_ADDRESS   
    if (GenerateStartStatus == 0x01)
    {
      /* Repeated Start */
      I2C_GenerateSTART(I2Cx, ENABLE);
      GenerateStartStatus = 0x00;
    }
    
#endif /* I2C_10BITS_ADDRESS */
  } 
  
  else if((I2C_GetITStatus(I2Cx, I2C_IT_RXNE)== SET)&&(I2C_GetITStatus(I2Cx, I2C_IT_BTF)== RESET))
  {
    /* Store I2C received data */
    RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx);
    NumberOfByteToReceive--;
    
    if (NumberOfByteToReceive == 0x03)
    {
      /* Disable buffer Interrupts */
      I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE);
    }

    if (NumberOfByteToReceive == 0x00)
    {
      /* Disable Error and Buffer Interrupts */
      I2C_ITConfig(I2Cx, (I2C_IT_EVT | I2C_IT_BUF), DISABLE);            
    }
  }    
  /* BUSY, MSL and RXNE flags */
  else if(I2C_GetITStatus(I2Cx, I2C_IT_BTF)== SET)
  {
    /* if Three bytes remaining for reception */
    if (NumberOfByteToReceive == 3)
    {
      I2C_AcknowledgeConfig(I2Cx, DISABLE);
      /* Store I2C received data */
      RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx);
      NumberOfByteToReceive--;        
    } 
    else if (NumberOfByteToReceive == 2)
    {           
      I2C_GenerateSTOP(I2Cx, ENABLE);    
      
      /* Store I2C received data */
      RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx);
      NumberOfByteToReceive--;
      /* Store I2C received data */
      RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx);
      NumberOfByteToReceive--;        
      /* Disable Error and Buffer Interrupts */
      I2C_ITConfig(I2Cx, (I2C_IT_EVT | I2C_IT_BUF), DISABLE);            
    }
    else 
    {
      /* Store I2C received data */
      RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx);
      NumberOfByteToReceive--;
    }
  } 
#endif /* I2C_MASTER*/
}
コード例 #11
0
/**
  * @brief  Reads a buffer of 2 bytes from the device registers.
  * @param  DeviceAddr: The address of the device, could be : IOE_1_ADDR
  *         or IOE_2_ADDR. 
  * @param  RegisterAddr: The target register address (between 00x and 0x24)
  * @retval A pointer to the buffer containing the two returned bytes (in halfword).  
  */
uint16_t I2C_ReadDataBuffer(uint8_t DeviceAddr, uint8_t RegisterAddr)
{ 
  uint8_t tmp= 0;
  uint8_t IOE_BufferRX[2] = {0x00, 0x00};  
  
  /* Configure DMA Peripheral */
  IOE_DMA_Config(IOE_DMA_RX, (uint8_t*)IOE_BufferRX);
  
  /* Enable DMA NACK automatic generation */
  I2C_DMALastTransferCmd(IOE_I2C, ENABLE);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(IOE_I2C, ENABLE);
  
  /* Test on SB Flag */
  IOE_TimeOut = TIMEOUT_MAX;
  while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }
  
  /* Send device address for write */
  I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  IOE_TimeOut = TIMEOUT_MAX;
  while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }
  
  /* Send the device's internal address to write to */
  I2C_SendData(IOE_I2C, RegisterAddr);  
  
  /* Test on TXE FLag (data dent) */
  IOE_TimeOut = TIMEOUT_MAX;
  while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }
  
  /* Send START condition a second time */  
  I2C_GenerateSTART(IOE_I2C, ENABLE);
  
  /* Test on SB Flag */
  IOE_TimeOut = TIMEOUT_MAX;
  while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }
  
  /* Send IOExpander address for read */
  I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Receiver);
  
  /* Test on ADDR Flag */
  IOE_TimeOut = TIMEOUT_MAX;
  while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(IOE_I2C,ENABLE);
  
  /* Enable DMA RX Channel */
  DMA_Cmd(IOE_DMA_RX_STREAM, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  IOE_TimeOut = 2 * TIMEOUT_MAX;
  while (!DMA_GetFlagStatus(IOE_DMA_RX_STREAM, IOE_DMA_RX_TCFLAG))
  {
    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
  }        
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(IOE_I2C, ENABLE);
  
  /* Disable DMA RX Channel */
  DMA_Cmd(IOE_DMA_RX_STREAM, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(IOE_I2C,DISABLE);
  
  /* Clear DMA RX Transfer Complete Flag */
  DMA_ClearFlag(IOE_DMA_RX_STREAM,IOE_DMA_RX_TCFLAG);
  
  /* Reorganize received data */  
  tmp = IOE_BufferRX[0];
  IOE_BufferRX[0] = IOE_BufferRX[1];
  IOE_BufferRX[1] = tmp;
  
  /* return a pointer to the IOE_Buffer */
  return (*(__IO uint16_t *) IOE_BufferRX);
}
コード例 #12
0
ファイル: PPP_init.c プロジェクト: mainbody/YellowDog
/********************
- 传感器I2C总线的事件中断服务程序
*********************/
void SENSOR_I2C_BUS_EV_ISR(void)
{
	//-SB
	if(I2C_GetITStatus(SENSOR_I2C_BUS, I2C_IT_SB))
		{
		I2C_AcknowledgeConfig(SENSOR_I2C_BUS, DISABLE);
		if((sensor_state.data_direction==I2C_Direction_Receiver) && sensor_state.SUB_Transmitted)
			{
			sensor_state.SUB_Transmitted = SET;
			I2C_Send7bitAddress(SENSOR_I2C_BUS, sensor_state.sensor_address, I2C_Direction_Receiver);
			}
		else
			{
			I2C_Send7bitAddress(SENSOR_I2C_BUS, sensor_state.sensor_address, I2C_Direction_Transmitter);
			}
		}
	
	//-ADDR
	else if(I2C_GetITStatus(SENSOR_I2C_BUS, I2C_IT_ADDR))
		{
		volatile uint8_t a=SENSOR_I2C_BUS->SR1;//Read SR1,2 to clear ADDR
		a=SENSOR_I2C_BUS->SR2;
		if(sensor_state.data_direction==I2C_Direction_Receiver && sensor_state.SUB_Transmitted) //已发送SUB,开始接收1字节[ref manual P735]
			{
			I2C_AcknowledgeConfig(SENSOR_I2C_BUS, DISABLE);//turn off ACK
			I2C_GenerateSTOP(SENSOR_I2C_BUS,ENABLE);//program the stop
			I2C_ITConfig(SENSOR_I2C_BUS, I2C_IT_BUF, ENABLE);
			}
		else //接收多于3字节;发送SUB或正在发送
			{
			I2C_ITConfig(SENSOR_I2C_BUS, I2C_IT_BUF, ENABLE);
			}
		}/*
	//-BTF										
	else if(I2C_GetITStatus(SENSOR_I2C_BUS, I2C_IT_BTF))
		{
		volatile uint8_t b=SENSOR_I2C_BUS->SR1;
		if(sensor_state.data_direction==I2C_Direction_Receiver && sensor_state.SUB_Transmitted)
			{}
		else
			{
			I2C_GenerateSTART(SENSOR_I2C_BUS, ENABLE);
			}
		}*/
	
	//-RXNE
	else if(I2C_GetITStatus(SENSOR_I2C_BUS, I2C_IT_RXNE))
		{
		sensor_state.receive_data=I2C_ReceiveData(SENSOR_I2C_BUS);
		I2C_ITConfig(SENSOR_I2C_BUS, I2C_IT_BUF, DISABLE);
		sensor_state.data_receive_finish=SET;
		}
	
	//-TXE
	else if(I2C_GetITStatus(SENSOR_I2C_BUS, I2C_IT_TXE))
		{
		I2C_SendData(SENSOR_I2C_BUS, sensor_state.SUB);
		sensor_state.SUB_Transmitted=SET;
		if(sensor_state.data_direction==I2C_Direction_Receiver)
			I2C_ITConfig(SENSOR_I2C_BUS, I2C_IT_BUF, DISABLE);
		I2C_GenerateSTART(SENSOR_I2C_BUS, ENABLE);
		}
/**/
	if(sensor_state.data_receive_finish)
		{
		uint8_t temp=(sensor_state.I2C_run_flag&0x07);//读出偏移量(低3位)
		
		sensor_state.data_receive_finish=RESET;
		sensor_state.SUB_Transmitted=RESET;

		switch(sensor_state.I2C_run_flag&0xE0)
			{
			case ACCER_READING:
				{
				(*(ACCER_DATA_BASE+temp))=sensor_state.receive_data;
				}
				break;
			case GYRO_READING:
				{
				(*(GYRO_DATA_BASE+temp))=sensor_state.receive_data;
				}
				break;
			case MEGN_READING://reserve!
				{
				}
				break;
			default:
				break;
			}
		
		if(temp<5)//未读够6个字节数据(0:5)
			{
			sensor_state.I2C_run_flag++;//接收完一个字节,标志加1
			sensor_state.SUB++;
			sensor_state.SUB_Transmitted=RESET;
			I2C_GenerateSTART(SENSOR_I2C_BUS, ENABLE);
			}
		else//接收到第6个字节
			{
			sensor_state.I2C_run_flag=0;//复位所有运行标志
			}		
		}
}
コード例 #13
0
ファイル: I2CDev.cpp プロジェクト: tqkhcmut/TwoWheels
I2C_RESULT I2CDev::readBytes(uint8_t devAddr, uint8_t regAddr, uint16_t count, uint8_t * buf)
{
	uint32_t tmpTime = millis();
	// busy check
	while(IsBusy);
	IsBusy = 1;
	
	// ENTR_CRT_SECTION();
 
  /* While the bus is busy */
  while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
 
  /* Send START condition */
  I2C_GenerateSTART(I2C2, ENABLE);
 
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
 
  /* Send MPU6050 address (0xD0) for write */ 
  I2C_Send7bitAddress(I2C2, devAddr, I2C_Direction_Transmitter);
 
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
  /* Clear EV6 by setting again the PE bit */
  I2C_Cmd(I2C2, ENABLE);
 
  /* Send the MPU6050_Magn's internal address to write to */
  I2C_SendData(I2C2, regAddr);
 
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
  /* Send STRAT condition a second time */
  I2C_GenerateSTART(I2C2, ENABLE);
 
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
 
  /* Send MPU6050 address for read */
  I2C_Send7bitAddress(I2C2, devAddr, I2C_Direction_Receiver);
 
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
 
  /* While there is data to be read */
  while(count)
  {
    if(count == 1)
    {
      /* Disable Acknowledgement */
      I2C_AcknowledgeConfig(I2C2, DISABLE);
 
      /* Send STOP Condition */
      I2C_GenerateSTOP(I2C2, ENABLE);
    }
 
    /* Test on EV7 and clear it */
    if(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED))
    {
      /* Read a byte from the MPU6050 */
      *buf = I2C_ReceiveData(I2C2);
 
      /* Point to the next location where the byte read will be saved */
      buf++;
 
      /* Decrement the read bytes counter */
      count--;
    }
  }
 
  /* Enable Acknowledgement to be ready for another reception */
  I2C_AcknowledgeConfig(I2C2, ENABLE);
//  EXT_CRT_SECTION();
	
	// 
	IsBusy = 0;
	return I2C_OK;	
}
コード例 #14
0
ファイル: I2CDev.cpp プロジェクト: tqkhcmut/TwoWheels
I2C_RESULT I2CDev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint16_t count, uint8_t * buf)
{
	uint32_t tmpTime = 0;
	// busy check
	while(IsBusy);
	IsBusy = 1;
	
	if (count == 1) // multi-bytes haven't been implemented yet
	{
		/* Test on BUSY Flag */
		tmpTime = millis();
		while (I2C_GetFlagStatus(I2C2,I2C_FLAG_BUSY)) 
		{
			if(millis() - tmpTime > TimeOut) 
			{
				IsBusy = 0;
				return I2C_TIMEOUT;
			}
		}
		
		
		/* Enable the I2C peripheral */
		I2C_GenerateSTART(I2C2, ENABLE);
		
		/* Test on SB Flag */
		tmpTime = millis();
		while (I2C_GetFlagStatus(I2C2,I2C_FLAG_SB) == RESET) 
		{
			if(millis() - tmpTime > TimeOut) 
			{
				IsBusy = 0;
				return I2C_TIMEOUT;
			}
		}
		
		/* Transmit the slave address and enable writing operation */
		I2C_Send7bitAddress(I2C2, devAddr, I2C_Direction_Transmitter);
		
		/* Test on ADDR Flag */
		tmpTime = millis();
		while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
		{
			if(millis() - tmpTime > TimeOut) 
			{
				IsBusy = 0;
				return I2C_TIMEOUT;
			}
		}
		
		/* Transmit the first address for r/w operations */
		I2C_SendData(I2C2, regAddr);
		
		/* Test on TXE FLag (data sent) */
		tmpTime = millis();
		while ((!I2C_GetFlagStatus(I2C2,I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(I2C2,I2C_FLAG_BTF)))  
		{
			if(millis() - tmpTime > TimeOut) 
			{
				IsBusy = 0;
				return I2C_TIMEOUT;
			}
		}  
			
		 /* Transmit the first address for r/w operations */
		I2C_SendData(I2C2, *buf);
		
		/* Test on TXE FLag (data sent) */
		tmpTime = millis();
		while ((!I2C_GetFlagStatus(I2C2,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(I2C2,I2C_FLAG_BTF)))  
		{
			if(millis() - tmpTime > TimeOut) 
			{
				IsBusy = 0;
				return I2C_TIMEOUT;
			}
		} 
			
		/*!< Send STOP Condition */
		I2C_GenerateSTOP(I2C2, ENABLE);
		 
			
		/* Wait to make sure that STOP control bit has been cleared */
		tmpTime = millis();
		while(I2C2->CR1 & I2C_CR1_STOP)
		{
			if(millis() - tmpTime > TimeOut) 
			{
				IsBusy = 0;
				return I2C_TIMEOUT;
			}
		}  
			
		// 
		IsBusy = 0;
		return I2C_OK;
	}
	
	// 
	IsBusy = 0;
	return I2C_FAIL;
}
コード例 #15
0
ファイル: MPU6050.c プロジェクト: edisonlee102/Balance_Robat
/**
 * @brief  Reads a block of data from the MPU6050.
 * @param  slaveAddr  : slave address MPU6050_DEFAULT_ADDRESS
 * @param  pBuffer : pointer to the buffer that receives the data read from the MPU6050.
 * @param  readAddr : MPU6050's internal address to read from.
 * @param  NumByteToRead : number of bytes to read from the MPU6050 ( NumByteToRead >1  only for the Mgnetometer readinf).
 * @return None
 */
void MPU6050_I2C_BufferRead(u8 slaveAddr, u8* pBuffer, u8 readAddr, u16 NumByteToRead)
{
    // ENTR_CRT_SECTION();

    /* While the bus is busy */
    while (I2C_GetFlagStatus(MPU6050_I2C, I2C_FLAG_BUSY));

    /* Send START condition */
    I2C_GenerateSTART(MPU6050_I2C, ENABLE);

    /* Test on EV5 and clear it */
    while (!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_MODE_SELECT));

    /* Send MPU6050 address for write */
    I2C_Send7bitAddress(MPU6050_I2C, slaveAddr, I2C_Direction_Transmitter);

    /* Test on EV6 and clear it */
    while (!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    /* Clear EV6 by setting again the PE bit */
    I2C_Cmd(MPU6050_I2C, ENABLE);

    /* Send the MPU6050's internal address to write to */
    I2C_SendData(MPU6050_I2C, readAddr);

    /* Test on EV8 and clear it */
    while (!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* Send STRAT condition a second time */
    I2C_GenerateSTART(MPU6050_I2C, ENABLE);

    /* Test on EV5 and clear it */
    while (!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_MODE_SELECT));

    /* Send MPU6050 address for read */
    I2C_Send7bitAddress(MPU6050_I2C, slaveAddr, I2C_Direction_Receiver);

    /* Test on EV6 and clear it */
    while (!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    /* While there is data to be read */
    while (NumByteToRead)
    {
        if (NumByteToRead == 1)
        {
            /* Disable Acknowledgement */
            I2C_AcknowledgeConfig(MPU6050_I2C, DISABLE);

            /* Send STOP Condition */
            I2C_GenerateSTOP(MPU6050_I2C, ENABLE);
        }

        /* Test on EV7 and clear it */
        if (I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            /* Read a byte from the MPU6050 */
            *pBuffer = I2C_ReceiveData(MPU6050_I2C);

            /* Point to the next location where the byte read will be saved */
            pBuffer++;

            /* Decrement the read bytes counter */
            NumByteToRead--;
        }
    }

    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(MPU6050_I2C, ENABLE);
    // EXT_CRT_SECTION();
}
コード例 #16
0
/**
  * @brief Reads and returns te value of an audio codec register through the 
  *        control interface (I2C).
  * @param RegisterAddr: Address of the register to be read.
  * @retval Value of the register to be read or dummy value if the communication
  *         fails.
  */
static uint32_t Codec_ReadRegister(uint32_t RegisterAddr)
{
  uint32_t result = 0;

  /*!< While the bus is busy */
  CODECTimeout = CODEC_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /* Start the config sequence */
  I2C_GenerateSTART(CODEC_I2C, ENABLE);

  /* Test on EV5 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }

  /* Transmit the register address to be read */
  I2C_SendData(CODEC_I2C, RegisterAddr);

  /* Test on EV8 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BTF) == RESET)
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /*!< Send STRAT condition a second time */  
  I2C_GenerateSTART(CODEC_I2C, ENABLE);
  
  /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  } 

  __disable_irq();
  
  /*!< Send Codec address for read */
  I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Receiver);  
  
  /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_ADDR) == RESET)
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }     
  
  /*!< Disable Acknowledgement */
  I2C_AcknowledgeConfig(CODEC_I2C, DISABLE);   
  
  /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
  (void)CODEC_I2C->SR2;
  
  /*!< Send STOP Condition */
  I2C_GenerateSTOP(CODEC_I2C, ENABLE);
  
  /* Wait for the byte to be received */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_RXNE) == RESET)
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /*!< Read the byte received from the Codec */
  result = I2C_ReceiveData(CODEC_I2C);
  
  /* Wait to make sure that STOP flag has been cleared */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while(CODEC_I2C->CR1 & I2C_CR1_STOP)
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }  
  
  /*!< Re-Enable Acknowledgement to be ready for another reception */
  I2C_AcknowledgeConfig(CODEC_I2C, ENABLE);  
  
  /* Clear AF flag for next communication */
  I2C_ClearFlag(CODEC_I2C, I2C_FLAG_AF); 

  /* Re-enable the interrupt mechanism */
  __enable_irq();
  
  /* Return the byte read from Codec */
  return result;
}
コード例 #17
0
ファイル: main.c プロジェクト: szymon2103/Stm32
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f2xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f2xx.c file
     */

  /* I2C configuration ---------------------------------------------------------*/
  I2C_Config();

  /* Initialize LEDs mounted on STM322xG-EVAL board */
  STM_EVAL_LEDInit(LED1);
  STM_EVAL_LEDInit(LED2);
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED4);

#if defined (I2C_MASTER)
  /* Initialize push-buttons mounted on STM322xG-EVAL board */
  TimeOut = USER_TIMEOUT;
  while ((IOE_Config() != IOE_OK) && (TimeOut != 0x00))
  {}

  if(TimeOut == 0)
  {
    TimeOut_UserCallback();
  }
#endif /* I2C_MASTER */

  /* SysTick configuration -----------------------------------------------------*/
  SysTickConfig();

/*************************************Master Code******************************/
#if defined (I2C_MASTER)
  /* I2C De-initialize */
  I2C_DeInit(I2Cx);

  /*!< I2C Struct Initialize */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;
  I2C_InitStructure.I2C_OwnAddress1 = 0xA0;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;

#ifndef I2C_10BITS_ADDRESS
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
#else
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_10bit;
#endif /* I2C_10BITS_ADDRESS */

  /*!< I2C Initialize */
  I2C_Init(I2Cx, &I2C_InitStructure);

  /* Enable Error Interrupt */
  I2C_ITConfig(I2Cx, I2C_IT_ERR , ENABLE);

  /* I2C ENABLE */
  I2C_Cmd(I2Cx, ENABLE);

  while (1)
  {
    CmdTransmitted = 0x00;
    NumberOfByte = 0x00;
    Tx_Idx = 0x00;

    /* Clear PressedButton by reading joystick */
    PressedButton = IOE_JoyStickGetState();

    /* Waiting joystick pressed */
    while (PressedButton == JOY_NONE)
    {
      PressedButton = IOE_JoyStickGetState();
    }

    /* I2C in Master Transmitter Mode ----------------------------------------*/
    switch (PressedButton)
    {
      /* JOY_RIGHT button pressed */
      case JOY_RIGHT:
        NumberOfByte = CMD_RIGHT_SIZE;
        CmdTransmitted = CMD_RIGHT;
        break;
      /* JOY_LEFT button pressed */
      case JOY_LEFT:
        NumberOfByte = CMD_LEFT_SIZE;
        CmdTransmitted = CMD_LEFT;
        break;
      /* JOY_UP button pressed */
      case JOY_UP:
        NumberOfByte = CMD_UP_SIZE;
        CmdTransmitted = CMD_UP;
        break;
      /* JOY_DOWN button pressed */
      case JOY_DOWN:
        NumberOfByte = CMD_DOWN_SIZE;
        CmdTransmitted = CMD_DOWN;
        break;
      /* JOY_SEL button pressed */
      case JOY_SEL:
        NumberOfByte = CMD_SEL_SIZE;
        CmdTransmitted = CMD_SEL;
        break;
      default:
        break;
    }

    if (CmdTransmitted != 0x00)
    {
      /* Enable Error and Buffer Interrupts */
      I2C_ITConfig(I2Cx, (I2C_IT_EVT | I2C_IT_BUF), ENABLE);
      /* Generate the Start condition */
      I2C_GenerateSTART(I2Cx, ENABLE);
      /* Data transfer is performed in the I2C interrupt routine */
      /* Wait until end of data transfer or time out */
       TimeOut = USER_TIMEOUT;
       while ((Tx_Idx < GetVar_NbrOfDataToTransfer())&&(TimeOut != 0x00))
       {}
       if(TimeOut == 0)
       {
         TimeOut_UserCallback();
       }

       TimeOut = USER_TIMEOUT;
       while ((I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))&&(TimeOut != 0x00))
       {}
       if(TimeOut == 0)
       {
         TimeOut_UserCallback();
       }
    }
  }
#endif /* I2C_MASTER */


  /**********************************Slave Code**********************************/
#if defined (I2C_SLAVE)

  I2C_DeInit(I2Cx);

  /* Initialize I2C peripheral */
  /*!< I2C Init */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;
  I2C_InitStructure.I2C_OwnAddress1 = SLAVE_ADDRESS;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;

#ifndef I2C_10BITS_ADDRESS
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
#else
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_10bit;
#endif /* I2C_10BITS_ADDRESS */

  I2C_Init(I2Cx, &I2C_InitStructure);

  /* Enable Error Interrupt */
  I2C_ITConfig(I2Cx, (I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);

  /* I2C ENABLE */
  I2C_Cmd(I2Cx, ENABLE);

  /* Infinite Loop */
  while (1)
  {
    CmdReceived = 0x00;
    NumberOfByte = 0x00;

    /* Clear the RxBuffer */
    Fill_Buffer(RxBuffer, RXBUFFERSIZE);

    while (CmdReceived == 0x00)
    {}

    /* Wait until end of data transfer */
    while (Rx_Idx < GetVar_NbrOfDataToReceive())
    {}

    /* I2C in Slave Receiver Mode --------------------------------------------*/
    if (CmdReceived != 0x00)
    {
      switch (Rx_Idx)
      {
        /* Right button pressed */
      case CMD_RIGHT_SIZE:
        if (Buffercmp(TxBuffer, RxBuffer, CMD_RIGHT_SIZE) == PASSED)
        {
          /* Turn ON LED2 and LED3 */
          STM_EVAL_LEDOn(LED2);
          STM_EVAL_LEDOn(LED3);
          /* Turn all other LEDs off */
          STM_EVAL_LEDOff(LED4);
        }
        break;
        /* Left button pressed*/
      case CMD_LEFT_SIZE:
        if (Buffercmp(TxBuffer, RxBuffer, CMD_LEFT_SIZE) == PASSED)
        {
          /* Turn ON LED4 */
          STM_EVAL_LEDOn(LED4);
          /* Turn all other LEDs off */
          STM_EVAL_LEDOff(LED2);
          STM_EVAL_LEDOff(LED3);
        }
        break;
        /* Up button pressed */
      case CMD_UP_SIZE:
        if (Buffercmp(TxBuffer, RxBuffer, CMD_UP_SIZE) == PASSED)
        {
          /* Turn ON LED2 */
          STM_EVAL_LEDOn(LED2);
          /* Turn all other LEDs off */
          STM_EVAL_LEDOff(LED3);
          STM_EVAL_LEDOff(LED4);
        }
        break;
        /* Down button pressed */
      case CMD_DOWN_SIZE:
        if (Buffercmp(TxBuffer, RxBuffer, CMD_DOWN_SIZE) == PASSED)
        {
          /* Turn ON LED3 */
          STM_EVAL_LEDOn(LED3);
          /* Turn all other LEDs off */
          STM_EVAL_LEDOff(LED2);
          STM_EVAL_LEDOff(LED4);
        }
        break;
        /* Sel button pressed */
      case CMD_SEL_SIZE:
        if (Buffercmp(TxBuffer, RxBuffer, CMD_SEL_SIZE) == PASSED)
        {
          /* Turn ON all LEDs */
          STM_EVAL_LEDOn(LED2);
          STM_EVAL_LEDOn(LED3);
          STM_EVAL_LEDOn(LED4);
        }
        break;
      default:
        break;
      }
    }
  }
#endif /* I2C_SLAVE */
}
コード例 #18
0
/**
  * @brief  Read the configuration register from the LM75.
  * @param  None
  * @retval LM75 configuration register value.
  */
uint8_t LM75_ReadConfReg(void)
{
  __IO uint8_t RegValue = 0;

  /* Enable LM75_I2C acknowledgement if it is already disabled by other function */
  I2C_AcknowledgeConfig(LM75_I2C, ENABLE);
  /*----------------------------- Transmission Phase --------------------------*/
  /* Send LM75_I2C START condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on LM75_I2C EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);

  /* Test on LM75_I2C EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }

  /* Send the configuration register data pointer */
  I2C_SendData(LM75_I2C, LM75_REG_CONF);

  /* Test on LM75_I2C EV8 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }

  /*----------------------------- Reception Phase -----------------------------*/
  /* Send Re-STRAT condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for read */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))  /* EV6 */
  {
  }

  /* Disable LM75_I2C acknowledgement */
  I2C_AcknowledgeConfig(LM75_I2C, DISABLE);

  /* Send LM75_I2C STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);

  /* Test on RXNE flag */
  while (I2C_GetFlagStatus(LM75_I2C, I2C_FLAG_RXNE) == RESET);

  /* Store LM75_I2C received data */
  RegValue = I2C_ReceiveData(LM75_I2C);

  /* Return configuration register value */
  return (RegValue);
}
コード例 #19
0
ファイル: stm32_eval_i2c_ee.c プロジェクト: Axis-Labs/STM32
/**
  * @brief  Reads a block of data from the EEPROM.
  * @param  pBuffer : pointer to the buffer that receives the data read from 
  *         the EEPROM.
  * @param  ReadAddr : EEPROM's internal address to start reading from.
  * @param  NumByteToRead : pointer to the variable holding number of bytes to 
  *         be read from the EEPROM.
  * 
  *        @note The variable pointed by NumByteToRead is reset to 0 when all the 
  *              data are read from the EEPROM. Application should monitor this 
  *              variable in order know when the transfer is complete.
  * 
  * @note When number of data to be read is higher than 1, this function just 
  *       configures the communication and enable the DMA channel to transfer data.
  *       Meanwhile, the user application may perform other tasks.
  *       When number of data to be read is 1, then the DMA is not used. The byte
  *       is read in polling mode.
  * 
  * @retval sEE_OK (0) if operation is correctly performed, else return value 
  *         different from sEE_OK (0) or the timeout user callback.
  */
uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{  
  /* Set the pointer to the Number of data to be read. This pointer will be used 
      by the DMA Transfer Completer interrupt Handler in order to reset the 
      variable to 0. User should check on this variable in order to know if the 
      DMA transfer has been complete or not. */
  sEEDataReadPointer = NumByteToRead;
  
  /*!< While the bus is busy */
  sEETimeout = sEE_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send START condition */
  I2C_GenerateSTART(sEE_I2C, ENABLE);
  
  /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send EEPROM address for write */
  I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);

  /*!< Test on EV6 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  } 

#ifdef sEE_M24C08  
  
  /*!< Send the EEPROM's internal address to read from: Only one byte address */
  I2C_SendData(sEE_I2C, ReadAddr);  

#elif defined (sEE_M24C64_32)

  /*!< Send the EEPROM's internal address to read from: MSB of the address first */
  I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));    

  /*!< Test on EV8 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }

  /*!< Send the EEPROM's internal address to read from: LSB of the address */
  I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF));    
  
#endif /*!< sEE_M24C08 */

  /*!< Test on EV8 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF) == RESET)
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send STRAT condition a second time */  
  I2C_GenerateSTART(sEE_I2C, ENABLE);
  
  /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  } 
  
  /*!< Send EEPROM address for read */
  I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Receiver);  
  
  /* If number of data to be read is 1, then DMA couldn't be used */
  /* One Byte Master Reception procedure (POLLING) ---------------------------*/
  if ((uint16_t)(*NumByteToRead) < 2)
  {
    /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_ADDR) == RESET)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }     
    
    /*!< Disable Acknowledgement */
    I2C_AcknowledgeConfig(sEE_I2C, DISABLE);   

    /* Call User callback for critical section start (should typically disable interrupts) */
    sEE_EnterCriticalSection_UserCallback();
    
    /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
    (void)sEE_I2C->SR2;
    
    /*!< Send STOP Condition */
    I2C_GenerateSTOP(sEE_I2C, ENABLE);
   
    /* Call User callback for critical section end (should typically re-enable interrupts) */
    sEE_ExitCriticalSection_UserCallback();
    
    /* Wait for the byte to be received */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_RXNE) == RESET)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }
    
    /*!< Read the byte received from the EEPROM */
    *pBuffer = I2C_ReceiveData(sEE_I2C);
    
    /*!< Decrement the read bytes counter */
    (uint16_t)(*NumByteToRead)--;        
    
    /* Wait to make sure that STOP control bit has been cleared */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(sEE_I2C->CR1 & I2C_CR1_STOP)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }  
    
    /*!< Re-Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(sEE_I2C, ENABLE);    
  }
  else/* More than one Byte Master Reception procedure (DMA) -----------------*/
  {
    /*!< Test on EV6 and clear it */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }  
    
    /* Configure the DMA Rx Channel with the buffer address and the buffer size */
    sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint16_t)(*NumByteToRead), sEE_DIRECTION_RX);
    
    /* Inform the DMA that the next End Of Transfer Signal will be the last one */
    I2C_DMALastTransferCmd(sEE_I2C, ENABLE); 
    
    /* Enable the DMA Rx Channel */
    DMA_Cmd(sEE_I2C_DMA_CHANNEL_RX, ENABLE);  
  }
  
  /* If all operations OK, return sEE_OK (0) */
  return sEE_OK;
}
コード例 #20
0
/**
  * @brief  Enables or disables the LM75.
  * @param  NewState: specifies the LM75 new status. This parameter can be ENABLE
  *         or DISABLE.
  * @retval None
  */
void LM75_ShutDown(FunctionalState NewState)
{
  __IO uint8_t RegValue = 0;

  /*---------------------------- Transmission Phase ---------------------------*/
  /* Send LM75_I2C START condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on LM75_I2C EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);

  /* Test on LM75_I2C EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }

  /* Send the configuration register data pointer */
  I2C_SendData(LM75_I2C, LM75_REG_CONF);

  /* Test on LM75_I2C EV8 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))  /* EV8 */
  {
  }

  /*-------------------------------- Reception Phase --------------------------*/
  /* Send Re-STRAT condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for read */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))  /* EV6 */
  {
  }

  /* Disable LM75_I2C acknowledgement */
  I2C_AcknowledgeConfig(LM75_I2C, DISABLE);

  /* Send LM75_I2C STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);

  /* Test on RXNE flag */
  while (I2C_GetFlagStatus(LM75_I2C, I2C_FLAG_RXNE) == RESET);

  /* Store LM75_I2C received data */
  RegValue = I2C_ReceiveData(LM75_I2C);

  /*------------------------------------ Transmission Phase -------------------*/
  /* Send LM75_I2C START condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on LM75_I2C EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);

  /* Test on LM75_I2C EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }

  /* Send the configuration register data pointer */
  I2C_SendData(LM75_I2C, LM75_REG_CONF);

  /* Test on LM75_I2C EV8 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }

  /* Enable or disable SD bit */
  if (NewState != DISABLE)
  {
    /* Enable LM75 */
    I2C_SendData(LM75_I2C, (uint8_t)(RegValue & LM75_SD_RESET));
  }
  else
  {
    /* Disable LM75 */
    I2C_SendData(LM75_I2C, (uint8_t)(RegValue | LM75_SD_SET));
  }

  /* Test on LM75_I2C EV8 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }

  /* Send LM75_I2C STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);

}
コード例 #21
0
ファイル: stm32_eval_i2c_ee.c プロジェクト: Axis-Labs/STM32
/**
  * @brief  Wait for EEPROM Standby state.
  * 
  * @note  This function allows to wait and check that EEPROM has finished the 
  *        last Write operation. It is mostly used after Write operation: after 
  *        receiving the buffer to be written, the EEPROM may need additional 
  *        time to actually perform the write operation. During this time, it 
  *        doesn't answer to I2C packets addressed to it. Once the write operation 
  *        is complete the EEPROM responds to its address.
  *        
  * @note  It is not necessary to call this function after sEE_WriteBuffer() 
  *        function (sEE_WriteBuffer() already calls this function after each
  *        write page operation).    
  * 
  * @param  None
  * @retval sEE_OK (0) if operation is correctly performed, else return value 
  *         different from sEE_OK (0) or the timeout user callback.
  */
uint32_t sEE_WaitEepromStandbyState(void)      
{
  __IO uint16_t tmpSR1 = 0;
  __IO uint32_t sEETrials = 0;

  /*!< While the bus is busy */
  sEETimeout = sEE_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }

  /* Keep looping till the slave acknowledge his address or maximum number 
     of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define
     in stm32_eval_i2c_ee.h file) */
  while (1)
  {
    /*!< Send START condition */
    I2C_GenerateSTART(sEE_I2C, ENABLE);

    /*!< Test on EV5 and clear it */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }    

    /*!< Send EEPROM address for write */
    I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
    
    /* Wait for ADDR flag to be set (Slave acknowledged his address) */
    sEETimeout = sEE_LONG_TIMEOUT;
    do
    {     
      /* Get the current value of the SR1 register */
      tmpSR1 = sEE_I2C->SR1;
      
      /* Update the timeout value and exit if it reach 0 */
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }
    /* Keep looping till the Address is acknowledged or the AF flag is 
       set (address not acknowledged at time) */
    while((tmpSR1 & (I2C_SR1_ADDR | I2C_SR1_AF)) == 0);
     
    /* Check if the ADDR flag has been set */
    if (tmpSR1 & I2C_SR1_ADDR)
    {
      /* Clear ADDR Flag by reading SR1 then SR2 registers (SR1 have already 
         been read) */
      (void)sEE_I2C->SR2;
      
      /*!< STOP condition */    
      I2C_GenerateSTOP(sEE_I2C, ENABLE);
        
      /* Exit the function */
      return sEE_OK;
    }
    else
    {
      /*!< Clear AF flag */
      I2C_ClearFlag(sEE_I2C, I2C_FLAG_AF);                  
    }
    
    /* Check if the maximum allowed numbe of trials has bee reached */
    if (sEETrials++ == sEE_MAX_TRIALS_NUMBER)
    {
      /* If the maximum number of trials has been reached, exit the function */
      return sEE_TIMEOUT_UserCallback();
    }
  }
}
コード例 #22
0
ファイル: i2c1.c プロジェクト: KONGLZ123/TPDT.FC_407
rt_size_t i2c1_master_xfer(struct rt_i2c_bus_device *bus,
						 struct rt_i2c_msg msgs[],
						 rt_uint32_t num)
{int de=0;
	struct rt_i2c_msg *msg;
    rt_int32_t i, ret;
	rt_tick_t tick=rt_tick_get();
	
	GPIO_SetBits(GPIOB,GPIO_Pin_8|GPIO_Pin_9);
	while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
		CHECKTIME(tick);
 	I2C_GenerateSTART(I2Cx, ENABLE);
    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
		CHECKTIME(tick);

    for (i = 0; i < num; i++)
    {de=0;
        msg = &msgs[i];
        if (!(msg->flags & RT_I2C_NO_START))
        {
            if (i)
            {
                I2C_GenerateSTART(I2Cx, ENABLE);
				while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
					CHECKTIME(tick);
            }de=1;
            if (msg->flags & RT_I2C_RD)
			{
				I2C_Send7bitAddress(I2Cx, msg->addr, I2C_Direction_Receiver);
                while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
					CHECKTIME(tick);
			}
            else
			{
				I2C_Send7bitAddress(I2Cx, msg->addr, I2C_Direction_Transmitter);
                while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
					CHECKTIME(tick);
			}
			I2C_Cmd(I2Cx, ENABLE);
        }
        if (msg->flags & RT_I2C_RD)
        {
            ret = i2c1_recv_bytes(msg);
            if (ret >= 1)
                i2c_dbg("read %d byte%s\n",
                        ret, ret == 1 ? "" : "s");
			
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_EIO;
                goto out;
            }
        }
        else
        {
			nostart=(i+1<num && (msg[i+1].flags & RT_I2C_NO_START))
							||(msg[i].flags & I2C_RA);
            ret = stm32_i2c_send_bytes(msg);
            if (ret >= 1)
                i2c_dbg("write %d byte%s\n",
                        ret, ret == 1 ? "" : "s");
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_ERROR;
                goto out;
            }
        }
    }
    ret = i;
	
    return ret;
out:
	de=-1;
	if(de==0)GPIO_ResetBits(GPIOB,GPIO_Pin_8);else if(de==1)GPIO_ResetBits(GPIOB,GPIO_Pin_9);
    i2c_dbg("error on stage %d\n",de);
//    I2C_GenerateSTOP(I2Cx, ENABLE);
	
    return ret;
}
コード例 #23
0
ファイル: I2C.c プロジェクト: luciengou/FinderV2
ErrorStatus I2C_ByteWrite(uint8_t I2C_Addrs, uint8_t WriteAddr, uint8_t I2C_Data)
{
	I2C_GenerateSTART(ENABLE);

	I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base
	while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT))	//EV5
#else
	while(!(I2C->SR1 & 0x01))  //等待START發送完 EV5
#endif
		if(!(I2C_Time_Out_Counter--))		//Timeout Detect
		{
			//UART1_Printf("Byte Write: EV5 Error!! \n");
			return ERROR;
		}

	I2C_Send7bitAddress(I2C_Addrs, I2C_DIRECTION_TX);

	I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base

	//while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))	//EV6
	while(!(I2C->SR1 & 0x02))  //等特7位器件地址?送完并且收到ack,ADDR置1
		if(!(I2C_Time_Out_Counter--))		//Timeout Detect
		{
			//UART1_Printf("Byte Write: EV6 Error!! \n");
			return ERROR;
		}

	//I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
	I2C_Clear_ADDRESSSENTMATCHED_Flag();

#else
	while(!(I2C->SR1 & 0x02))		//等特7位器件地址?送完并且收到ack,ADDR置1
		if(!(I2C_Time_Out_Counter--))		//Timeout Detect
		{
			//UART1_Printf("Byte Write: EV6 Error!! \n");
			return ERROR;
		}

	I2C_Clear_ADDRESSSENTMATCHED_Flag();
#endif
	I2C_SendData((uint8_t) (WriteAddr));	//Send LSB Address

	I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base
	while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))	//EV8
#else
								//EV8_2 TxE=1 ,BTF=1,產生停止條件時由硬件清除。
	while(!(I2C->SR1 & 0x84))	//檢測SR1 TXE1 BTF位置(只有當stm8收到ack,TxE才會置1,其實這句相當于判斷收到ack沒有?)
								//在發送地址和清除ADDR 之后,I2C接口進入主設備接收模式。以下見stm8s中文數据手冊P252(圖97主設備接收模式接收序列圖)
#endif
		if(!(I2C_Time_Out_Counter--))		//Timeout Detect
		{
			//UART1_Printf("Byte Write: EV8 Error!! \n");
			return ERROR;
		}

	I2C_SendData(I2C_Data);

	I2C_Time_Out_Counter=I2C_Time_Out;
#ifdef	I2C_By_Function_Base
	while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))	//EV8_2
#else
								//EV8_2 TxE=1 ,BTF=1,產生停止條件時由硬件清除。
	while(!(I2C->SR1 & 0x84))	//檢測SR1 TXE1 BTF位置(只有當stm8收到ack,TxE才會置1,其實這句相當于判斷收到ack沒有?)
								//在發送地址和清除ADDR 之后,I2C接口進入主設備接收模式。以下見stm8s中文數据手冊P252(圖97主設備接收模式接收序列圖)
#endif
		if(!(I2C_Time_Out_Counter--))		//Timeout Detect
		{
			//UART1_Printf("Byte Write: EV8 Error!! \n");
			return ERROR;
		}

	I2C_GenerateSTOP(ENABLE);

	return	SUCCESS;
}
コード例 #24
0
ファイル: i2c1.c プロジェクト: KONGLZ123/TPDT.FC_407
rt_err_t i2c_register_read(struct rt_i2c_bus_device *bus,
						rt_uint16_t daddr,
						rt_uint8_t raddr,
						void *buffer,
						rt_size_t count)
{
	rt_int32_t ret;
	rt_tick_t tick=rt_tick_get();
#ifdef 	NO_RT_DEVICE
	rt_uint16_t NumByteToRead=count;
	rt_uint8_t * pBuffer=(rt_uint8_t *)buffer;
	rt_mutex_take(&I2C1_mutex,RT_WAITING_FOREVER);
	rt_enter_critical();
	  /* While the bus is busy */
	while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
		CHECKTIME(tick);

	/* Send START condition */
	I2C_GenerateSTART(I2C1, ENABLE);

	/* Test on EV5 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
	CHECKTIME(tick);

	/* Send MPU6050 address for write */
	I2C_Send7bitAddress(I2C1, daddr, I2C_Direction_Transmitter); 

	/* Test on EV6 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
		CHECKTIME(tick);

	/* Clear EV6 by setting again the PE bit */
	I2C_Cmd(I2C1, ENABLE);

	/* Send the MPU6050's internal address to write to */
	I2C_SendData(I2C1, raddr);

	/* Test on EV8 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
		CHECKTIME(tick);

	/* Send STRAT condition a second time */
	I2C_GenerateSTART(I2C1, ENABLE);

	/* Test on EV5 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
		CHECKTIME(tick);

	/* Send MPU6050 address for read */
	I2C_Send7bitAddress(I2C1, daddr, I2C_Direction_Receiver);

	/* Test on EV6 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
		CHECKTIME(tick);

	/* While there is data to be read */
	while(NumByteToRead)
	{
		if(NumByteToRead == 1)
		{
			/* Disable Acknowledgement */
			I2C_AcknowledgeConfig(I2C1, DISABLE);

			/* Send STOP Condition */
			I2C_GenerateSTOP(I2C1, ENABLE);
		}

		/* Test on EV7 and clear it */
		while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
			CHECKTIME(tick);
		{
			/* Read a byte from the MPU6050 */
			*pBuffer = I2C_ReceiveData(I2C1);

			/* Point to the next location where the byte read will be saved */
			pBuffer++;

			/* Decrement the read bytes counter */
			NumByteToRead--;
			
		}
	}

	/* Enable Acknowledgement to be ready for another reception */
	I2C_AcknowledgeConfig(I2C1, ENABLE);
	//  EXT_CRT_SECTION();
	rt_exit_critical();
	rt_mutex_release(&I2C1_mutex);
#else
	struct rt_i2c_msg msgs[2];
    RT_ASSERT(bus != RT_NULL);
    RT_ASSERT(buffer != RT_NULL);
	
	msgs[0].addr=daddr;
	msgs[0].buf=&raddr;
	msgs[0].len=1;
	msgs[0].flags=RT_I2C_WR|I2C_RA;
	
	msgs[1].addr=daddr;
	msgs[1].buf=buffer;
	msgs[1].len=count;
	msgs[1].flags=RT_I2C_RD|RT_I2C_NO_READ_ACK;
	err=rt_i2c_transfer(bus,msgs,2);	
#endif
	
	return RT_EOK;
	out:	
#ifdef 	NO_RT_DEVICE
//	I2C_GenerateSTOP(I2C1, ENABLE);
	rt_exit_critical();
	rt_mutex_release(&I2C1_mutex);
#endif
	return ret;
}
コード例 #25
0
ファイル: i2c.c プロジェクト: pandc/unitek
void I2Cx_EV_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
uint32_t lasteve;

	i2c_cntr++;
	switch(i2c_oper)
	{
	case I2C_Direction_Transmitter:
		lasteve = I2C_GetLastEvent(I2Cx);
		switch(lasteve)
		{
		case I2C_EVENT_MASTER_MODE_SELECT:
		/* If SB = 1, I2Cx master sent a START on the bus: EV5) */
			// Send the slave address for transmssion or for reception
			// according to the configured value in the write master write routine
			I2C_Send7bitAddress(I2Cx, i2c_addr, job->dir);
			break;
	//---------------------------------------------------------------------------
	//--- TX States -------------------------------------------------------------
	//---------------------------------------------------------------------------
		case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
			/* Initialize the Transmit counter */
			i2c_pb = job->buf;
			i2c_len = job->len;
			/* Write the first data in the data register */
			I2Cx->DR = *i2c_pb++;
			/* If no further data to be sent, disable the I2C BUF IT
			in order to not have a TxE  interrupt */
			if (--i2c_len == 0)
			{
				if (job->last || (job[1].dir != I2C_Direction_Transmitter))
				{
					/* Disable the BUF IT in order to wait the BTF event */
					I2C_ITConfig(I2Cx,I2C_IT_BUF,DISABLE);
				}
				else
				{
					job++;
					i2c_pb = job->buf;
					i2c_len = job->len;
				}
			}
			break;
		case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
			/* Master transmits the remaing data: from data2 until the last one.  */
			/* If TXE is set */
			/* If there is still data to write */
			if (i2c_len)
			{
				/* Write the data in DR register */
				I2Cx->DR = *i2c_pb++;
				// If  no data remains to write, disable the BUF IT in order
				// to not have again a TxE interrupt
				if (--i2c_len == 0)
				{
					if (job->last || (job[1].dir != I2C_Direction_Transmitter))
					{
						/* Disable the BUF IT */
						I2C_ITConfig(I2Cx,I2C_IT_BUF,DISABLE);
					}
					else
					{
						job++;
						i2c_pb = job->buf;
						i2c_len = job->len;
					}
				}
			}
			break;
		case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
			/* If BTF and TXE are set (EV8_2), program the STOP */
			if (job->last)
			{
				/* Program the STOP */
				I2C_GenerateSTOP(I2Cx,ENABLE);
				/* Disable EVT IT In order to not have again a BTF IT */
				I2C_ITConfig(I2Cx,I2C_IT_EVT | I2C_IT_BUF,DISABLE);
				i2c_done = TRUE;
				xSemaphoreGiveFromISR(xSemaphoreI2C_Work,&xHigherPriorityTaskWoken);
			}
			else
			{
				job++;
				i2c_oper = job->dir;
				/* Send START condition */
				I2C_GenerateSTART(I2Cx, ENABLE);
			}
			break;
		}
		break;
	//---------------------------------------------------------------------------
	//--- RX States -------------------------------------------------------------
	//---------------------------------------------------------------------------
	case I2C_Direction_Receiver:
		if (I2C_GetITStatus(I2Cx,I2C_IT_SB) == SET)
		{
			/* Send slave Address for read */
			I2C_Send7bitAddress(I2Cx, i2c_addr, I2C_Direction_Receiver);
			i2c_pb = job->buf;
			i2c_len = job->len;
			if (i2c_len == 3)
			{
				/* Disable buffer Interrupts */
				I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE);
			}
			else
			{
				/* Enable buffer Interrupts */
				I2C_ITConfig(I2Cx, I2C_IT_BUF , ENABLE);
			}
		}
		else if (I2C_GetITStatus(I2Cx, I2C_IT_ADDR) == SET)
		{
			if (i2c_len == 1)
			{
				I2C_AcknowledgeConfig(I2Cx, DISABLE);
			}
			/* Clear ADDR Register */
			(void)(I2Cx->SR1);
			(void)(I2Cx->SR2);
			if (i2c_len == 1)
			{
				I2C_GenerateSTOP(I2Cx, ENABLE);
			}
			else if (i2c_len == 2)
			{
				I2C_AcknowledgeConfig(I2Cx, DISABLE);
				I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next);
				/* Disable buffer Interrupts */
				I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE);
			}
		}
		else if ((I2C_GetITStatus(I2Cx, I2C_IT_RXNE) == SET) && (I2C_GetITStatus(I2Cx, I2C_IT_BTF) == RESET))
		{
			/* Store I2C received data */
			*i2c_pb++ = I2C_ReceiveData (I2Cx);
			i2c_len--;

			if (i2c_len == 3)
			{
				/* Disable buffer Interrupts */
				I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE);
			}
			else if (i2c_len == 0)
			{
				/* Disable Error, Event and Buffer Interrupts */
				I2C_ITConfig(I2Cx,I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE);
				i2c_done = TRUE;
				xSemaphoreGiveFromISR(xSemaphoreI2C_Work,&xHigherPriorityTaskWoken);
			}
		}    
		/* BUSY, MSL and RXNE flags */
		else if (I2C_GetITStatus(I2Cx, I2C_IT_BTF) == SET)
		{
			/* if Three bytes remaining for reception */
			if (i2c_len == 3)
			{
				I2C_AcknowledgeConfig(I2Cx, DISABLE);
				/* Store I2C received data */
				*i2c_pb++ = I2C_ReceiveData(I2Cx);
				i2c_len--;
			} 
			else if (i2c_len == 2)
			{           
				I2C_GenerateSTOP(I2Cx, ENABLE);    

				/* Store I2C received data */
				*i2c_pb++ = I2C_ReceiveData(I2Cx);
				i2c_len--;
				/* Store I2C received data */
				*i2c_pb++ = I2C_ReceiveData(I2Cx);
				i2c_len--;
				/* Disable Error, Event and Buffer Interrupts */
				I2C_ITConfig(I2Cx,I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE);
				i2c_done = TRUE;
				xSemaphoreGiveFromISR(xSemaphoreI2C_Work,&xHigherPriorityTaskWoken);
			}
			else 
			{
				/* Store I2C received data */
				*i2c_pb++ = I2C_ReceiveData(I2Cx);
				i2c_len--;
			}
		}
		break;
	}
	portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
コード例 #26
0
ファイル: i2c1.c プロジェクト: KONGLZ123/TPDT.FC_407
rt_err_t i2c_register_write(struct rt_i2c_bus_device *bus,
						rt_uint16_t daddr,
						rt_uint8_t raddr,
						void *buffer,
						rt_size_t count)
{
	rt_int32_t ret;
	rt_tick_t tick=rt_tick_get();
#ifdef 	NO_RT_DEVICE
	rt_uint8_t * pBuffer=(rt_uint8_t *)buffer;
	
	rt_mutex_take(&I2C1_mutex,RT_WAITING_FOREVER);
	rt_enter_critical();
	I2C_GenerateSTART(I2C1, ENABLE);

	/* Test on EV5 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
		CHECKTIME(tick);

	/* Send MPU6050 address for write */
	I2C_Send7bitAddress(I2C1, daddr, I2C_Direction_Transmitter);

	/* Test on EV6 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
		CHECKTIME(tick);

	/* Send the MPU6050's internal address to write to */
	I2C_SendData(I2C1, raddr);

	/* Test on EV8 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
		CHECKTIME(tick);

	/* Send the byte to be written */
	I2C_SendData(I2C1, *pBuffer);

	/* Test on EV8 and clear it */
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
		CHECKTIME(tick);

	/* Send STOP condition */
	I2C_GenerateSTOP(I2C1, ENABLE);
	rt_exit_critical();
	rt_mutex_release(&I2C1_mutex);
#else
	struct rt_i2c_msg msgs[2];
	rt_err_t err;
    RT_ASSERT(bus != RT_NULL);
    RT_ASSERT(buffer != RT_NULL);
	
	if(count>1)
	{
		msgs[0].addr=daddr;
		msgs[0].buf=&raddr;
		msgs[0].len=1;
		msgs[0].flags=RT_I2C_WR;
		
		msgs[1].addr=daddr;
		msgs[1].buf=buffer;
		msgs[1].len=count;
		msgs[1].flags=RT_I2C_WR|RT_I2C_NO_START;
		
		err=rt_i2c_transfer(bus,msgs,2);
	}
	else
	{
		rt_uint8_t data[2];
		data[0]=raddr;
		data[1]=*((rt_uint8_t *)buffer);
		
		msgs[0].addr=daddr;
		msgs[0].buf=data;
		msgs[0].len=2;
		msgs[0].flags=RT_I2C_WR;
		
		err=rt_i2c_transfer(bus,msgs,1);
	}
#endif
	
	return RT_EOK;
	out:	
	
#ifdef 	NO_RT_DEVICE
//	I2C_GenerateSTOP(I2C1, ENABLE);
	rt_exit_critical();
	rt_mutex_release(&I2C1_mutex);
#endif
	return ret;
}
コード例 #27
0
ファイル: i2c.c プロジェクト: blackphoenix208/ARMWork
boolean i2c_receive(I2CBus * wirex, uint8_t addr, uint8_t req, uint8_t * recv, uint16_t lim) {
	uint16_t i;
	uint16_t wc;

	wirex->mode = I2C_MODE_MASTERRECEIVER;
	//
	if ( !i2c_start(wirex, addr) )
		return false;

	/* Send the EEPROM's internal address to read from: MSB of the address first */
	I2C_SendData(wirex->I2Cx, req);
	wirex->status = BYTE_TRANSMITTING;
	/* Test on EV8 and clear it */

	for (wc = 5; !I2C_CheckEvent(wirex->I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED ); wc--) {
		if (wc == 0)
			return false;
		delay_us(667);
	}
	wirex->status = TRANSMISSION_COMPLETED;

	/* Send STRAT condition a second time */
	I2C_GenerateSTART(wirex->I2Cx, ENABLE);
	/* Test on EV5 and clear it */
	for (wc = 5; !I2C_CheckEvent(wirex->I2Cx, I2C_EVENT_MASTER_MODE_SELECT ); wc--) {
		if (wc == 0)
			return false;
		delay_us(667);
	}
	wirex->status = RESTART_ISSUED;

	/* Send EEPROM address for read */
	I2C_Send7bitAddress(wirex->I2Cx, addr << 1, I2C_Direction_Receiver );
	/* Test on EV6 and clear it */
	for (wc = 5; !I2C_CheckEvent(wirex->I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ); wc--) {
		if (wc == 0)
			return false;
		delay_us(667);
	}
	wirex->status = SRC_ADDRESS_SENT;
	for (i = 1; i < lim; i++) {
		wirex->status = RECEIVE_BYTE_READY;
		for(wc = 5; !I2C_CheckEvent(wirex->I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED ); wc--) {
			if (wc == 0)
				return false;
			delay_us(667);

		}
		/* Read a byte from the EEPROM */
		*recv++ = I2C_ReceiveData(wirex->I2Cx );
		wirex->status = BYTE_RECEIVED;
	}
	wirex->status = BEFORELAST_BYTE_RECEIVED;

	/* Disable Acknowledgement */
	I2C_AcknowledgeConfig(wirex->I2Cx, DISABLE);
	/* Send STOP Condition */
	I2C_GenerateSTOP(wirex->I2Cx, ENABLE);
	wirex->status = LAST_BYTE_READY;

	for(wc = 5; !I2C_CheckEvent(wirex->I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED ); wc--) {
		if (wc == 0)
			return false;
		delay_us(667);
	}
	/* Read a byte from the EEPROM */
	*recv = I2C_ReceiveData(wirex->I2Cx );
	wirex->status = RECEIVE_BYTE_COMPLETED;

	/* Enable Acknowledgement to be ready for another reception */
	I2C_AcknowledgeConfig(wirex->I2Cx, ENABLE);
	wirex->status = NOT_READY;
	wirex->mode = I2C_MODE_NOTDEFINED;

	return true;
}
コード例 #28
0
ファイル: i2c_ee.c プロジェクト: Hackerdd/STM32F103_APP
/*
 * 函数名:I2C_EE_BufferRead
 * 描述  :从EEPROM里面读取一块数据。 
 * 输入  :-pBuffer 存放从EEPROM读取的数据的缓冲区指针。
 *         -WriteAddr 接收数据的EEPROM的地址。 
 *         -NumByteToWrite 要从EEPROM读取的字节数。
 * 输出  :无
 * 返回  :无
 * 调用  :外部调用
 */
void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
{  
  //*((u8 *)0x4001080c) |=0x80; 
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008
    
    
  /* Send START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  //*((u8 *)0x4001080c) &=~0x80;
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /* Send EEPROM address for write */
  I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  
  /* Clear EV6 by setting again the PE bit */
  I2C_Cmd(I2C1, ENABLE);

  /* Send the EEPROM's internal address to write to */
  I2C_SendData(I2C1, ReadAddr);  

  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  
  /* Send STRAT condition a second time */  
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  
  /* Send EEPROM address for read */
  I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  
  /* While there is data to be read */
  while(NumByteToRead)  
  {
    if(NumByteToRead == 1)
    {
      /* Disable Acknowledgement */
      I2C_AcknowledgeConfig(I2C1, DISABLE);
      
      /* Send STOP Condition */
      I2C_GenerateSTOP(I2C1, ENABLE);
    }

    /* Test on EV7 and clear it */
    if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  
    {      
      /* Read a byte from the EEPROM */
      *pBuffer = I2C_ReceiveData(I2C1);

      /* Point to the next location where the byte read will be saved */
      pBuffer++; 
      
      /* Decrement the read bytes counter */
      NumByteToRead--;        
    }   
  }

  /* Enable Acknowledgement to be ready for another reception */
  I2C_AcknowledgeConfig(I2C1, ENABLE);
}
コード例 #29
0
/**
  * @brief  Write to the specified register of the LM75.
  * @param  RegName: specifies the LM75 register to be written.
  *              This member can be one of the following values:    
  *                  - LM75_REG_TOS: Over-limit temperature register
  *                  - LM75_REG_THYS: Hysteresis temperature register
  * @param  RegValue: value to be written to LM75 register.  
  * @retval None
  */
uint8_t LM75_WriteReg(uint8_t RegName, uint16_t RegValue)
{   
  uint8_t LM75_BufferTX[2] ={0,0};
  LM75_BufferTX[0] = (uint8_t)(RegValue >> 8);
  LM75_BufferTX[1] = (uint8_t)(RegValue);
  
  /* Test on BUSY Flag */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY)) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Configure DMA Peripheral */
  LM75_DMA_Config(LM75_DMA_TX, (uint8_t*)LM75_BufferTX, 2);
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(LM75_I2C, ENABLE);
  
  /* Test on SB Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB) == RESET) 
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);
  
  /* Test on ADDR Flag */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Transmit the first address for r/w operations */
  I2C_SendData(LM75_I2C, RegName);
  
  /* Test on TXE FLag (data sent) */
  LM75_Timeout = LM75_FLAG_TIMEOUT;
  while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF)))  
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Enable I2C DMA request */
  I2C_DMACmd(LM75_I2C,ENABLE);
  
  /* Enable DMA TX Channel */
  DMA_Cmd(LM75_DMA_TX_CHANNEL, ENABLE);
  
  /* Wait until DMA Transfer Complete */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (!DMA_GetFlagStatus(LM75_DMA_TX_TCFLAG))
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }  
  
  /* Wait until BTF Flag is set before generating STOP */
  LM75_Timeout = LM75_LONG_TIMEOUT;
  while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF))  
  {
    if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
  }
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);
  
  /* Disable DMA TX Channel */
  DMA_Cmd(LM75_DMA_TX_CHANNEL, DISABLE);
  
  /* Disable I2C DMA request */  
  I2C_DMACmd(LM75_I2C,DISABLE);
  
  /* Clear DMA TX Transfer Complete Flag */
  DMA_ClearFlag(LM75_DMA_TX_TCFLAG);
  
  return LM75_OK;
}
コード例 #30
0
ファイル: clMPU6050.cpp プロジェクト: jtec/flightcode
bool clMPU6050::readHMC5883L(float* xyz)
{
	static float pBuffer[6] = {0};
	static uint8_t address = 0x3C<<1;
	// Disable automatic generation of STOP condition.
	I2C_GenerateSTOP(this->i2c, DISABLE);

	// Wait while the bus is busy
	this->restartTimeoutTimer();
	while(I2C_GetFlagStatus(this->i2c, I2C_FLAG_BUSY)){
		if(this->getTimeoutTimerTime() > this->timeForOneByte){
			return false;
		}
	}

	// Send START condition
	I2C_GenerateSTART(this->i2c, ENABLE);

	// Check if START condition has been sent by checking the SB bit in SR 1,
	// this flag is cleared by reading SR1 and writing to DR, this will be done when sending the slave address.
	bool startConditionSent = false;
	this->restartTimeoutTimer();
	while(!startConditionSent){
		startConditionSent = (this->i2c->SR1 & BIT0) > 0;
		if(this->getTimeoutTimerTime() > this->timeForOneByte){
			return false;
		}
	}

	// Send address for write
	I2C_Send7bitAddress(this->i2c, address, I2C_Direction_Transmitter);

	// Wait until the slave has acknowledged the address. To do this, we check the ADDR bit
	// in SR1. This bit is cleared by subsequently reading SR1 and SR2.
	this->restartTimeoutTimer();
	bool addressHasBeenReceived = false;
	while(!addressHasBeenReceived){
		addressHasBeenReceived = (this->i2c->SR1 & BIT1) > 0;
		if(this->getTimeoutTimerTime() > 2*this->timeForOneByte){
			return false;
		}
	}
	// Clear ADDR flag by reading SR2; variable is declared as volatile to keep the compiler from optimizing it away.
	volatile uint16_t tmp = this->i2c->SR2;

	I2C_GenerateSTOP(this->i2c, ENABLE);
	// Move the sensor's read pointer to the first data output register.
	I2C_SendData(this->i2c, 3);

	// Wait until the byte transfer has been finished by checking on the BTF bit in SR1. It will
	// be cleared by the next read operation of the DR register.
	this->restartTimeoutTimer();
	bool byteHasBeenTransmitted = false;
	while(!byteHasBeenTransmitted){
		byteHasBeenTransmitted = (this->i2c->SR1 & BIT2) > 0;
		if(this->getTimeoutTimerTime() > 2*this->timeForOneByte){
			return false;
		}
	}

	// Send START condition a second time
	I2C_GenerateSTART(this->i2c, ENABLE);

	// Check if START condition has been sent by checking the SB bit in SR1,
	// this flag is cleared by reading SR1 and writing to DR, this will be done when sending the slave address.
	startConditionSent = false;
	this->restartTimeoutTimer();
	while(!startConditionSent){
		startConditionSent = (this->i2c->SR1 & BIT0) > 0;
		if(this->getTimeoutTimerTime() > this->timeForOneByte){
			return false;
		}
	}

	// Send address for read
	I2C_Send7bitAddress(this->i2c, address, I2C_Direction_Receiver);

	// Wait until the slave has acknowledged the address. To do this, we check the ADDR bit
	// in SR1. This bit is cleared by subsequently reading SR1 and SR2.
	this->restartTimeoutTimer();
	addressHasBeenReceived = false;
	while(!addressHasBeenReceived){
		addressHasBeenReceived = (this->i2c->SR1 & BIT1) > 0;
		if(this->getTimeoutTimerTime() > 2*this->timeForOneByte){
			return false;
		}
	}
	// Clear ADDR flag by reading SR2:
	tmp = this->i2c->SR2;

	// Read in bytes sent by the slave:
	// If we are about to receive 1 single byte, there is no need to acknowledge it, since the last byte
	// is not acknowledged. If we will receive more than one byte, every byte except the last one has to be acknowledged
	// by the master.
	I2C_AcknowledgeConfig(this->i2c, ENABLE);
	uint8_t NumByteToRead = 6;
	uint8_t i = 0;
	if(NumByteToRead == 1){
		I2C_AcknowledgeConfig(this->i2c, DISABLE);
	}
	// While there is data to be read:
	uint32_t timeoutTime = 2* NumByteToRead * this->timeForOneByte;
	this->restartTimeoutTimer();
	while(NumByteToRead > 0)
	{
		// Check for timeout:
		if(this->getTimeoutTimerTime() > timeoutTime){
			return false;
		}

		// When we are about to receive the last byte:
		if(NumByteToRead == 1)
		{
			// Disable Acknowledgement:
			I2C_AcknowledgeConfig(this->i2c, DISABLE);
		}

		// Check whether a byte has been received:
		bool newByteReceived = (this->i2c->SR1 & BIT6) > 0;
		if(newByteReceived)
		{
			newByteReceived = false;
			// Read a byte from the MPU6050
			pBuffer[i] = this->i2c->DR;

			// Point to the location where the next byte will be saved.
			i++;

			// Decrement the read bytes counter.
			NumByteToRead--;
		}
	}
	// We have received all bytes, send STOP condition.
	I2C_GenerateSTOP(this->i2c, ENABLE);

	return true;
}