/** * @brief Process an i2c transaction. * * Transactions are composed of one or more i2c_msg's, and may be read * or write tranfers. Multiple i2c_msg's will generate a repeated * start in between messages. * * @param dev I2C device * @param msgs Messages to send/receive * @param num Number of messages to send/receive * @param timeout Bus idle timeout in milliseconds before aborting the * transfer. 0 denotes no timeout. * @return 0 on success, * I2C_ERROR_PROTOCOL if there was a protocol error, * I2C_ERROR_TIMEOUT if the transfer timed out. */ int32 i2c_master_xfer(i2c_dev *dev, i2c_msg *msgs, uint16 num, uint32 timeout) { int32 rc; ASSERT(dev->state == I2C_STATE_IDLE); dev->msg = msgs; dev->msgs_left = num; dev->timestamp = systick_uptime(); dev->state = I2C_STATE_BUSY; i2c_enable_irq(dev, I2C_IRQ_EVENT); i2c_start_condition(dev); rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout); if (rc < 0) { goto out; } dev->state = I2C_STATE_IDLE; out: return rc; }
/** * @brief Process an i2c transaction. * * Transactions are composed of one or more i2c_msg's, and may be read * or write tranfers. Multiple i2c_msg's will generate a repeated * start in between messages. * * @param dev I2C device * @param msgs Messages to send/receive * @param num Number of messages to send/receive * @param timeout Bus idle timeout in milliseconds before aborting the * transfer. 0 denotes no timeout. * @return 0 on success, * I2C_ERROR_PROTOCOL if there was a protocol error, * I2C_ERROR_TIMEOUT if the transfer timed out. */ int32 i2c_master_xfer(i2c_dev *dev, i2c_msg *msgs, uint16 num, uint32 timeout) { int32 rc; fooprint("master xfer1"); //fooprint("me1"); ASSERT(dev->state == I2C_STATE_IDLE); dev->msg = msgs; dev->msgs_left = num; // what is this????????????????????????????????????????? dev->timestamp = systick_uptime(); dev->state = I2C_STATE_BUSY; // workaround repeated start issue identified in SiM3U1XX Errata dev->regs->SCONFIG |= 1 << I2C_SCONFIG_SETUP_BIT; // already enabled in master enable //i2c_enable_irq(dev, I2C_IRQ_EVENT); fooprint("master exfer2"); i2c_start_condition(dev); fooprint("master exfer3"); rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout); fooprint("master exfer after wait for state"); if (rc < 0) { goto out; } dev->state = I2C_STATE_IDLE; out: return rc; }
void terminate() { print_log("On terminating..."); OMX_STATETYPE state; OMX_BOOL bWaitForCamera, bWaitForRender; // Execute -> Idle bWaitForCamera = bWaitForRender = OMX_FALSE; if(isState(mContext.pCamera, OMX_StateExecuting)) { OMX_SendCommand(mContext.pCamera, OMX_CommandStateSet, OMX_StateIdle, NULL); bWaitForCamera = OMX_TRUE; } if(isState(mContext.pRender, OMX_StateExecuting)) { OMX_SendCommand(mContext.pRender, OMX_CommandStateSet, OMX_StateIdle, NULL); bWaitForRender = OMX_TRUE; } if(bWaitForCamera) wait_for_state_change(OMX_StateIdle, mContext.pCamera, NULL); if(bWaitForRender) wait_for_state_change(OMX_StateIdle, mContext.pRender, NULL); // Idle -> Loaded bWaitForCamera = bWaitForRender = OMX_FALSE; if(isState(mContext.pCamera, OMX_StateIdle)) { OMX_SendCommand(mContext.pCamera, OMX_CommandStateSet, OMX_StateLoaded, NULL); bWaitForCamera = OMX_TRUE; } if(isState(mContext.pRender, OMX_StateIdle)) { OMX_SendCommand(mContext.pRender, OMX_CommandStateSet, OMX_StateLoaded, NULL); bWaitForRender = OMX_TRUE; } if(bWaitForCamera) wait_for_state_change(OMX_StateLoaded, mContext.pCamera, NULL); if(bWaitForRender) wait_for_state_change(OMX_StateLoaded, mContext.pRender, NULL); // Loaded -> Free if(isState(mContext.pCamera, OMX_StateLoaded)) OMX_FreeHandle(mContext.pCamera); if(isState(mContext.pRender, OMX_StateLoaded)) OMX_FreeHandle(mContext.pRender); OMX_Deinit(); print_log("Press enter to terminate."); getchar(); }
int main(void) { /* Temporary variables */ OMX_ERRORTYPE err; OMX_PARAM_PORTDEFINITIONTYPE portDef; /* Initialize application variables */ memset(&mContext, 0, (size_t)sizeof(mContext)); mContext.nWidth = 640; mContext.nHeight = 480; mContext.nFramerate = 25; // RPI initialize. bcm_host_init(); // OMX initialize. print_log("Initialize OMX"); if((err = OMX_Init()) != OMX_ErrorNone) { print_omx_error(err, "FAIL"); OMX_Deinit(); exit(-1); } // For loading component, Callback shall provide. OMX_CALLBACKTYPE callbackOMX; callbackOMX.EventHandler = onOMXevent; callbackOMX.EmptyBufferDone = onEmptyRenderIn; callbackOMX.FillBufferDone = onFillCameraOut; componentLoad(&callbackOMX); componentConfigure(); componentPrepare(); // Request state of component to be EXECUTE. print_log("STATE : CAMERA - EXECUTING request"); if((err = OMX_SendCommand(mContext.pCamera, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { print_omx_error(err, "FAIL"); terminate(); exit(-1); } print_log("STATE : RENDER - EXECUTING request"); if((err = OMX_SendCommand(mContext.pRender, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { print_omx_error(err, "FAIL"); terminate(); exit(-1); } if(!wait_for_state_change(OMX_StateExecuting, mContext.pCamera, mContext.pRender, NULL)) { print_log("FAIL"); terminate(); exit(-1); } print_log("STATE : EXECUTING OK!"); // Since #71 is capturing port, needs capture signal like other handy capture devices print_log("Capture start."); OMX_CONFIG_PORTBOOLEANTYPE portCapturing; OMX_INIT_STRUCTURE(portCapturing); portCapturing.nPortIndex = 71; portCapturing.bEnabled = OMX_TRUE; OMX_SetConfig(mContext.pCamera, OMX_IndexConfigPortCapturing, &portCapturing); OMX_U8* pY = NULL; OMX_U8* pU = NULL; OMX_U8* pV = NULL; unsigned int nOffsetU = mContext.nWidth * mContext.nHeight; unsigned int nOffsetV = nOffsetU * 5 / 4; unsigned int nFrameMax = mContext.nFramerate * 5; unsigned int nFrames = 0; print_log("Capture for %d frames.", nFrameMax); OMX_FillThisBuffer(mContext.pCamera, mContext.pBufferCameraOut); while(nFrames < nFrameMax) { if(mContext.isFilled) { OMX_BUFFERHEADERTYPE* pBuffer = mContext.pBufferPool[mContext.nBufferPoolIndex]; if(pBuffer->nFilledLen == 0) { pY = pBuffer->pBuffer; pU = pY + nOffsetU; pV = pY + nOffsetV; } memcpy(pY, mContext.pSrcY, mContext.nSizeY); pY += mContext.nSizeY; memcpy(pU, mContext.pSrcU, mContext.nSizeU); pU += mContext.nSizeU; memcpy(pV, mContext.pSrcV, mContext.nSizeV); pV += mContext.nSizeV; pBuffer->nFilledLen += mContext.pBufferCameraOut->nFilledLen; if(mContext.pBufferCameraOut->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) { print_log("BUFFER 0x%08x filled", pBuffer); OMX_EmptyThisBuffer(mContext.pRender, pBuffer); mContext.nBufferPoolIndex++; if(mContext.nBufferPoolIndex == mContext.nBufferPoolSize) mContext.nBufferPoolIndex = 0; nFrames++; } mContext.isFilled = OMX_FALSE; OMX_FillThisBuffer(mContext.pCamera, mContext.pBufferCameraOut); } usleep(1); } portCapturing.bEnabled = OMX_FALSE; OMX_SetConfig(mContext.pCamera, OMX_IndexConfigPortCapturing, &portCapturing); print_log("Capture stop."); terminate(); }
void componentPrepare() { OMX_ERRORTYPE err; OMX_PARAM_PORTDEFINITIONTYPE portDef; // Request state of components to be IDLE. // The command will turn the component into waiting mode. // After allocating buffer to all enabled ports than the component will be IDLE. print_log("STATE : CAMERA - IDLE request"); if((err = OMX_SendCommand(mContext.pCamera, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { print_omx_error(err, "FAIL"); terminate(); exit(-1); } print_log("STATE : RENDER - IDLE request"); if((err = OMX_SendCommand(mContext.pRender, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { print_omx_error(err, "FAIL"); terminate(); exit(-1); } // Allocate buffers to render print_log("Allocate buffer to renderer #90 for input."); OMX_INIT_STRUCTURE(portDef); portDef.nPortIndex = 90; OMX_GetParameter(mContext.pRender, OMX_IndexParamPortDefinition, &portDef); print_log("Size of predefined buffer : %d * %d", portDef.nBufferSize, portDef.nBufferCountActual); mContext.nBufferPoolSize = portDef.nBufferCountActual; mContext.nBufferPoolIndex = 0; mContext.pBufferPool = malloc(sizeof(OMX_BUFFERHEADERTYPE*) * mContext.nBufferPoolSize); for(int i = 0; i < mContext.nBufferPoolSize; i++) { mContext.pBufferPool[i] = 0x00; if((err = OMX_AllocateBuffer(mContext.pRender, &(mContext.pBufferPool[i]), 90, &mContext, portDef.nBufferSize)) != OMX_ErrorNone) { print_omx_error(err, "FAIL"); terminate(); exit(-1); } } // Allocate buffer to camera OMX_INIT_STRUCTURE(portDef); portDef.nPortIndex = 71; OMX_GetParameter(mContext.pCamera, OMX_IndexParamPortDefinition, &portDef); print_log("Size of predefined buffer : %d * %d", portDef.nBufferSize, portDef.nBufferCountActual); if((err = OMX_AllocateBuffer(mContext.pCamera, &mContext.pBufferCameraOut, 71, &mContext, portDef.nBufferSize)) != OMX_ErrorNone) { print_omx_error(err, "FAIL"); terminate(); exit(-1); } mContext.pSrcY = mContext.pBufferCameraOut->pBuffer; mContext.pSrcU = mContext.pSrcY + mContext.nSizeY; mContext.pSrcV = mContext.pSrcU + mContext.nSizeU; print_log("0x%08x 0x%08x 0x%08x", mContext.pSrcY, mContext.pSrcU, mContext.pSrcV); // Wait up for component being idle. if(!wait_for_state_change(OMX_StateIdle, mContext.pRender, mContext.pCamera, NULL)) { print_log("FAIL"); terminate(); exit(-1); } print_log("STATE : IDLE OK!"); }