633 lines
21 KiB
C
633 lines
21 KiB
C
/******************** (C) COPYRIGHT 2020 GEEKIMU *******************************
|
||
* File Name : gpio.c
|
||
* Current Version : V2.0 & ST 3.5.0
|
||
* Author : zhanli 719901725@qq.com & JustFeng.
|
||
* Date of Issued : 2017.1.11 zhanli : Create
|
||
* Comments : USB feature reports
|
||
********************************************************************************/
|
||
#include "feature_config.h"
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include "platform_config.h"
|
||
#include "usb_core.h"
|
||
#include "usb_init.h"
|
||
#include "calibrate.h"
|
||
//#include "eeprom.h"
|
||
#include "gpio.h"
|
||
#include "sys.h"
|
||
#include "stmflash.h"
|
||
|
||
enum {
|
||
FEATURE_CONFIG = 2,
|
||
FEATURE_CALIBRATE = 3,
|
||
FEATURE_RANGE = 4,
|
||
FEATURE_REGISTER = 5,
|
||
FEATURE_DFU = 6,
|
||
FEATURE_GPIO = 7,
|
||
FEATURE_KEEP_ALIVE = 8,
|
||
FEATURE_DISPLAY_INFO = 9,
|
||
FEATURE_SERIAL = 10,
|
||
FEATURE_OFFSET = 11
|
||
};
|
||
|
||
// Report ID and Command ID
|
||
#define FEATURE_HEADER_SIZE 3
|
||
|
||
#define FEATURE_CONFIG_SIZE (FEATURE_HEADER_SIZE+4)
|
||
#define FEATURE_CALIBRATE_SIZE (FEATURE_HEADER_SIZE+CALIBRATION_SIZE)
|
||
#define FEATURE_RANGE_SIZE (FEATURE_HEADER_SIZE+5)
|
||
#define FEATURE_REGISTER_SIZE (FEATURE_HEADER_SIZE+3)
|
||
#define FEATURE_DFU_SIZE (FEATURE_HEADER_SIZE+1)
|
||
#define FEATURE_GPIO_SIZE (FEATURE_HEADER_SIZE+2)
|
||
#define FEATURE_KEEP_ALIVE_SIZE (FEATURE_HEADER_SIZE+2)
|
||
#define FEATURE_DISPLAY_INFO_SIZE (FEATURE_HEADER_SIZE+53)
|
||
#define FEATURE_SERIAL_SIZE (FEATURE_HEADER_SIZE+12)
|
||
#define FEATURE_OFFSET_SIZE (FEATURE_HEADER_SIZE+49)
|
||
#define FLASH_DFU_FLASH 0X0800FF48 //Ä£ÄâEEPROMµÄÓÃÓÚDFUµØÖ·
|
||
|
||
#define FEATURE_OFFSET_SET_GYRO 1
|
||
#define FEATURE_OFFSET_SET_ACC 2
|
||
#define FEATURE_OFFSET_SET_MAG 3
|
||
#define FEATURE_OFFSET_SET_LED 4
|
||
#define FEATURE_OFFSET_GET_GYRO 0x11
|
||
#define FEATURE_OFFSET_GET_ACC 0x12
|
||
#define FEATURE_OFFSET_GET_MAG 0x13
|
||
|
||
feature_config_s global_config = {0};
|
||
bool global_config_set = 0;
|
||
feature_calibrate_s global_calibrate = {0};
|
||
bool global_calibrate_set = 0;
|
||
feature_range_s global_range = {0};
|
||
bool global_range_set = 0;
|
||
feature_register_s global_reg = {0};
|
||
bool global_reg_set = 0;
|
||
feature_dfu_s global_dfu = {0};
|
||
bool global_dfu_set = 0;
|
||
feature_gpio_s global_gpio = {0};
|
||
feature_keep_alive_s global_keep_alive = {0};
|
||
bool global_keep_alive_set = 0;
|
||
feature_display_info_s global_display_info = {0};
|
||
feature_serial_s global_serial = {0};
|
||
bool global_offset_set = 0;
|
||
feature_offset_s global_offset = {0};
|
||
|
||
//enum LED_COLOR global_LED_color;
|
||
// Most recent command ID globally
|
||
static uint16_t feature_config_command_id = 0;
|
||
u8 DM_USB_Command = 0;
|
||
bool got_command = 0;
|
||
|
||
// For the largest buffer we need
|
||
uint8_t feature_get_buf[FEATURE_CALIBRATE_SIZE];
|
||
uint8_t feature_set_buf[FEATURE_CALIBRATE_SIZE];
|
||
|
||
/******************************************************
|
||
*º¯ Êý£º feature_config_pack_config
|
||
*¹¦ ÄÜ£º
|
||
*ÐÞ¸Äʱ¼ä£º 2015-5-14
|
||
*Êä È룺 ÎÞ
|
||
*******************************************************/
|
||
static void feature_config_pack_config(void)
|
||
{
|
||
feature_get_buf[0] = FEATURE_CONFIG;
|
||
*(uint16_t *)(feature_get_buf+1) = global_config.command_id;
|
||
feature_get_buf[3] = global_config.use_raw | /*´«¸ÐÆ÷ÔʼÊý¾ÝÔÚÓÚÄÚ²¿µ÷ÊÔ²ÅʹÓà config.use_raw*/
|
||
(global_config.calibrate << 1) |
|
||
(global_config.use_calibration << 2) |
|
||
(global_config.autocalibration << 3) |
|
||
(global_config.motion_keep_alive << 4) |
|
||
(global_config.command_keep_alive << 5) |
|
||
(global_config.use_ovr_coordinates << 6);
|
||
feature_get_buf[4] = global_config.interval;
|
||
// For now, just hard code to 1000 Hz. This is for forwards compatibility
|
||
// with future trackers with different sample rates.
|
||
*(uint16_t *)(feature_get_buf+5) = global_config.sample_rate = 1000;
|
||
}
|
||
|
||
/******************************************************
|
||
*º¯ Êý£º feature_config_pack_range
|
||
*¹¦ ÄÜ£º Oculus SDK»áÇëÇ󴫸ÐÆ÷Êý¾Ý·¶Î§
|
||
ͨ¹ýÕâ¸öº¯Êý´ò°üÊý¾ÝÕâ¸öº¯Êý»áÔÚUSB´¦ÀíÖÐ
|
||
ÐÄÖб»µ÷ÓÃ
|
||
*ÐÞ¸Äʱ¼ä£º 2015-5-11
|
||
*******************************************************/
|
||
static void feature_config_pack_range(void)
|
||
{
|
||
feature_get_buf[0] = FEATURE_RANGE; /*report ID = 4 */
|
||
*(uint16_t *)(feature_get_buf+1) = global_range.command_id;
|
||
|
||
feature_get_buf[3] = 2; /* ĬÈϼÓËٶȼƵķ¶Î§Îª+¡ª2G£¬²Î¿¼ÊÖ²á */
|
||
|
||
*(uint16_t *)(feature_get_buf+4) = 2000; /* ÍÓÂÝÒǵķ¶Î§ÊÇ+-2000deg/s£¬²Î¿¼ÊÖ²á */
|
||
*(uint16_t *)(feature_get_buf+6) = 1300; /* µØ´Å¼ÆµÄ·¶Î§Îª+-1300£¬²Î¿¼ÊÖ²á */
|
||
}
|
||
/*******************************************************
|
||
**ÌṩÉÏλ»ú¼Ä´æÆ÷ÐÅÏ¢
|
||
********************************************************/
|
||
static void feature_config_pack_register(void)
|
||
{
|
||
feature_get_buf[0] = FEATURE_REGISTER;
|
||
*(uint16_t *)(feature_get_buf+1) = global_reg.command_id;
|
||
feature_get_buf[3] = global_reg.device;
|
||
feature_get_buf[4] = global_reg.reg;
|
||
feature_get_buf[5] = global_reg.payload;
|
||
}
|
||
/******************************************************
|
||
*º¯ Êý£º *feature_config_getreport
|
||
*¹¦ ÄÜ£º Oculus SDK »á·¢ËÍÇëÇ󣬴ÓÕâÀï·µ»ØÊý¾Ý¸ø
|
||
Oculus SDK
|
||
*ÐÞ¸Äʱ¼ä£º 2015-3-29
|
||
*Êä È룺 ÎÞ
|
||
*******************************************************/
|
||
uint8_t *feature_config_getreport(uint16_t length)
|
||
{
|
||
// ¸ù¾Ý±¨¸æIDÑ¡Ôñ
|
||
switch (pInformation->USBwValue0)
|
||
{
|
||
// ÅäÖÃÌØÐÔ
|
||
case FEATURE_CONFIG:
|
||
// On the first callback, we supply the length
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_CONFIG_SIZE;
|
||
} else {
|
||
// On the second we return the filled buffer
|
||
feature_config_pack_config();
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
// У׼ÌØÐÔ
|
||
case FEATURE_CALIBRATE:
|
||
// if (!length) {
|
||
// pInformation->Ctrl_Info.Usb_wLength = FEATURE_CALIBRATE_SIZE;
|
||
// }
|
||
// else {
|
||
// feature_get_buf[0] = FEATURE_CALIBRATE;
|
||
// *(uint16_t *)(feature_get_buf+1) = global_calibrate.command_id;
|
||
// /*¶ÁȡУ׼ÐÅÏ¢*/
|
||
// calibrate_get(feature_get_buf+3);
|
||
// // Calibrate is above 64 bytes, so we get called again with offset
|
||
// return feature_get_buf + pInformation->Ctrl_Info.Usb_wOffset;
|
||
// }
|
||
// break;
|
||
// ·¶Î§ÌØÐÔ
|
||
case FEATURE_RANGE:
|
||
if (!length)
|
||
{
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_RANGE_SIZE;
|
||
}
|
||
else
|
||
{
|
||
feature_config_pack_range(); /*´ò°ü·¶Î§ÌØÐÔ*/
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
/********************************************************
|
||
FEATURE_REGISTER Õâ¸öÀàÐÍÊÇÓÃÀ´ÅäÖô«¸ÐÆ÷µÄ¼Ä´æÆ÷ʹÓõÄ,
|
||
Laputa ʹÓõÄÊÇMPU9150£¬ËùÒÔÕâ¸ö¹¦ÄÜÊÇÎÞЧµÄ
|
||
********************************************************/
|
||
case FEATURE_REGISTER:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_REGISTER_SIZE;
|
||
} else {
|
||
feature_config_pack_register(); /*´ò°ü¼Ä´æÆ÷ÐÅÏ¢*/
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_DFU:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_DFU_SIZE;
|
||
} else {
|
||
feature_get_buf[0] = FEATURE_DFU;
|
||
*(uint16_t *)(feature_get_buf+1) = global_dfu.command_id;
|
||
feature_get_buf[3] = global_dfu.use_dfu;
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_GPIO:
|
||
|
||
if (!length)
|
||
{
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_GPIO_SIZE;
|
||
} else
|
||
{
|
||
feature_get_buf[0] = FEATURE_GPIO;
|
||
*(uint16_t *)(feature_get_buf+1) = global_gpio.command_id;
|
||
feature_get_buf[3] = global_gpio.direction;
|
||
//feature_get_buf[4] = global_gpio.value = gpio_get_value();
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_KEEP_ALIVE:
|
||
if (!length)
|
||
{
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_KEEP_ALIVE_SIZE;
|
||
} else
|
||
{
|
||
feature_get_buf[0] = FEATURE_KEEP_ALIVE;
|
||
*(uint16_t *)(feature_get_buf+1) = global_keep_alive.command_id;
|
||
*(uint16_t *)(feature_get_buf+3) = global_keep_alive.keep_alive;
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
/*»ñÈ¡ÏÔʾÉ豸µÄÐÅÏ¢*/
|
||
case FEATURE_DISPLAY_INFO:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_DISPLAY_INFO_SIZE;
|
||
} else {
|
||
feature_get_buf[0] = FEATURE_DISPLAY_INFO;
|
||
*(uint16_t *)(feature_get_buf+1) = global_display_info.command_id;
|
||
// fill the actual parameters
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
/*»ñÈ¡É豸µÄÐòÁкÅÐÅÏ¢*/
|
||
case FEATURE_SERIAL: /*Oculus UtilityÇëÇóSensor SerialÐÅÏ¢*/
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_SERIAL_SIZE;
|
||
} else {
|
||
feature_get_buf[0] = FEATURE_SERIAL;
|
||
*(uint16_t *)(feature_get_buf+1) = global_serial.command_id;
|
||
//Get_SerialNum((char *)(feature_get_buf+3), 0); /*¶ÁÈ¡Sensor Serial*/
|
||
GetChipId((uint8_t *)(feature_get_buf+3));
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
case FEATURE_OFFSET: //OFFSET
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_OFFSET_SIZE;
|
||
} else {
|
||
feature_get_buf[0] = FEATURE_OFFSET;
|
||
*(uint16_t *)(feature_get_buf+1) = global_offset.command_id;
|
||
//global_offset.dev=*(uint8_t*)(feature_get_buf+3);
|
||
feature_get_buf[3] = global_offset.dev;
|
||
switch (global_offset.dev)
|
||
{
|
||
case FEATURE_OFFSET_GET_GYRO:
|
||
Get_Gyro_Offset((float*)(feature_get_buf+4));
|
||
break;
|
||
case FEATURE_OFFSET_GET_ACC:
|
||
Get_Acc_Offset((float*)(feature_get_buf+4));
|
||
break;
|
||
case FEATURE_OFFSET_GET_MAG:
|
||
Get_Mag_Offset((float*)(feature_get_buf+4));
|
||
break;
|
||
}
|
||
return feature_get_buf;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
uint8_t *feature_config_setreport(uint16_t length)
|
||
{
|
||
// Switch based on ReportID
|
||
switch (pInformation->USBwValue0)
|
||
{
|
||
case FEATURE_CONFIG:
|
||
// On the first callback, we supply the length
|
||
if (!length)
|
||
{
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_CONFIG_SIZE;
|
||
} else
|
||
{
|
||
// On the second, we return the buffer to fill
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_CALIBRATE:
|
||
if (!length)
|
||
{
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_CALIBRATE_SIZE;
|
||
} else {
|
||
// Calibrate is above 64 bytes, so we get called again with offset
|
||
return feature_set_buf + pInformation->Ctrl_Info.Usb_wOffset;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_RANGE:
|
||
if (!length)
|
||
{
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_RANGE_SIZE;
|
||
} else {
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_REGISTER:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_REGISTER_SIZE;
|
||
} else {
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_DFU:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_DFU_SIZE;
|
||
} else {
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_GPIO:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_GPIO_SIZE;
|
||
} else {
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_KEEP_ALIVE:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_KEEP_ALIVE_SIZE;
|
||
} else {
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_DISPLAY_INFO:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_DISPLAY_INFO_SIZE;
|
||
} else {
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
|
||
case FEATURE_SERIAL:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_SERIAL_SIZE;
|
||
} else {
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
case FEATURE_OFFSET:
|
||
if (!length) {
|
||
pInformation->Ctrl_Info.Usb_wLength = FEATURE_OFFSET_SIZE;
|
||
} else {
|
||
return feature_set_buf;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
/*ÃüÁîÏÂλ»úÍê³ÉijЩÊÂÇé*/
|
||
void feature_config_parse_report(void)
|
||
{
|
||
// Get the latest set command ID regardless of report type
|
||
unsigned short int DFU_State = 0x1111;
|
||
unsigned short int DFU_State_Read = 0xffff;
|
||
feature_config_command_id = *(uint16_t *)(feature_set_buf+1);
|
||
got_command = 1;
|
||
|
||
switch (feature_set_buf[0])
|
||
{
|
||
case FEATURE_CONFIG:
|
||
global_config.command_id = *(uint16_t *)(feature_set_buf+1);
|
||
global_config.use_raw = feature_set_buf[3] & 1;
|
||
global_config.calibrate = feature_set_buf[3] & (1 << 1);
|
||
global_config.use_calibration = feature_set_buf[3] & (1 << 2);
|
||
global_config.autocalibration = feature_set_buf[3] & (1 << 3);
|
||
global_config.motion_keep_alive = feature_set_buf[3] & (1 << 4);
|
||
global_config.command_keep_alive = feature_set_buf[3] & (1 << 5);
|
||
global_config.use_ovr_coordinates = feature_set_buf[3] & (1 << 6);
|
||
global_config.interval = feature_set_buf[4];
|
||
|
||
/* ²ÉÑùʱ¼äÏÖÔÚÇ¿ÖÆΪ1000Hz Sample rate is forced to 1000 for now */
|
||
global_config.sample_rate = 1000; // *(uint16_t *)(feature_set_buf+5);
|
||
global_config_set = 1;
|
||
break;
|
||
|
||
case FEATURE_CALIBRATE:
|
||
// update the last command in on any feature report
|
||
global_calibrate.command_id = *(uint16_t *)(feature_set_buf+1);
|
||
// pass the payload of calibration data
|
||
memcpy(global_calibrate.payload, feature_set_buf+FEATURE_HEADER_SIZE, CALIBRATION_SIZE);
|
||
global_calibrate_set = 1;
|
||
break;
|
||
|
||
case FEATURE_RANGE: /*´ÓÕâÀïÉÏλ»úÉèÖÃÏÂλ»úµÄ´«¸ÐÆ÷·¶Î§*/
|
||
global_range.command_id = *(uint16_t *)(feature_set_buf+1);
|
||
global_range.accel_range = 4;
|
||
global_range.gyro_range = 500;
|
||
global_range.mag_range = 1300;
|
||
global_range_set = 1;
|
||
break;
|
||
|
||
case FEATURE_REGISTER: /*Ö±½ÓÐÞ¸ÄÏÂλ»ú´«¸ÐÆ÷µÄ¼Ä´æÆ÷£¬Ä¿Ç°Laputa ²»Ö§³Ö*/
|
||
global_reg.command_id = *(uint16_t *)(feature_set_buf+1);
|
||
global_reg.device = feature_set_buf[3];
|
||
global_reg.reg = feature_set_buf[4];
|
||
global_reg.payload = feature_set_buf[5];
|
||
global_reg_set = 1;
|
||
break;
|
||
|
||
case FEATURE_DFU: /*ÕâÊÇOculus ÔÚÏßÉý¼¶µÄÒ»¸ö¹¦ÄÜ*/
|
||
global_dfu.command_id = *(uint16_t *)(feature_set_buf+1);
|
||
global_dfu.use_dfu = (feature_set_buf[3] == 1);
|
||
global_dfu_set = 1;
|
||
break;
|
||
/*Õâ¸öµØ·½£¬ÉÏλ»ú¿ÉÒÔÉèÖÃÏÂλ»úµÄGPIOÌØÐÔ£¬ÒÔºóLaputa ¿ÉÒÔÓÃÉÏλ»úÉèÖÃÏÂλ»úµÄ
|
||
¸÷ÖÖ¹¦ÄÜ*/
|
||
case FEATURE_GPIO:
|
||
global_gpio.command_id = *(uint16_t *)(feature_set_buf+1);
|
||
global_gpio.direction = feature_set_buf[3];
|
||
//gpio_set_direction(global_gpio.direction); /*ÆÁ±ÎÁ˺ÍGPIOÏà¹ØµÄ¹¦ÄÜ£¬³ýÁËOculusÎÞ·¨¿ØÖÆ*/
|
||
// gpio_set_value(feature_set_buf[4]);
|
||
break;
|
||
// ÎÒÃÇÓÃͨÐÅÐÒéÖеÄKeepAliveÓÃ×÷ΪÎÒÃǵÄ×Ô¼ºµÄͨÐŲ¿·Ö
|
||
case FEATURE_KEEP_ALIVE:
|
||
DM_USB_Command = feature_set_buf[4];
|
||
if(DM_USB_Command == 0x26)
|
||
{
|
||
TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE);
|
||
Compute_Gyro_Offset();
|
||
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
|
||
}
|
||
if(DM_USB_Command == 0x25)
|
||
{
|
||
/*ÔÚÖ¸¶¨µØַдÈë±ê־λ,ÓÃÓÚÅжÏÊÇ·ñ½øÈëDFUÄ£?
|
||
*ÔÚÊÕµ½DFUÃüÁîºó£¬ÕâÀïÏòÖ¸¶¨µØַдÈë0x1111£¬ÉèÖÃDFUµÄ±ê־룬
|
||
*¿ª»úµÄʱºò£¬DFU³ÌÐò¼ì²âµ½0x1111,¾ÍÍ£ÁôÔÚDFUģʽ£¬ÕâÀï×¢Ò⣬²»ÂÛÊÇ·ñÔÚºÎÖÖģʽÏ£¬¼ì²âµ½0x1111ºó
|
||
ÐèÒªÁ¢¼´²Á³ö¸Ã±ê־λ
|
||
*/
|
||
STMFLASH_Write(FLASH_DFU_FLASH,&DFU_State,1); //2¸ö×Ö½Ú = °ë¸ö×Ö
|
||
STMFLASH_Read(FLASH_DFU_FLASH,&DFU_State_Read,1); //2¸ö×Ö½Ú = °ë¸ö×Ö
|
||
if(DFU_State_Read == 0x1111)NVIC_SystemReset();
|
||
}
|
||
break;
|
||
|
||
case FEATURE_DISPLAY_INFO:
|
||
global_display_info.command_id = *(uint16_t *)(feature_set_buf+1);
|
||
/*°ÑÏÔʾÐÅÏ¢´æµ½EEROMÖУ¬Ä¿Ç°Laputa ²»Ö§³Ö¸Ã¹¦ÄÜ*/
|
||
break;
|
||
|
||
case FEATURE_SERIAL:
|
||
global_serial.command_id = *(uint16_t *)(feature_set_buf+1);
|
||
Set_Stored_Serial((char *)feature_set_buf+3); /*°ÑSerialNum ´æµ½EEROMÖУ¬Ä¿Ç°ÊDz»Ö§³ÖµÄ*/
|
||
break;
|
||
|
||
case FEATURE_OFFSET:
|
||
global_offset.command_id=*(uint16_t *)(feature_set_buf+1);
|
||
global_offset.dev=*(uint8_t *)(feature_set_buf+3);
|
||
|
||
switch(global_offset.dev)
|
||
{
|
||
case FEATURE_OFFSET_SET_GYRO:
|
||
Save_Gyro_Offset((float*)(feature_set_buf+4));
|
||
//Load_Gyro_Offset();
|
||
break;
|
||
case FEATURE_OFFSET_SET_ACC:
|
||
//Save_Acc_Offset((float*)(feature_set_buf+4));
|
||
//Load_Acc_Offset();
|
||
break;
|
||
case FEATURE_OFFSET_SET_MAG:
|
||
Save_Mag_Offset((float*)(feature_set_buf+4));
|
||
Load_Mag_Offset();
|
||
break;
|
||
case FEATURE_OFFSET_SET_LED:
|
||
//global_LED_color=(enum LED_COLOR)feature_set_buf[4];
|
||
break;
|
||
//case FEATURE_OFFSET_GET_GYRO :
|
||
//case FEATURE_OFFSET_GET_ACC :
|
||
//case FEATURE_OFFSET_GET_MAG :
|
||
//global_offset.dev=global_offset.dev&0x0F;
|
||
//break;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
bool feature_config_got_command(bool peek)
|
||
{
|
||
bool ret = got_command;
|
||
|
||
if (!peek)
|
||
got_command = 0;
|
||
|
||
return ret;
|
||
}
|
||
|
||
uint16_t feature_config_latest_command_id(void)
|
||
{
|
||
return feature_config_command_id;
|
||
}
|
||
|
||
void feature_config_set(feature_config_p config)
|
||
{
|
||
memcpy(&global_config, config, sizeof(feature_config_s));
|
||
}
|
||
|
||
void feature_keep_alive_set(feature_keep_alive_p keep_alive)
|
||
{
|
||
memcpy(&global_keep_alive, keep_alive, sizeof(feature_keep_alive_s));
|
||
}
|
||
|
||
bool feature_config_get(feature_config_p config)
|
||
{
|
||
// TODO: protect this
|
||
// Only mark as changed if we got a new packet and the contents differ from the last
|
||
if (global_config_set && memcmp(config, &global_config, sizeof(feature_config_s))) {
|
||
global_config_set = 0;
|
||
memcpy(config, &global_config, sizeof(feature_config_s));
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
bool feature_calibrate_get(feature_calibrate_p calibrate)
|
||
{
|
||
// TODO: protect this
|
||
if (global_calibrate_set && memcmp(calibrate, &global_calibrate, sizeof(feature_calibrate_s))) {
|
||
global_calibrate_set = 0;
|
||
memcpy(calibrate, &global_calibrate, sizeof(feature_calibrate_s));
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
bool feature_range_get(feature_range_p range)
|
||
{
|
||
// TODO: protect this
|
||
if (global_range_set && memcmp(range, &global_range, sizeof(feature_range_s))) {
|
||
global_range_set = 0;
|
||
memcpy(range, &global_range, sizeof(feature_range_s));
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
bool feature_register_get(feature_register_p reg)
|
||
{
|
||
// TODO: protect this
|
||
// A register could be set twice intentionally here, so don't condition on
|
||
// the contents differing
|
||
if (global_reg_set) {
|
||
global_reg_set = 0;
|
||
memcpy(reg, &global_reg, sizeof(feature_register_s));
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
bool feature_dfu_get(feature_dfu_p dfu)
|
||
{
|
||
// TODO: protect this
|
||
if (global_dfu_set && memcmp(dfu, &global_dfu, sizeof(feature_dfu_s)))
|
||
{
|
||
global_dfu_set = 0;
|
||
memcpy(dfu, &global_dfu, sizeof(feature_dfu_s));
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
bool feature_keep_alive_get(feature_keep_alive_p keep_alive)
|
||
{
|
||
// TODO: protect this
|
||
// This report is lightweight, so just let it through if it is the same
|
||
if (global_keep_alive_set)
|
||
{
|
||
global_keep_alive_set = 0;
|
||
memcpy(keep_alive, &global_keep_alive, sizeof(feature_keep_alive_s));
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
void GetChipId(uint8_t *temp)
|
||
{
|
||
u32 temp0,temp1,temp2;
|
||
temp0=*(__IO u32*)(0x1FFFF7E8);
|
||
temp1=*(__IO u32*)(0x1FFFF7EC);
|
||
temp2=*(__IO u32*)(0x1FFFF7F0);
|
||
temp[0] = (u8)(temp0 & 0x000000FF);
|
||
temp[1] = (u8)((temp0 & 0x0000FF00)>>8);
|
||
temp[2] = (u8)((temp0 & 0x00FF0000)>>16);
|
||
temp[3] = (u8)((temp0 & 0xFF000000)>>24);
|
||
temp[4] = (u8)(temp1 & 0x000000FF);
|
||
temp[5] = (u8)((temp1 & 0x0000FF00)>>8);
|
||
temp[6] = (u8)((temp1 & 0x00FF0000)>>16);
|
||
temp[7] = (u8)((temp1 & 0xFF000000)>>24);
|
||
temp[8] = (u8)(temp2 & 0x000000FF);
|
||
temp[9] = (u8)((temp2 & 0x0000FF00)>>8);
|
||
temp[10] = (u8)((temp2 & 0x00FF0000)>>16);
|
||
temp[11] = (u8)((temp2 & 0xFF000000)>>24);
|
||
}
|