299 lines
9 KiB
C
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);
|
|
}
|
|
}
|