uint8 hw_wait(uint8 x,int MoudleNum) { uint16 ErrTime, i; I2C_MemMapPtr num = hw_i2c_get_base_address(MoudleNum); ErrTime = 255*10; //定义查询超时时限 //获取i2c模块基址 for (i = 0; i < ErrTime; i++) { if (x == 'A') //等待应答信号 { if(( I2C_S_REG(num) & I2C_S_RXAK_MASK)==0) return 0; //传送完一个字节后,收到了从机的应答信号 } else if (x == 'T') //等待传送完成一个字节信号 { if ((I2C_S_REG(num) & I2C_S_IICIF_MASK) != 0) { (I2C_S_REG(num) |=(0 | I2C_S_IICIF_MASK)); //清IICIF标志位 return 0; //成功发送完一个字节 } } } if (i >= ErrTime) return 1; //超时,没有收到应答信号或发送完一个字节 }
uint8_t my_i2c_Wait(I2Cn_e I2Cn) { set_timeout(3); while(( I2C_S_REG(I2C0_BASE_PTR) & I2C_S_IICIF_MASK)==0) { if(timeout()) { my_i2c_reset_sda(); error_count++; return 0; } } I2C_S_REG(I2C0_BASE_PTR) |= I2C_S_IICIF_MASK; return 1; }
/* * LPLD_I2C_WaitAck * I2C设置等待应答信号,开启则等待,关闭则不等待 * * 参数: * i2cx--选择I2C模块号 * |__I2C0 --I2C0号模块 * |__I2C1 --I2C1号模块 * is_wait--选择是否等待应答 * |__I2C_ACK_OFF --关闭等待Ack * |__I2C_ACK_ON --开启等待Ack,并等待ACK信号 */ void LPLD_I2C_WaitAck(I2Cx i2cx, uint8 is_wait) { I2C_MemMapPtr i2cptr = I2Cx_Ptr[i2cx]; uint16 time_out; if(is_wait == I2C_ACK_ON) { while(!(I2C_S_REG(I2Cx_Ptr[i2cx]) & I2C_S_IICIF_MASK)) { if(time_out>60000) //如果等待超时,强行退出 break; else time_out++; } I2C_S_REG(i2cptr) |= I2C_S_IICIF_MASK; } else { //关闭I2C的ACK I2C_C1_REG(i2cptr) |= I2C_C1_TXAK_MASK; } }
void i2c_interrupt_process (i2c_buf_t *buf) { /* * this is the i2c interrupt handler, will be called from a wrapper function, * processor failexpert recommended using register for status, not sure if * necessary. assuming device is always in master mode. */ uint8_t status = I2C_S_REG(I2C0_BASE_PTR); uint8_t errormask = 0x00; // clear interrupt flag I2C_S_REG(I2C0_BASE_PTR) = (uint_8)(status | ((I2C_S_IICIF_MASK & I2C_S_ARBL_MASK) & I2C_S_REG(I2C0_BASE_PTR))); if (I2C_PDD_GetMasterMode(I2C0_BASE_PTR) == I2C_PDD_MASTER_MODE) { /* Is device in master mode? */ if (I2C_PDD_GetTransmitMode(I2C0_BASE_PTR) == I2C_PDD_TX_DIRECTION) { /* Is device in Tx mode? */ if ((status & I2C_PDD_RX_ACKNOWLEDGE) != 0x00U){ /* NACK received? */ I2C_PDD_SetMasterMode(I2C0_BASE_PTR, I2C_PDD_SLAVE_MODE); /* Switch device to slave mode (stop signal sent) */ I2C_PDD_SetTransmitMode(I2C0_BASE_PTR, I2C_PDD_RX_DIRECTION); /* Switch to Rx mode */ buf->tx_req = 0x00U; /* No character for sending */ buf->rx_req = 0x00U; /* No character for reception */ buf->flags &= ~(MASTER_IN_PROGRES); /* No character for sending or reception */ buf->flags |= (ADDR_COMPLETE | REP_ADDR_COMPLETE); /* Set the flag */ errormask |= LDD_I2C_MASTER_NACK; /* Set the Master Nack error mask */ } else { if ((buf->flags & ADDR_COMPLETE) != 0x00U) { /* If 10-bit addr has been completed */ if (buf->tx_req != 0x00U) { /* Is any char. for transmitting? */ buf->tx_req--; /* Decrease number of chars for the transmit */ I2C_PDD_WriteDataReg(I2C0_BASE_PTR, buf->tx_buf[buf->tx_idx++]); /* Send character */ } else { if (buf->rx_req != 0x00U) { /* Is any char. for reception? */ if ((buf->flags & REP_ADDR_COMPLETE) != 0x00U) { /* If repeated start and addr tx has been completed for 10-bit mode ?*/ if (buf->rx_req == 0x01U) { /* If only one char to receive */ I2C_PDD_EnableTransmitAcknowledge(I2C0_BASE_PTR, PDD_DISABLE); /* then transmit ACK disable */ } else { I2C_PDD_EnableTransmitAcknowledge(I2C0_BASE_PTR, PDD_ENABLE); /* else transmit ACK enable */ } I2C_PDD_SetTransmitMode(I2C0_BASE_PTR, I2C_PDD_RX_DIRECTION); /* Switch to Rx mode */ (void)I2C_PDD_ReadDataReg(I2C0_BASE_PTR); /* Dummy read character */ } else { /* Repeated address has not been completed for 10-bit addressing mode */ I2C_PDD_RepeatStart(I2C0_BASE_PTR); /* Repeat start cycle generated */ I2C_PDD_WriteDataReg(I2C0_BASE_PTR, (uint8_t)(buf->slave_addr_high | 0x01U)); /* Send slave address high byte*/ buf->flags |= REP_ADDR_COMPLETE; } } else { buf->flags &= ~(MASTER_IN_PROGRES); /* Clear flag "busy" */ if (buf->sendstop == TRUE) { I2C_PDD_SetMasterMode(I2C0_BASE_PTR, I2C_PDD_SLAVE_MODE); /* Switch device to slave mode (stop signal sent) */ I2C_PDD_SetTransmitMode(I2C0_BASE_PTR, I2C_PDD_RX_DIRECTION); /* Switch to Rx mode */ } } } } else { I2C_PDD_WriteDataReg(I2C0_BASE_PTR, buf->slave_addr_low); /* Send second part of the 10-bit addres */ buf->flags |= (ADDR_COMPLETE); /* Address complete */ } } } else { buf->rx_req--; /* Decrease number of chars for the receive */ if (buf->rx_req != 0x00U) { /* Is any char. for reception? */ if (buf->rx_req == 0x01U) { I2C_PDD_EnableTransmitAcknowledge(I2C0_BASE_PTR, PDD_DISABLE); /* Transmit NACK */ } } else { buf->flags &= ~(MASTER_IN_PROGRES); /* Clear flag "busy" */ I2C_PDD_SetMasterMode(I2C0_BASE_PTR, I2C_PDD_SLAVE_MODE); /* If no, switch device to slave mode (stop signal sent) */ I2C_PDD_EnableTransmitAcknowledge(I2C0_BASE_PTR, PDD_ENABLE); /* Transmit ACK */ } buf->rx_buf[buf->rx_idx++] = I2C_PDD_ReadDataReg(I2C0_BASE_PTR); /* Receive character */ } } else { if ((status & I2C_PDD_ARBIT_LOST) != 0x00U) { /* Arbitration lost? */ buf->tx_req = 0x00U; /* Any character is not for sent */ buf->rx_req = 0x00U; /* Any character is not for reception */ buf->sendstop = TRUE; /* Set variable for sending stop condition (for master mode) */ buf->flags &= ~(MASTER_IN_PROGRES); /* Any character is not for sent or reception*/ I2C_PDD_SetTransmitMode(I2C0_BASE_PTR, I2C_PDD_RX_DIRECTION); /* Switch to Rx mode */ errormask |= LDD_I2C_ARBIT_LOST; /* Set the ArbitLost error mask */ } } if (errormask != 0x00) { /* Is any error mask set? */ buf->errors |= errormask; /* Update list of error mask value */ // maybe do something here to handle error? } }