/* ** ISR to handler i2c interrupts */ void I2CCodecIsr(void) { unsigned int status; status = I2CMasterIntStatus(SOC_I2C_1_REGS); I2CMasterIntClearEx(SOC_I2C_1_REGS, (status & ~(I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY))); if (status & I2C_INT_TRANSMIT_READY) { /* Put data to data transmit register of i2c */ I2CMasterDataPut(SOC_I2C_1_REGS, slaveData[dataIdx]); I2CMasterIntClearEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY); dataIdx++; if(dataMax == dataIdx) { I2CMasterIntDisableEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY); } } if(status & I2C_INT_RECV_READY) { /* Receive data from data receive register */ slaveData[dataIdx] = I2CMasterDataGet(SOC_I2C_1_REGS); I2CMasterIntClearEx(SOC_I2C_1_REGS, I2C_INT_RECV_READY); dataIdx++; if(dataMax == dataIdx) { I2CMasterIntDisableEx(SOC_I2C_1_REGS, I2C_INT_RECV_READY); /* Generate a STOP */ I2CMasterStop(SOC_I2C_1_REGS); } } if (status & I2C_INT_STOP_CONDITION) { /* Disable transmit data ready and receive data read interupt */ I2CMasterIntDisableEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY | I2C_INT_STOP_CONDITION | I2C_INT_RECV_READY); txCompFlag = 0; } if(status & I2C_INT_NO_ACK) { I2CMasterIntDisableEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY | I2C_INT_RECV_READY | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION); /* Generate a STOP */ I2CMasterStop(SOC_I2C_1_REGS); txCompFlag = 0; } }
/** * \brief This function reads data from EEPROM. * * \param data Address where data is to be read. * \param length Length of data to be read * \param offset Address of the byte from which data to be read. * * \return None. * * \note This muxing depends on the profile in which the EVM is configured. * EEPROMI2CSetUp Shall be called Before this API is used */ void EEPROMI2CRead(unsigned char *data, unsigned int length, unsigned short offset) { unsigned int idx = 0; /* First send the register offset - TX operation */ I2CSetDataCount(I2C_BASE_ADDR, 2); StatusClear(); I2CMasterControl(I2C_BASE_ADDR, I2C_CFG_MST_TX); I2CMasterStart(I2C_BASE_ADDR); /* Wait for the START to actually occir on the bus */ while (0 == I2CMasterBusBusy(I2C_BASE_ADDR)); I2CMasterDataPut(I2C_BASE_ADDR, (unsigned char)((offset >> 8) & 0xFF)); /* Wait for the Tx register to be empty */ while (0 == I2CMasterIntRawStatusEx(I2C_BASE_ADDR, I2C_INT_TRANSMIT_READY)); /* Push offset out and tell CPLD from where we intend to read the data */ I2CMasterDataPut(I2C_BASE_ADDR, (unsigned char)(offset & 0xFF)); I2CMasterIntClearEx(I2C_BASE_ADDR, I2C_INT_TRANSMIT_READY); while(0 == (I2CMasterIntRawStatus(I2C_BASE_ADDR) & I2C_INT_ADRR_READY_ACESS)); StatusClear(); I2CSetDataCount(I2C_BASE_ADDR, length); /* Now that we have sent the register offset, start a RX operation*/ I2CMasterControl(I2C_BASE_ADDR, I2C_CFG_MST_RX); /* Repeated start condition */ I2CMasterStart(I2C_BASE_ADDR); while (length--) { while (0 == I2CMasterIntRawStatusEx(I2C_BASE_ADDR, I2C_INT_RECV_READY)); data[idx++] = (unsigned char)I2CMasterDataGet(I2C_BASE_ADDR); I2CMasterIntClearEx(I2C_BASE_ADDR, I2C_INT_RECV_READY); } I2CMasterStop(I2C_BASE_ADDR); while(0 == (I2CMasterIntRawStatus(I2C_BASE_ADDR) & I2C_INT_STOP_CONDITION)); I2CMasterIntClearEx(I2C_BASE_ADDR, I2C_INT_STOP_CONDITION); }
void i2c3_master_interrupt(void) { unsigned long status = I2CMasterIntStatusEx(I2C3_MASTER_BASE, false); if (status & I2C_MASTER_INT_TIMEOUT) { i2c_flag = 2; I2CMasterIntClearEx(I2C3_MASTER_BASE, I2C_MASTER_INT_TIMEOUT); } if (status & I2C_MASTER_INT_DATA) { err = I2CMasterErr(I2C3_MASTER_BASE); if (err != I2C_MASTER_ERR_NONE) i2c_flag = 2; if (what_we_re_doing == sending) { sent_bytes++; if (sent_bytes < sizeof(data)-1) { //Continuing I2CMasterDataPut(I2C3_MASTER_BASE, ((unsigned char *)&data)[sent_bytes]); I2CMasterControl(I2C3_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); } else if (sent_bytes == sizeof(data)-1) { //Last byte remaining I2CMasterDataPut(I2C3_MASTER_BASE, ((unsigned char *)&data)[sent_bytes]); I2CMasterControl(I2C3_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); } else { //Transaction is done i2c_flag = 1; } } else if (what_we_re_doing == receiving) { unsigned char *p = (unsigned char *)&data_recv + received_bytes; *p = I2CMasterDataGet(I2C3_MASTER_BASE); received_bytes++; if (received_bytes < sizeof(data_recv) - 1) { I2CMasterControl(I2C3_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT); } else if (received_bytes == sizeof(data_recv) - 1) { I2CMasterControl(I2C3_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); } else { //Transaction is done i2c_flag = 1; } } I2CMasterIntClearEx(I2C3_MASTER_BASE, I2C_MASTER_INT_DATA); } }
/* Sends command to the I2C module and waits for it to be processed. */ static enum i2c_ack_type i2c_command(struct i2c_state *c, uint32_t cmd) { I2CMasterIntClear(c->base); I2CMasterTimeoutSet(c->base, 0x20); /* 5 ms @ 100 KHz */ I2CMasterControl(c->base, cmd); unsigned long mcs; while ((MAP_I2CMasterIntStatusEx(c->base, 0) & (I2C_MRIS_RIS | I2C_MRIS_CLKRIS)) == 0) { mcs = HWREG(c->base + I2C_O_MCS); dprintf(("busy mcs %lx cnt %lx\n", mcs, HWREG(c->base + I2C_O_MCLKOCNT))); } I2CMasterIntClearEx(c->base, I2C_MRIS_RIS | I2C_MRIS_CLKRIS); mcs = HWREG(c->base + I2C_O_MCS); dprintf(("mcs %lx\n", mcs)); if ((mcs & (I2C_MCS_ARBLST | I2C_MCS_ACK | I2C_MCS_ADRACK | I2C_MCS_CLKTO)) == 0) { return I2C_ACK; } else { /* This does not actually put STOP condition on the bus (bit 0 = 0), * but resets the error condition in the module. */ I2CMasterControl(c->base, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP); return I2C_NAK; } }
/* Clear status of all interrupts */ void CleanUpInterrupts(new_twi* TwiStruct) { if(TwiStruct->WithInterrupt)I2CMasterIntEnableEx(TwiStruct->BaseAddr, 0x7FF); I2CMasterIntClearEx(TwiStruct->BaseAddr, 0x7FF); if(TwiStruct->WithInterrupt)I2CMasterIntDisableEx(TwiStruct->BaseAddr, 0x7FF); }
/* ** I2C Interrupt Service Routine. This function will read and write ** data through I2C bus. */ void I2CIsr(new_twi* TwiStruct) { unsigned int status = 0; /* Get only Enabled interrupt status */ status = I2CMasterIntStatus(TwiStruct->BaseAddr); /* ** Clear all enabled interrupt status except receive ready and ** transmit ready interrupt status */ I2CMasterIntClearEx(TwiStruct->BaseAddr, (status & ~(I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY | I2C_INT_NO_ACK))); if(status & I2C_INT_RECV_READY) { /* Receive data from data receive register */ TwiStruct->RxBuff[TwiStruct->rCount++] = I2CMasterDataGet(TwiStruct->BaseAddr); /* Clear receive ready interrupt status */ I2CMasterIntClearEx(TwiStruct->BaseAddr, I2C_INT_RECV_READY); if(TwiStruct->rCount == TwiStruct->numOfBytes) { /* Disable the receive ready interrupt */ I2CMasterIntDisableEx(TwiStruct->BaseAddr, I2C_INT_RECV_READY); /* Generate a STOP */ I2CMasterStop(TwiStruct->BaseAddr); } } if (status & I2C_INT_TRANSMIT_READY) { /* Put data to data transmit register of i2c */ I2CMasterDataPut(TwiStruct->BaseAddr, TwiStruct->TxBuff[TwiStruct->tCount++]); /* Clear Transmit interrupt status */ I2CMasterIntClearEx(TwiStruct->BaseAddr, I2C_INT_TRANSMIT_READY); if(TwiStruct->tCount == TwiStruct->numOfBytes) { /* Disable the transmit ready interrupt */ I2CMasterIntDisableEx(TwiStruct->BaseAddr, I2C_INT_TRANSMIT_READY); } } if (status & I2C_INT_STOP_CONDITION) { /* Disable transmit data ready and receive data read interupt */ I2CMasterIntDisableEx(TwiStruct->BaseAddr, I2C_INT_TRANSMIT_READY | I2C_INT_RECV_READY | I2C_INT_STOP_CONDITION); TwiStruct->flag = 0; } if(status & I2C_INT_NO_ACK) { I2CMasterIntDisableEx(TwiStruct->BaseAddr, I2C_INT_TRANSMIT_READY | I2C_INT_RECV_READY | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION); /* Generate a STOP */ I2CMasterStop(TwiStruct->BaseAddr); TwiStruct->flag = 0; TwiStruct->error_flag = 1; } //I2CEndOfInterrupt(TwiStruct->BaseAddr, 0); }
/* Clear the status of all interrupts */ static void StatusClear(void) { I2CMasterIntClearEx(I2C_BASE_ADDR, 0x7FF); }
/* ** I2C Interrupt Service Routine. This function will read and write ** data through I2C bus. */ static void mpu6050_isr(int irqno, void* param) { unsigned int status = 0; /* Get only Enabled interrupt status */ status = I2CMasterIntStatus(I2C0_BASE); /* ** Clear all enabled interrupt status except receive ready and ** transmit ready interrupt status */ I2CMasterIntClearEx(I2C0_BASE, (status & ~(I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY))); if(status & I2C_INT_RECV_READY) { /* Receive data from data receive register */ dataFromSlave[rCount++] = I2CMasterDataGet(I2C0_BASE); /* Clear receive ready interrupt status */ I2CMasterIntClearEx(I2C0_BASE, I2C_INT_RECV_READY); if(rCount == numOfBytes) { /* Disable the receive ready interrupt */ I2CMasterIntDisableEx(I2C0_BASE, I2C_INT_RECV_READY); /* Generate a STOP */ I2CMasterStop(I2C0_BASE); } } if (status & I2C_INT_TRANSMIT_READY) { /* Put data to data transmit register of i2c */ I2CMasterDataPut(I2C0_BASE, dataToSlave[tCount++]); /* Clear Transmit interrupt status */ I2CMasterIntClearEx(I2C0_BASE, I2C_INT_TRANSMIT_READY); if(tCount == numOfBytes) { /* Disable the transmit ready interrupt */ I2CMasterIntDisableEx(I2C0_BASE, I2C_INT_TRANSMIT_READY); } } if (status & I2C_INT_STOP_CONDITION) { /* Disable transmit data ready and receive data read interupt */ I2CMasterIntDisableEx(I2C0_BASE, I2C_INT_TRANSMIT_READY | I2C_INT_RECV_READY | I2C_INT_STOP_CONDITION); flag = 0; } if(status & I2C_INT_NO_ACK) { I2CMasterIntDisableEx(I2C0_BASE, I2C_INT_TRANSMIT_READY | I2C_INT_RECV_READY | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION); /* Generate a STOP */ I2CMasterStop(I2C0_BASE); flag = 0; } }
void I2C_0_ISR(void) { unsigned int status = 0; /* interrupt status */ status = I2CMasterIntStatus(SOC_I2C_0_REGS); if(status & I2C_INT_RECV_READY) { /* Receive data from data receive register */ *I2C_0_Buffers.p_Receive = I2CMasterDataGet(SOC_I2C_0_REGS); I2C_0_Buffers.p_Receive++; I2C_0_Buffers.BytesReceived++; /* Clear interrupt flag */ I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_INT_RECV_READY); if(I2C_0_Buffers.BytesReceived == I2C_0_Buffers.ReceiveBytes) { /* Disable the receive ready interrupt */ I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_RECV_READY); /* Generate a STOP */ I2CMasterStop(SOC_I2C_0_REGS); } } if (status & I2C_INT_TRANSMIT_READY) { /* Put data to data transmit register of i2c */ I2CMasterDataPut(SOC_I2C_0_REGS, *I2C_0_Buffers.p_Transmit); I2C_0_Buffers.p_Transmit++; I2C_0_Buffers.BytesTransmitted++; /* Clear Transmit interrupt status */ I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY); if(I2C_0_Buffers.BytesTransmitted == I2C_0_Buffers.TransmitBytes) { /* Disable the transmit ready interrupt */ I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY); if(!I2C_0_Buffers.ReceiveBytes) { /* Generate a STOP */ I2CMasterStop(SOC_I2C_0_REGS); } } } if (status & I2C_INT_STOP_CONDITION) { /* Disable transmit data ready and receive data read interupt */ I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY | I2C_INT_RECV_READY | I2C_INT_STOP_CONDITION); /* Clear interrupt flag */ I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_INT_STOP_CONDITION); I2C_SetFailFlag0(); } if(status & I2C_INT_NO_ACK) { I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY | I2C_INT_RECV_READY | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION); /* Generate a STOP */ I2CMasterStop(SOC_I2C_0_REGS); /* Clear interrupt flag */ I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_INT_NO_ACK); I2C_SetFailFlag0(); } }