/** * @brief Configures I2C Analog noise filter. * @param hi2c : pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2Cx peripheral. * @param AnalogFilter : new state of the Analog filter. * @retval HAL status */ HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) { /* Check the parameters */ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); if((hi2c->State == HAL_I2C_STATE_BUSY) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX)) { return HAL_BUSY; } /* Process Locked */ __HAL_LOCK(hi2c); hi2c->State = HAL_I2C_STATE_BUSY; /* Disable the selected I2C peripheral */ __HAL_I2C_DISABLE(hi2c); /* Reset I2Cx ANOFF bit */ hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF); /* Set analog filter bit*/ hi2c->Instance->CR1 |= AnalogFilter; __HAL_I2C_ENABLE(hi2c); hi2c->State = HAL_I2C_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_OK; }
/** * @brief Configures I2C Analog noise filter. * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2Cx peripheral. * @param AnalogFilter: new state of the Analog filter. * @retval HAL status */ HAL_StatusTypeDef HAL_I2CEx_AnalogFilter_Config(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) { uint32_t tmp = 0; /* Check the parameters */ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); tmp = hi2c->State; if((tmp == HAL_I2C_STATE_BUSY) || (tmp == HAL_I2C_STATE_BUSY_TX) || (tmp == HAL_I2C_STATE_BUSY_RX)) { return HAL_BUSY; } hi2c->State = HAL_I2C_STATE_BUSY; /* Disable the selected I2C peripheral */ __HAL_I2C_DISABLE(hi2c); /* Reset I2Cx ANOFF bit */ hi2c->Instance->FLTR &= ~(I2C_FLTR_ANOFF); /* Disable the analog filter */ hi2c->Instance->FLTR |= AnalogFilter; __HAL_I2C_ENABLE(hi2c); hi2c->State = HAL_I2C_STATE_READY; return HAL_OK; }
/** * @brief Disable I2C wakeup from stop mode. * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2Cx peripheral. * @retval HAL status */ HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp (I2C_HandleTypeDef *hi2c) { /* Check the parameters */ assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance)); if(hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); hi2c->State = HAL_I2C_STATE_BUSY; /* Disable the selected I2C peripheral */ __HAL_I2C_DISABLE(hi2c); /* Enable wakeup from stop mode */ hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN); __HAL_I2C_ENABLE(hi2c); hi2c->State = HAL_I2C_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Enables I2C wakeup from stop mode. * @param hi2c : pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2Cx peripheral. * @retval HAL status */ HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp (I2C_HandleTypeDef *hi2c) { /* Check the parameters */ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); if((hi2c->State == HAL_I2C_STATE_BUSY) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX)) { return HAL_BUSY; } /* Process Locked */ __HAL_LOCK(hi2c); hi2c->State = HAL_I2C_STATE_BUSY; /* Disable the selected I2C peripheral */ __HAL_I2C_DISABLE(hi2c); /* Enable wakeup from stop mode */ hi2c->Instance->CR1 |= I2C_CR1_WUPEN; __HAL_I2C_ENABLE(hi2c); hi2c->State = HAL_I2C_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_OK; }
int initMPU(void){ int initOkay = -1; HAL_I2C_StateTypeDef state; uint8_t tempByte = 13; uint8_t buffer[10] = {0,0,0,0,0,0,0,0,0,0}; hnd.Instance = I2C1; hnd.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hnd.Init.ClockSpeed = 400000; hnd.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hnd.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hnd.Init.DutyCycle = I2C_DUTYCYCLE_2; hnd.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; hnd.Init.OwnAddress1 = 0x00; HAL_I2C_Init(&hnd); __HAL_I2C_ENABLE(&hnd); state = HAL_I2C_GetState(&hnd); if(state == HAL_I2C_STATE_READY){ initOkay = 0; } buffer[0]=MPU6050_RA_PWR_MGMT_1; buffer[1]=0x80; printf("READ: %u",SCCB_Read(MPU6050_RA_WHO_AM_I)); printf("error: %u",HAL_I2C_GetError(&hnd)); return initOkay; }
/** * @brief Configures I2C Digital noise filter. * @param hi2c : pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2Cx peripheral. * @param DigitalFilter : Coefficient of digital noise filter between 0x00 and 0x0F. * @retval HAL status */ HAL_StatusTypeDef HAL_I2CEx_DigitalFilter_Config(I2C_HandleTypeDef * hi2c, uint32_t DigitalFilter) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); if ((hi2c->State == HAL_I2C_STATE_BUSY) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX)) { return HAL_BUSY; } /* Process Locked */ __HAL_LOCK(hi2c); hi2c->State = HAL_I2C_STATE_BUSY; /* Disable the selected I2C peripheral */ __HAL_I2C_DISABLE(hi2c); /* Get the old register value */ tmpreg = hi2c->Instance->CR1; /* Reset I2Cx DNF bits [11:8] */ tmpreg &= ~(I2C_CR1_DFN); /* Set I2Cx DNF coefficient */ tmpreg |= DigitalFilter << 8; /* Store the new register value */ hi2c->Instance->CR1 = tmpreg; __HAL_I2C_ENABLE(hi2c); hi2c->State = HAL_I2C_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_OK; }
void I2C_Configuration(I2C_HandleTypeDef* i2cHandle) { i2cHandle->Instance = I2C1; i2cHandle->Init.ClockSpeed = 400000; //400000 i2cHandle->Init.DutyCycle = I2C_DUTYCYCLE_2; i2cHandle->Init.OwnAddress1 = 0x00; i2cHandle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; i2cHandle->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; i2cHandle->Init.OwnAddress2 = 0x00; i2cHandle->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; i2cHandle->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(i2cHandle) != HAL_OK) { errorHandler("I2C_INIT"); } __HAL_I2C_ENABLE(i2cHandle); }
/** * @brief Configures I2C Digital noise filter. * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2Cx peripheral. * @param DigitalFilter: Coefficient of digital noise filter between 0x00 and 0x0F. * @retval HAL status */ HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) { uint16_t tmpreg = 0; /* Check the parameters */ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); if(hi2c->State == HAL_I2C_STATE_READY) { hi2c->State = HAL_I2C_STATE_BUSY; /* Disable the selected I2C peripheral */ __HAL_I2C_DISABLE(hi2c); /* Get the old register value */ tmpreg = hi2c->Instance->FLTR; /* Reset I2Cx DNF bit [3:0] */ tmpreg &= ~(I2C_FLTR_DNF); /* Set I2Cx DNF coefficient */ tmpreg |= DigitalFilter; /* Store the new register value */ hi2c->Instance->FLTR = tmpreg; __HAL_I2C_ENABLE(hi2c); hi2c->State = HAL_I2C_STATE_READY; return HAL_OK; } else { return HAL_BUSY; } }
// this function is based on STM code int machine_hard_i2c_writeto(mp_obj_base_t *self_in, uint16_t addr, const uint8_t *src, size_t len, bool stop) { machine_hard_i2c_obj_t *self = (machine_hard_i2c_obj_t*)self_in; I2C_HandleTypeDef *hi2c = self->pyb->i2c; uint32_t Timeout = *self->timeout; /* Init tickstart for timeout management*/ uint32_t tickstart = HAL_GetTick(); #if 0 // TODO: for multi-master, here we could wait for the bus to be free // we'd need a flag to tell if we were in the middle of a set of transactions // (ie didn't send a stop bit in the last call) /* Wait until BUSY flag is reset */ if (!I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart)) { return -MP_EBUSY; } #endif /* Check if the I2C is already enabled */ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) { /* Enable I2C peripheral */ __HAL_I2C_ENABLE(hi2c); } /* Disable Pos */ hi2c->Instance->CR1 &= ~I2C_CR1_POS; /* Send Slave Address */ int ret = send_addr_byte(hi2c, I2C_7BIT_ADD_WRITE(addr << 1), Timeout, tickstart); if (ret != 0) { return ret; } /* Clear ADDR flag */ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); int num_acks = 0; while (len > 0U) { /* Wait until TXE flag is set */ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) { /* Check if a NACK is detected */ if (I2C_IsAcknowledgeFailed(hi2c)) { goto nack; } /* Check for the Timeout */ if (Timeout != HAL_MAX_DELAY) { if ((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) { goto timeout; } } } /* Write data to DR */ hi2c->Instance->DR = *src++; len--; /* Wait until BTF flag is set */ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) { /* Check if a NACK is detected */ if (I2C_IsAcknowledgeFailed(hi2c)) { goto nack; } /* Check for the Timeout */ if (Timeout != HAL_MAX_DELAY) { if ((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) { goto timeout; } } } ++num_acks; } nack: /* Generate Stop */ if (stop) { hi2c->Instance->CR1 |= I2C_CR1_STOP; } return num_acks; timeout: // timeout, release the bus cleanly hi2c->Instance->CR1 |= I2C_CR1_STOP; return -MP_ETIMEDOUT; }
// this function is based on STM code int machine_hard_i2c_readfrom(mp_obj_base_t *self_in, uint16_t addr, uint8_t *dest, size_t len, bool stop) { machine_hard_i2c_obj_t *self = (machine_hard_i2c_obj_t*)self_in; I2C_HandleTypeDef *hi2c = self->pyb->i2c; uint32_t Timeout = *self->timeout; /* Init tickstart for timeout management*/ uint32_t tickstart = HAL_GetTick(); #if 0 // TODO: for multi-master, here we could wait for the bus to be free // we'd need a flag to tell if we were in the middle of a set of transactions // (ie didn't send a stop bit in the last call) /* Wait until BUSY flag is reset */ if (!I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart)) { return -MP_EBUSY; } #endif /* Check if the I2C is already enabled */ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) { /* Enable I2C peripheral */ __HAL_I2C_ENABLE(hi2c); } /* Disable Pos */ hi2c->Instance->CR1 &= ~I2C_CR1_POS; /* Enable Acknowledge */ hi2c->Instance->CR1 |= I2C_CR1_ACK; /* Send Slave Address */ int ret = send_addr_byte(hi2c, I2C_7BIT_ADD_READ(addr << 1), Timeout, tickstart); if (ret != 0) { return ret; } if (len == 0U) { /* Clear ADDR flag */ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); /* Generate Stop */ if (stop) { hi2c->Instance->CR1 |= I2C_CR1_STOP; } } else if (len == 1U) { /* Disable Acknowledge */ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; /* Clear ADDR flag */ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); /* Generate Stop */ if (stop) { hi2c->Instance->CR1 |= I2C_CR1_STOP; } } else if (len == 2U) { /* Disable Acknowledge */ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; /* Enable Pos */ hi2c->Instance->CR1 |= I2C_CR1_POS; /* Clear ADDR flag */ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); } else { /* Enable Acknowledge */ hi2c->Instance->CR1 |= I2C_CR1_ACK; /* Clear ADDR flag */ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); } while (len > 0U) { if (len <= 3U) { if (len == 1U) { /* Wait until RXNE flag is set */ int ret = I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart); if (ret != 0) { return ret; } /* Read data from DR */ *dest++ = hi2c->Instance->DR; len--; } else if (len == 2U) { /* Wait until BTF flag is set */ if (!I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart)) { return -MP_ETIMEDOUT; } /* Generate Stop */ if (stop) { hi2c->Instance->CR1 |= I2C_CR1_STOP; } /* Read data from DR */ *dest++ = hi2c->Instance->DR; len--; /* Read data from DR */ *dest++ = hi2c->Instance->DR; len--; } else { /* Wait until BTF flag is set */ if (!I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart)) { return -MP_ETIMEDOUT; } /* Disable Acknowledge */ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; /* Read data from DR */ *dest++ = hi2c->Instance->DR; len--; /* Wait until BTF flag is set */ if (!I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart)) { return -MP_ETIMEDOUT; } /* Generate Stop */ if (stop) { hi2c->Instance->CR1 |= I2C_CR1_STOP; } /* Read data from DR */ *dest++ = hi2c->Instance->DR; len--; /* Read data from DR */ *dest++ = hi2c->Instance->DR; len--; } } else { /* Wait until RXNE flag is set */ int ret = I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart); if (ret != 0) { return ret; } /* Read data from DR */ *dest++ = hi2c->Instance->DR; len--; if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) { /* Read data from DR */ *dest++ = hi2c->Instance->DR; len--; } } } return 0; }