AT32F435_437_Firmware_Library/project/at_start_f435/examples/acc/calibration/src/main.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);
}
/**
* @}
*/
/**
* @}
*/