打印

FX3 I2C Read DMA模式(新手入门手册)

[复制链接]
2905|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zengweitotty|  楼主 | 2015-11-5 11:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zengweitotty 于 2015-11-5 11:13 编辑

新手入门的系列文档【原创】

作为FX3DMA方式进行read的时候需要注意一下事项。
以下是I2C的配置。当产生RX_DONE时应该手动SetWrapUp
#ifdef WEIZ
void I2cIntrCb(
       CyU3PI2cEvt_t evt,      /**< Type of event that occured.*/
       CyU3PI2cError_t error   /**< Specifies the actual error/statuscode when
                                     the eventis of type CY_U3P_I2C_EVENT_ERROR. */
       ){
       if(evt == CY_U3P_I2C_EVENT_RX_DONE){
              CyU3PDebugPrint (4, "RX done isdetect!\n");
              CyU3PDmaChannelSetWrapUp(&glI2cRxHandle);
       }
}
CyU3PReturnStatus_t
CyU3PInitializeI2c (
              CyU3PI2cFreq_t freq  /* Frequency 100KHz or 400KHz */
)
{
       CyU3PI2cConfig_t i2cConfig;
       CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
       CyU3PDmaChannelConfig_t dmaConfig;
       /* Initialize andconfigure the I2C master module.
       If the block is already started go aheadand set
       configuration to override any presetconfiguration*/
       status= CyU3PI2cInit ();
       if ((status != CY_U3P_SUCCESS) && (status!= CY_U3P_ERROR_ALREADY_STARTED))
       {
              return status;
       }
       /* Start the I2Cmaster block. The bit rate is set to 100KHz or 400KHz. */
       CyU3PMemSet ((uint8_t *)&i2cConfig, 0,sizeof(i2cConfig));
       i2cConfig.bitRate = 100000;
       switch (freq)
       {
       case CY_U3P_I2C_100KHZ:
              i2cConfig.bitRate = 100000;
              break;
       case CY_U3P_I2C_400KHZ:
              i2cConfig.bitRate = 400000;
              break;
       default:
              return CY_U3P_ERROR_BAD_ARGUMENT;
       }
       i2cConfig.busTimeout = 0xFFFFFFFF;
       i2cConfig.dmaTimeout = 0xFFFF;
       //    i2cConfig.isDma      = CyFalse;
       i2cConfig.isDma      = CyTrue;
       status= CyU3PI2cSetConfig (&i2cConfig,I2cIntrCb);
       CyU3PMemSet ((uint8_t *)&dmaConfig, 0,sizeof(dmaConfig));
       dmaConfig.size           = 64;
       /* No buffers needto be allocated as this will be used
        * only in override mode. */
       dmaConfig.count          = 2;
       dmaConfig.prodAvailCount = 0;
       dmaConfig.dmaMode        = CY_U3P_DMA_MODE_BYTE;
       dmaConfig.prodHeader     = 0;
       dmaConfig.prodFooter     = 0;
       dmaConfig.consHeader     = 0;
       dmaConfig.notification   = 0;
       dmaConfig.cb             = NULL;
       /* Create a channelto write to the EEPROM. */
       dmaConfig.prodSckId = CY_U3P_CPU_SOCKET_PROD;
       dmaConfig.consSckId = CY_U3P_LPP_SOCKET_I2C_CONS;
       status= CyU3PDmaChannelCreate (&glI2cTxHandle,
                     CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaConfig);
       if (status != CY_U3P_SUCCESS)
       {
//            CyCx3AppErrorHandler(status);
       }
       /* Create a channelto read from the EEPROM. */
       dmaConfig.prodSckId = CY_U3P_LPP_SOCKET_I2C_PROD;
       dmaConfig.consSckId = CY_U3P_CPU_SOCKET_CONS;
       status= CyU3PDmaChannelCreate (&glI2cRxHandle,
                     CY_U3P_DMA_TYPE_MANUAL_IN, &dmaConfig);
       if (status != CY_U3P_SUCCESS)
       {
//            CyCx3AppErrorHandler(status);
       }
       return status;
}
#endif

以下是进行操作的函数。注意buf_p.size应该是16的倍数。传输完成需要通过callback手动提交到Consumersocket
#ifdef WEIZ
CyU3PReturnStatus_t
SensorRead (
              uint8_t slaveAddr,
              uint8_t highAddr,
              uint8_t lowAddr,
              uint8_t count,
              uint8_t *buf)
{
       CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
       CyU3PI2cPreamble_t preamble;
       /* Validate the I2Cslave address. */
       if ((slaveAddr !=SENSOR_ADDR_WR) && (slaveAddr != I2C_MEMORY_ADDR_WR))
       {
              CyU3PDebugPrint (4, "I2C Slaveaddress is not valid!\n");
              return 1;
       }
       if (count > 64)
       {
              CyU3PDebugPrint (4, "ERROR:SensorWrite count > 64\n");
              return 1;
       }
       CyU3PDmaBuffer_t buf_p;
       /* Update the preambleinformation. */
       /* Set theparameters for the I2C API access and then call the write API. */
       preamble.buffer[0] = slaveAddr &I2C_SLAVEADDR_MASK;        /*  Mask out the transfer type bit. */
       preamble.buffer[1] = highAddr;
       preamble.buffer[2] = lowAddr;
       preamble.buffer[3] = slaveAddr;
       preamble.length    = 4;
       preamble.ctrlMask  = 0x0004;
       buf_p.size = (count + 15) &0xF0;
       buf_p.count = count;
       buf_p.status = 0;
       buf_p.buffer = buf;
       apiRetStatus= CyU3PDmaChannelSetupSendBuffer(&glI2cTxHandle,&buf_p);
       if (apiRetStatus != CY_U3P_SUCCESS)
       {
              CyU3PDebugPrint (4, "Write Notsuccessful 1 return value %x\r\n",apiRetStatus);
              return apiRetStatus;
       }
       apiRetStatus= CyU3PI2cSendCommand (&preamble,count, CyFalse);
       if (apiRetStatus != CY_U3P_SUCCESS)
       {
              CyU3PDebugPrint (4, "Write Notsuccessful 2 return value %x\r\n",apiRetStatus);
              return apiRetStatus;
       }
       //     CyU3PThreadSleep(4);
       apiRetStatus= CyU3PDmaChannelWaitForCompletion(&glI2cTxHandle,
                     (count+ 20 )/ 10);
       if (apiRetStatus != CY_U3P_SUCCESS)
       {
//            CyU3PDebugPrint(4, "Read Not successful 3\r\n");
//            CyU3PDmaChannelSetWrapUp(&glI2cTxHandle);
              return apiRetStatus;
       }
       return apiRetStatus;
}
#endif
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

61

帖子

19

粉丝