static void HAL_I2C_SoftwareReset(HAL_I2C_Interface i2c) { /* Disable the I2C peripheral */ I2C_Cmd(i2cMap[i2c]->I2C_Peripheral, DISABLE); /* Reset all I2C registers */ I2C_SoftwareResetCmd(i2cMap[i2c]->I2C_Peripheral, ENABLE); I2C_SoftwareResetCmd(i2cMap[i2c]->I2C_Peripheral, DISABLE); /* Clear all I2C interrupt error flags, and re-enable them */ I2C_ClearITPendingBit(i2cMap[i2c]->I2C_Peripheral, I2C_IT_SMBALERT | I2C_IT_PECERR | I2C_IT_TIMEOUT | I2C_IT_ARLO | I2C_IT_OVR | I2C_IT_BERR | I2C_IT_AF); I2C_ITConfig(i2cMap[i2c]->I2C_Peripheral, I2C_IT_ERR, ENABLE); /* Re-enable Event and Buffer interrupts in Slave mode */ if(i2cMap[i2c]->mode == I2C_MODE_SLAVE) { I2C_ITConfig(i2cMap[i2c]->I2C_Peripheral, I2C_IT_EVT | I2C_IT_BUF, ENABLE); } /* Enable the I2C peripheral */ I2C_Cmd(i2cMap[i2c]->I2C_Peripheral, ENABLE); /* Apply I2C configuration after enabling it */ I2C_Init(i2cMap[i2c]->I2C_Peripheral, &i2cMap[i2c]->I2C_InitStructure); }
static void i2c_er_handler(I2CDevice device) { I2C_TypeDef *I2Cx; I2Cx = i2cHardwareMap[device].dev; i2cState_t *state; state = &(i2cState[device]); // Read the I2C1 status register volatile uint32_t SR1Register = I2Cx->SR1; if (SR1Register & 0x0F00) // an error state->error = true; // If AF, BERR or ARLO, abandon the current job and commence new if there are jobs if (SR1Register & 0x0700) { (void)I2Cx->SR2; // read second status register to clear ADDR if it is set (note that BTF will not be set after a NACK) I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // disable the RXNE/TXE interrupt - prevent the ISR tailchaining onto the ER (hopefully) if (!(SR1Register & I2C_SR1_ARLO) && !(I2Cx->CR1 & I2C_CR1_STOP)) { // if we dont have an ARLO error, ensure sending of a stop if (I2Cx->CR1 & I2C_CR1_START) { // We are currently trying to send a start, this is very bad as start, stop will hang the peripheral while (I2Cx->CR1 & I2C_CR1_START) {; } // wait for any start to finish sending I2C_GenerateSTOP(I2Cx, ENABLE); // send stop to finalise bus transaction while (I2Cx->CR1 & I2C_CR1_STOP) {; } // wait for stop to finish sending i2cInit(device); // reset and configure the hardware } else { I2C_GenerateSTOP(I2Cx, ENABLE); // stop to free up the bus I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts while bus inactive } } } I2Cx->SR1 &= ~0x0F00; // reset all the error bits to clear the interrupt state->busy = 0; }
/********************************************************************************************* I2C 作为 主机部分 **********************************************************************************************/ I2C_Return I2C_Master_Transmitter(I2C_InformationSendAndRecerve * I2CPram) { I2C_Return retStat; retStat=I2C_Ok; ARC_SetI2C_Information(I2CPram); // 存储数据到缓冲变量 // I2C_InterruptBuff=I2CPram; /* Enable EVT IT*/ I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE); // 缓冲中断使能 /* wait for Bus is not busy */ CODECTimeout = CODEC_LONG_TIMEOUT; while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY)) { if((CODECTimeout--) == 0) return I2C_Error; // return this function } /* Start the config sequence */ I2C_GenerateSTART(CODEC_I2C, ENABLE); /* Then to go to interrupt to deal */ // while()// 发送数据可以不等带 。。主机程序中必须 等待发送成功,,可以适当延时 while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); if(I2CPram->TX_Generate_stop == 0) I2C_AcknowledgeConfig(I2C1, ENABLE); return retStat; }
static void i2c_er_handler(void) { volatile uint32_t SR1Register, SR2Register; /* Read the I2C1 status register */ SR1Register = I2Cx->SR1; if (SR1Register & 0x0F00) { //an error error = true; // I2C1error.error = ((SR1Register & 0x0F00) >> 8); //save error // I2C1error.job = job; //the task } /* If AF, BERR or ARLO, abandon the current job and commence new if there are jobs */ if (SR1Register & 0x0700) { SR2Register = I2Cx->SR2; //read second status register to clear ADDR if it is set (note that BTF will not be set after a NACK) SR2Register = SR2Register; I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); //disable the RXNE/TXE interrupt - prevent the ISR tailchaining onto the ER (hopefully) if (!(SR1Register & 0x0200) && !(I2Cx->CR1 & 0x0200)) { //if we dont have an ARLO error, ensure sending of a stop if (I2Cx->CR1 & 0x0100) { //We are currently trying to send a start, this is very bad as start,stop will hang the peripheral while (I2Cx->CR1 & 0x0100); //wait for any start to finish sending I2C_GenerateSTOP(I2Cx, ENABLE); //send stop to finalise bus transaction while (I2Cx->CR1 & 0x0200); //wait for stop to finish sending i2cInit(I2Cx); //reset and configure the hardware } else { I2C_GenerateSTOP(I2Cx, ENABLE); //stop to free up the bus I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); //Disable EVT and ERR interrupts while bus inactive } } } I2Cx->SR1 &= ~0x0F00; //reset all the error bits to clear the interrupt busy = 0; }
static void i2c_er_handler(void) { // Read the I2Cx status register uint32_t SR1Register = I2Cx->SR1; if (SR1Register & 0x0F00) { // an error error = true; } // If AF, BERR or ARLO, abandon the current job and commence new if there are jobs if (SR1Register & 0x0700) { (void)I2Cx->SR2; // read second status register to clear ADDR if it is set (note that BTF will not be set after a NACK) I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // disable the RXNE/TXE interrupt - prevent the ISR tailchaining onto the ER (hopefully) if (!(SR1Register & 0x0200) && !(I2Cx->CR1 & 0x0200)) { // if we dont have an ARLO error, ensure sending of a stop if (I2Cx->CR1 & 0x0100) { // We are currently trying to send a start, this is very bad as start, stop will hang the peripheral // TODO - busy waiting in highest priority IRQ. Maybe only set flag and handle it from main loop while (I2Cx->CR1 & 0x0100) { ; } // wait for any start to finish sending I2C_GenerateSTOP(I2Cx, ENABLE); // send stop to finalise bus transaction while (I2Cx->CR1 & 0x0200) { ; } // wait for stop to finish sending i2cInit(I2Cx_index); // reset and configure the hardware } else { I2C_GenerateSTOP(I2Cx, ENABLE); // stop to free up the bus I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts while bus inactive } } } I2Cx->SR1 &= ~0x0F00; // reset all the error bits to clear the interrupt busy = 0; }
void I2C_ER_Handler(void) { volatile uint32_t SR1Register, SR2Register; SR1Register = I2Cx->SR1; // Read the I2Cx status register if (SR1Register & (I2C_SR1_AF | I2C_SR1_ARLO | I2C_SR1_BERR )) // If AF, BERR or ARLO, abandon the current job and commence new if there are jobs { SR2Register = I2Cx->SR2; // Read second status register to clear ADDR if it is set (note that BTF will not be set after a NACK) I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // Disable the RXNE/TXE interrupt - prevent the ISR tailchaining onto the ER (hopefully) if (!(SR1Register & I2C_SR1_ARLO) && !(I2Cx->CR1 & I2C_CR1_STOP)) // If we dont have an ARLO error, ensure sending of a stop { if (I2Cx->CR1 & I2C_CR1_START) // We are currently trying to send a start, this is very bad as start,stop will hang the peripheral { while (I2Cx->CR1 & I2C_CR1_START); // Wait for any start to finish sending I2C_GenerateSTOP(I2Cx, ENABLE); // Send stop to finalise bus transaction while (I2Cx->CR1 & I2C_CR1_STOP); // Wait for stop to finish sending i2cInit(I2Cx); // Reset and configure the hardware } else { I2C_GenerateSTOP(I2Cx, ENABLE); // Stop to free up the bus I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts while bus inactive } } } I2Cx->SR1 &= ~(I2C_SR1_OVR | I2C_SR1_AF | I2C_SR1_ARLO | I2C_SR1_BERR ); // Reset all the error bits to clear the interrupt busy = 0; }
void i2c_config() { // RCC /* Enable GPIOB clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // GPIO GPIO_InitTypeDef GPIO_InitStructure; /* Configure I2C1 pins: SCL and SDA */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Enable I2C1 reset state */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); /* Release I2C1 from reset state */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); I2C_DeInit(I2C1); // I2C /* Enable I2C1 */ I2C_Cmd(I2C1, ENABLE); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = ID; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = ClockSpeed; I2C_Init(I2C1, &I2C_InitStructure); I2C_GeneralCallCmd(I2C1, ENABLE); /* Enable Event IT needed for ADDR and STOPF events ITs */ I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); /* Enable Error IT */ I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE); /* Enable Buffer IT (TXE and RXNE ITs) */ I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE); // NVIC /* 1 bit for pre-emption priority, 3 bits for subpriority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); NVIC_SetPriority(I2C1_EV_IRQn, 0x00); NVIC_EnableIRQ(I2C1_EV_IRQn); NVIC_SetPriority(I2C1_ER_IRQn, 0x01); NVIC_EnableIRQ(I2C1_ER_IRQn); }
//______________________________________________________________________________________ void I2C1_EV_IRQHandler(void) { static int n=0; switch (I2C_GetLastEvent(I2C1)) { case I2C_EVENT_MASTER_MODE_SELECT : if(__i2c1->ntx) I2C_Send7bitAddress(I2C1, (uint8_t)(__i2c1->addr)<<1, I2C_Direction_Transmitter); else I2C_Send7bitAddress(I2C1, (uint8_t)(__i2c1->addr)<<1, I2C_Direction_Receiver); n=0; break; case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: I2C_SendData(I2C1, __i2c1->txbuf[n++]); break; case I2C_EVENT_MASTER_BYTE_TRANSMITTING: case I2C_EVENT_MASTER_BYTE_TRANSMITTED: if (n == __i2c1->ntx) { __i2c1->ntx=0; if(__i2c1->nrx) I2C_GenerateSTART(I2C1, ENABLE); else { I2C_GenerateSTOP(I2C1, ENABLE); I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE); } } else I2C_SendData(I2C1, __i2c1->txbuf[n++]); break; case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: if(__i2c1->nrx==1) { I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_GenerateSTOP(I2C1, ENABLE); } break; case I2C_EVENT_MASTER_BYTE_RECEIVED: __i2c1->rxbuf[n++]=I2C_ReceiveData (I2C1); if(n==__i2c1->nrx-1) { I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_GenerateSTOP(I2C1, ENABLE); } if(n==__i2c1->nrx) { I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE); I2C_AcknowledgeConfig(I2C1, ENABLE); __i2c1->nrx=0; } break; default: break; } }
void i2cInit(I2CDevice index) { NVIC_InitTypeDef nvic; I2C_InitTypeDef i2c; if (index > I2CDEV_MAX) index = I2CDEV_MAX; // Turn on peripheral clock, save device and index I2Cx = i2cHardwareMap[index].dev; I2Cx_index = index; RCC_APB1PeriphClockCmd(i2cHardwareMap[index].peripheral, ENABLE); // diable I2C interrrupts first to avoid ER handler triggering I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // clock out stuff to make sure slaves arent stuck // This will also configure GPIO as AF_OD at the end i2cUnstick(); // Init I2C peripheral I2C_DeInit(I2Cx); I2C_StructInit(&i2c); I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts - they are enabled by the first request i2c.I2C_Mode = I2C_Mode_I2C; i2c.I2C_DutyCycle = I2C_DutyCycle_2; i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // Overclocking i2c, test results // Default speed, conform specs is 400000 (400 kHz) // 2.0* : 800kHz - worked without errors // 3.0* : 1200kHz - worked without errors // 3.5* : 1400kHz - failed, hangup, bootpin recovery needed // 4.0* : 1600kHz - failed, hangup, bootpin recovery needed i2c.I2C_ClockSpeed = CLOCKSPEED; I2C_Cmd(I2Cx, ENABLE); I2C_Init(I2Cx, &i2c); // I2C ER Interrupt nvic.NVIC_IRQChannel = i2cHardwareMap[index].er_irq; nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_ER); nvic.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_I2C_ER); nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); // I2C EV Interrupt nvic.NVIC_IRQChannel = i2cHardwareMap[index].ev_irq; nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_EV); nvic.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_I2C_EV); NVIC_Init(&nvic); }
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 i2cInit(I2CDevice index) { NVIC_InitTypeDef nvic; I2C_InitTypeDef i2c; if (index > I2CDEV_MAX) index = I2CDEV_MAX; // Turn on peripheral clock, save device and index I2Cx = i2cHardwareMap[index].dev; I2Cx_index = index; RCC_APB1PeriphClockCmd(i2cHardwareMap[index].peripheral, ENABLE); // diable I2C interrrupts first to avoid ER handler triggering I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // clock out stuff to make sure slaves arent stuck // This will also configure GPIO as AF_OD at the end i2cUnstick(); // Init I2C peripheral I2C_DeInit(I2Cx); I2C_StructInit(&i2c); I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts - they are enabled by the first request i2c.I2C_Mode = I2C_Mode_I2C; i2c.I2C_DutyCycle = I2C_DutyCycle_2; i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; if (i2cOverClock) { i2c.I2C_ClockSpeed = 800000; // 800khz Maximum speed tested on various boards without issues } else { i2c.I2C_ClockSpeed = 400000; // 400khz Operation according specs } I2C_Cmd(I2Cx, ENABLE); I2C_Init(I2Cx, &i2c); // I2C ER Interrupt nvic.NVIC_IRQChannel = i2cHardwareMap[index].er_irq; nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_ER); nvic.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_I2C_ER); nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); // I2C EV Interrupt nvic.NVIC_IRQChannel = i2cHardwareMap[index].ev_irq; nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_EV); nvic.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_I2C_EV); NVIC_Init(&nvic); }
static void i2cdrvStartTransfer(I2cDrv *i2c) { if (i2c->txMessage.direction == i2cRead) { i2c->DMAStruct.DMA_BufferSize = i2c->txMessage.messageLength; i2c->DMAStruct.DMA_Memory0BaseAddr = (uint32_t)i2c->txMessage.buffer; DMA_Init(i2c->def->dmaRxStream, &i2c->DMAStruct); DMA_Cmd(i2c->def->dmaRxStream, ENABLE); } I2C_ITConfig(i2c->def->i2cPort, I2C_IT_BUF, DISABLE); I2C_ITConfig(i2c->def->i2cPort, I2C_IT_EVT, ENABLE); i2c->def->i2cPort->CR1 = (I2C_CR1_START | I2C_CR1_PE); }
static rt_err_t stm_i2c_init(struct rt_i2c_bus_device *bus, rt_uint32_t bitrate) { struct stm32_i2c_bus *stm32_i2c; I2C_InitTypeDef I2C_InitStructure; RT_ASSERT(bus != RT_NULL); if(bitrate != 100000 && bitrate != 400000) { return RT_EIO; } stm32_i2c = (struct stm32_i2c_bus *) bus; I2C_Cmd(stm32_i2c->I2C, DISABLE); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2CADDR; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = bitrate; I2C_Init(stm32_i2c->I2C, &I2C_InitStructure); I2C_Cmd(stm32_i2c->I2C, ENABLE); I2C_ITConfig(stm32_i2c->I2C, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, ENABLE); stm32_i2c_nvic_Config(stm32_i2c->I2C); return RT_EOK; }
uint8_t i2cRead(I2C_TypeDef* I2Cx, I2C_context_t * context, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t * buf) { uint32_t timeout = I2C_DEFAULT_TIMEOUT; context->addr = addr_ << 1; context->reg = reg_; context->writing = 0; context->reading = 1; context->read_p = buf; context->write_p = buf; context->bytes = len; context->busy = 1; if (!(I2Cx->CR2 & I2C_IT_EVT)) //if we are restarting the driver { if (!(I2Cx->CR1 & 0x0100)) //ensure sending a start { while (I2Cx->CR1 & 0x0200) {; } //wait for any stop to finish sending I2C_GenerateSTART(I2Cx, ENABLE); //send the start for the new job } I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, ENABLE); //allow the interrupts to fire off again } while (context->busy && --timeout > 0); if (timeout == 0) { context->i2cErrorCount++; // reinit peripheral + clock out garbage i2c_init(I2Cx); return 0; } return 1; }
void I2C1_ER_IRQHandler(void) { uint32_t sr1 = I2C1->SR1; uint32_t sr2 = I2C1->SR2; i2cErr = sr1 | (sr2 << 16); I2C_ITConfig(I2C1, I2C_IT_ERR, DISABLE); }
/* I2C Slave with Interrupt Init */ void I2C_SlaveWithInterrupt_Init(I2C_TypeDef* I2Cx, uint32_t freq, int SlaveAddr, pin_t scl, pin_t sda){ NVIC_InitTypeDef i2c_slave_nvic; uint8_t _i2c_er_irq; I2C_Master_Init(I2Cx, freq, scl, sda); I2C_Slave_Mode(I2Cx, 1); I2C_Slave_Address(I2Cx, SlaveAddr); /* Configure the Priority Group to 1 bit */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); if(I2Cx == I2C1){ _i2c_er_irq = I2C1_ER_IRQn; i2c_slave_nvic.NVIC_IRQChannel = I2C1_EV_IRQn; }else if(I2Cx == I2C2){ _i2c_er_irq = I2C2_ER_IRQn; i2c_slave_nvic.NVIC_IRQChannel = I2C2_EV_IRQn; } i2c_slave_nvic.NVIC_IRQChannelPreemptionPriority = 1; i2c_slave_nvic.NVIC_IRQChannelSubPriority = 0; i2c_slave_nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&i2c_slave_nvic); i2c_slave_nvic.NVIC_IRQChannel = _i2c_er_irq; NVIC_Init(&i2c_slave_nvic); /* Enable Error Interrupt */ I2C_ITConfig(I2Cx, (I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE); }
bool i2cRead(I2C_TypeDef *I2C, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t *buf) { uint32_t timeout = I2C_DEFAULT_TIMEOUT; I2Cx = I2C; addr = addr_ << 1; reg = reg_; writing = 0; reading = 1; read_p = buf; write_p = buf; bytes = len; busy = 1; if (!(I2Cx->CR2 & I2C_IT_EVT)) // If we are restarting the driver { if (!(I2Cx->CR1 & I2C_CR1_START)) // Ensure sending a start { while (I2Cx->CR1 & I2C_CR1_STOP) { ; } // Wait for any stop to finish sending I2C_GenerateSTART(I2Cx, ENABLE); // Send the start for the new job } I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, ENABLE); // Allow the interrupts to fire off again } while (busy && --timeout > 0); if (timeout == 0) { if (I2Cx == I2C1) i2c1ErrorCount++; if (I2Cx == I2C2) i2c2ErrorCount++; i2cInit(I2Cx); // Reinit peripheral + clock out garbage return false; } return true; }
bool i2cRead(uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t* buf) { uint32_t timeout = I2C_DEFAULT_TIMEOUT; addr = addr_ << 1; reg = reg_; writing = 0; reading = 1; read_p = buf; write_p = buf; bytes = len; busy = 1; error = false; if (!I2Cx) return false; if (!(I2Cx->CR2 & I2C_IT_EVT)) { // if we are restarting the driver if (!(I2Cx->CR1 & 0x0100)) { // ensure sending a start while (I2Cx->CR1 & 0x0200 && --timeout > 0) { ; } // wait for any stop to finish sending if (timeout == 0) return i2cHandleHardwareFailure(); I2C_GenerateSTART(I2Cx, ENABLE); // send the start for the new job } I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, ENABLE); // allow the interrupts to fire off again } timeout = I2C_DEFAULT_TIMEOUT; while (busy && --timeout > 0) { ; } if (timeout == 0) return i2cHandleHardwareFailure(); return !error; }
//______________________________________________________________________________________ int writeI2C( _i2c *p, char *dBuffer, int length) { static int nrpt=3; int to=__time__+25; if(p) { memcpy(p->txbuf,dBuffer,length); p->ntx=length; I2C_ITConfig(I2C1, (I2C_IT_EVT | I2C_IT_BUF), ENABLE); I2C_GenerateSTART(I2C1, ENABLE); while(p->ntx && __time__< to) _proc_loop(); if(p->ntx) { Reset_I2C(p); if(--nrpt) return writeI2C(p, dBuffer, length); } nrpt=3; if(p->ntx) { return(0); } } _CLEAR_ERROR(pfm,PFM_I2C_ERR); if(_DBG(pfm,_DBG_I2C_TX)) { _io *io=_stdio(__dbug); int i; __print(":%04d",__time__ % 10000); for(i=0;i<length;++i) __print(" %02X",p->txbuf[i]); __print("\r\n>"); _stdio(io); } return(-1); }
void TwoWire::begin(uint8_t address) { if (onBeginCallback) onBeginCallback(); status = SLAVE_IDLE; if (twi==I2C1) { RCC_I2CCLKConfig(RCC_I2C1CLK_HSI); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); pinMode(SDA, ALTERNATE); pinMode(SCL, ALTERNATE); } I2C_DeInit(twi); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; I2C_InitStructure.I2C_DigitalFilter = 0x00; I2C_InitStructure.I2C_OwnAddress1 = address; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_Timing = 0x00E0D3FF; I2C_Init(twi, &I2C_InitStructure); NVIC_SetPriority(I2C1_IRQn, 0); NVIC_EnableIRQ(I2C1_IRQn); I2C_Cmd(twi, ENABLE); I2C_ITConfig(twi, I2C_IT_ADDRI, ENABLE); }
void i2c1_hw_init(void) { i2c1.reg_addr = I2C1; i2c1.init_struct = &I2C1_InitStruct; i2c1.scl_pin = GPIO_Pin_6; i2c1.sda_pin = GPIO_Pin_7; i2c1.errors = &i2c1_errors; /* zeros error counter */ ZEROS_ERR_COUNTER(i2c1_errors); // Extra #ifdef I2C_DEBUG_LED LED_INIT(); #else /* reset peripheral to default state ( sometimes not achieved on reset :( ) */ //I2C_DeInit(I2C1); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitTypeDef NVIC_InitStructure; /* Configure and enable I2C1 event interrupt --------------------------------*/ NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Configure and enable I2C1 err interrupt ----------------------------------*/ NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable peripheral clocks -------------------------------------------------*/ /* Enable I2C1 clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); /* Enable GPIOB clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = i2c1.scl_pin | i2c1.sda_pin; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); I2C_DeInit(I2C1); // enable peripheral I2C_Cmd(I2C1, ENABLE); I2C_Init(I2C1, i2c1.init_struct); // enable error interrupts I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE); #endif }
void SendDataBy_I2C1() { DMA_ConfigForI2C1Send(); I2C_AcknowledgeConfig(I2C1, ENABLE); I2C_ITConfig(I2C1, I2C_IT_BUF , DISABLE); while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY)) //wait for bus is not busy { } /* Start the config sequence */ I2C_GenerateSTART(CODEC_I2C, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) // EV5 { } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter); DMA_Cmd(DMA1_Stream6, ENABLE); I2C_DMACmd(I2C2, ENABLE); /* DMA1 Channel6 transfer complete test */ while(DMA_GetFlagStatus(DMA1_Stream6,DMA_FLAG_TCIF6)==RESET) { } I2C_DMACmd(I2C1, DISABLE); DMA_Cmd(DMA1_Stream6, DISABLE); // wait until BTF while (!(I2C1->SR1 & 0x04)); I2C_GenerateSTOP(I2C1, ENABLE); // wait until BUSY clear while (I2C1->SR2 & 0x02); if(I2C1->CR1 & 0x200) I2C1->CR1 &= 0xFDFF; }
void i2cSetup(uint32_t speed) { I2C_InitTypeDef i2cConfig; // GPIO Init RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); GPIO_Init(GPIOB, &(GPIO_InitTypeDef){GPIO_Pin_6, GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL}); GPIO_Init(GPIOB, &(GPIO_InitTypeDef){GPIO_Pin_9, GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL}); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // I2C init I2C_StructInit(&i2cConfig); // TODO - Figure out why the speed isn't being set porperly i2cConfig.I2C_ClockSpeed = speed; i2cConfig.I2C_DutyCycle = I2C_DutyCycle_16_9; I2C_DeInit(I2C1); I2C_Init(I2C1, &i2cConfig); I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE); NVIC_EnableIRQ(I2C1_ER_IRQn); I2C_Cmd(I2C1, ENABLE); }
bool i2cRead(uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t* buf) { uint32_t timeout = I2C_DEFAULT_TIMEOUT; addr = addr_ << 1; reg = reg_; writing = 0; reading = 1; read_p = buf; write_p = buf; bytes = len; busy = 1; error = false; if (!(I2Cx->CR2 & I2C_IT_EVT)) { //if we are restarting the driver if (!(I2Cx->CR1 & 0x0100)) { // ensure sending a start while (I2Cx->CR1 & 0x0200) { ; } //wait for any stop to finish sending I2C_GenerateSTART(I2Cx, ENABLE); //send the start for the new job } I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, ENABLE); //allow the interrupts to fire off again } while (busy && --timeout > 0); if (timeout == 0) { i2cErrorCount++; // reinit peripheral + clock out garbage i2cInit(I2Cx); return false; } return !error; }
/** * @brief Main program. * @param None * @retval None */ void main(void) { /* I2C clock Enable*/ CLK_PeripheralClockConfig(CLK_Peripheral_I2C, ENABLE); /* system_clock / 1 */ CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv1); /* Initialize LEDs mounted on the EVAL board */ STM_EVAL_LEDInit(LED2); STM_EVAL_LEDInit(LED3); I2C_DeInit(); /* Initialize I2C peripheral */ #ifdef I2C_slave_7Bits_Address I2C_Init(100000, SLAVE_ADDRESS, I2C_DutyCycle_2, I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit); #else I2C_Init(100000, SLAVE_ADDRESS, I2C_DutyCycle_2, I2C_Ack_Enable, I2C_AcknowledgedAddress_10bit); #endif /* Enable Error Interrupt*/ I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE); /* Enable general interrupts */ enableInterrupts(); /*Main Loop */ while (1) { /* infinite loop */ } }
void init_i2c(void) { I2C_InitTypeDef I2C_InitStruct; GPIO_InitTypeDef GPIO_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // SCL,SDA GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStruct); I2C_SoftwareResetCmd(I2C2, ENABLE); I2C_ITConfig(I2C2,I2C_IT_ERR,ENABLE); I2C_StructInit(&I2C_InitStruct); I2C_DeInit(I2C2); I2C_InitStruct.I2C_ClockSpeed = 100000; I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStruct.I2C_OwnAddress1 = 0x00; I2C_Init(I2C2, &I2C_InitStruct); I2C_Cmd(I2C2, ENABLE); }
void i2c_init(i2c_dev *dev, uint16_t address, uint32_t speed) { I2C_InitTypeDef I2C_InitStructure; i2c_lowLevel_init(dev); /* I2C configuration */ I2C_StructInit(&I2C_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = address; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = speed; I2C_ITConfig(dev->I2Cx, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE); /* I2C Peripheral Enable */ I2C_Cmd(dev->I2Cx, ENABLE); /* Apply I2C configuration after enabling it */ I2C_Init(dev->I2Cx, &I2C_InitStructure); sEEAddress = sEE_HW_ADDRESS; I2C_BLOCKED = 0; }
void TwoWire::onService(void) { if (I2C_GetITStatus(twi, I2C_IT_ADDR) == SET) { I2C_ITConfig(twi, I2C_IT_RXI | I2C_IT_TXI | I2C_IT_STOPI, ENABLE); srvBufferLength = 0; srvBufferIndex = 0; if (twi->ISR & (1 << 16)) { status = SLAVE_SEND; if (onRequestCallback) onRequestCallback(); } else { status = SLAVE_RECV; } I2C_ClearITPendingBit(twi, I2C_IT_ADDR); } if (I2C_GetITStatus(twi, I2C_IT_TXIS) == SET) { uint8_t c = 'x'; if (srvBufferIndex < srvBufferLength) c = srvBuffer[srvBufferIndex++]; I2C_SendData(twi, c); } if (I2C_GetITStatus(twi, I2C_IT_RXNE) == SET) { if (srvBufferLength < BUFFER_LENGTH) srvBuffer[srvBufferLength++] = I2C_ReceiveData(twi); } if (I2C_GetITStatus(twi, I2C_IT_STOPF) == SET) { if (status == SLAVE_RECV && onReceiveCallback) { // Copy data into rxBuffer // (allows to receive another packet while the // user program reads actual data) for (uint8_t i = 0; i < srvBufferLength; ++i) rxBuffer[i] = srvBuffer[i]; rxBufferIndex = 0; rxBufferLength = srvBufferLength; // Alert calling program onReceiveCallback( rxBufferLength); } I2C_ITConfig(twi, I2C_IT_ADDRI, ENABLE); I2C_ITConfig(twi, I2C_IT_RXI | I2C_IT_TXI | I2C_IT_STOPI, DISABLE); I2C_ClearITPendingBit(twi, I2C_IT_STOPF); } }
void arch_I2cStart(p_dev_i2c p) { I2C_TypeDef *pI2c = stm32_tblI2cId[p->parent->id]; I2C_GenerateSTART(pI2c, ENABLE); I2C_AcknowledgeConfig(pI2c, ENABLE); I2C_ITConfig(pI2c, I2C_IT_EVT | I2C_IT_BUF, ENABLE); }
/************************************************************************* * Function Name: I2C1_Init * Parameters: none * * Return: none * * Description: Init I2C1 interface * *************************************************************************/ void I2C1_Init (void) { I2C_InitTypeDef I2C_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; s_I2C_NotUsed = TRUE; // Enable clock RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, DISABLE); I2C_DeInit(I2C1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE); // I2C configuration I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_OwnAddress1 = 0xAA; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C1_SPEED; // I2C Peripheral Enable I2C_Cmd(I2C1, ENABLE); // Apply I2C configuration after enabling it I2C_Init(I2C1, &I2C_InitStructure); // Enable the I2C1 Events Interrupt NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = I2C1_INTR_PRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = I2C1_INTR_SUBPRIO; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // Enable the I2C1 Errors Interrupt NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = I2C1_INTR_PRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = I2C1_INTR_SUBPRIO; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // Enable interrupts from I2C1 module I2C_ITConfig(I2C1, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, ENABLE); }