mirror of
https://gitee.com/xiaohuolufeihua/bizhang_-obav.git
synced 2026-05-22 01:12:31 +00:00
stm32:Add board Revision and version API for FMUv5 HW detection
This commit is contained in:
committed by
Daniel Agar
parent
d4892bf179
commit
04f7a7a47a
@@ -39,6 +39,7 @@ if (NOT ${LABEL} STREQUAL "bootloader")
|
||||
list(APPEND SRCS
|
||||
board_mcu_version.c
|
||||
board_reset.c
|
||||
board_hw_rev_ver.c
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
343
src/drivers/boards/common/stm32/board_hw_rev_ver.c
Normal file
343
src/drivers/boards/common/stm32/board_hw_rev_ver.c
Normal file
@@ -0,0 +1,343 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (C) 2017 PX4 Development Team. All rights reserved.
|
||||
* Author: @author David Sidrane <david_s5@nscdg.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file board_hw_rev_ver.c
|
||||
* Implementation of STM32 based Board Hardware Revision and Version ID API
|
||||
*/
|
||||
|
||||
#include <px4_config.h>
|
||||
#include <stdio.h>
|
||||
#include "board_config.h"
|
||||
|
||||
#include "../board_internal_common.h"
|
||||
|
||||
#include <systemlib/px4_macros.h>
|
||||
|
||||
#if defined(BOARD_HAS_HW_VERSIONING)
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
static int hw_version = -1;
|
||||
static int hw_revision = -1;
|
||||
static char hw_info[] = HW_INFO_INIT;
|
||||
|
||||
/****************************************************************************
|
||||
* Protected Functions
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
* Name: determin_hw_version
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function fist determines if revision and version resistors are in place.
|
||||
* if they it will read the ADC channels and decode the DN to ordinal numbers
|
||||
* that will be returned by board_get_hw_version and board_get_hw_revision API
|
||||
*
|
||||
* This will return OK on success and -1 on not supported
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int dn_to_ordinal(uint16_t dn)
|
||||
{
|
||||
|
||||
const struct {
|
||||
uint16_t low; // High(n-1) + 1
|
||||
uint16_t high; // Average High(n)+Low(n+1) EX. 1356 = AVRG(1331,1382)
|
||||
} dn2o[] = {
|
||||
// R1(up) R2(down) V min V Max DN Min DN Max
|
||||
{0, 0 }, // 0 No Resistors
|
||||
{1, 579 }, // 1 24.9K 442K 0.166255191 0.44102252 204 553
|
||||
{580, 967 }, // 2 32.4K 174K 0.492349322 0.770203609 605 966
|
||||
{968, 1356}, // 3 38.3K 115K 0.787901749 1.061597759 968 1331
|
||||
{1357, 1756}, // 4 46.4K 84.5K 1.124833577 1.386007306 1382 1738
|
||||
{1757, 2137}, // 5 51.1K 61.9K 1.443393279 1.685367869 1774 2113
|
||||
{2138, 2519}, // 6 61.9K 51.1K 1.758510242 1.974702534 2161 2476
|
||||
{2520, 2919}, // 7 84.5K 46.4K 2.084546498 2.267198261 2562 2842
|
||||
{2920, 3308}, // 8 115K 38.3K 2.437863827 2.57656294 2996 3230
|
||||
{3309, 3699}, // 9 174K 32.4K 2.755223792 2.847933804 3386 3571
|
||||
{3700, 4095}, // 10 442K 24.9K 3.113737849 3.147347506 3827 3946
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < arraySize(dn2o); i++) {
|
||||
if (dn >= dn2o[i].low && dn <= dn2o[i].high) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: read_id_dn
|
||||
*
|
||||
* Description:
|
||||
* Read the HW sense set to get a DN of the value formed by
|
||||
* 0 VDD
|
||||
* |
|
||||
* /
|
||||
* \ R1
|
||||
* /
|
||||
* |
|
||||
* +--------------- GPIO_HW_xxx_SENCE | ADC channel N
|
||||
* |
|
||||
* /
|
||||
* \ R2
|
||||
* /
|
||||
* |
|
||||
* |
|
||||
* +--------------- GPIO_HW_xxx_DRIVE
|
||||
*
|
||||
* Input Parameters:
|
||||
* id - pointer to receive the dn for the id set
|
||||
* gpio_drive - gpio that is the drive
|
||||
* gpio_sense - gpio that is the sence
|
||||
* adc_channel - the Channel number associated with gpio_sense
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 - Success and id is set
|
||||
* -EIO - FAiled to init or read the ADC
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc_channel)
|
||||
{
|
||||
int rv = -EIO;
|
||||
const unsigned int samples = 16;
|
||||
/*
|
||||
* Step one is there resistors?
|
||||
*
|
||||
* If we set the mid-point of the ladder which is the ADC input to an
|
||||
* output, then whatever state is driven out should be seen by the GPIO
|
||||
* that is on the bottom of the ladder that is switched to an input.
|
||||
* The SENCE line is effectively an output with a high value pullup
|
||||
* resistor on it driving an input through a series resistor with a pull up.
|
||||
* If present the series resistor will form a low pass filter due to stray
|
||||
* capacitance, but this is fine as long as we give it time to settle.
|
||||
*/
|
||||
|
||||
/* Turn the drive lines to digital inputs with No pull up */
|
||||
|
||||
stm32_configgpio(_MK_GPIO_INPUT(gpio_drive) & ~GPIO_PUPD_MASK);
|
||||
|
||||
/* Turn the sense lines to digital outputs LOW */
|
||||
|
||||
stm32_configgpio(_MK_GPIO_OUTPUT(gpio_sense));
|
||||
|
||||
|
||||
up_udelay(100); /* About 10 TC assuming 485 K */
|
||||
|
||||
/* Read Drive lines while sense are driven low */
|
||||
|
||||
int low = stm32_gpioread(_MK_GPIO_INPUT(gpio_drive));
|
||||
|
||||
|
||||
/* Write the sense lines HIGH */
|
||||
|
||||
stm32_gpiowrite(_MK_GPIO_OUTPUT(gpio_sense), 1);
|
||||
|
||||
up_udelay(100); /* About 10 TC assuming 485 K */
|
||||
|
||||
/* Read Drive lines while sense are driven high */
|
||||
|
||||
int high = stm32_gpioread(_MK_GPIO_INPUT(gpio_drive));
|
||||
|
||||
/* restore the pins to ANALOG */
|
||||
|
||||
stm32_configgpio(gpio_sense);
|
||||
|
||||
/* Turn the drive lines to digital outputs LOW */
|
||||
|
||||
stm32_configgpio(gpio_drive ^ GPIO_OUTPUT_SET);
|
||||
|
||||
up_udelay(100); /* About 10 TC assuming 485 K */
|
||||
|
||||
/* Are Resistors in place ?*/
|
||||
|
||||
uint32_t dn_sum = 0;
|
||||
uint16_t dn = 0;
|
||||
|
||||
if ((high ^ low) && low == 0) {
|
||||
|
||||
|
||||
/* Yes - Fire up the ADC (it has once control) */
|
||||
|
||||
if (board_adc_init() == OK) {
|
||||
|
||||
/* Read the value */
|
||||
for (unsigned av = 0; av < samples; av++) {
|
||||
dn = board_adc_sample(adc_channel);
|
||||
|
||||
if (dn == 0xffff) {
|
||||
break;
|
||||
}
|
||||
|
||||
dn_sum += dn;
|
||||
}
|
||||
|
||||
if (dn != 0xffff) {
|
||||
*id = dn_sum / samples;
|
||||
rv = OK;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* No - No Resistors is ID 0 */
|
||||
*id = 0;
|
||||
rv = OK;
|
||||
}
|
||||
|
||||
/* Turn the drive lines to digital outputs High */
|
||||
|
||||
stm32_configgpio(gpio_drive);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static int determine_hw_info(int *revision, int *version)
|
||||
{
|
||||
int dn;
|
||||
int rv = read_id_dn(&dn, GPIO_HW_REV_DRIVE, GPIO_HW_REV_SENSE, ADC_HW_REV_SENSE_CHANNEL);
|
||||
|
||||
if (rv == OK) {
|
||||
*revision = dn_to_ordinal(dn);
|
||||
rv = read_id_dn(&dn, GPIO_HW_VER_DRIVE, GPIO_HW_VER_SENSE, ADC_HW_VER_SENSE_CHANNEL);
|
||||
|
||||
if (rv == OK) {
|
||||
*version = dn_to_ordinal(dn);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
/************************************************************************************
|
||||
* Name: board_get_hw_type
|
||||
*
|
||||
* Description:
|
||||
* Optional returns a 0 terminated string defining the HW type.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* a 0 terminated string defining the HW type. This my be a 0 length string ""
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
__EXPORT const char *board_get_hw_type_name()
|
||||
{
|
||||
return (const char *) hw_info;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: board_get_hw_version
|
||||
*
|
||||
* Description:
|
||||
* Optional returns a integer HW version
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* An integer value of this boards hardware version.
|
||||
* A value of 0 is the default for boards not supporting the BOARD_HAS_VERSIONING API.
|
||||
* A value of -1 is the default for boards supporting the API but not having version.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
__EXPORT int board_get_hw_version()
|
||||
{
|
||||
return hw_version;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: board_get_hw_revision
|
||||
*
|
||||
* Description:
|
||||
* Optional returns a integer HW revision
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* An integer value of this boards hardware revision.
|
||||
* A value of 0 is the default for boards not supporting the BOARD_HAS_VERSIONING API.
|
||||
* A value of -1 is the default for boards supporting the API but not having revision.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
__EXPORT int board_get_hw_revision()
|
||||
{
|
||||
return hw_revision;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: board_determine_hw_info
|
||||
*
|
||||
* Description:
|
||||
* Uses the HW revision and version detection added in FMUv5.
|
||||
* See https://docs.google.com/spreadsheets/d/1-n0__BYDedQrc_2NHqBenG1DNepAgnHpSGglke-QQwY
|
||||
* HW REV and VER ID tab.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 - on success or negated errono
|
||||
* 1) The values for integer value of this boards hardware revision is set
|
||||
* 2) The integer value of this boards hardware version is set.
|
||||
* 3) hw_info is populated
|
||||
*
|
||||
* A value of 0 is the default for boards supporting the BOARD_HAS_HW_VERSIONING API.
|
||||
* but not having R1 and R2.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int board_determine_hw_info()
|
||||
{
|
||||
int rv = determine_hw_info(&hw_revision, &hw_version);
|
||||
|
||||
if (rv == OK) {
|
||||
hw_info[HW_INFO_INIT_REV] = board_get_hw_revision() + '0';
|
||||
hw_info[HW_INFO_INIT_VER] = board_get_hw_version() + '0';
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user