Beispiel #1
0
/**
 * @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;
}
Beispiel #2
0
/**
 * @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!");
}