xmclib/ThirdPartyLibraries/USBlib/Examples/Device/WinUSB/main.c
2024-10-17 17:09:59 +02:00

299 lines
9 KiB
C

/*
* Copyright (C) 2014 Infineon Technologies AG. All rights reserved.
*
* Infineon Technologies AG (Infineon) is supplying this software for use with
* Infineon's microcontrollers.
* This file can be freely distributed within development tools that are
* supporting such microcontrollers.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*/
/**
* @file
* @date 18 Feb, 2015
* @version 1.0.0
*
* @brief USB demo example
*
* The example implements a communication through WINUSB with a Host (Computer).
*
* History <br>
*
* Version 1.0.0 Initial <br>
*
*/
/*********************************************************************************************************************
* HEADER FILES
********************************************************************************************************************/
#include "WinUSB.h"
/*********************************************************************************************************************
* MACROS
********************************************************************************************************************/
/* Pin P14.1 is measured and converted */
#define CHANNEL_NUMBER (1U)
#define VADC_GROUP_PTR (VADC_G0)
/* Register result */
#define RES_REG_NUMBER (0)
/* IO expander address on HMI board */
#define HMI_PCA9502_ADDRESS (0x9A)
#define IO_EXPANDER_ADDRESS HMI_PCA9502_ADDRESS
/* PCA9502 register address */
typedef enum PCA9502_REGADDR {
IO_DIR = 0xA << 3,
IO_STATE = 0xB << 3,
IO_INTE = 0xC << 3,
IO_CTRL = 0xE << 3
} PCA9502_REGADDR_t;
#define SDA_PIN P2_14
#define SCL_PIN P5_8
/*********************************************************************************************************************
* GLOBAL DATA
********************************************************************************************************************/
/* SCU configuration */
XMC_SCU_CLOCK_CONFIG_t clock_config =
{
.syspll_config.p_div = 2,
.syspll_config.n_div = 80,
.syspll_config.k_div = 4,
.syspll_config.mode = XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL,
.syspll_config.clksrc = XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP,
.enable_oschp = true,
.calibration_mode = XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_FACTORY,
.fsys_clksrc = XMC_SCU_CLOCK_SYSCLKSRC_PLL,
.fsys_clkdiv = 1,
.fcpu_clkdiv = 1,
.fccu_clkdiv = 1,
.fperipheral_clkdiv = 1
};
void SystemCoreClockSetup(void)
{
/* Setup settings for USB clock */
XMC_SCU_CLOCK_Init(&clock_config);
XMC_SCU_CLOCK_EnableUsbPll();
XMC_SCU_CLOCK_StartUsbPll(2, 64);
XMC_SCU_CLOCK_SetUsbClockDivider(4);
XMC_SCU_CLOCK_SetUsbClockSource(XMC_SCU_CLOCK_USBCLKSRC_USBPLL);
XMC_SCU_CLOCK_EnableClock(XMC_SCU_CLOCK_USB);
SystemCoreClockUpdate();
}
/* VADC configuration */
/* Initialization data of VADC Global resources */
XMC_VADC_GLOBAL_CONFIG_t g_global_config =
{
.clock_config =
{
.analog_clock_divider = 3,
.msb_conversion_clock = 0,
.arbiter_clock_divider = 1
},
};
/* Initialization data of a VADC group */
XMC_VADC_GROUP_CONFIG_t g_group_config =
{
.class1 =
{
.conversion_mode_standard = XMC_VADC_CONVMODE_12BIT,
.sample_time_std_conv = 3U,
}
};
XMC_VADC_QUEUE_CONFIG_t g_queue_config;
/* Channel configuration data */
XMC_VADC_CHANNEL_CONFIG_t g_channel_config =
{
.input_class = XMC_VADC_CHANNEL_CONV_GROUP_CLASS1,
.result_reg_number = RES_REG_NUMBER,
.alias_channel = -1
};
/* Result configuration data */
XMC_VADC_RESULT_CONFIG_t g_result_config =
{
.wait_for_read_mode = true
};
/* Queue Entry */
XMC_VADC_QUEUE_ENTRY_t g_queue_entry =
{
.channel_num = CHANNEL_NUMBER,
.refill_needed = true, /* Refill is needed */
.generate_interrupt = false, /* Interrupt generation is needed */
.external_trigger = false /* External trigger is required */
};
/* I2C configuration */
XMC_I2C_CH_CONFIG_t i2c_cfg =
{
.baudrate = 100000U,
};
/*********************************************************************************************************************
* MAIN APPLICATION
********************************************************************************************************************/
void LED_SetIODir(uint8_t dir)
{
/* Start I2C transaction */
XMC_I2C_CH_MasterStart(XMC_I2C1_CH0, IO_EXPANDER_ADDRESS, XMC_I2C_CH_CMD_WRITE);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
/* Transmit IO_DIR */
XMC_I2C_CH_MasterTransmit(XMC_I2C1_CH0, IO_DIR);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
/* Transmit Direction*/
XMC_I2C_CH_MasterTransmit(XMC_I2C1_CH0, dir);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
/* Finish I2C transaction */
XMC_I2C_CH_MasterStop(XMC_I2C1_CH0);
}
void LED_SetIOState(uint8_t state)
{
/* Start I2C transaction */
XMC_I2C_CH_MasterStart(XMC_I2C1_CH0, IO_EXPANDER_ADDRESS, XMC_I2C_CH_CMD_WRITE);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
/* Write register address */
XMC_I2C_CH_MasterTransmit(XMC_I2C1_CH0, IO_STATE);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
/* Write IO state */
XMC_I2C_CH_MasterTransmit(XMC_I2C1_CH0, state);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
/* Finish I2C transaction */
XMC_I2C_CH_MasterStop(XMC_I2C1_CH0);
}
/**
* Main program entry point. This routine configures the hardware required by
* the application, then enters a loop to run the application tasks in sequence.
*/
int main(void)
{
/* Variables Initialization*/
XMC_VADC_RESULT_SIZE_t adc;
uint8_t led = 0;
/* VADC Initialization */
/* Initialize the VADC global registers */
XMC_VADC_GLOBAL_Init(VADC, &g_global_config);
/* Configure a conversion kernel */
XMC_VADC_GROUP_Init(VADC_GROUP_PTR, &g_group_config);
XMC_VADC_GROUP_QueueInit(VADC_GROUP_PTR, &g_queue_config);
/* Configure a channel belonging to the aforesaid conversion kernel */
XMC_VADC_GROUP_ChannelInit(VADC_GROUP_PTR,CHANNEL_NUMBER, &g_channel_config);
/* Configure a result resource belonging to the aforesaid conversion kernel */
XMC_VADC_GROUP_ResultInit(VADC_GROUP_PTR, RES_REG_NUMBER, &g_result_config);
/* Add the channel to the queue */
XMC_VADC_GROUP_QueueInsertChannel(VADC_GROUP_PTR, g_queue_entry);
/* Enable the analog converters */
XMC_VADC_GROUP_SetPowerMode(VADC_GROUP_PTR, XMC_VADC_GROUP_POWERMODE_NORMAL);
/* Perform calibration of the converter */
XMC_VADC_GLOBAL_StartupCalibration(VADC);
/* I2C Initialization */
XMC_I2C_CH_Init(XMC_I2C1_CH0, &i2c_cfg);
XMC_I2C_CH_SetInputSource(XMC_I2C1_CH0, XMC_I2C_CH_INPUT_SDA, USIC1_C0_DX0_P2_14);
XMC_I2C_CH_SetInputSource(XMC_I2C1_CH0, XMC_I2C_CH_INPUT_SCL, USIC1_C0_DX1_P5_8);
XMC_I2C_CH_Start(XMC_I2C1_CH0);
/* GPIO Initialization */
XMC_GPIO_SetMode(SCL_PIN, XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT2);
XMC_GPIO_SetMode(SDA_PIN, XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT2);
/* USB Initialization */
USB_Init();
/*Set IO directions on the HMI OLED board to output mode*/
LED_SetIODir(0xff);
/*Turn ON the LEDs on OLED board*/
LED_SetIOState(0x00);
/* Trigger next conversion */
XMC_VADC_GROUP_QueueTriggerConversion(VADC_GROUP_PTR);
while (1)
{
/* Check for the reception of LED state info from USB host */
if (USBD_WINUSB_BytesReceived(WinUSBInfo.Config.OutEndpoint.Address))
{
/* Read the data received */
USBD_WINUSB_ReadData(WinUSBInfo.Config.OutEndpoint.Address,&led,1);
LED_SetIOState(led);
}
/* Get the ADC result according to Pot value */
adc = XMC_VADC_GROUP_GetResult(VADC_GROUP_PTR, RES_REG_NUMBER);
/*Send the adc result to USB host*/
USBD_WINUSB_WriteData(WinUSBInfo.Config.InEndpoint.Address,&adc,2);
}
}