int I2C_Read(uint8_t addr,void *pbuffer,uint16_t len) { struct i2c_job_st i2c_job; 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_Receiver; job = &i2c_job; i2c_addr = addr << 1; i2c_job.buf = (uint8_t *)pbuffer; i2c_job.len = len; i2c_job.dir = I2C_Direction_Receiver; i2c_job.last = TRUE; i2c_done = i2c_err = FALSE; // clear the semaphore while (xSemaphoreTake(xSemaphoreI2C_Work,0)); if ((i2c_oper == I2C_Direction_Receiver) && (len == 2)) I2C_NACKPositionConfig(I2Cx,I2C_NACKPosition_Next); else I2C_NACKPositionConfig(I2Cx,I2C_NACKPosition_Current); I2C_AcknowledgeConfig(I2Cx,ENABLE); 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; }
void DS1307SetTime() { uint8_t index; uint8_t values[8] = { 0x00, 0x15, 0x00, 0x01, 0x15, 0x05, 0x13, 0x10 }; I2C_AcknowledgeConfig(I2C2, ENABLE); // Start setting register I2C_GenerateSTART(I2C2, ENABLE); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) ; I2C_Send7bitAddress(I2C2, I2C2_SLAVE_ADDRESS, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) ; I2C_SendData(I2C2, 0x00); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) ; for (index = 0; index < 8; index++) { I2C_SendData(I2C2, values[index]); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) ; } I2C_NACKPositionConfig(I2C2, I2C_NACKPosition_Current); I2C_AcknowledgeConfig(I2C2, DISABLE); I2C_GenerateSTOP(I2C2, ENABLE); while (I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF)) ; }
void DS1307ReadTime(DATE_TYPE* date) { uint8_t index; uint8_t values[8] = { 0 }; I2C_AcknowledgeConfig(I2C2, ENABLE); // Start setting register I2C_GenerateSTART(I2C2, ENABLE); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) ; I2C_Send7bitAddress(I2C2, I2C2_SLAVE_ADDRESS, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) ; I2C_SendData(I2C2, 0x00); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) ; I2C_GenerateSTART(I2C2, ENABLE); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) ; I2C_Send7bitAddress(I2C2, I2C2_SLAVE_ADDRESS, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) ; for (index = 0; index < 8; index++) { while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)) ; values[index] = I2C_ReceiveData(I2C2); if (index == 6) { I2C_NACKPositionConfig(I2C2, I2C_NACKPosition_Current); I2C_AcknowledgeConfig(I2C2, DISABLE); } } I2C_GenerateSTOP(I2C2, ENABLE); while (I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF)) ; date->sec1 = (values[0] & 0xF0) >> 4; date->sec0 = values[0] & 0x0F; date->min1 = (values[1] & 0xF0) >> 4; date->min0 = values[1] & 0x0F; date->hour1 = (values[2] & 0x30) >> 4; date->hour0 = values[2] & 0x0F; date->day1 = (values[4] & 0x30) >> 4; date->day0 = values[4] & 0x0F; date->month1 = (values[5] & 0x10) >> 4; date->month0 = values[5] & 0x0F; date->year1 = (values[6] & 0xF0) >> 4; date->year0 = values[6] & 0x0F; }
u8 i2c_read_reg(u8 dev_adr, u8 reg_adr) { u8 res; /*re-enable ACK bit incase it was disabled last call*/ I2C_AcknowledgeConfig(I2C2, ENABLE); /* Test on BUSY Flag */ while (I2C_GetFlagStatus(I2C2,I2C_FLAG_BUSY)); /* Enable the I2C peripheral */ I2C_GenerateSTART(I2C2, ENABLE); /* Test on start flag */ while (!I2C_GetFlagStatus(I2C2,I2C_FLAG_SB)) __asm("nop");; /* Send device address for write */ I2C_Send7bitAddress(I2C2, dev_adr, I2C_Direction_Transmitter); /* Test on master Flag */ while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) __asm("nop");; /* Send the device's internal address to write to */ I2C_SendData(I2C2, reg_adr); /* Test on TXE FLag (data sent) */ while (!I2C_GetFlagStatus(I2C2,I2C_FLAG_TXE)) __asm("nop");; /* Send START condition a second time (Re-Start) */ I2C_GenerateSTART(I2C2, ENABLE); /* Test start flag */ while (!I2C_GetFlagStatus(I2C2,I2C_FLAG_SB)) __asm("nop");; /* Send address for read */ I2C_Send7bitAddress(I2C2, dev_adr, I2C_Direction_Receiver); /* Test Receive mode Flag */ while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) __asm("nop");; /* load in all 6 registers */ while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)) __asm("nop");; res = I2C_ReceiveData(I2C2); /*enable NACK bit */ I2C_NACKPositionConfig(I2C2, I2C_NACKPosition_Current); I2C_AcknowledgeConfig(I2C2, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(I2C2, ENABLE); while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF)) __asm("nop");; // stop bit flag return res; }
short read8(I2C_TypeDef* I2Cx){ uint8_t msb=0, lsb=0; unsigned char dummy1; unsigned short data; I2C_AcknowledgeConfig(I2Cx, ENABLE); while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2Cx, ENABLE); while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_SB)); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2Cx,0x6B<<1,I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2Cx,0x28); while(!I2C_GetFlagStatus(I2Cx,I2C_FLAG_TXE)); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2Cx, ENABLE); while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_SB)); I2C_Send7bitAddress(I2Cx, 0x6B<<1, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); msb = I2C_ReceiveData(I2Cx); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current); I2C_AcknowledgeConfig(I2Cx, DISABLE); lsb = I2C_ReceiveData(I2Cx); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); //dummy1 = I2C_ReceiveData(I2Cx); //while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_GenerateSTOP(I2Cx, ENABLE); while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF)); data = msb<<8; data |= lsb; return data; }
void MPU6050_Read_Data() { uint8_t i; I2C_AcknowledgeConfig(I2C2, ENABLE); I2C_GenerateSTART(I2C2, ENABLE); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C2, MPU6050_I2C_ADDR, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C2, MPU6050_ACCEL_XOUT_H); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2C2, ENABLE); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C2, MPU6050_I2C_ADDR, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); for (i=0;i<14;i++) { while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)); MPU6050_Data_Buffer[i] = I2C_ReceiveData(I2C2); if (i == 12) { I2C_NACKPositionConfig(I2C2, I2C_NACKPosition_Current); I2C_AcknowledgeConfig(I2C2, DISABLE); } } Acc_X = MPU6050_Data_Buffer[0]<<8 | MPU6050_Data_Buffer[1]; Acc_Y = MPU6050_Data_Buffer[2]<<8 | MPU6050_Data_Buffer[3]; Acc_Z = MPU6050_Data_Buffer[4]<<8 | MPU6050_Data_Buffer[5]; Gyr_X = MPU6050_Data_Buffer[8]<<8 | MPU6050_Data_Buffer[9]; Gyr_Y = MPU6050_Data_Buffer[10]<<8 | MPU6050_Data_Buffer[11]; Gyr_Z = MPU6050_Data_Buffer[12]<<8 | MPU6050_Data_Buffer[13]; Temp = MPU6050_Data_Buffer[6]<<8 | MPU6050_Data_Buffer[7]; Temp = (float)((float)((int16_t)Temp/(float)340.0) + (float)36.53); }
uint8_t i2c_read(uint8_t DeviceAddr, uint8_t IntAddr) { printf("r\n\r"); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); printf("r\n\r"); I2C_Send7bitAddress(I2C1, MPU6050, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); printf("ack\n\r"); I2C_SendData(I2C1,IntAddr); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); printf("r\n\r"); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, MPU6050, I2C_Direction_Receiver); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Current); I2C_GenerateSTOP(I2C1, ENABLE); return I2C_ReceiveData(I2C1); }
uint8_t I2C_Read8(uint8_t addr, uint8_t reg) { uint8_t data = 0; I2C_AcknowledgeConfig(I2C1, ENABLE); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB)); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, addr<<1,I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, reg); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB)); I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Current); I2C_AcknowledgeConfig(I2C1, DISABLE); //need to add a wait here for new data, right now it goes to fast to get the new data. while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE)); data = I2C_ReceiveData(I2C1); //while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_GenerateSTOP(I2C1, ENABLE); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)); return data; }
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); }
/** * @brief Reads a buffer of 2 bytes from the device registers. * @param RegisterAddr: The target register adress (between 00x and 0x24) * @retval The data in the buffer containing the two returned bytes (in halfword). */ uint16_t I2C_ReadDataBuffer(uint32_t RegisterAddr) { uint8_t IOE_BufferRX[2] = {0x00, 0x00}; /* Enable the I2C peripheral */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ 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, IOE_ADDR, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_ADDR)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Read status register 2 to clear ADDR flag */ IOE_I2C->SR2; /* Test on EV8 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_TXE)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send the device's internal address to write to */ I2C_SendData(IOE_I2C, RegisterAddr); /* Send START condition a second time */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send IO Expander address for read */ I2C_Send7bitAddress(IOE_I2C, IOE_ADDR, I2C_Direction_Receiver); /* Test on EV6 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_ADDR)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Disable Acknowledgement and set Pos bit */ I2C_AcknowledgeConfig(IOE_I2C, DISABLE); I2C_NACKPositionConfig(IOE_I2C, I2C_NACKPosition_Next); /* Read status register 2 to clear ADDR flag */ IOE_I2C->SR2; /* Test on EV7 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_BTF)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send STOP Condition */ I2C_GenerateSTOP(IOE_I2C, ENABLE); /* Read the first byte from the IO Expander */ IOE_BufferRX[1] = I2C_ReceiveData(IOE_I2C); /* Read the second byte from the IO Expander */ IOE_BufferRX[0] = I2C_ReceiveData(IOE_I2C); /* Enable Acknowledgement and reset POS bit to be ready for another reception */ I2C_AcknowledgeConfig(IOE_I2C, ENABLE); I2C_NACKPositionConfig(IOE_I2C, I2C_NACKPosition_Current); /* return the data */ return ((uint16_t) IOE_BufferRX[0] | ((uint16_t)IOE_BufferRX[1]<< 8)); }
uint8_t I2C_ReadShort(uint16_t reg_address, uint16_t dev_address) { uint16_t data = 0; uint32_t timeout = I2C_TIMEOUT; dev_address = dev_address << 1; I2C_AcknowledgeConfig(I2C1, ENABLE); while (I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)) { if (! timeout--) Usart1Put('q'); } I2C_GenerateSTART(I2C1, ENABLE); timeout = I2C_TIMEOUT; while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)){ if (! timeout--) Usart1Put('w'); } I2C_Send7bitAddress(I2C1, dev_address, I2C_Direction_Transmitter); timeout = I2C_TIMEOUT; while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){ if (! timeout--) Usart1Put('e'); } I2C_SendData(I2C1, reg_address); // write register address timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){ if (! timeout--) Usart1Put('r'); } /* restart */ I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)){ if (! timeout--) Usart1Put('t'); } I2C_Send7bitAddress(I2C1, dev_address, I2C_Direction_Receiver); timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){ if (! timeout--) Usart1Put('y'); } /* before last one, disable ACK */ I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Next); I2C_AcknowledgeConfig(I2C1, DISABLE); /* Receive */ I2C_ReceiveData(I2C1); timeout = I2C_TIMEOUT; while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)){ if (! timeout--) Usart1Put('u'); } /* Receive */ data = I2C_ReceiveData(I2C1); timeout = I2C_TIMEOUT; while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)){ if (! timeout--) Usart1Put('i'); } I2C_GenerateSTOP(I2C1, ENABLE); timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)){ if (! timeout--) Usart1Put('o'); } return data; }
/* --------------------------------------------------------------------------- ** Reads data from the SFR02 sensor ** Implements the communication protocol specific to the SFR02 sensors ** -------------------------------------------------------------------------*/ uint16_t I2CReadData(uint8_t device_address, uint8_t register_address) { uint16_t timeout; static uint16_t data=0; /*!< While the bus is busy */ timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_FLAG_BUSY_TIMEOUT); } //1. Send a start sequence /*!< Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); /*!< Test on EV5 and clear it */ timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_MASTER_MODE_TIMEOUT); } //2. Send 0xE0 ( I2C address of the SRF02 with the R/W bit low (even address - write)) /*!< Send Sonar address for write */ timeout = I2C_TIMEOUT; I2C_Send7bitAddress(I2C1, device_address, I2C_Direction_Transmitter); /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_FLAG_ADDR_TIMEOUT); } /*!< Test on EV6 and clear it */ timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_MASTER_TRANSMITTER_TIMEOUT); } //3. Send 0x02 (Internal address of the first distance register) /*!< Send the sonar internal register address to read from */ I2C_SendData(I2C1, register_address); /*!< Test on EV8 and clear it */ timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_BYTE_TRANSMITTED_TIMEOUT); } I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Next); //4. Send a start sequence again (repeated start) /*!< Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); /*!< Test on EV5 and clear it */ timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_MASTER_MODE_TIMEOUT); } //5. Send 0xE1 ( I2C address of the SRF02 with the R/W bit high (odd address - read)) /*!< Send sonar address for read */ I2C_Send7bitAddress(I2C1, device_address, I2C_Direction_Receiver); /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_FLAG_ADDR_TIMEOUT); } /* Call User callback for critical section start (should typically disable interrupts) */ __disable_irq(); /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */ (void)I2C1->SR2; /*!< Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C1, DISABLE); /* Call User callback for critical section end (should typically re-enable interrupts) */ __enable_irq(); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == RESET) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_FLAG_BTF_TIMEOUT); } //6. Read the two data bytes, high and low from SRF02 /* Wait for the byte to be received */ timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_FLAG_RXNE_TIMEOUT); } /*!< Read first data byte from sonar */ data = I2C_ReceiveData(I2C1) << 8; /* Wait for the byte to be received */ timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_FLAG_RXNE_TIMEOUT); } /*!< Read second data byte from sonar */ data |= I2C_ReceiveData(I2C1); //7. Send the stop sequence. __disable_irq(); /*!< Send STOP Condition */ I2C_GenerateSTOP(I2C1, ENABLE); /* Call User callback for critical section end (should typically re-enable interrupts) */ __enable_irq(); /* Wait to make sure that STOP control bit has been cleared */ timeout = I2C_TIMEOUT; while(I2C1->CR1 & I2C_CR1_STOP) { if((timeout--) == 0) return I2Ctimeout(I2C_RX_CLEAR_STOP_TIMEOUT); } /*!< Re-Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(I2C1, ENABLE); I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Current); return data; }
/** @brief Read from I2C @param[in] devnum I2C peripheral number (1 or 2) @param[in] adr I2C address @param[out] buf pointer to caller allocated buffer for data @param[in] nbyte number of bytes to read (nbyte <= sizeof(buf)) @return 0 on success, non-zero otherwise */ uint8_t i2c_rd(uint8_t devnum, uint8_t adr, uint8_t *buf, uint32_t nbyte) { I2C_TypeDef* I2Cx = i2c_get_pdef(devnum)->i2c; //__IO uint32_t Timeout = 0; // I2Cx->CR2 |= I2C_IT_ERR; interrupts for errors if (!nbyte) { return 1; } // Wait for idle I2C interface i2c_waitfor(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY), 1); // Enable Acknowledgement, clear POS flag I2C_AcknowledgeConfig(I2Cx, ENABLE); I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current); // Intiate Start Sequence (wait for EV5) I2C_GenerateSTART(I2Cx, ENABLE); i2c_waitfor(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT), 2); // Send Address I2C_Send7bitAddress(I2Cx, adr, I2C_Direction_Receiver); // EV6 i2c_waitfor(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR), 3); if (nbyte == 1) { // Clear Ack bit I2C_AcknowledgeConfig(I2Cx, DISABLE); // EV6_1 -- must be atomic -- Clear ADDR, generate STOP __disable_irq(); (void) I2Cx->SR2; I2C_GenerateSTOP(I2Cx,ENABLE); __enable_irq(); // Receive data EV7 i2c_waitfor(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_RXNE), 4); *buf++ = I2C_ReceiveData(I2Cx); } else if (nbyte == 2) { // Set POS flag I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next); // EV6_1 -- must be atomic and in this order __disable_irq(); (void) I2Cx->SR2; // Clear ADDR flag I2C_AcknowledgeConfig(I2Cx, DISABLE); // Clear Ack bit __enable_irq(); // EV7_3 -- Wait for BTF, program stop, read data twice i2c_waitfor(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF), 5); __disable_irq(); I2C_GenerateSTOP(I2Cx,ENABLE); *buf++ = I2Cx->DR; __enable_irq(); *buf++ = I2Cx->DR; } else { (void) I2Cx->SR2; // Clear ADDR flag while (nbyte-- != 3) { // EV7 -- cannot guarantee 1 transfer completion time, wait for BTF // instead of RXNE i2c_waitfor(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF), 6); *buf++ = I2C_ReceiveData(I2Cx); } i2c_waitfor(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF), 7); // EV7_2 -- Figure 1 has an error, doesn't read N-2 ! I2C_AcknowledgeConfig(I2Cx, DISABLE); // clear ack bit __disable_irq(); *buf++ = I2C_ReceiveData(I2Cx); // receive byte N-2 I2C_GenerateSTOP(I2Cx,ENABLE); // program stop __enable_irq(); *buf++ = I2C_ReceiveData(I2Cx); // receive byte N-1 // wait for byte N i2c_waitfor(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED), 8); *buf++ = I2C_ReceiveData(I2Cx); nbyte = 0; } // Wait for stop i2c_waitfor(I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF), 9); return 0; }
/** * @brief This function handles I2Cx event interrupt request. * @param None * @retval None */ void I2Cx_EV_IRQHANDLER(void) { #if defined (I2C_MASTER) /* Once the Start condition is sent the master can be master receiver or master transmitter */ if (MasterMode == MASTER_MODE_TRANSMITTER) { /* Get Last I2C Event */ Event = I2C_GetLastEvent(I2Cx); switch (Event) { /* ************************************************************************/ /* Master Transmitter Events */ /* */ /* ************************************************************************/ /* Sending the header sequence for Master Transmitter case ----------------*/ #ifdef I2C_10BITS_ADDRESS /* Check on EV5 */ case I2C_EVENT_MASTER_MODE_SELECT : /* Send Header to Slave for write */ I2C_SendData(I2Cx, HEADER_ADDRESS_Write); break; /* Check on EV9 */ case I2C_EVENT_MASTER_MODE_ADDRESS10: /* Send slave Address for write */ I2C_Send7bitAddress(I2Cx, (uint8_t)SLAVE_ADDRESS, I2C_Direction_Transmitter); break; #else /* I2C_7BITS_ADDRESS */ /* Check on EV5 */ case I2C_EVENT_MASTER_MODE_SELECT : /* Send slave Address for write */ I2C_Send7bitAddress(I2Cx, (uint8_t)SLAVE_ADDRESS, I2C_Direction_Transmitter); break; #endif /* I2C_10BITS_ADDRESS */ /* Check on EV6 */ case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: /* Transmit the First Data */ I2C_SendData(I2Cx, TxBuffer[Tx_Idx++]); break; /* Check on EV8 */ case I2C_EVENT_MASTER_BYTE_TRANSMITTING: case I2C_EVENT_MASTER_BYTE_TRANSMITTED: if (Tx_Idx == (uint8_t)NumberOfByteToTransmit) { /* Send STOP condition */ I2C_GenerateSTOP(I2Cx, ENABLE); I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_BUF, DISABLE); } else { /* Transmit Data TxBuffer */ I2C_SendData(I2Cx, TxBuffer[Tx_Idx++]); } break; default: break; } } /*************************************************************************/ /* Master Receiver Events */ /* */ /*************************************************************************/ else /* MASTER_MODE_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*/ #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++]); 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 < NumberOfByteToTransmit) { I2C_SendData(I2Cx, TxBuffer[Tx_Idx++]); } else { /* Disable I2C event interrupt */ I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_BUF, DISABLE); } break; /* ****************************************************************************/ /* Slave Receiver Events */ /* */ /* ****************************************************************************/ /* check on EV1*/ case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: Rx_Idx = 0x00; break; /* Check on EV2*/ case I2C_EVENT_SLAVE_BYTE_RECEIVED: case (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF): RxBuffer[Rx_Idx++] = I2C_ReceiveData(I2Cx); break; /* Check on EV4 */ case I2C_EVENT_SLAVE_STOP_DETECTED: I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF); I2C_Cmd(I2Cx, ENABLE); break; default: break; } #endif /* I2C_SLAVE*/ }
// Read data from I2C port // input: // buf - pointer to data buffer // nbytes - number of bytes to receive // SlaveAddress - address of slave device // return: // I2C_ERROR if there was a timeout during I2C operations, I2C_SUCCESS otherwise I2C_Status I2C2_Read(uint8_t *buf, uint32_t nbytes, uint8_t SlaveAddress) { volatile uint32_t TimeOut; I2C_AcknowledgeConfig(I2C2_PORT,ENABLE); // Enable Acknowledgment I2C_NACKPositionConfig(I2C2_PORT,I2C_NACKPosition_Current); // Clear POS flag // Initiate start sequence I2C_GenerateSTART(I2C2_PORT,ENABLE); // Wait for EV5 TimeOut = 0; while (!I2C_CheckEvent(I2C2_PORT,I2C_EVENT_MASTER_MODE_SELECT) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++; if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR; // Send slave address I2C_Send7bitAddress(I2C2_PORT,SlaveAddress,I2C_Direction_Receiver); // Send slave address // Wait for EV6 TimeOut = 0; while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_ADDR) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++; if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR; // There are can be three cases: // read 1 byte // read 2 bytes // read more than 2 bytes if (nbytes == 1) { // Receive 1 byte (AN2824 figure 2) I2C_AcknowledgeConfig(I2C2_PORT,DISABLE); // Disable I2C acknowledgment (clear ACK bit) // EV6_1 must be atomic operation (AN2824) __disable_irq(); (void) I2C2_PORT->SR1; // Clear ADDR (void) I2C2_PORT->SR2; I2C_GenerateSTOP(I2C2_PORT,ENABLE); // Send STOP condition __enable_irq(); // Wait for RxNE flag (receive buffer not empty) EV7 TimeOut = 0; while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_RXNE) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++; if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR; *buf++ = I2C_ReceiveData(I2C2_PORT); // Receive byte } else if (nbytes == 2) { // Receive 2 bytes (AN2824 figure 2) I2C_NACKPositionConfig(I2C2_PORT,I2C_NACKPosition_Next); // Set POS flag // EV6_1 must be atomic operation (AN2824) __disable_irq(); (void) I2C2_PORT->SR2; // Clear ADDR I2C_AcknowledgeConfig(I2C2_PORT,DISABLE); // Clear ACK bit __enable_irq(); // Wait for BTF flag set (byte transfer finished) EV7_3 TimeOut = 0; while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_BTF) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++; if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR; __disable_irq(); I2C_GenerateSTOP(I2C2_PORT,ENABLE); // Send STOP condition *buf++ = I2C2_PORT->DR; // Faster than call I2C_ReceiveData() __enable_irq(); *buf++ = I2C2_PORT->DR; // Read second received byte } else { // Receive more than 2 bytes (AN2824 figure 1) (void) I2C2_PORT->SR2; // Clear ADDR flag while (nbytes-- != 3) { // Wait for BTF (cannot guarantee 1 transfer completion time) TimeOut = 0; while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_BTF) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++; if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR; *buf++ = I2C_ReceiveData(I2C2_PORT); } // Wait for BTF flag set (byte transfer finished) EV7_2 TimeOut = 0; while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_BTF) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++; if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR; I2C_AcknowledgeConfig(I2C2_PORT,DISABLE); // Clear ACK bit __disable_irq(); *buf++ = I2C_ReceiveData(I2C2_PORT); // Receive byte N-2 I2C_GenerateSTOP(I2C2_PORT,ENABLE); // Send STOP condition __enable_irq(); *buf++ = I2C_ReceiveData(I2C2_PORT); // Receive byte N-1 // Wait for last byte received TimeOut = 0; while (!I2C_CheckEvent(I2C2_PORT,I2C_EVENT_MASTER_BYTE_RECEIVED) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++; if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR; *buf++ = I2C_ReceiveData(I2C2_PORT); // Receive last byte nbytes = 0; } // Wait for STOP flag TimeOut = 0; while (I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_STOPF) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++; if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR; return I2C_SUCCESS; }
int readFrom(byte _dev_address,byte address, int num, byte _buff[]) { int a=0,i=0; int timeout; uint8_t flag1=0,flag2=0; a=i2c_beginTransmission(I2Ci,_dev_address,i2c_write); // start transmission to device if(a<0) return -1; // usart_printfm(USART1,(const int *)"Reading from this device address: %2x\n\r",_dev_address); a=i2c_sendData(I2Ci,address); // sends address to read from if(a<0) return -1; //usart_printfm(USART1,(const int *)"sent this data which is the address to read from: %2x\n\r",address); // if(a<0) // return (a-1); //i2c_stopTransmission(I2Cx); // end transmission // if(a<0) // return (a-2); a=i2c_beginTransmission(I2Ci,_dev_address,i2c_read); // start transmission to device if(a<0) return -1; //usart_printfm(USART1,(const int *)"Initiated the register read cycle: %2x\n\r",_dev_address); // if(a<0) // return a; // request 6 bytes from device if(num==1){ I2C_AcknowledgeConfig(I2Ci, DISABLE); /* Test on I2C1 EV8 and clear it */ timeout = I2C_TIMEOUT_MAX; /* Initialize timeout value */ // wait until one byte has been received while( !I2C_CheckEvent(I2Ci, I2C_EVENT_MASTER_BYTE_RECEIVED) ){ ms_delay(100); if((timeout--)==0){ flag1 = I2Ci->SR1; flag2 = I2Ci->SR2; usart_printf(USARTx,"Flag1:%04x \n\r Flag2:%04x\n\r",flag1,flag2); usart_printf(USARTx,"Failing at read nnack stage\n\r"); return -1; } } // wait until one byte has been received I2C_GenerateSTOP(I2Ci, ENABLE); // read data from I2C data register and return data byte _buff[i] = I2C_ReceiveData(I2Ci); return 0; } if(num==2) { timeout = I2C_TIMEOUT_MAX; // while(I2C_GetFlagStatus(I2Ci,I2C_FLAG_ADDR)!=SET){ // ms_delay(100); // if((timeout--)==0){ // flag1 = I2Ci->SR1; // flag2 = I2Ci->SR2; // usart_printf(USARTx,"Flag1:%04x \n\r Flag2:%04x\n\r",flag1,flag2); // usart_printf(USARTx,"Failing at reading 2 bytes stage\n\r"); // return ; // }} I2C_AcknowledgeConfig(I2Ci, DISABLE); I2C_NACKPositionConfig(I2Ci, I2C_NACKPosition_Next); timeout = I2C_TIMEOUT_MAX; while(I2C_GetFlagStatus(I2Ci,I2C_FLAG_BTF)!=SET){ ms_delay(100); if((timeout--)==0){ flag1 = I2Ci->SR1; flag2 = I2Ci->SR2; usart_printf(USARTx,"Flag1:%04x \n\r Flag2:%04x\n\r",flag1,flag2); usart_printf(USARTx,"Failing at reading 2 bytes stage2\n\r"); return -1; }} i2c_stopTransmission(I2Ci); _buff[i] = I2C_ReceiveData(I2Ci); i++; _buff[i] = I2C_ReceiveData(I2Ci); num-=2; // receive a byte //usart_printfm(USART1,(const int *)"this byte read from accel: %2x\n\r",i); return 0; } while(num>0) // device may send less than requested (abnormal) if(num==3){ //_buff[i]=I2C_read_ack(I2Cx); timeout = I2C_TIMEOUT_MAX; while(I2C_GetFlagStatus(I2Ci,I2C_FLAG_BTF)!=SET){ ms_delay(100); if((timeout--)==0){ flag1 = I2Ci->SR1; flag2 = I2Ci->SR2; usart_printf(USARTx,"Flag1:%04x \n\r Flag2:%04x\n\r",flag1,flag2); usart_printf(USARTx,"Failing at reading 2 bytes stage2\n\r"); return -1; }} I2C_AcknowledgeConfig(I2Ci, DISABLE); _buff[i]=I2C_ReceiveData(I2Ci); i++; num--; while(I2C_GetFlagStatus(I2Ci,I2C_FLAG_BTF)!=SET) { ms_delay(100); if((timeout--)==0){ flag1 = I2Ci->SR1; flag2 = I2Ci->SR2; usart_printf(USARTx,"Flag1:%04x \n\r Flag2:%04x\n\r",flag1,flag2); usart_printf(USARTx,"Failing at reading 2 bytes stage2\n\r"); return -1; }} i2c_stopTransmission(I2Ci); _buff[i]=I2C_ReceiveData(I2Ci); i++; _buff[i]=I2C_ReceiveData(I2Ci); i++; num-=2; //usart_print(USART1,"This byte read from nack: %2x\n\r",i); return 0; } else{ a=I2C_read(I2Ci,_buff[i]); if(a<0) return -1; i++; num--; } // if(i != num){ // status = ADXL345_ERROR; // error_code = ADXL345_READ_ERROR; // } //ms_delay(10); //i2c_stopTransmission(I2Cx); // end transmission //end : // usart_printf(USARTx,"Error occured !! Restarting the interface!!"); // ms_delay(5000); // return -1; return 0; }
/** * @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*/ }
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; }
Status I2C_Read(I2C_TypeDef* I2Cx, uint8_t *buf,uint32_t nbyte, uint8_t SlaveAddress) { __IO uint32_t Timeout = 0; // I2Cx->CR2 |= I2C_IT_ERR; interrupts for errors if (!nbyte) return Success; // Wait for idle I2C interface Timed(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); // Enable Acknowledgement, clear POS flag I2C_AcknowledgeConfig(I2Cx, ENABLE); I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current); // Intiate Start Sequence (wait for EV5 I2C_GenerateSTART(I2Cx, ENABLE); Timed(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); // Send Address I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Receiver); // EV6 Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR)); if (nbyte == 1) { // Clear Ack bit I2C_AcknowledgeConfig(I2Cx, DISABLE); // EV6_1 -- must be atomic -- Clear ADDR, generate STOP __disable_irq(); (void) I2Cx->SR2; I2C_GenerateSTOP(I2Cx,ENABLE); __enable_irq(); // Receive data EV7 Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_RXNE)); *buf++ = I2C_ReceiveData(I2Cx); } else if (nbyte == 2) { // Set POS flag I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next); // EV6_1 -- must be atomic and in this order __disable_irq(); (void) I2Cx->SR2; // Clear ADDR flag I2C_AcknowledgeConfig(I2Cx, DISABLE); // Clear Ack bit __enable_irq(); // EV7_3 -- Wait for BTF, program stop, read data twice Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF)); __disable_irq(); I2C_GenerateSTOP(I2Cx,ENABLE); *buf++ = I2Cx->DR; __enable_irq(); *buf++ = I2Cx->DR; } else { (void) I2Cx->SR2; // Clear ADDR flag while (nbyte-- != 3) { // EV7 -- cannot guarantee 1 transfer completion time, wait for BTF // instead of RXNE Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF)); *buf++ = I2C_ReceiveData(I2Cx); } Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF)); // EV7_2 -- Figure 1 has an error, doesn't read N-2 ! I2C_AcknowledgeConfig(I2Cx, DISABLE); // clear ack bit __disable_irq(); *buf++ = I2C_ReceiveData(I2Cx); // receive byte N-2 I2C_GenerateSTOP(I2Cx,ENABLE); // program stop __enable_irq(); *buf++ = I2C_ReceiveData(I2Cx); // receive byte N-1 // wait for byte N Timed(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); *buf++ = I2C_ReceiveData(I2Cx); nbyte = 0; } // Wait for stop Timed(I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF)); return Success; errReturn: // Any cleanup here return Error; }