377 lines
9.3 KiB
C
377 lines
9.3 KiB
C
/**
|
|
**************************************************************************
|
|
* @file main.c
|
|
* @brief main program
|
|
**************************************************************************
|
|
* Copyright notice & Disclaimer
|
|
*
|
|
* The software Board Support Package (BSP) that is made available to
|
|
* download from Artery official website is the copyrighted work of Artery.
|
|
* Artery authorizes customers to use, copy, and distribute the BSP
|
|
* software and its related documentation for the purpose of design and
|
|
* development in conjunction with Artery microcontrollers. Use of the
|
|
* software is governed by this copyright notice and the following disclaimer.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
|
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
|
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
|
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
|
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
|
*
|
|
**************************************************************************
|
|
*/
|
|
|
|
#include "at32f435_437_board.h"
|
|
#include "at32f435_437_clock.h"
|
|
|
|
#include "usb_conf.h"
|
|
#include "usb_core.h"
|
|
#include "usbd_int.h"
|
|
#include "cdc_class.h"
|
|
#include "cdc_desc.h"
|
|
|
|
/** @addtogroup AT32F435_periph_examples
|
|
* @{
|
|
*/
|
|
|
|
/** @addtogroup 435_ACC_calibration ACC_calibration
|
|
* @{
|
|
*/
|
|
|
|
/* usb global struct define */
|
|
otg_core_type otg_core_struct;
|
|
uint8_t usb_buffer[256];
|
|
|
|
void usb_clock48m_select(usb_clk48_s clk_s);
|
|
void usb_gpio_config(void);
|
|
void usb_low_power_wakeup_config(void);
|
|
|
|
/* ACC_CAL : the step is incremented or decremented by one, the hickcal will be incremented or decremented by 40khz */
|
|
/* ACC_TRIM : the step is incremented or decremented by one, the hicktrim will be incremented or decremented by 20khz */
|
|
/* define ACC_TRIM in order to get higher calibration accuracy */
|
|
//#define ACC_CAL
|
|
#define ACC_TRIM
|
|
|
|
uint32_t acc_c2_value = 0;
|
|
|
|
/**
|
|
* @brief this function config gpio.
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void usb_gpio_config(void)
|
|
{
|
|
gpio_init_type gpio_init_struct;
|
|
|
|
crm_periph_clock_enable(OTG_PIN_GPIO_CLOCK, TRUE);
|
|
gpio_default_para_init(&gpio_init_struct);
|
|
|
|
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
|
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
|
|
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
|
|
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
|
|
|
|
/* dp and dm */
|
|
gpio_init_struct.gpio_pins = OTG_PIN_DP | OTG_PIN_DM;
|
|
gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
|
|
|
|
gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_DP_SOURCE, OTG_PIN_MUX);
|
|
gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_DM_SOURCE, OTG_PIN_MUX);
|
|
|
|
#ifdef USB_SOF_OUTPUT_ENABLE
|
|
crm_periph_clock_enable(OTG_PIN_SOF_GPIO_CLOCK, TRUE);
|
|
gpio_init_struct.gpio_pins = OTG_PIN_SOF;
|
|
gpio_init(OTG_PIN_SOF_GPIO, &gpio_init_struct);
|
|
gpio_pin_mux_config(OTG_PIN_SOF_GPIO, OTG_PIN_SOF_SOURCE, OTG_PIN_MUX);
|
|
#endif
|
|
|
|
/* otgfs use vbus pin */
|
|
#ifndef USB_VBUS_IGNORE
|
|
gpio_init_struct.gpio_pins = OTG_PIN_VBUS;
|
|
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
|
|
gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_VBUS_SOURCE, OTG_PIN_MUX);
|
|
gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
|
|
#endif
|
|
}
|
|
#ifdef USB_LOW_POWER_WAKUP
|
|
/**
|
|
* @brief usb low power wakeup interrupt config
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void usb_low_power_wakeup_config(void)
|
|
{
|
|
exint_init_type exint_init_struct;
|
|
|
|
crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);
|
|
exint_default_para_init(&exint_init_struct);
|
|
|
|
exint_init_struct.line_enable = TRUE;
|
|
exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
|
|
exint_init_struct.line_select = OTG_WKUP_EXINT_LINE;
|
|
exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
|
|
exint_init(&exint_init_struct);
|
|
|
|
nvic_irq_enable(OTG_WKUP_IRQ, 0, 0);
|
|
}
|
|
|
|
/**
|
|
* @brief this function handles otgfs wakup interrupt.
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void OTG_WKUP_HANDLER(void)
|
|
{
|
|
exint_flag_clear(OTG_WKUP_EXINT_LINE);
|
|
}
|
|
|
|
#endif
|
|
|
|
/**
|
|
* @brief this function handles otgfs interrupt.
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void OTG_IRQ_HANDLER(void)
|
|
{
|
|
usbd_irq_handler(&otg_core_struct);
|
|
}
|
|
/**
|
|
* @brief acc interrupt handler
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void ACC_IRQHandler(void)
|
|
{
|
|
if(acc_flag_get(ACC_CALRDY_FLAG) != RESET)
|
|
{
|
|
at32_led_toggle(LED2);
|
|
|
|
/* clear acc calibration ready flag */
|
|
acc_flag_clear(ACC_CALRDY_FLAG);
|
|
}
|
|
if(acc_flag_get(ACC_RSLOST_FLAG) != RESET)
|
|
{
|
|
at32_led_toggle(LED3);
|
|
|
|
/* clear acc reference signal lost flag */
|
|
acc_flag_clear(ACC_RSLOST_FLAG);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief main function.
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
int main(void)
|
|
{
|
|
uint16_t data_len;
|
|
|
|
uint8_t send_zero_packet = 0;
|
|
|
|
uint32_t timeout;
|
|
|
|
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
|
|
|
|
system_clock_config();
|
|
|
|
at32_board_init();
|
|
|
|
usb_gpio_config();
|
|
#ifdef USB_LOW_POWER_WAKUP
|
|
usb_low_power_wakeup_config();
|
|
#endif
|
|
|
|
/* enable otgfs clock */
|
|
crm_periph_clock_enable(OTG_CLOCK, TRUE);
|
|
|
|
/* select usb 48m clcok source */
|
|
usb_clock48m_select(USB_CLK_HICK);
|
|
|
|
/* enable otgfs irq */
|
|
nvic_irq_enable(OTG_IRQ, 0, 0);
|
|
|
|
/* init usb */
|
|
usbd_init(&otg_core_struct,
|
|
USB_FULL_SPEED_CORE_ID,
|
|
USB_ID,
|
|
&cdc_class_handler,
|
|
&cdc_desc_handler);
|
|
|
|
|
|
/* acc config */
|
|
crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE);
|
|
|
|
/* enable the acc calibration ready interrupt */
|
|
acc_interrupt_enable(ACC_CALRDYIEN_INT, TRUE);
|
|
|
|
/* enable the acc reference signal lost interrupt */
|
|
acc_interrupt_enable(ACC_EIEN_INT, TRUE);
|
|
|
|
/* config nvic for acc int */
|
|
nvic_irq_enable(ACC_IRQn, 1, 0);
|
|
|
|
/* update the c1\c2\c3 value */
|
|
acc_c2_value = 8000;
|
|
#ifdef ACC_CAL
|
|
acc_write_c1(acc_c2_value - 20);
|
|
acc_write_c2(acc_c2_value);
|
|
acc_write_c3(acc_c2_value + 20);
|
|
#else
|
|
acc_write_c1(acc_c2_value - 10);
|
|
acc_write_c2(acc_c2_value);
|
|
acc_write_c3(acc_c2_value + 10);
|
|
#endif
|
|
|
|
#if (USB_ID == 0)
|
|
acc_sof_select(ACC_SOF_OTG1);
|
|
#else
|
|
acc_sof_select(ACC_SOF_OTG2);
|
|
#endif
|
|
|
|
/* open acc calibration */
|
|
#if defined(ACC_CAL)
|
|
acc_calibration_mode_enable(ACC_CAL_HICKCAL, TRUE);
|
|
#elif defined(ACC_TRIM)
|
|
acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE);
|
|
#endif
|
|
|
|
while(1)
|
|
{
|
|
/* get usb vcp receive data */
|
|
data_len = usb_vcp_get_rxdata(&otg_core_struct.dev, usb_buffer);
|
|
|
|
if(data_len > 0 || send_zero_packet == 1)
|
|
{
|
|
|
|
/* bulk transfer is complete when the endpoint does one of the following
|
|
1 has transferred exactly the amount of data expected
|
|
2 transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet
|
|
*/
|
|
if(data_len > 0)
|
|
send_zero_packet = 1;
|
|
|
|
if(data_len == 0)
|
|
send_zero_packet = 0;
|
|
|
|
timeout = 5000000;
|
|
do
|
|
{
|
|
/* send data to host */
|
|
if(usb_vcp_send_data(&otg_core_struct.dev, usb_buffer, data_len) == SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
}while(timeout --);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief usb 48M clock select
|
|
* @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
|
|
* @retval none
|
|
*/
|
|
void usb_clock48m_select(usb_clk48_s clk_s)
|
|
{
|
|
if(clk_s == USB_CLK_HICK)
|
|
{
|
|
crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK);
|
|
}
|
|
else
|
|
{
|
|
switch(system_core_clock)
|
|
{
|
|
/* 48MHz */
|
|
case 48000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_1);
|
|
break;
|
|
|
|
/* 72MHz */
|
|
case 72000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_1_5);
|
|
break;
|
|
|
|
/* 96MHz */
|
|
case 96000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_2);
|
|
break;
|
|
|
|
/* 120MHz */
|
|
case 120000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_2_5);
|
|
break;
|
|
|
|
/* 144MHz */
|
|
case 144000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_3);
|
|
break;
|
|
|
|
/* 168MHz */
|
|
case 168000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_3_5);
|
|
break;
|
|
|
|
/* 192MHz */
|
|
case 192000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_4);
|
|
break;
|
|
|
|
/* 216MHz */
|
|
case 216000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_4_5);
|
|
break;
|
|
|
|
/* 240MHz */
|
|
case 240000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_5);
|
|
break;
|
|
|
|
/* 264MHz */
|
|
case 264000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_5_5);
|
|
break;
|
|
|
|
/* 288MHz */
|
|
case 288000000:
|
|
crm_usb_clock_div_set(CRM_USB_DIV_6);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief usb delay millisecond function.
|
|
* @param ms: number of millisecond delay
|
|
* @retval none
|
|
*/
|
|
void usb_delay_ms(uint32_t ms)
|
|
{
|
|
/* user can define self delay function */
|
|
delay_ms(ms);
|
|
}
|
|
|
|
/**
|
|
* @brief usb delay microsecond function.
|
|
* @param us: number of microsecond delay
|
|
* @retval none
|
|
*/
|
|
void usb_delay_us(uint32_t us)
|
|
{
|
|
delay_us(us);
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|