/**************************************************************************//** * * @brief Starts the I2C monitor * * @retval CMD_STATUS_OK If successfully started * @retval CMD_STATUS_ERR_* If the I2C monitor could not be started * *****************************************************************************/ cmd_status_t monitor_i2c_Start(void) { if (!validConfiguration) { // no point in arming if the configuration is invalid return CMD_STATUS_ERR_MON_I2C_NOT_CONFIGURED; } CLR_MEAS_PIN_1(); TIM_Init(LPC_TIMER3, TIM_TIMER_MODE, &timerCfg); TIM_Cmd(LPC_TIMER3, ENABLE); circbuff_Reset(pSampleBuffer); bytesToCapture = pSampleBuffer->size / SAMPLE_SIZE; pSampleData = (uint32_t*)pSampleBuffer->data; done = FALSE; I2C_IntCmd(LPC_I2C0, TRUE); I2C_MonitorModeCmd(LPC_I2C0, ENABLE); while (!done) { TIM_Waitms(10); } return CMD_STATUS_OK; }
/*********************************************************************//** * @brief Main I2C0 interrupt handler sub-routine * @param[in] None * @return None **********************************************************************/ void I2C0_IRQHandler(void) { done = I2C_MonitorHandler(LPC_I2C0,buffer,count); if(done) { I2C_MonitorModeConfig(I2CDEV,(uint32_t)I2C_MONITOR_CFG_MATCHALL, DISABLE); I2C_MonitorModeCmd(I2CDEV, DISABLE); } }
/**************************************************************************//** * * @brief Stops the I2C monitor * * @retval CMD_STATUS_OK If successfully stopped * @retval CMD_STATUS_ERR_* If the I2C monitor could not be stopped * *****************************************************************************/ cmd_status_t monitor_i2c_Stop(void) { I2C_MonitorModeCmd(LPC_I2C0, DISABLE); TIM_Cmd(LPC_TIMER3, DISABLE); TIM_DeInit(LPC_TIMER3); // Disable use of I2C buffers LPC_GPIO_PORT->DIR[5] |= (1UL << 8); LPC_GPIO_PORT->CLR[5] |= (1UL << 8); return CMD_STATUS_OK; }
int _I2C_MonitorModeCmd(uint8_t * args) { uint8_t * arg_ptr; LPC_I2C_TypeDef* I2Cx; FunctionalState NewState; if ((arg_ptr = (uint8_t *) strtok(NULL, " ")) == NULL) return 1; I2Cx = (LPC_I2C_TypeDef*) strtoul((char *) arg_ptr, NULL, 16); if ((arg_ptr = (uint8_t *) strtok(NULL, " ")) == NULL) return 1; NewState = (FunctionalState) strtoul((char *) arg_ptr, NULL, 16); I2C_MonitorModeCmd(I2Cx, NewState); return 0; }
/**************************************************************************//** * * @brief I2C Interrupt handler, saves all I2C samples * @ingroup RES_IRQ * *****************************************************************************/ void I2C0_IRQHandler(void) { SET_MEAS_PIN_1(); *pSampleData++ = LPC_TIMER3->TC; *pSampleData++ = LPC_I2C0->STAT; *pSampleData++ = LPC_I2C0->DATA_BUFFER; /* As (soon to be) explained in LPC43xx User Manual Errata: Introduction: The I2C monitor allows the device to monitor the I2C traffic on the I2C bus in a non-intrusive way. Problem: In the slave-transmitter mode, the device set in the monitor mode must write a dummy value of 0xFF into the DAT register. If this is not done, the received data from the slave device will be corrupted. To allow the monitor mode to have sufficient time to process the data on the I2C bus, the device may need to have the ability to stretch the I2C clock. Under this condition, the I2C monitor mode is not 100% non-intrusive. */ switch (LPC_I2C0->STAT) { case 0xA8: // Own SLA + R has been received, ACK returned case 0xB0: case 0xB8: // data byte in DAT transmitted, ACK received case 0xC0: // (last) data byte transmitted, NACK received case 0xC8: // last data byte in DAT transmitted, ACK received LPC_I2C0->DAT = 0xFF; // Pretend to shift out 0xFF break; } LPC_I2C0->CONCLR = I2C_I2CONCLR_SIC; if (--bytesToCapture == 0) { I2C_MonitorModeCmd(LPC_I2C0, DISABLE); I2C_IntCmd(LPC_I2C0, FALSE); done = TRUE; } CLR_MEAS_PIN_1(); }
/*********************************************************************//** * @brief c_entry: Main program body * @param[in] None * @return int **********************************************************************/ int c_entry(void) { PINSEL_CFG_Type PinCfg; uint8_t idx,i; /* Initialize debug via UART0 * – 115200bps * – 8 data bit * – No parity * – 1 stop bit * – No flow control */ debug_frmwrk_init(); //print menu screen print_menu(); /* I2C block ------------------------------------------------------------------- */ /* * Init I2C pin connect */ PinCfg.OpenDrain = 0; PinCfg.Pinmode = 0; PinCfg.Funcnum = 1; PinCfg.Pinnum = 27; PinCfg.Portnum = 0; PINSEL_ConfigPin(&PinCfg);//SDA0 PinCfg.Pinnum = 28; PINSEL_ConfigPin(&PinCfg);//SCL0 // Initialize I2C peripheral I2C_Init(I2CDEV, 100000); /* Configure interrupt for I2C in NVIC of ARM core */ /* Disable I2C0 interrupt */ NVIC_DisableIRQ(I2C0_IRQn); /* preemption = 1, sub-priority = 0 */ NVIC_SetPriority(I2C0_IRQn, ((0x01<<3)|0x01)); //enable I2C interrupt I2C_IntCmd(LPC_I2C0, ENABLE); /* Enable I2C operation */ I2C_Cmd(I2CDEV, ENABLE); while(1) { idx=0;count=0; while(idx<2) { if(idx==0) { _DBG_("\n\rEnter monitor buffer size: "); } idx++; switch(_DG) { case '0': count=(count<<4)|0x00;break; case '1': count=(count<<4)|0x01;break; case '2': count=(count<<4)|0x02;break; case '3': count=(count<<4)|0x03;break; case '4': count=(count<<4)|0x04;break; case '5': count=(count<<4)|0x05;break; case '6': count=(count<<4)|0x06;break; case '7': count=(count<<4)|0x07;break; case '8': count=(count<<4)|0x08;break; case '9': count=(count<<4)|0x09;break; case 'a': count=(count<<4)|0x0A;break; case 'A': count=(count<<4)|0x0A;break; case 'b': count=(count<<4)|0x0B;break; case 'B': count=(count<<4)|0x0B;break; case 'c': count=(count<<4)|0x0C;break; case 'C': count=(count<<4)|0x0C;break; case 'd': count=(count<<4)|0x0D;break; case 'D': count=(count<<4)|0x0D;break; case 'e': count=(count<<4)|0x0E;break; case 'E': count=(count<<4)|0x0E;break; case 'f': count=(count<<4)|0x0F;break; case 'F': count=(count<<4)|0x0F;break; default: idx=0;count=0;break; } if(idx==2) { if(count>BUFFER_SIZE) { _DBG_("invalid! The size is bigger than ");_DBH(BUFFER_SIZE); idx=0;count=0; } else _DBH(count); } } //Configure I2C in monitor mode I2C_MonitorModeConfig(I2CDEV,(uint32_t)I2C_MONITOR_CFG_MATCHALL, ENABLE); I2C_MonitorModeCmd(I2CDEV, ENABLE); _DBG_("\n\rStart monitoring I2C bus..."); while(done==FALSE); done=FALSE; _DBG_("done!"); for(i=0;i<count;i++) { if((i%16)==0) _DBG_(""); _DBH(buffer[i]);_DBC(0x20); buffer[i]=0; } } return 1; }