/*---------------------------------------------------------------------------------------------------------*/ int32_t main(void) { uint32_t i; /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Lock protected registers */ SYS_LockReg(); /* Init UART0 for printf */ UART0_Init(); /* This sample code sets I2C bus clock to 100kHz. Then, Master accesses Slave with Byte Write and Byte Read operations, and check if the read data is equal to the programmed data. */ printf("+-------------------------------------------------------+\n"); printf("| NUC029xDE I2C Driver Sample Code(Slave) for access Slave |\n"); printf("| |\n"); printf("| I2C Master (I2C0) <---> I2C Slave(I2C0) |\n"); printf("+-------------------------------------------------------+\n"); printf("Configure I2C0 as a slave.\n"); printf("The I/O connection for I2C0:\n"); printf("I2C0_SDA(PA.8), I2C0_SCL(PA.9)\n"); /* Init I2C0 */ I2C0_Init(); /* I2C enter no address SLV mode */ I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); for(i = 0; i < 0x100; i++) { g_au8SlvData[i] = 0; } /* I2C function to Slave receive/transmit data */ s_I2C0HandlerFn = I2C_SlaveTRx; printf("\n"); printf("I2C Slave Mode is Running.\n"); while(1); }
/************************************************************************* Send one byte to I2C device Input: byte to be transfered Return: 0 write successful 1 write failed *************************************************************************/ unsigned char lib_i2c_write(unsigned char data) { I2C_SET_DATA(I2C, data); I2C_SET_CONTROL_REG(I2C, I2C_SI); if (!I2C_WAIT_READY_ERROR(I2C)) return 2; // Check ACK uint8_t status = I2C_GET_STATUS(I2C); // Master TX/RX Address/Data ACKs if (status != 0x18 && status != 0x28 && status != 0x40 && status != 0x50) return 1; return 0; }
void LM75A_I2C_SingleWrite(uint8_t index, uint8_t data) { I2C_START(LM75A_I2C_PORT); //Start I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(LM75A_I2C_PORT, LM75A_I2C_SLA); //send slave address I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI); I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(LM75A_I2C_PORT, index); //send index I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI); I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(LM75A_I2C_PORT, data); //send Data I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI); I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI|I2C_STO);//Stop }
/*---------------------------------------------------------------------------------------------------------*/ void I2C_MasterTxWakeup(uint32_t u32Status) { if(u32Status == 0x08) /* START has been transmitted */ { I2C0->DAT = g_u8DeviceAddr << 1; /* Write SLA+W to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI); } else if(u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */ { I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI); g_u8MstEndFlag = 1; } else if(u32Status == 0x20) /* SLA+W has been transmitted and NOT ACK has been received */ { I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI); g_u8MstEndFlag = 1; } else { /* TO DO */ printf("Status 0x%x is NOT processed\n", u32Status); } }
/*---------------------------------------------------------------------------------------------------------*/ void I2C_MasterTx(uint32_t u32Status) { if (u32Status == 0x08) { /* START has been transmitted */ I2C_SET_DATA(I2C3, g_u8DeviceAddr << 1); /* Write SLA+W to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C3, I2C_SI); } else if (u32Status == 0x18) { /* SLA+W has been transmitted and ACK has been received */ I2C_SET_DATA(I2C3, g_au8TxData[g_u8DataLen++]); I2C_SET_CONTROL_REG(I2C3, I2C_SI); } else if (u32Status == 0x20) { /* SLA+W has been transmitted and NACK has been received */ I2C_SET_CONTROL_REG(I2C3, I2C_STA | I2C_STO | I2C_SI); } else if (u32Status == 0x28) { /* DATA has been transmitted and ACK has been received */ if (g_u8DataLen != 3) { I2C_SET_DATA(I2C3, g_au8TxData[g_u8DataLen++]); I2C_SET_CONTROL_REG(I2C3, I2C_SI); } else { I2C_SET_CONTROL_REG(I2C3, I2C_STO | I2C_SI); g_u8EndFlag = 1; } } else { /* TO DO */ printf("Status 0x%x is NOT processed\n", u32Status); } }
void MPU6050_I2C_SingleWrite(uint8_t index, uint8_t data) { I2C_START(MPU6050_I2C_PORT); //Start I2C_WAIT_READY(MPU6050_I2C_PORT); MPU6050_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(MPU6050_I2C_PORT, MPU6050_I2C_SLA); //send slave address I2C_SET_CONTROL_REG(MPU6050_I2C_PORT, I2C_SI); I2C_WAIT_READY(MPU6050_I2C_PORT); MPU6050_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(MPU6050_I2C_PORT, index); //send index I2C_SET_CONTROL_REG(MPU6050_I2C_PORT, I2C_SI); I2C_WAIT_READY(MPU6050_I2C_PORT); MPU6050_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(MPU6050_I2C_PORT, data); //send Data I2C_SET_CONTROL_REG(MPU6050_I2C_PORT, I2C_SI); I2C_WAIT_READY(MPU6050_I2C_PORT); MPU6050_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_STOP(MPU6050_I2C_PORT); //STOP }
void TwoWire::begin(uint8_t address) { IRQn_Type irq=I2C0_IRQn; NVIC_DisableIRQ(irq); NVIC_ClearPendingIRQ(irq); NVIC_SetPriority(irq, 3); NVIC_EnableIRQ(irq); I2C_Open(i2c,I2C_CLOCK); status = SLAVE_IDLE; I2C_SetSlaveAddr(i2c, 0, address, 0); /* Slave Address */ I2C_EnableInt(i2c); I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); /* I2C enter no address SLV mode */ }
/*---------------------------------------------------------------------------------------------------------*/ void I2C_MasterTx(uint32_t u32Status) { if(u32Status == 0x08) /* START has been transmitted */ { I2CMstState=0; I2C_SetData(I2C_MS_PORT, I2CMstAddr << 1); /* Write SLA+W to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI); } else if(u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */ { I2C_SetData(I2C_MS_PORT, I2CMstCmd); I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI); I2CMstStage=0; } else if(u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */ { //------TimeOut Recover Master state----------- if(I2CMstEndFlag==0 && (getTickCount() - I2CMstTimeOutCounter) > 1) { I2CMstWakeupEnStartFlag=1; I2CMstTRxEnStartFlag=1; I2CMstSleepEnStartFlag=1; I2CMstEndFlag=1; I2CMstTimeOutFlag=1; } I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_STA_STO_SI); } else if(u32Status == 0x28) /* DATA has been transmitted and ACK has been received */ { if(I2CMstStage==0) { I2C_SetData(I2C_MS_PORT, I2CMstCmd>>8); I2CMstStage=1; I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI); } else if(I2CCurrentLen < I2CDataEndBit)
/*---------------------------------------------------------------------------------------------------------*/ void I2C_MasterTx(uint32_t u32Status) { if(u32Status == 0x08) /* START has been transmitted */ { I2C0->DAT = g_u8DeviceAddr << 1; /* Write SLA+W to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI); } else if(u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */ { I2C0->DAT = g_au8MstTxData[g_u8MstDataLen++]; I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI); } else if(u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */ { I2C_STOP(I2C0); I2C_START(I2C0); } else if(u32Status == 0x28) /* DATA has been transmitted and ACK has been received */ { if(g_u8MstDataLen != 3) { I2C0->DAT = g_au8MstTxData[g_u8MstDataLen++]; I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI); } else { I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI); g_u8MstEndFlag = 1; } } else { /* TO DO */ printf("Status 0x%x is NOT processed\n", u32Status); } }
void I2C_MasterRx(uint32_t u32Status) { if (u32Status == 0x08) { /* START has been transmitted and prepare SLA+W */ I2C_SET_DATA(I2C0, g_u8DeviceAddr);//(g_u8DeviceAddr << 1)); /* Write SLA+W to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x18) { /* SLA+W has been transmitted and ACK has been received */ I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]); I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x20) { /* SLA+W has been transmitted and NACK has been received */ I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_STO | I2C_SI); } else if (u32Status == 0x28) { /* DATA has been transmitted and ACK has been received */ if (g_u8DataLen != 1){ // 2) { I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]); I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else { I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_SI); } } else if (u32Status == 0x10) { /* Repeat START has been transmitted and prepare SLA+R */ I2C_SET_DATA(I2C0, g_u8DeviceAddr | 0x01);//(g_u8DeviceAddr << 1) | 0x01); /* Write SLA+R to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x40) { /* SLA+R has been transmitted and ACK has been received */ I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x58) { /* DATA has been received and NACK has been returned */ g_u8RxData = I2C_GET_DATA(I2C0); I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI); g_u8EndFlag = 1; } else { /* TO DO */ #ifdef I2C_TIMEOUT_ENABLE if(i2c_novalidack_timeout++>I2C_TIMEOUT_NOVALIDACK_COUNT) { I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI); g_u8EndFlag = 1; } #endif // printf("Status 0x%x is NOT processed\n", u32Status); } }
/*---------------------------------------------------------------------------------------------------------*/ void I2C_SlaveTRx(uint32_t u32Status) { if(u32Status == 0x60) /* Own SLA+W has been receive; ACK has been return */ { g_u8SlvDataLen = 0; I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); } else if(u32Status == 0x80) /* Previously address with own SLA address Data has been received; ACK has been returned*/ { g_au8SlvRxData[g_u8SlvDataLen] = (unsigned char)(I2C0->I2CDAT); g_u8SlvDataLen++; if(g_u8SlvDataLen == 2) { slave_buff_addr = (g_au8SlvRxData[0] << 8) + g_au8SlvRxData[1]; } if(g_u8SlvDataLen == 3) { g_au8SlvData[slave_buff_addr] = g_au8SlvRxData[2]; g_u8SlvDataLen = 0; } I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); } else if(u32Status == 0xA8) /* Own SLA+R has been receive; ACK has been return */ { I2C0->I2CDAT = g_au8SlvData[slave_buff_addr]; slave_buff_addr++; I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); } else if(u32Status == 0xC0) /* Data byte or last data in I2CDAT has been transmitted Not ACK has been received */ { I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); } else if(u32Status == 0x88) /* Previously addressed with own SLA address; NOT ACK has been returned */ { g_u8SlvDataLen = 0; I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); } else if(u32Status == 0xA0) /* A STOP or repeated START has been received while still addressed as Slave/Receiver*/ { g_u8SlvDataLen = 0; I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); } else { /* TO DO */ printf("Status 0x%x is NOT processed\n", u32Status); } }
void I2C1_Init(void) { /* Open I2C1 and set clock to 100k */ I2C_Open(I2C1, 400000); /* Get I2C1 Bus Clock */ printf("I2C1 clock %d Hz\n", I2C_GetBusClockFreq(I2C1)); /* Set I2C1 2 Slave Addresses */ I2C_SetSlaveAddr(I2C1, 0, SLAVE_ADDRESS, I2C_GCMODE_DISABLE); /* Set Slave Address */ I2C_EnableInt(I2C1); NVIC_EnableIRQ(I2C1_IRQn); /* I2C enter no address SLV mode */ I2C_SET_CONTROL_REG(I2C1, I2C_SI | I2C_AA); }
uint16_t LM75A_I2C_DoubleRead(uint8_t index) { uint8_t msb, lsb; uint16_t tmp; I2C_START(LM75A_I2C_PORT); //Start I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(LM75A_I2C_PORT, LM75A_I2C_SLA); //send slave address+W I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI); I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(LM75A_I2C_PORT, index); //send index I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI); I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_STA | I2C_SI); //Start I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_DATA(LM75A_I2C_PORT, (LM75A_I2C_SLA+1)); //send slave address+R I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI); I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI); I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag msb = I2C_GET_DATA(LM75A_I2C_PORT); //read data I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI); I2C_WAIT_READY(LM75A_I2C_PORT); LM75A_I2C_PORT->INTSTS |= I2C_INTSTS_INTSTS_Msk; //clear flag lsb = I2C_GET_DATA(LM75A_I2C_PORT); //read data I2C_SET_CONTROL_REG(LM75A_I2C_PORT, I2C_SI|I2C_STO);//Stop tmp = msb; tmp = tmp<<8 | lsb; return tmp; }
void I2C_MasterTx_var(uint32_t u32Status) { if (u32Status == 0x08) { /* START has been transmitted */ I2C_SET_DATA(I2C0, g_u8DeviceAddr);//g_u8DeviceAddr << 1); /* Write SLA+W to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x18) { /* SLA+W has been transmitted and ACK has been received */ I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]); I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x20) { /* SLA+W has been transmitted and NACK has been received */ I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_STO | I2C_SI); } else if (u32Status == 0x28) { /* DATA has been transmitted and ACK has been received */ if (g_u8DataLen != 3) // 2 { I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]); I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else { I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI); g_u8EndFlag = 1; } } else { /* TO DO */ #ifdef I2C_TIMEOUT_ENABLE if(i2c_novalidack_timeout++>I2C_TIMEOUT_NOVALIDACK_COUNT) { I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI); g_u8EndFlag = 1; } #endif #ifdef DEBUG_ENABLE printf("Status txvar 0x%x is NOT processed\n", u32Status); #endif } }
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { if (quantity > BUFFER_LENGTH) quantity = BUFFER_LENGTH; int readed = 0; int timeout_=TIMEOUT; while(timeout_--) { /* Send start */ I2C_START(i2c); I2C_WAIT_READY(i2c); /* Send control byte */ I2C_SET_DATA(i2c, (address<<1)+1); I2C_SET_CONTROL_REG(i2c, I2C_SI | I2C_AA); I2C_WAIT_READY(i2c); if(I2C_GET_STATUS(i2c)!=0x40) { /* Send stop */ I2C_SET_CONTROL_REG(i2c, I2C_STO | I2C_SI); continue; } readed = 0; while (readed < quantity){ /* Read data */ if((readed+1)==quantity) I2C_SET_CONTROL_REG(i2c, I2C_SI); else I2C_SET_CONTROL_REG(i2c, I2C_SI | I2C_AA); I2C_WAIT_READY(i2c); rxBuffer[readed++] = I2C_GET_DATA(i2c); }; if(sendStop==true){ /* Send stop */ I2C_SET_CONTROL_REG(i2c, I2C_STO | I2C_SI); }else I2C_SET_CONTROL_REG(i2c, I2C_SI); break; } // set rx buffer iterator vars rxBufferIndex = 0; rxBufferLength = readed; return readed; }
void I2C_MasterRx_var(uint32_t u32Status) { uint16_t i=0; if (u32Status == 0x08) { /* START has been transmitted and prepare SLA+W */ I2C_SET_DATA(I2C0, g_u8DeviceAddr);//(g_u8DeviceAddr << 1)); /* Write SLA+W to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x18 ) { /* SLA+W has been transmitted and ACK has been received */ I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]); I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x20) { /* SLA+W has been transmitted and NACK has been received */ I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_STO | I2C_SI); } else if (u32Status == 0x28) { /* DATA has been transmitted and ACK has been received */ #if 0//def DEBUG_ENABLE printf("Status rx 0x%x\n", u32Status); #endif for(i=0;i<65535;i++);//very important // for(i=0;i<50000;i++); // for(i=0;i<50000;i++); if (g_u8DataLen != 1) // 2 { I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]); I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else { I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_SI); } } else if (u32Status == 0x10) { /* Repeat START has been transmitted and prepare SLA+R */ I2C_SET_DATA(I2C0, g_u8DeviceAddr | 0x01);//(g_u8DeviceAddr << 1) | 0x01); /* Write SLA+R to Register I2CDAT */ I2C_SET_CONTROL_REG(I2C0, I2C_SI); } else if (u32Status == 0x40) { /* SLA+R has been transmitted and ACK has been received */ #if 0//def DEBUG_ENABLE printf("Status rx 0x%x\n", u32Status); #endif I2C_SET_CONTROL_REG(I2C0, I2C_SI|I2C_AA); } #if 1//ericyang add for HDC1000 else if (u32Status == 0x50) { /* DATA has been received and ACK has been returned */ g_u8RxData = I2C_GET_DATA(I2C0); //I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI); I2C_SET_CONTROL_REG(I2C0, I2C_SI); //g_u8EndFlag = 1; } #endif else if (u32Status == 0x58) { /* DATA has been received and NACK has been returned */ g_u8RxData1 = I2C_GET_DATA(I2C0); I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI); g_u8EndFlag = 1; #ifdef DEBUG_ENABLE printf("g_u8RxData 0x%x g_u8RxData1:0x%x\n", g_u8RxData,g_u8RxData1); #endif } else { /* TO DO */ #ifdef I2C_TIMEOUT_ENABLE if(i2c_novalidack_timeout++>I2C_TIMEOUT_NOVALIDACK_COUNT) { I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI); g_u8EndFlag = 1; } #endif #ifdef DEBUG_ENABLE printf("Status rxvar 0x%x is NOT processed\n", u32Status); #endif } }
/*---------------------------------------------------------------------------------------------------------*/ int32_t main(void) { uint32_t i; /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Init UART0 for printf */ UART0_Init(); /* Lock protected registers */ SYS_LockReg(); /* This sample code sets I2C bus clock to 100kHz. Then, accesses Slave (GC Mode) with Byte Write and Byte Read operations, and check if the read data is equal to the programmed data. */ printf("\n"); printf("+-----------------------------------------------------------------+\n"); printf("| M05xx I2C Driver Sample Code (Master) for access Slave (GC Mode)|\n"); printf("| |\n"); printf("| I2C Master (I2C0) <---> I2C Slave(I2C0)(Address: 0x00) |\n"); printf("+-----------------------------------------------------------------+\n"); printf("Configure I2C0 as a master.\n"); printf("The I/O connection for I2C0:\n"); printf("I2C0_SDA(P3.4), I2C0_SCL(P3.5)\n"); /* Init I2C0 to access EEPROM */ I2C0_Init(); printf("\n"); /* Send Slave GC Mode address */ g_u8DeviceAddr = 0x00; printf("Check I2C Slave(I2C0) is running first!\n"); printf("Press any key to continue.\n"); getchar(); for(i = 0; i < 0x100; i++) { g_au8TxData[0] = (uint8_t)((i & 0xFF00) >> 8); g_au8TxData[1] = (uint8_t)(i & 0x00FF); g_au8TxData[2] = (uint8_t)(g_au8TxData[1] + 3); g_u8DataLen = 0; g_u8EndFlag = 0; /* I2C function to write data to slave */ s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterTx; /* I2C as master sends START signal */ I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA); /* Wait I2C Tx Finish */ while(g_u8EndFlag == 0); } printf("Master Access Slave(0x%X) at GC Mode Test OK\n", g_u8DeviceAddr); s_I2C0HandlerFn = NULL; /* Close I2C0 */ I2C0_Close(); return 0; }
/*---------------------------------------------------------------------------------------------------------*/ int32_t main(void) { /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Lock protected registers */ SYS_LockReg(); /* Init UART0 for printf */ UART0_Init(); /* This sample code sets I2C bus clock to 100kHz. After wake-up, then accesses Slave with Byte Write and Byte Read operations, and check if the read data is equal to the programmed data. */ printf("+------------------------------------------------------------------------+\n"); printf("| M451 I2C Driver Sample Code (Master) for wake-up & access Slave test |\n"); printf("| |\n"); printf("| I2C Master (I2C0) <---> I2C Slave(I2C0) |\n"); printf("+------------------------------------------------------------------------+\n"); printf("Configure I2C0 as a master.\n"); printf("The I/O connection for I2C0:\n"); printf("I2C0_SDA(PA.2), I2C0_SCL(PA.3)\n"); /* Init I2C0 to access Slave */ I2C0_Init(); printf("\n Check I2C slave at power down status.\n"); printf("Press any key to Wake up slave.\n"); getchar(); /* Set the Slave address to wake-up*/ g_u8DeviceAddr = 0x15; /* I2C function to wake-up slave*/ s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterTxWakeup; /* Send a START condition to bus */ I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STA); while(g_u8MstEndFlag == 0); /*Access to the corresponding address Slave*/ printf("\n\n"); printf("Slave address no mask test.\n"); Read_Write_SLAVE(0x15); Read_Write_SLAVE(0x35); Read_Write_SLAVE(0x55); Read_Write_SLAVE(0x75); /* Access Slave with address mask */ printf("\n\n"); printf("Slave address mask test.\n"); Read_Write_SLAVE(0x15 & ~0x01); Read_Write_SLAVE(0x35 & ~0x04); Read_Write_SLAVE(0x55 & ~0x01); Read_Write_SLAVE(0x75 & ~0x04); s_I2C0HandlerFn = NULL; /* Close I2C0 */ I2C0_Close(); while(1); }
void I2C0_IRQHandler(void) { if (i2c_ctrl[0].enable == 0) goto end; if (I2C0->TOCTL & I2C_TOCTL_TOIF_Msk) { goto error; } else if (I2C0->CTL & I2C_CON_I2C_STS) { uint32_t status = I2C0->STATUS; struct vsfi2c_msg_t *msg = &i2c_ctrl[0].msg[i2c_ctrl[0].msg_prt]; if (msg->flag & VSFI2C_READ) { if ((status == 0x08) || (status == 0x10)) { I2C0->DAT = (i2c_ctrl[0].chip_addr << 1) + 1; I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS); } else if (status == 0x40) { if (msg->len > 1) { // host reply ack I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS | I2C_CON_ACK); } else if (msg->len == 1) { // host reply nack I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS); } else { goto error; } } else if (status == 0x50) { if (i2c_ctrl[0].msg_buf_prt < msg->len) msg->buf[i2c_ctrl[0].msg_buf_prt++] = I2C0->DAT; if (i2c_ctrl[0].msg_buf_prt < msg->len - 1) { // host reply ack I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS | I2C_CON_ACK); } else { // host reply nack I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS); } } else if (status == 0x58) { if (i2c_ctrl[0].msg_buf_prt < msg->len) msg->buf[i2c_ctrl[0].msg_buf_prt++] = I2C0->DAT; if (++i2c_ctrl[0].msg_prt < i2c_ctrl[0].msg_len) { i2c_ctrl[0].msg_buf_prt = 0; I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS | I2C_CON_START); } else { I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS | I2C_CON_STOP); I2C0->TOCTL = I2C_TOCTL_TOIF_Msk; if (nuc505_i2c_callback[0] != NULL) { i2c_ctrl[0].enable = 0; nuc505_i2c_callback[0](nuc505_i2c_param[0], VSFERR_NONE); } } } else { goto error; } } else { if ((status == 0x08) || (status == 0x10)) // start send finish { I2C0->DAT = i2c_ctrl[0].chip_addr << 1; I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS); } else if ((status == 0x18) || (status == 0x28)) // addr/data send finish and ACK received { if (i2c_ctrl[0].msg_buf_prt < msg->len) { I2C0->DAT = msg->buf[i2c_ctrl[0].msg_buf_prt++]; I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS); } else { if (++i2c_ctrl[0].msg_prt < i2c_ctrl[0].msg_len) { i2c_ctrl[0].msg_buf_prt = 0; I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS | I2C_CON_START); } else { I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS | I2C_CON_STOP); I2C0->TOCTL = I2C_TOCTL_TOIF_Msk; if (nuc505_i2c_callback[0] != NULL) { i2c_ctrl[0].enable = 0; nuc505_i2c_callback[0](nuc505_i2c_param[0], VSFERR_NONE); } } } } else { goto error; } } } error: I2C_SET_CONTROL_REG(I2C0, I2C_CON_I2C_STS | I2C_CON_STOP); i2c_ctrl[0].enable = 0; if (nuc505_i2c_callback[0] != NULL) { nuc505_i2c_callback[0](nuc505_i2c_param[0], VSFERR_FAIL); } end: I2C0->TOCTL = I2C_TOCTL_TOIF_Msk; }
/*---------------------------------------------------------------------------------------------------------*/ int32_t main(void) { uint32_t i; /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Lock protected registers */ SYS_LockReg(); /* Init UART0 for printf */ UART0_Init(); /* This sample code sets I2C bus clock to 100kHz. Then, accesses Slave (GC Mode) with Byte Write and Byte Read operations, and check if the read data is equal to the programmed data. */ printf("\n"); printf("+------------------------------------------------------------------+\n"); printf("| NUC029xDE I2C Driver Sample Code (Slave) for access Slave (GC Mode) |\n"); printf("| |\n"); printf("| I2C Master (I2C0) <---> I2C Slave(I2C0)(Address: 0x00) |\n"); printf("+------------------------------------------------------------------+\n"); printf("Configure I2C0 as a slave.\n"); printf("The I/O connection for I2C0:\n"); printf("I2C0_SDA(PA.8), I2C0_SCL(PA.9)\n"); /* Init I2C0 */ I2C0_Init(); /* Enable GC Mode */ I2C0->I2CADDR0 |= I2C_I2CADDR_GC_Msk; /* I2C enter no address SLV mode */ I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); /* Clear receive buffer */ for(i = 0; i < 0x100; i++) { g_au8SlvData[i] = 0; } g_u8SlvEndFlag = 0; /* I2C function to Slave receive data */ s_I2C0HandlerFn = I2C_GCSlaveRx; printf("\n"); printf("Slave(GC Mode) waiting for receiving data.\n"); while(g_u8SlvEndFlag == 0); /* Check receive data correct or not */ for(i = 0; i < 0x100; i++) { g_au8SlvTxData[0] = (uint8_t)((i & 0xFF00) >> 8); g_au8SlvTxData[1] = (uint8_t)(i & 0x00FF); g_au8SlvTxData[2] = (uint8_t)(g_au8SlvTxData[1] + 3); if(g_au8SlvData[i] != g_au8SlvTxData[2]) { printf("GC Mode Receive data fail.\n"); while(1); } } printf("GC Mode receive data OK.\n"); s_I2C0HandlerFn = NULL; /* Close I2C0 */ I2C0_Close(); while(1); }
void TwoWire::I2C_SlaveTRx(uint32_t u32Status) { if(u32Status == 0x60) /* Own SLA+W has been receive; ACK has been return */ { status = SLAVE_RECV; srvBufferLength = 0; I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); } else if(u32Status == 0x80 || u32Status==0x10) /* Previously address with own SLA address Data has been received; ACK has been returned*/ { srvBuffer[srvBufferLength] = (unsigned char) I2C_GET_DATA(i2c); srvBufferLength++; I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); } else if(u32Status == 0xA8) /* Own SLA+R has been receive; ACK has been return */ { // Alert calling program to generate a response ASAP if (onRequestCallback && status != SLAVE_SEND) { srvBufferLength = 0; srvBufferIndex = 0; onRequestCallback(); } status = SLAVE_SEND; if (srvBufferIndex < srvBufferLength) { //Serial.print("==============>"); //Serial.println((char)srvBuffer[srvBufferIndex]); I2C_SET_DATA(i2c, srvBuffer[srvBufferIndex++]); I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); } if (srvBufferIndex == srvBufferLength) status = SLAVE_IDLE; }else if(u32Status == 0xB8) { if (srvBufferIndex < srvBufferLength){ //Serial.print("==============>"); //Serial.println((char)srvBuffer[srvBufferIndex]); I2C_SET_DATA(i2c, srvBuffer[srvBufferIndex++]); I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); } if (srvBufferIndex == srvBufferLength) status = SLAVE_IDLE; } else if(u32Status == 0xC0) /* Data byte or last data in I2CDAT has been transmitted Not ACK has been received */ { I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); } else if(u32Status == 0x88) /* Previously addressed with own SLA address; NOT ACK has been returned */ { srvBufferLength = 0; I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); } else if(u32Status == 0xA0) /* A STOP or repeated START has been received while still addressed as Slave/Receiver*/ { srvBufferIndex = 0; I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); if (status != SLAVE_IDLE) { for (uint8_t i = 0; i < srvBufferLength; ++i) rxBuffer[i] = srvBuffer[i]; rxBufferIndex = 0; rxBufferLength = srvBufferLength; onReceiveCallback( rxBufferLength); // Alert calling program status = SLAVE_IDLE; } } }
/************************************************************************* Terminates the data transfer and releases the I2C bus *************************************************************************/ void lib_i2c_stop(void) { // ? use I2C_STOP I2C_SET_CONTROL_REG(I2C, I2C_STO | I2C_SI); }
/*---------------------------------------------------------------------------------------------------------*/ int32_t main(void) { uint32_t i; /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Lock protected registers */ SYS_LockReg(); /* Init UART0 for printf */ UART0_Init(); /* This sample code sets I2C bus clock to 100kHz. Then, accesses EEPROM 24LC64 with Byte Write and Byte Read operations, and check if the read data is equal to the programmed data. */ printf("+-------------------------------------------------------+\n"); printf("| M05xx I2C Driver Sample Code with EEPROM 24LC64 |\n"); printf("+-------------------------------------------------------+\n"); /* Init I2C0 to access EEPROM */ I2C0_Init(); g_u8DeviceAddr = 0x50; for(i = 0; i < 0x100; i++) { g_au8TxData[0] = (uint8_t)((i & 0xFF00) >> 8); g_au8TxData[1] = (uint8_t)(i & 0x00FF); g_au8TxData[2] = (uint8_t)(g_au8TxData[1] + 3); g_u8DataLen = 0; g_u8EndFlag = 0; /* I2C function to write data to slave */ s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterTx; /* I2C as master sends START signal */ I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA); /* Wait I2C Tx Finish */ while(g_u8EndFlag == 0); g_u8EndFlag = 0; /* I2C function to read data from slave */ s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterRx; g_u8DataLen = 0; g_u8DeviceAddr = 0x50; I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA); /* Wait I2C Rx Finish */ while(g_u8EndFlag == 0); /* Compare data */ if(g_u8RxData != g_au8TxData[2]) { printf("I2C Byte Write/Read Failed, Data 0x%x\n", g_u8RxData); return -1; } } printf("I2C0 Access EEPROM Test OK\n"); s_I2C0HandlerFn = NULL; /* Close I2C0 */ I2C0_Close(); return 0; }
/*---------------------------------------------------------------------------------------------------------*/ void I2C_MS_Slave(uint32_t status) { if ((status == 0x60) || (status == 0x68)) /* SLA+W has been received and ACK has been returned */ { I2CSlvStage = 0; I2CSlvState = 0; I2CCurrentLen = 0; I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); } else if (status == 0x80) /* DATA has been received and ACK has been returned */ { if (I2CSlvStage == 0) { if(I2CSlvState == 0) { I2CSlvCmd = (unsigned char) I2C_GET_DATA(I2C_MS_PORT); I2CSlvState = 1; if(I2CSlvCmd==4 || I2CSlvCmd==6) I2CMS_SlvRxFin=0; } else if (I2CSlvState == 1) { I2CSlvCmd = ((unsigned char) I2C_GET_DATA(I2C_MS_PORT)<<8 | I2CSlvCmd); I2CSlvState = 0; I2CSlvStage = 1; } } else if (I2CSlvStage == 1) { if(I2CSlvState==0) { I2CMS_SlvRxData[I2CCurrentLen++] = (unsigned char) I2C_GET_DATA(I2C_MS_PORT); I2CDataEndBit = I2CMS_SlvRxData[0]; I2CSlvState=1; } else if(I2CSlvState==1) { I2CMS_SlvRxData[I2CCurrentLen++] = (unsigned char) I2C_GET_DATA(I2C_MS_PORT); I2CDataEndBit = (I2CMS_SlvRxData[1]<<8)|(I2CDataEndBit); I2CSlvState=0; I2CSlvStage=2; } } else if (I2CSlvStage == 2) { if(I2CCurrentLen < I2CDataEndBit) { I2CMS_SlvRxData[I2CCurrentLen++] = (unsigned char) I2C_GET_DATA(I2C_MS_PORT); } if(I2CCurrentLen == I2CDataEndBit) { I2CMS_SlvRxFin=1; } } I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); } else if ((status == 0xB0) || (status == 0xA8)) /* SLA+R has been received and ACK has been returned */ { I2CCurrentLen = 0; //I2C is awake and Sleep flag is unset I2CSlvState = 1; if(I2CSlv_InitFlag==0) { I2CSlv_readyFlag=0; I2CDataEndBit = DEV_NOT_INIT; I2C_SET_DATA(I2C_MS_PORT, DEV_NOT_INIT); I2CCurrentLen++; } else if(I2CSlv_InitFlag==1) { I2CSlv_readyFlag = 1; switch (I2CSlvCmd) { case 1: //Device descriptor I2CDataEndBit = I2CMS_SlvTxDevDesData[0]; I2C_SET_DATA(I2C_MS_PORT, I2CMS_SlvTxDevDesData[I2CCurrentLen++]); break; case 2: //Report descriptor I2CDataEndBit = I2CMS_SlvTxRPDesData[0]; I2C_SET_DATA(I2C_MS_PORT, I2CMS_SlvTxRPDesData[I2CCurrentLen++]); break; case 3: //Input report I2CDataEndBit = I2CMS_SlvTxInRPData[0]; I2C_SET_DATA(I2C_MS_PORT, I2CMS_SlvTxInRPData[I2CCurrentLen++]); break; case 5: //Feature report I2CDataEndBit = I2CMS_SlvTxGetFTData[0]; I2C_SET_DATA(I2C_MS_PORT, I2CMS_SlvTxGetFTData[I2CCurrentLen++]); break; } } I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); } else if (status == 0xB8) /* DATA has been transmitted and ACK has been received */ { if(I2CCurrentLen < I2CDataEndBit) { if(I2CSlv_readyFlag==0) { I2C_SET_DATA(I2C_MS_PORT, 0); I2CCurrentLen++; } else if(I2CSlv_readyFlag==1) { switch (I2CSlvCmd) { case 1: I2C_SET_DATA(I2C_MS_PORT, I2CMS_SlvTxDevDesData[I2CCurrentLen++]); break; case 2: I2C_SET_DATA(I2C_MS_PORT, I2CMS_SlvTxRPDesData[I2CCurrentLen++]); break; case 3: I2C_SET_DATA(I2C_MS_PORT, I2CMS_SlvTxInRPData[I2CCurrentLen++]); break; case 5: I2C_SET_DATA(I2C_MS_PORT, I2CMS_SlvTxGetFTData[I2CCurrentLen++]); break; } } } I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); } else if (status == 0xC0) /* DATA has been transmitted and NACK has been received */ { I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); } else if(status == 0x88) /* Previously addressed with own SLA address; NOT ACK has been returned */ { I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); } else if (status == 0xA0) /* STOP or Repeat START has been received */ { I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); } else { I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI); //DEBUG_PRINT("Status 0x%x is NOT processed\n", status); } }
/*---------------------------------------------------------------------------------------------------------*/ I2C_Loopback (void) { uint32_t i; /* Init System, IP clock and multi-function I/O */ SysInit(); /* Init UART to 115200-8n1 for print message */ UART_Open(UART0, 115200); printf("+-------------------------------------------------------+\n"); printf("| Nano1x2 Series I2C Cross Test Sample Code |\n"); printf("+-------------------------------------------------------+\n"); printf(" I/O Configuration:\n"); printf(" SCK: GPC0 <--> GPC2\n"); printf(" SDA: GPC1 <--> GPC3\n"); printf("\n\n"); printf("..... Press a key to continue ...\n"); UART_GetChar(); /* Configure I2C0 as master and I2C1 as slave */ I2C0_Init(); I2C1_Init(); for (i = 0; i < 0x100; i++) { g_u8SlvData[i] = 0; } /* I2C function to Slave receive/transmit data */ s_I2C1HandlerFn = (I2C_FUNC)I2C_SlaveTRx; g_u8DeviceAddr = SLAVE_ADDRESS; printf("Test Loop =>"); for (i = 0; i < 0x100; i++) { printf("%d..", i); g_au8MasterTxData[0] = (uint8_t)((i & 0xFF00) >> 8); g_au8MasterTxData[1] = (uint8_t)(i & 0x00FF); g_au8MasterTxData[2] = (uint8_t)(g_au8MasterTxData[1] + 3); g_u8MasterDataLen = 0; g_u8EndFlag = 0; /* I2C function to write data to slave */ s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterTx; /* I2C as master sends START signal */ I2C_SET_CONTROL_REG(I2C0, I2C_STA); /* Wait I2C Tx Finish */ while (g_u8EndFlag == 0); g_u8EndFlag = 0; /* I2C function to read data from slave */ s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterRx; g_u8MasterDataLen = 0; g_u8DeviceAddr = SLAVE_ADDRESS; /* I2C as master sends START signal */ I2C_SET_CONTROL_REG(I2C0, I2C_STA); /* Wait I2C Rx Finish */ while (g_u8EndFlag == 0); /* Compare Tx and Rx data */ if (g_u8MasterRxData != g_au8MasterTxData[2]) { printf("I2C Byte Write/Read Failed, Data 0x%x\n", g_u8MasterRxData); return -1; } printf("[OK]\n"); } printf("\nTest Completely !!\n"); while(1); }
/************************************************************************* Read one byte from the I2C device, read is followed by a stop condition Return: byte read from I2C device *************************************************************************/ unsigned char lib_i2c_readnak(void) { I2C_SET_CONTROL_REG(I2C, I2C_SI); I2C_WAIT_READY_ERROR(I2C); return I2C_GET_DATA(I2C); }
// ********************************************************************** // I2C Slave Initialize called by I2CWakeUpInit // ********************************************************************** void I2C_MS_Slave_Init() { // =============PIN SETTNG================== #ifdef I2C_MS_PORT0 CLK_EnableModuleClock(I2C0_MODULE); /* Set I2C PA multi-function pins */ SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE12MFP_Msk | SYS_GPE_MFPH_PE13MFP_Msk); SYS->GPE_MFPH |= ( SYS_GPE_MFPH_PE12MFP_I2C0_SCL | SYS_GPE_MFPH_PE13MFP_I2C0_SDA); #else CLK_EnableModuleClock(I2C1_MODULE); /* Set I2C PA multi-function pins */ SYS->GPC_MFPL &= ~SYS_GPC_MFPL_PC4MFP_Msk; SYS->GPC_MFPL |= SYS_GPC_MFPL_PC4MFP_I2C1_SCL; SYS->GPE_MFPL &= ~SYS_GPE_MFPL_PE0MFP_Msk; SYS->GPE_MFPL |= SYS_GPE_MFPL_PE0MFP_I2C1_SDA; #endif /* Open I2C module and set bus clock */ I2C_Open(I2C_MS_PORT, 100000); /* Get I2C0 Bus Clock */ printf("I2C MS Slave clock %d Hz\n", I2C_GetBusClockFreq(I2C_MS_PORT)); /* Set I2C 4 Slave Addresses */ #if 1 I2C_SetSlaveAddr(I2C_MS_PORT, 0, devNum+0x14, 0); #else if(devNum == 1) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x15, 0); /* Slave Address : 21,Buzzer */ else if(devNum == 2) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x16, 0); /* Slave Address : 22,Led */ else if(devNum == 3) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x17, 0); /* Slave Address : 23,AHRS */ else if(devNum == 4) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x18, 0); /* Slave Address : 24,SONAR */ else if(devNum == 5) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x19, 0); /* Slave Address : 25,TEMPERATURE */ else if(devNum == 6) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1a, 0); /* Slave Address : 26,Gas */ else if(devNum == 7) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1b, 0); /* Slave Address : 27,IR */ else if(devNum == 8) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1c, 0); /* Slave Address : 28,KEY */ else if(devNum == 9) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1d, 0); /* Slave Address : 29, Reserved device 9 */ else if(devNum == 10) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1e, 0); /* Slave Address : 30, Reserved device 10 */ else if(devNum == 11) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1f, 0); /* Slave Address : 31, Reserved device 11 */ else if(devNum == 12) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x20, 0); /* Slave Address : 32, Reserved device 12 */ else if(devNum == 13) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x21, 0); /* Slave Address : 33, Reserved device 13 */ else if(devNum == 14) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x22, 0); /* Slave Address : 34, Reserved device 14 */ #endif I2C_SetSlaveAddr(I2C_MS_PORT, 1, 0x35, 0); /* Slave Address : 0x35 */ I2C_SetSlaveAddr(I2C_MS_PORT, 2, 0x55, 0); /* Slave Address : 0x55 */ I2C_SetSlaveAddr(I2C_MS_PORT, 3, 0x75, 0); /* Slave Address : 0x75 */ /* Enable I2C interrupt */ I2C_EnableInt(I2C_MS_PORT); #ifdef I2C_MS_PORT0 NVIC_EnableIRQ(I2C0_IRQn); #else NVIC_EnableIRQ(I2C1_IRQn); #endif #ifdef I2C_MS_PORT0 s_I2C0HandlerFn = (I2C_FUNC)I2C_MS_Slave; #else s_I2C1HandlerFn = (I2C_FUNC)I2C_MS_Slave; #endif /* Enable I2C wake-up */ I2C_EnableWakeup(I2C_MS_PORT); /* Set I2C0 enter Not Address SLAVE mode */ I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); }
/*---------------------------------------------------------------------------------------------------------*/ int32_t main(void) { uint32_t i; /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Init UART0 for printf */ UART0_Init(); /* Lock protected registers */ SYS_LockReg();; /* This sample code is I2C SLAVE mode and it simulates EEPROM function */ printf("\n"); printf("+---------------------------------------------------------------------------+\n"); printf("| NUC029xEE I2C Driver Sample Code (Slave) for wake-up & access Slave test |\n"); printf("| |\n"); printf("| I2C Master (I2C0) <---> I2C Slave(I2C0) |\n"); printf("+---------------------------------------------------------------------------+\n"); printf("Configure I2C0 as a slave.\n"); printf("The I/O connection for I2C0:\n"); printf("I2C0_SDA(PA.8), I2C0_SCL(PA.9)\n"); /* Init I2C0 */ I2C0_Init(); for(i = 0; i < 0x100; i++) { g_au8SlvData[i] = 0; } /* I2C function to Transmit/Receive data as slave */ s_I2C0HandlerFn = I2C_SlaveTRx; /* Set I2C0 enter Not Address SLAVE mode */ I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA); /* Unlock protected registers */ SYS_UnlockReg(); /* Enable power wake-up interrupt */ CLK->PWRCON |= CLK_PWRCON_PD_WU_INT_EN_Msk; NVIC_EnableIRQ(PWRWU_IRQn); /* Enable I2C wake-up */ I2C0-> I2CWKUPCON |= I2C_I2CWKUPCON_WKUPEN_Msk; /* Enable Chip enter power down mode */ CLK->PWRCON |= CLK_PWRCON_PD_WAIT_CPU_Msk; /* Processor use deep sleep */ SCB->SCR = SCB_SCR_SLEEPDEEP_Msk; /* System power down enable */ CLK->PWRCON |= CLK_PWRCON_PWR_DOWN_EN_Msk; printf("\n"); printf("Enter PD 0x%x 0x%x\n", I2C0->I2CON , I2C0->I2CSTATUS); printf("\n"); printf("CHIP enter power down status.\n"); /* Waiting for UART printf finish*/ while(((UART0->FSR) & UART_FSR_TE_FLAG_Msk) == 0); if(((I2C0->I2CON)&I2C_I2CON_SI_Msk) != 0) { I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI); } /* Use WFI instruction to idle the CPU. NOTE: If ICE is attached, system will wakeup immediately because ICE is a wakeup event. */ __WFI(); __NOP(); __NOP(); __NOP(); while((g_u8SlvPWRDNWK & g_u8SlvI2CWK) == 0); printf("Power-down Wake-up INT 0x%x\n", ((CLK->PWRCON) & CLK_PWRCON_PD_WU_STS_Msk)); printf("I2C0 WAKE INT 0x%x\n", I2C0->I2CWKUPSTS); /* Disable power wake-up interrupt */ CLK->PWRCON &= ~CLK_PWRCON_PD_WU_INT_EN_Msk; NVIC_DisableIRQ(PWRWU_IRQn); /* Lock protected registers */ SYS_LockReg(); printf("\n"); printf("Slave wake-up from power down status.\n"); printf("\n"); printf("Slave Waiting for receiving data.\n"); while(1); }