/* Entry function for the gpioPWMThread */
void
GpioPWMThread_Entry (
        uint32_t input)
{
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;

    /* Initialize Debug module */
    apiRetStatus = CyFxDebugInit();
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Initialize GPIO module. */
    CyFxGpioInit ();

    /* Now resume the other two threads. */
    CyU3PThreadResume (&gpioMeasureThread);
    CyU3PThreadResume (&gpioCounterThread);

    for (;;)
    {
        /* Wait for 1s. */
        CyU3PThreadSleep (1000);

        /* Change the PWM duty cycle to 75%. */
        apiRetStatus = CyU3PGpioComplexUpdate (50,
                CY_FX_PWM_75P_THRESHOLD, CY_FX_PWM_PERIOD);
        if (apiRetStatus != CY_U3P_SUCCESS)
        {
            CyU3PDebugPrint (4, "CyU3PGpioComplexUpdate failed, error code = %d\n",
                    apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }

        /* Wait for 1s. */
        CyU3PThreadSleep (1000);

        /* Change the PWM duty cycle to 25%. */
        apiRetStatus = CyU3PGpioComplexUpdate (50,
                CY_FX_PWM_25P_THRESHOLD, CY_FX_PWM_PERIOD);
        if (apiRetStatus != CY_U3P_SUCCESS)
        {
            CyU3PDebugPrint (4, "CyU3PGpioComplexUpdate failed, error code = %d\n",
                    apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }
    }
}
/* Entry function for the gpioOutputThread */
void
GpioOutputThread_Entry (
        uint32_t input)
{
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;

    /* Initialize Debug module */
    apiRetStatus = CyFxDebugInit();
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        /* Error handling */
        CyU3PDebugPrint (4, "Debug module initialization failed, error code = %d\n",
                apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }

    /* Initialize GPIO module. */
    CyFxGpioInit ();

    for (;;)
    {
        /* Set the GPIO 21 to high */
        apiRetStatus = CyU3PGpioSetValue (21, CyTrue);
        if (apiRetStatus != CY_U3P_SUCCESS)
        {
            /* Error handling */
            CyU3PDebugPrint (4, "CyU3PGpioSetValue failed, error code = %d\n",
                    apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }

        /* Wait for two seconds */
        CyU3PThreadSleep(2000);

        /* Set the GPIO 21 to low */
        apiRetStatus = CyU3PGpioSetValue (21, CyFalse);
        if (apiRetStatus != CY_U3P_SUCCESS)
        {
            /* Error handling */
            CyU3PDebugPrint (4, "CyU3PGpioSetValue failed, error code = %d\n",
                    apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }

        /* Wait for two seconds */
        CyU3PThreadSleep(2000);
    }
}
/* Entry function for the gpioCounterThread */
void
GpioCounterThread_Entry (
        uint32_t input)
{
    uint32_t threshold = 0;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;

    for (;;)
    {
        /* This will retreive the current counter value. */
        apiRetStatus = CyU3PGpioComplexSampleNow (52, &threshold);
        if (apiRetStatus != CY_U3P_SUCCESS)
        {
            CyU3PDebugPrint (4, "CyU3PGpioComplexSampleNow failed, error code = %d\n",
                    apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }

        /* Print out the counter value. */
        CyU3PDebugPrint (4, "GPIO 52 counter reading = %d.\n", threshold);

        /* Sample every 2s. */
        CyU3PThreadSleep (2000);
    }
}
Ejemplo n.º 4
0
/* This function initializes the USB module. */
CyU3PReturnStatus_t
CyFxApplnInit (void)
{
    CyU3POtgConfig_t otgCfg;
    CyU3PGpioClock_t clkCfg;
    CyU3PGpioSimpleConfig_t simpleCfg;
    CyU3PReturnStatus_t status;

    /* Initialize GPIO module. */
    clkCfg.fastClkDiv = 2;
    clkCfg.slowClkDiv = 0;
    clkCfg.halfDiv = CyFalse;
    clkCfg.simpleDiv = CY_U3P_GPIO_SIMPLE_DIV_BY_2;
    clkCfg.clkSrc = CY_U3P_SYS_CLK;
    status = CyU3PGpioInit (&clkCfg, NULL);
    if (status != CY_U3P_SUCCESS)
    {
        return status;
    }

    /* Override GPIO 21 for VBUS control. */
    status = CyU3PDeviceGpioOverride (21, CyTrue);
    if (status != CY_U3P_SUCCESS)
    {
        return status;
    }

    /* Configure GPIO 21 as output for VBUS control. */
    simpleCfg.outValue = CY_FX_HOST_VBUS_DISABLE_VALUE;
    simpleCfg.driveLowEn = CyTrue;
    simpleCfg.driveHighEn = CyTrue;
    simpleCfg.inputEn = CyFalse;
    simpleCfg.intrMode = CY_U3P_GPIO_NO_INTR;
    status = CyU3PGpioSetSimpleConfig (21, &simpleCfg);
    if (status != CY_U3P_SUCCESS)
    {
        return status;
    }

    /* Wait until VBUS is stabilized. */
    CyU3PThreadSleep (100);

    /* Initialize the OTG module. */
    otgCfg.otgMode = CY_U3P_OTG_MODE_OTG;
    otgCfg.chargerMode = CY_U3P_OTG_CHARGER_DETECT_ACA_MODE;
    otgCfg.cb = CyFxOtgEventCb;
    status = CyU3POtgStart (&otgCfg);
    if (status != CY_U3P_SUCCESS)
    {
        return status;
    }

    /* Since VBATT or VBUS is required for OTG operation enable it. */
    status = CyU3PUsbVBattEnable (CyTrue);

    return status;
}
Ejemplo n.º 5
0
void AR0330_SetHue(int32_t hue) {
	CyU3PDebugPrint(4, "AR0330_SetHue: %d\r\n", hue);

#define SetLow(io) CyU3PGpioSetValue(io, CyFalse)
#define SetHigh(io) CyU3PGpioSetValue(io, CyTrue)
#define SetBit(io, value) CyU3PGpioSetValue(io, 0 != (value & 0x80))

#if 0
	CyU3PReturnStatus_t status;
	status = CyU3PGpioSetValue(LED_DRIVER_SDI, 0 != (hue & 1));
	if (CY_U3P_SUCCESS != status) {
		CyU3PDebugPrint(4, "AR0330_SetHue: error = %d 0x%x\r\n", status, status);
	}
	status = CyU3PGpioSetValue(LED_DRIVER_CLK, 0 != (hue & 2));
	if (CY_U3P_SUCCESS != status) {
		CyU3PDebugPrint(4, "AR0330_SetHue: error = %d 0x%x\r\n", status, status);
	}
	status = CyU3PGpioSetValue(LED_DRIVER_ED1, 0 != (hue & 4));
	if (CY_U3P_SUCCESS != status) {
		CyU3PDebugPrint(4, "AR0330_SetHue: error = %d 0x%x\r\n", status, status);
	}
	status = CyU3PGpioSetValue(LED_DRIVER_ED2, 0 != (hue & 8));
	if (CY_U3P_SUCCESS != status) {
		CyU3PDebugPrint(4, "AR0330_SetHue: error = %d 0x%x\r\n", status, status);
	}

#else
	// initialise
	SetLow(LED_DRIVER_CLK);
	SetHigh(LED_DRIVER_ED2);
	SetLow(LED_DRIVER_ED1);
	CyU3PThreadSleep(1);

	for (int i = 0; i < 8; ++i) {
		SetBit(LED_DRIVER_SDI, hue);
		hue <<= 1; // output bit big endian
		CyU3PBusyWait(10);
		//CyU3PThreadSleep(10);
		SetHigh(LED_DRIVER_CLK);
		CyU3PBusyWait(10);
		//CyU3PThreadSleep(10);
		SetLow(LED_DRIVER_CLK);
	}
	//CyU3PThreadSleep(1);
	CyU3PBusyWait(10);
	SetHigh(LED_DRIVER_ED1);
	//CyU3PThreadSleep(10);
	CyU3PBusyWait(10);
	SetLow(LED_DRIVER_ED1);
	//CyU3PThreadSleep(1);
	CyU3PBusyWait(10);
	SetLow(LED_DRIVER_ED2);
#endif
}
/* Entry function for the gpioMeasureThread. */
void
GpioMeasureThread_Entry (
        uint32_t input)
{
    uint32_t threshold = 0;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;

    for (;;)
    {
        /* Invoke the measure API. This will measure the low period for the PWM */
        apiRetStatus = CyU3PGpioComplexMeasureOnce (51,
                CY_U3P_GPIO_MODE_MEASURE_LOW_ONCE);
        if (apiRetStatus != CY_U3P_SUCCESS)
        {
            CyU3PDebugPrint (4, "CyU3PGpioComplexMeasureOnce failed, error code = %d\n",
                    apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }

        /* Since this thread should not block other threads, do not wait. */
        do
        {
            CyU3PThreadSleep (1);
            apiRetStatus = CyU3PGpioComplexWaitForCompletion (51, &threshold, CyFalse);

        } while (apiRetStatus == CY_U3P_ERROR_TIMEOUT);

        if (apiRetStatus != CY_U3P_SUCCESS)
        {
            CyU3PDebugPrint (4, "CyU3PGpioComplexWaitForCompletion failed, error code = %d\n",
                    apiRetStatus);
            CyFxAppErrorHandler(apiRetStatus);
        }

        /* Print out the threshold value. */
        CyU3PDebugPrint (4, "GPIO 51 low threshold = %d.\n", threshold);

        /* Sample every 0.5s. */
        CyU3PThreadSleep (500);
    }
}
Ejemplo n.º 7
0
/* Entry function for the AppThread. */
void
ApplnThread_Entry (
    uint32_t input)
{
    CyBool_t isPresent = CyFalse;
    CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

    /* Initialize the debug logger. */
    CyFxApplnDebugInit ();

    /* Initialize the example application. */
    status = CyFxApplnInit();
    if (status != CY_U3P_SUCCESS)
    {
        CyU3PDebugPrint (2, "Application initialization failed. Aborting.\r\n");
        CyFxAppErrorHandler (status);
    }

    for (;;)
    {
        CyU3PThreadSleep (100);
        if (isPresent != glIsPeripheralPresent)
        {
            /* Stop previously started application. */
            if (glIsApplnActive)
            {
                CyFxApplnStop ();
            }

            /* If a peripheral got connected, then enumerate
             * and start the application. */
            if (glIsPeripheralPresent)
            {
                status = CyU3PUsbHostPortEnable ();
                if (status == CY_U3P_SUCCESS)
                {
                    CyFxApplnStart ();
                }
            }

            /* Update the state variable. */
            isPresent = glIsPeripheralPresent;
        }

        /* Since the test needs to be done from a thread,
         * this function is called at fixed interval. */
        if (glHostOwner == CY_FX_HOST_OWNER_MSC_DRIVER)
        {
            CyFxMscDriverDoWork ();
        }
    }
}
Ejemplo n.º 8
0
/*
 * Reset the image sensor using GPIO.
 */
void SensorReset(void) {
	CyU3PReturnStatus_t apiRetStatus;
	uint16_t preTick, posTick;
	/* Drive the GPIO low to reset the sensor. */
	//apiRetStatus = CyU3PGpioSetValue(SENSOR_POWER_GPIO, CyFalse);
	apiRetStatus = CyU3PGpioSetValue(SENSOR_RESET_GPIO, CyFalse);
	if (apiRetStatus != CY_U3P_SUCCESS) {
		CyU3PDebugPrint(4, "GPIO Set Value Error, Error Code = %d\n",
				apiRetStatus);
		return;
	}
	CyU3PDebugPrint(4, "GPIO Set Value\r\n");
	/* Wait for some time to allow proper reset. */
	uint8_t i = 0;
	while (i++ < 2){
		preTick = CyU3PGetTime();
		CyU3PThreadSleep(500);  // change the value into 100 from 10.
		posTick = CyU3PGetTime();
		CyU3PDebugPrint(4, "The ticks %d %d \r\n", preTick, posTick); //additional debug
		//;//CyU3PDebugPrint(4, "cpu pause \r\n");
	}

	/* Drive the GPIO high to bring the sensor out of reset. */
	//apiRetStatus = CyU3PGpioSetValue(SENSOR_POWER_GPIO, CyTrue);
	apiRetStatus = CyU3PGpioSetValue(SENSOR_RESET_GPIO, CyTrue);
	if (apiRetStatus != CY_U3P_SUCCESS) {
		CyU3PDebugPrint(4, "GPIO Set Value Error, Error Code = %d\n",
				apiRetStatus);
		return;
	}
/* pause the cpu */
	while (i++ < 4){
		CyU3PThreadSleep(600);  // change the value into 100 from 10.
		//;//CyU3PDebugPrint(4, "cpu pause \r\n");
	}

	return;
}
/* Application error handler. */
void
CyFxAppErrorHandler (
        CyU3PReturnStatus_t apiRetStatus    /* API return status */
        )
{
    /* Application failed with the error code apiRetStatus */

    /* Add custom debug or recovery actions here */

    /* Loop indefinitely */
    for (;;)
    {
        /* Thread sleep : 100 ms */
        CyU3PThreadSleep (100);
    }
}
/* Application error handler */
void
CyFxGpifAppErrorHandler (
        CyU3PReturnStatus_t status)
{

    /* Application failed with the error code status */

    /* Add custom debug or recovery actions here */

    /* Loop Indefinitely */
    for (;;)
    {
        /* Thread Sleep : 100 ms */
        CyU3PThreadSleep (100);
    }
}
Ejemplo n.º 11
0
static void step(int direction) {

	const uint8_t full_fwd_step[] = {
		//0355, 0345, 0344, 0354 // low
		0333, 0332, 0322, 0323 // medium
		//0311, 0301, 0300, 0310, // high
	};


	s_index += direction;
	if (s_index < 0) {
		s_index = sizeof(full_fwd_step) - 1;
	} else if (s_index >= sizeof(full_fwd_step)) {
		s_index = 0;
	}
	CyU3PSpiTransmitWords((uint8_t *)&full_fwd_step[s_index], 1);
	CyU3PThreadSleep(10);
}
Ejemplo n.º 12
0
CyBool_t handle_serial_num(uint8_t bReqType, uint16_t wLength) {
  CyU3PI2cPreamble_t preamble;
  uint32_t reg_addr = FX3_PROM_SERIALNUM0_0;
  uint8_t dev_addr = 0x50;
  uint8_t size = 17; // size of prom
  uint16_t status;

  if (wLength != 16) {
    log_error("Bad length=%d \n", wLength);
    return CY_U3P_ERROR_BAD_ARGUMENT;
  }

  switch(bReqType) {
  case 0xC0:
    preamble.length    = 4;
    preamble.buffer[0] = m24xx_get_dev_addr(dev_addr, reg_addr, size, 0);
    preamble.buffer[1] = (uint8_t)(reg_addr >> 8);
    preamble.buffer[2] = (uint8_t)(reg_addr & 0xFF);
    preamble.buffer[3] = m24xx_get_dev_addr(dev_addr, reg_addr, size, 1);
    preamble.ctrlMask  = 0x0004;
    status = CyU3PI2cReceiveBytes (&preamble, gSerialNum, 16, 1);
    if(status) {
      log_error("Error reading serial num from prom (%d)\n", status);
      return CyFalse;
    }
    status = CyU3PUsbSendEP0Data(16, gSerialNum);
    if(status) {
      log_error("Error Sending serial num to EP0 (%d)\n", status);
      return CyFalse;
    }
    return CyTrue;

  case 0x40:
    status = CyU3PUsbGetEP0Data(wLength, gSerialNum, 0);
    if(status) {
      log_error("Error getting serial num from EP0 (%d)\n", status);
      return status;
    }

    preamble.length    = 3;
    preamble.buffer[0] = m24xx_get_dev_addr(dev_addr, reg_addr, size, 0);
    preamble.buffer[1] = (uint8_t)(reg_addr >> 8);
    preamble.buffer[2] = (uint8_t)(reg_addr & 0xFF);
    preamble.ctrlMask  = 0x0000;
    
    status = CyU3PI2cTransmitBytes(&preamble, gSerialNum, 16, 1);
    if(status) {
      log_error("Error writing serial num to I2C (%d)\n", status);
      return CyFalse;
    }
    
    /* Wait for the write to complete. */
    preamble.length = 1;
    status = CyU3PI2cWaitForAck(&preamble, 200);
    if(status) {
      log_error("Error waiting for i2c ACK after writing serial num (%d)\n", status);
      return CyFalse;
    }
    
    /* An additional delay seems to be required after receiving an ACK. */
    CyU3PThreadSleep (1);
    return CyTrue;


  default:
    log_error("Bad ReqType=%d \n", bReqType);
    return CY_U3P_ERROR_BAD_ARGUMENT;
  }
}
Ejemplo n.º 13
0
/* This function initializes the mouse driver application. */
void
CyFxApplnStart ()
{
    uint16_t length;
    CyU3PReturnStatus_t status;
    CyU3PUsbHostEpConfig_t epCfg;

    /* Add EP0 to the scheduler. */
    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof(epCfg));
    epCfg.type = CY_U3P_USB_EP_CONTROL;
    epCfg.mult = 1;
    /* Start off with 8 byte EP0 packet size. */
    epCfg.maxPktSize = 8;
    epCfg.pollingRate = 0;
    epCfg.fullPktSize = 8;
    epCfg.isStreamMode = CyFalse;
    status = CyU3PUsbHostEpAdd (0, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    CyU3PThreadSleep (100);

    /* Get the device descriptor. */
    status = CyFxSendSetupRqt (0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
                               (CY_U3P_USB_DEVICE_DESCR << 8), 0, 8, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the EP0 packet size and update the scheduler. */
    if (glEp0Buffer[7] != 8)
    {
        CyU3PUsbHostEpRemove (0);
        epCfg.maxPktSize = glEp0Buffer[7];
        epCfg.fullPktSize = glEp0Buffer[7];
        status = CyU3PUsbHostEpAdd (0, &epCfg);
        if (status != CY_U3P_SUCCESS)
        {
            goto enum_error;
        }
    }

    /* Read the full device descriptor. */
    status = CyFxSendSetupRqt (0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
                               (CY_U3P_USB_DEVICE_DESCR << 8), 0, 18, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Set the peripheral device address. */
    status = CyFxSendSetupRqt (0x00, CY_U3P_USB_SC_SET_ADDRESS,
                               CY_FX_HOST_PERIPHERAL_ADDRESS, 0, 0, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostSetDeviceAddress (CY_FX_HOST_PERIPHERAL_ADDRESS);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Read first four bytes of configuration descriptor to determine
     * the total length. */
    status = CyFxSendSetupRqt (0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
                               (CY_U3P_USB_CONFIG_DESCR << 8), 0, 4, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the length of the data received. */
    length = CY_U3P_MAKEWORD(glEp0Buffer[3], glEp0Buffer[2]);
    if (length > CY_FX_HOST_EP0_BUFFER_SIZE)
    {
        goto enum_error;
    }

    /* Read the full configuration descriptor. */
    status = CyFxSendSetupRqt (0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
                               (CY_U3P_USB_CONFIG_DESCR << 8), 0, length, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify if this is an HID mouse or MSC device that can be
     * supported. If the device cannot be supported, just disable
     * the port and wait for a new device to be attached. We support
     * only single interface with interface class = HID(0x03),
     * interface sub class = Boot (0x01)
     * and interface protocol = Mouse (0x02).
     * or single interface with interface class = MSC(0x08),
     * interface sub class 0x06 and interface protocol BOT (0x50). */
    if ((glEp0Buffer[5] == 1) && (glEp0Buffer[14] == 0x03) &&
            (glEp0Buffer[15] == 0x01) && (glEp0Buffer[16] == 0x02) &&
            (glEp0Buffer[28] == CY_U3P_USB_ENDPNT_DESCR))
    {
        status = CyFxMouseDriverInit ();
        if (status == CY_U3P_SUCCESS)
        {
            glIsApplnActive = CyTrue;
            glHostOwner = CY_FX_HOST_OWNER_MOUSE_DRIVER;
            return;
        }
    }
    else if ((glEp0Buffer[5] == 1) && (glEp0Buffer[14] == 0x08) &&
             (glEp0Buffer[15] == 0x06) && (glEp0Buffer[16] == 0x50))
    {
        status = CyFxMscDriverInit ();
        if (status == CY_U3P_SUCCESS)
        {
            glIsApplnActive = CyTrue;
            glHostOwner = CY_FX_HOST_OWNER_MSC_DRIVER;
            return;
        }
    }
    else
    {
        /* Do nothing here. Fall-through to disable the USB port.
         * We do not support this device. */
        status = CY_U3P_ERROR_NOT_SUPPORTED;
    }

enum_error:
    /* Remove EP0. and disable the port. */
    glHostOwner = CY_FX_HOST_OWNER_NONE;
    CyU3PUsbHostEpRemove (0);
    CyU3PUsbHostPortDisable ();
    CyU3PDebugPrint (4, "Application start failed with error: %d.\r\n", status);
}
CyU3PReturnStatus_t
CyFxMscDriverInit ()
{
    uint8_t maxLun = 0, i, retry;
    uint16_t length, size, offset;
    CyU3PReturnStatus_t status;
    CyU3PUsbHostEpConfig_t epCfg;
    CyU3PDmaChannelConfig_t dmaCfg;

    /* Read first four bytes of configuration descriptor to determine
     * the total length. */
    status = CyFxSendSetupRqt (0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_CONFIG_DESCR << 8), 0, 4, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the length of the data received. */
    length = CY_U3P_MAKEWORD(glEp0Buffer[3], glEp0Buffer[2]);
    if (length > CY_FX_HOST_EP0_BUFFER_SIZE)
    {
        goto enum_error;
    }

    /* Read the full configuration descriptor. */
    status = CyFxSendSetupRqt (0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_CONFIG_DESCR << 8), 0, length, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the EP characteristics. */
    offset = 0;
    while (offset < length)
    {
        if (glEp0Buffer[offset + 1] == CY_U3P_USB_ENDPNT_DESCR)
        {
            if (glEp0Buffer[offset + 3] != CY_U3P_USB_EP_BULK)
            {
                goto enum_error;
            }

            /* Retreive the information. */
            glMscEpSize = CY_U3P_MAKEWORD(glEp0Buffer[offset + 5],
                    glEp0Buffer[offset + 4]);
            if (glEp0Buffer[offset + 2] & 0x80)
            {
                glMscInEp = glEp0Buffer[offset + 2];
            }
            else
            {
                glMscOutEp = glEp0Buffer[offset + 2];
            }
        }

        /* Advance to next descriptor. */
        offset += glEp0Buffer[offset];
    }

    /* Set the new configuration. */
    status = CyFxSendSetupRqt (0x00, CY_U3P_USB_SC_SET_CONFIGURATION,
            1, 0, 0, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the number of LUNs available.
     * We will use only the first available LUN. */
    status = CyFxSendSetupRqt (0xA1, CY_FX_MSC_GET_MAX_LUN,
            0, 0, 1, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    maxLun = glEp0Buffer[0];

    /* Add the IN endpoint. */
    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof(epCfg));
    epCfg.type = CY_U3P_USB_EP_BULK;
    epCfg.mult = 1;
    epCfg.maxPktSize = glMscEpSize;
    epCfg.pollingRate = 0;
    /* Since DMA buffer sizes can only be multiple of 16 bytes and
     * also since this is an interrupt endpoint where the max data
     * packet size is same as the maxPktSize field, the fullPktSize
     * has to be a multiple of 16 bytes. */
    size = ((glMscEpSize + 0x0F) & ~0x0F);
    epCfg.fullPktSize = size;
    epCfg.isStreamMode = CyFalse;
    status = CyU3PUsbHostEpAdd (glMscInEp, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Add the OUT EP. */
    status = CyU3PUsbHostEpAdd (glMscOutEp, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Create a DMA channel for IN EP. */
    CyU3PMemSet ((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));
    dmaCfg.size = glMscEpSize;
    dmaCfg.count = 0;
    dmaCfg.prodSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_PROD_0 + (0x0F & glMscInEp));
    dmaCfg.consSckId = CY_U3P_CPU_SOCKET_CONS;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = 0;
    dmaCfg.cb = NULL;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;
    status = CyU3PDmaChannelCreate (&glMscInCh, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    /* Create a DMA channel for OUT EP. */
    dmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
    dmaCfg.consSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_0 + (0x0F & glMscOutEp));
    status = CyU3PDmaChannelCreate (&glMscOutCh, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    for (retry = 0; retry < CY_FX_MSC_MAX_RETRY; retry++)
    {
        /* Give some time for the device to initialize. */
        CyU3PThreadSleep (1000);
        for (i = 0; i <= maxLun; i++)
        {
            /* Check if the unit is ready. */
            status = CyFxMscTestUnitReady (maxLun);
            if (status == CY_U3P_SUCCESS)
            {
                glMscTestLun = i;
                break;
            }
        }

        if (status == CY_U3P_SUCCESS)
        {
            break;
        }
    }
    if (status != CY_U3P_SUCCESS)
    {
        glMscTestLun = 0;
        goto app_error;
    }

    /* Read the device capacity. */
    status = CyFxMscReadCapacity (glMscTestLun);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    glMscIsActive = CyTrue;
    return status;

app_error:
    CyU3PDmaChannelDestroy (&glMscInCh);
    if (glMscInEp != 0)
    {
        CyU3PUsbHostEpRemove (glMscInEp);
        glMscInEp = 0;
    }
    CyU3PDmaChannelDestroy (&glMscOutCh);
    if (glMscOutEp != 0)
    {
        CyU3PUsbHostEpRemove (glMscOutEp);
        glMscOutEp = 0;
    }

    glMscEpSize = 0;
    glMscSectorSize = 0;
    glMscCapacity = 0;
    glMscTestLun = 0;
    glMscTestSector = 0;
    glTimerCount = 0;

enum_error:
    return CY_U3P_ERROR_FAILURE;
}
Ejemplo n.º 15
0
void AR0330_Power_Up(void) {
	CyU3PDebugPrint(4, "AR0330_Power_Up\r\n");

	// set test mode
#if defined(TEST_MODE)
	sensor_write(0x301E, 0x00a8);            // data_pedestal
	sensor_write(0x3070, 0x0001);            // set test mode

#define pedestal 0x80
#define full (0x0fff - pedestal)
#define low  (0x001f + pedestal)

#if TEST_MODE == TEST_MODE_IDENTIFY
	sensor_write(0x3072, 0x01aa + pedestal); // red
	sensor_write(0x3074, 0x02bb + pedestal); // green (in red row)
	sensor_write(0x3076, 0x03cc + pedestal); // blue
	sensor_write(0x3078, 0x04dd + pedestal); // green (in blue row)

#elif TEST_MODE == TEST_MODE_RED
	sensor_write(0x3072, full);              // red
	sensor_write(0x3074, low);               // green (in red row)
	sensor_write(0x3076, low);               // blue
	sensor_write(0x3078, low);               // green (in blue row)

#elif TEST_MODE == TEST_MODE_GREEN_RED
	sensor_write(0x3072, low);               // red
	sensor_write(0x3074, full);              // green (in red row)
	sensor_write(0x3076, low);               // blue
	sensor_write(0x3078, low);               // green (in blue row)

#elif TEST_MODE == TEST_MODE_BLUE
	sensor_write(0x3072, low);               // red
	sensor_write(0x3074, low);               // green (in red row)
	sensor_write(0x3076, full);              // blue
	sensor_write(0x3078, low);               // green (in blue row)

#elif TEST_MODE == TEST_MODE_GREEN_BLUE
	sensor_write(0x3072, low);               // red
	sensor_write(0x3074, low);               // green (in red row)
	sensor_write(0x3076, low);               // blue
	sensor_write(0x3078, full);              // green (in blue row)

#elif TEST_MODE == TEST_MODE_GREEN_ALL
	sensor_write(0x3072, low);               // red
	sensor_write(0x3074, full);              // green (in red row)
	sensor_write(0x3076, low);               // blue
	sensor_write(0x3078, full);              // green (in blue row)

#elif TEST_MODE == TEST_MODE_COLOUR_BARS
	sensor_write(0x3070, 0x0002);            // set test mode

#else
#error "undefined test mode"
#endif

#else
	// normal mode
	sensor_write(0x3070, 0x0000);            // disable test mode
#endif

	// start streaming
	//sensor_write(0x301a, 0x005c);
	sensor_write(0x301a, 0x0054);

	CyU3PThreadSleep(10);

	AR0330_Debug();
}
/* This function initializes the mouse driver application. */
static void
CyFxApplnStart ()
{
    uint16_t length, size, offset;
    CyU3PDmaBuffer_t buf_p;
    CyU3PReturnStatus_t status;
    CyU3PUsbHostEpConfig_t epCfg;
    CyU3PDmaChannelConfig_t dmaCfg;
    CyU3PUsbHostEpStatus_t epStatus;

    /* Add EP0 to the scheduler. */
    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof(epCfg));
    epCfg.type = CY_U3P_USB_EP_CONTROL;
    epCfg.mult = 1;
    /* Start off with 8 byte EP0 packet size. */
    epCfg.maxPktSize = 8;
    epCfg.pollingRate = 0;
    epCfg.fullPktSize = 8;
    epCfg.isStreamMode = CyFalse;
    status = CyU3PUsbHostEpAdd (0, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    CyU3PThreadSleep (100);
    /* Get the device descriptor. */
    CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_DEVICE_DESCR << 8), 0, 8);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the EP0 packet size and update the scheduler. */
    if (glEp0Buffer[7] != 8)
    {
        status = CyU3PUsbHostEpRemove (0);
        if (status != CY_U3P_SUCCESS)
        {
            goto enum_error;
        }
        /* Update the correct size. */
        epCfg.maxPktSize = glEp0Buffer[7];
        epCfg.fullPktSize = glEp0Buffer[7];
        status = CyU3PUsbHostEpAdd (0, &epCfg);
        if (status != CY_U3P_SUCCESS)
        {
            goto enum_error;
        }
    }

    /* Read the full device descriptor. */
    CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_DEVICE_DESCR << 8), 0, 18);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Check for the VID and PID of the attached peripheral. */
    if ((CY_U3P_MAKEWORD(glEp0Buffer[9], glEp0Buffer[8]) != CY_FX_HOST_PERIPHERAL_VID) ||
            (CY_U3P_MAKEWORD(glEp0Buffer[11], glEp0Buffer[10]) != CY_FX_HOST_PERIPHERAL_PID))
    {
        status = CY_U3P_ERROR_NOT_SUPPORTED;
        goto enum_error;
    }

    /* Check for device class, sub-class and protocol all of which has to be zero. */
    if ((glEp0Buffer[4] != 0) || (glEp0Buffer[5] != 0) || (glEp0Buffer[6] != 0))
    {
        status = CY_U3P_ERROR_NOT_SUPPORTED;
        goto enum_error;
    }

    /* Set the peripheral device address. */
    CyFxFormatSetupRqt (glSetupPkt, 0x00, CY_U3P_USB_SC_SET_ADDRESS,
            CY_FX_HOST_PERIPHERAL_ADDRESS, 0, 0);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostSetDeviceAddress (CY_FX_HOST_PERIPHERAL_ADDRESS);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Read the OTG descriptor to identify its characteristics.
     * Do this only if we are not already in role change. */
    glIsHnpSupported = CyFalse;
    if (!CyU3POtgIsHnpEnabled ())
    {
        CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
                (CY_U3P_USB_OTG_DESCR << 8), 0, 5);
        status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
        if (status != CY_U3P_SUCCESS)
        {
            goto enum_error;
        }
        status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
                CY_FX_HOST_EP0_WAIT_TIMEOUT);
        /* If the device does not support OTG, the request will be stalled. */
        if ((status == CY_U3P_SUCCESS) && (glEp0Buffer[2] & 0x02))
        {
            /* Let the device know that the host is HNP capable. */
            CyFxFormatSetupRqt (glSetupPkt, 0x00, CY_U3P_USB_SC_SET_FEATURE,
                    CY_U3P_USB2_OTG_A_HNP_SUPPORT, 0, 0);
            status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
            if (status != CY_U3P_SUCCESS)
            {
                goto enum_error;
            }
            status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
                    CY_FX_HOST_EP0_WAIT_TIMEOUT);

        }
        if (status == CY_U3P_SUCCESS)
        {
            glIsHnpSupported = CyTrue;
        }
    }

    /* Read first four bytes of configuration descriptor to determine
     * the total length. */
    CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_CONFIG_DESCR << 8), 0, 4);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Identify the length of the data received. */
    length = CY_U3P_MAKEWORD(glEp0Buffer[3], glEp0Buffer[2]);
    if (length > CY_FX_HOST_EP0_BUFFER_SIZE)
    {
        goto enum_error;
    }

    /* Read the full configuration descriptor. */
    CyFxFormatSetupRqt (glSetupPkt, 0x80, CY_U3P_USB_SC_GET_DESCRIPTOR,
            (CY_U3P_USB_CONFIG_DESCR << 8), 0, length);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Check if the device can be supported. Number of interfaces should be 1,
     * the intreface class must be vendor (0xFF) and the subclass and protocol
     * must be zero. The number of endpoints must be two. Also the endpoints
     * should be bulk. */
    if ((glEp0Buffer[5] != 1) || (glEp0Buffer[14] != 0xFF) ||
            (glEp0Buffer[15] != 0x00) || (glEp0Buffer[16] != 0x00) ||
            (glEp0Buffer[13] != 2))
    {
        status = CY_U3P_ERROR_NOT_SUPPORTED;
        goto enum_error;
    }

    /* Identify the EP characteristics. */
    offset = 0;
    while (offset < length)
    {
        if (glEp0Buffer[offset + 1] == CY_U3P_USB_ENDPNT_DESCR)
        {
            if (glEp0Buffer[offset + 3] != CY_U3P_USB_EP_BULK)
            {
                status = CY_U3P_ERROR_NOT_SUPPORTED;
                goto enum_error;
            }

            /* Retreive the information. */
            glHostEpSize = CY_U3P_MAKEWORD(glEp0Buffer[offset + 5],
                    glEp0Buffer[offset + 4]);
            if (glEp0Buffer[offset + 2] & 0x80)
            {
                glHostInEp = glEp0Buffer[offset + 2];
            }
            else
            {
                glHostOutEp = glEp0Buffer[offset + 2];
            }
        }

        /* Advance to next descriptor. */
        offset += glEp0Buffer[offset];
    }

    /* If there is any error in the configuration abort. */
    if ((glHostOutEp == 0) || (glHostInEp == 0))
    {
        status = CY_U3P_ERROR_NOT_SUPPORTED;
        goto enum_error;
    }

    /* Set the new configuration. */
    CyFxFormatSetupRqt (glSetupPkt, 0x00, CY_U3P_USB_SC_SET_CONFIGURATION, 1, 0, 0);
    status = CyU3PUsbHostSendSetupRqt (glSetupPkt, glEp0Buffer);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpWaitForCompletion (0, &epStatus,
            CY_FX_HOST_EP0_WAIT_TIMEOUT);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }

    /* Initialize the loopback application. */
    CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof(epCfg));
    epCfg.type = CY_U3P_USB_EP_BULK;
    epCfg.mult = 1;
    epCfg.maxPktSize = glHostEpSize;
    epCfg.pollingRate = 0;
    size = ((glHostEpSize + 0x0F) & ~0x0F);
    epCfg.fullPktSize = glHostEpSize;
    epCfg.isStreamMode = CyFalse;
    status = CyU3PUsbHostEpAdd (glHostOutEp, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto enum_error;
    }
    status = CyU3PUsbHostEpAdd (glHostInEp, &epCfg);
    if (status != CY_U3P_SUCCESS)
    {
        glHostInEp = 0;
        goto app_error;
    }

    /* Reset counter to zero. */
    glDMARxCount = 0;
    glDMATxCount = 0;

    /* Create a DMA channels for IN and OUT directions. */
    CyU3PMemSet ((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));
    dmaCfg.size = size;
    dmaCfg.count = CY_FX_HOST_DMA_BUF_COUNT;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;

    dmaCfg.prodSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_PROD_0 + (0x0F & glHostInEp));
    dmaCfg.consSckId = CY_U3P_CPU_SOCKET_CONS;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;
    dmaCfg.cb = CyFxHostDmaCb;
    status = CyU3PDmaChannelCreate (&glHostInCh, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    dmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
    dmaCfg.consSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_0 + (0x0F & glHostOutEp));
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.notification = CY_U3P_DMA_CB_CONS_EVENT;
    dmaCfg.cb = CyFxHostDmaCb;
    status = CyU3PDmaChannelCreate (&glHostOutCh, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    /* Set infinite transfer on both the channels. */
    status = CyU3PDmaChannelSetXfer (&glHostInCh, 0);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }
    status = CyU3PDmaChannelSetXfer (&glHostOutCh, 0);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    /* Pre-load all OUT buffers with fixed data. */
    for (offset = 0; offset < CY_FX_HOST_DMA_BUF_COUNT; offset++)
    {
        status = CyU3PDmaChannelGetBuffer (&glHostOutCh, &buf_p, CYU3P_NO_WAIT);
        if (status != CY_U3P_SUCCESS)
        {
            goto app_error;
        }
        CyU3PMemSet (buf_p.buffer, (uint8_t)CY_FX_HOST_DATA_BYTE, glHostEpSize);
        status = CyU3PDmaChannelCommitBuffer (&glHostOutCh, glHostEpSize, 0);
        if (status != CY_U3P_SUCCESS)
        {
            goto app_error;
        }
    }

    /* Queue a single read and single write request. */
    status = CyU3PUsbHostEpSetXfer (glHostInEp, CY_U3P_USB_HOST_EPXFER_NORMAL, glHostEpSize);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }
    status = CyU3PUsbHostEpSetXfer (glHostOutEp, CY_U3P_USB_HOST_EPXFER_NORMAL, glHostEpSize);
    if (status != CY_U3P_SUCCESS)
    {
        goto app_error;
    }

    glTimerCount = 0;
    glIsApplnActive = CyTrue;
    glIsHnp = CyFalse;
    glDoHnp = CyFalse;

    if (glIsHnpSupported)
    {
        CyU3PDebugPrint (4, "USB bulk loopback host mode operation started with HNP enabled.\r\n");
    }
    else
    {
        CyU3PDebugPrint (4, "USB bulk loopback host mode operation started with HNP disabled.\r\n");
    }

    return;

app_error:
    CyU3PDmaChannelDestroy (&glHostInCh);
    if (glHostInEp != 0)
    {
        CyU3PUsbHostEpRemove (glHostInEp);
        glHostInEp = 0;
    }
    CyU3PDmaChannelDestroy (&glHostOutCh);
    if (glHostOutEp != 0)
    {
        CyU3PUsbHostEpRemove (glHostOutEp);
        glHostOutEp = 0;
    }

enum_error:
    /* Remove EP0. and disable the port. */
    CyU3PUsbHostEpRemove (0);
    glHostEpSize = 0;
    CyU3PUsbHostPortDisable ();
    CyU3PDebugPrint (4, "Host mode application start failed with error: %d.\r\n", status);
}