/** * @brief Read data from I2C slave. * @param[in] fd is interface number. * @param[in] buf is receive buffer pointer. * @param[in] len is receive buffer length. * @return read status. * @retval >0 length when success. * @retval I2C_ERR_BUSY Interface busy. * @retval I2C_ERR_IO Interface not opened. * @retval I2C_ERR_NODEV No such device. * @retval I2C_ERR_NACK Slave returns an erroneous ACK. * @retval I2C_ERR_LOSTARBITRATION arbitration lost happen. */ int32_t i2cRead(int32_t fd, uint8_t* buf, uint32_t len) { i2c_dev *dev; if(fd != 1 && fd != 0) return(I2C_ERR_NODEV); dev = (i2c_dev *)( (uint32_t)&i2c_device[fd] ); if(dev->openflag == 0) return(I2C_ERR_IO); if(len == 0) return 0; if(!i2cIsBusFree(dev)) return(I2C_ERR_BUSY); if(len > I2C_MAX_BUF_LEN - 10) len = I2C_MAX_BUF_LEN - 10; dev->state = I2C_STATE_READ; dev->pos = 1; /* Current ISR design will get one garbage byte */ dev->len = dev->subaddr_len + 1 + len + 2; /* plus 1 unused char */ dev->last_error = 0; _i2cCalcAddr(dev, I2C_STATE_READ); i2cEnable(dev); i2c_out(dev, dev->buffer[0] & 0xff, I2C_TxR); if(!i2cIsBusFree(dev)) return(I2C_ERR_BUSY); _i2cCommand(dev, I2C_CMD_START | I2C_CMD_WRITE); while(dev->state != I2C_STATE_NOP); i2cDisable(dev); if(dev->last_error) return(dev->last_error); memcpy(buf, dev->buffer + dev->subaddr_len + 3, len); dev->subaddr += len; return len; }
/** * @brief Write data from I2C slave. * @param[in] fd is interface number. * @param[in] buf is transmit buffer pointer. * @param[in] len is transmit buffer length. * @return write status. * @retval >0 length when success. * @retval I2C_ERR_BUSY Interface busy. * @retval I2C_ERR_IO Interface not opened. * @retval I2C_ERR_NODEV No such device. * @retval I2C_ERR_NACK Slave returns an erroneous ACK. * @retval I2C_ERR_LOSTARBITRATION arbitration lost happen. */ int32_t i2cWrite(int32_t fd, uint8_t* buf, uint32_t len) { i2c_dev *dev; if(fd != 1 && fd != 0) return(I2C_ERR_NODEV); dev = (i2c_dev *)( (uint32_t)&i2c_device[fd] ); if(dev->openflag == 0) return(I2C_ERR_IO); if(len == 0) return 0; if(!i2cIsBusFree(dev)) return(I2C_ERR_BUSY); if(len > I2C_MAX_BUF_LEN - 10) len = I2C_MAX_BUF_LEN - 10; memcpy(dev->buffer + dev->subaddr_len + 1 , buf, len); dev->state = I2C_STATE_WRITE; dev->pos = 1; dev->len = dev->subaddr_len + 1 + len; dev->last_error = 0; _i2cCalcAddr(dev, I2C_STATE_WRITE); i2cEnable(dev); i2c_out(dev, dev->buffer[0] & 0xff, I2C_TxR); if(!i2cIsBusFree(dev)) return(I2C_ERR_BUSY); _i2cCommand(dev, I2C_CMD_START | I2C_CMD_WRITE); while(dev->state != I2C_STATE_NOP); i2cDisable(dev); if(dev->last_error) return(dev->last_error); dev->subaddr += len; return len; }
static BT_HANDLE i2c_probe(const BT_INTEGRATED_DEVICE *pDevice, BT_ERROR *pError) { BT_ERROR Error = BT_ERR_NONE; BT_HANDLE hI2C = NULL; const BT_RESOURCE *pResource = BT_GetIntegratedResource(pDevice, BT_RESOURCE_MEM, 0); if(!pResource) { Error = BT_ERR_NO_MEMORY; goto err_free_out; } hI2C = BT_CreateHandle(&oHandleInterface, sizeof(struct _BT_OPAQUE_HANDLE), pError); if(!hI2C) { goto err_out; } hI2C->pRegs = (LPC11xx_I2C_REGS *) pResource->ulStart; pResource = BT_GetIntegratedResource(pDevice, BT_RESOURCE_ENUM, 0); if(!pResource) { Error = BT_ERR_NO_MEMORY; goto err_free_out; } hI2C->i2c_master.pDevice = pDevice; pResource = BT_GetIntegratedResource(pDevice, BT_RESOURCE_INTEGER, 0); if(!pResource) { Error = BT_ERR_GENERIC; goto err_free_out; } i2cSetPowerState(hI2C, BT_POWER_STATE_AWAKE); // Reset all registers to their defaults! ResetI2C(hI2C); i2cEnable(hI2C); i2c_set_clock_rate(hI2C, pResource->ulStart); pResource = BT_GetIntegratedResource(pDevice, BT_RESOURCE_IRQ, 0); if(!pResource) { Error = BT_ERR_GENERIC; goto err_free_out; } /* On NVIC we don't need to register interrupts, LINKER has patched vector for us * Error = BT_RegisterInterrupt(pResource->ulStart, I2C_irq_handler, hI2C); if(Error) { goto err_free_out; }*/ //@@Error = BT_EnableInterrupt(pResource->ulStart); pResource = BT_GetIntegratedResource(pDevice, BT_RESOURCE_BUSID, 0); if(!pResource) { goto err_free_out; } BT_u32 ulBusID = pResource->ulStart; hI2C->i2c_master.ulBusID = ulBusID; hI2C->i2c_master.hBus = hI2C; // Save pointer to bus's private data. hI2C->i2c_master.pDevice = pDevice; BT_I2C_RegisterBus(&hI2C->i2c_master); if(pError) { *pError = Error; } return hI2C; err_free_out: BT_DestroyHandle(hI2C); err_out: if(pError) { *pError = Error; } return NULL; }