mirror of
https://jihulab.com/mr-one/openpilot.git
synced 2026-10-26 20:43:49 +08:00
test: sync full panda tree to upstream 8a16e08 (stage 2e)
This commit is contained in:
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
name: jenkins scan
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
|
||||
jobs:
|
||||
# TODO: gc old branches in a separate job in this workflow
|
||||
scan-comments:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
steps:
|
||||
- name: Check for trigger phrase
|
||||
id: check_comment
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const triggerPhrase = "trigger-jenkins";
|
||||
const comment = context.payload.comment.body;
|
||||
const commenter = context.payload.comment.user.login;
|
||||
|
||||
const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
username: commenter
|
||||
});
|
||||
|
||||
const hasWriteAccess = permissions.permission === 'write' || permissions.permission === 'admin';
|
||||
|
||||
return (hasWriteAccess && comment.includes(triggerPhrase));
|
||||
result-encoding: json
|
||||
|
||||
- name: Checkout repository
|
||||
if: steps.check_comment.outputs.result == 'true'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: refs/pull/${{ github.event.issue.number }}/head
|
||||
|
||||
- name: Push to tmp-jenkins branch
|
||||
if: steps.check_comment.outputs.result == 'true'
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git checkout -b tmp-jenkins-${{ github.event.issue.number }}
|
||||
GIT_LFS_SKIP_PUSH=1 git push -f origin tmp-jenkins-${{ github.event.issue.number }}
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
name: tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref != 'refs/heads/master' && github.ref || github.run_id }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUN: source .venv/bin/activate && /bin/bash -c
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: ./setup.sh
|
||||
- name: Test python package installer
|
||||
run: ${{ env.RUN }} "pip install --break-system-packages .[dev]"
|
||||
- name: Build debug FW
|
||||
run: ${{ env.RUN }} "scons"
|
||||
- name: Build release FW
|
||||
run: ${{ env.RUN }} "CERT=board/crypto/certs/debug RELEASE=1 scons"
|
||||
|
||||
test:
|
||||
name: ./test.sh
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ['macos-latest', 'ubuntu-latest']
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: ./test.sh
|
||||
|
||||
windows:
|
||||
name: windows pip package test
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
- name: Install package with uv
|
||||
run: uv pip install --system .
|
||||
- name: Verify importing panda
|
||||
run: python -c "from panda import Panda"
|
||||
Vendored
+24
-25
@@ -1,17 +1,3 @@
|
||||
def docker_run(String step_label, int timeout_mins, String cmd) {
|
||||
timeout(time: timeout_mins, unit: 'MINUTES') {
|
||||
sh script: "docker run --rm --privileged \
|
||||
--env PYTHONWARNINGS=error \
|
||||
--volume /dev/bus/usb:/dev/bus/usb \
|
||||
--volume /var/run/dbus:/var/run/dbus \
|
||||
--net host \
|
||||
${env.DOCKER_IMAGE_TAG} \
|
||||
bash -c 'scons && ${cmd}'", \
|
||||
label: step_label
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def phone(String ip, String step_label, String cmd) {
|
||||
withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) {
|
||||
def ssh_cmd = """
|
||||
@@ -73,12 +59,12 @@ pipeline {
|
||||
environment {
|
||||
CI = "1"
|
||||
PYTHONWARNINGS= "error"
|
||||
DOCKER_IMAGE_TAG = "panda:build-${env.GIT_COMMIT}"
|
||||
|
||||
TEST_DIR = "/data/panda"
|
||||
SOURCE_DIR = "/data/panda_source/"
|
||||
}
|
||||
options {
|
||||
skipDefaultCheckout()
|
||||
timeout(time: 3, unit: 'HOURS')
|
||||
disableConcurrentBuilds(abortPrevious: env.BRANCH_NAME != 'master')
|
||||
}
|
||||
@@ -89,20 +75,30 @@ pipeline {
|
||||
lock(resource: "pandas")
|
||||
}
|
||||
stages {
|
||||
stage('Build Docker Image') {
|
||||
stage('Setup') {
|
||||
steps {
|
||||
timeout(time: 20, unit: 'MINUTES') {
|
||||
deleteDir()
|
||||
script {
|
||||
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}", "--build-arg CACHEBUST=${env.GIT_COMMIT} .")
|
||||
def revision = checkout scm
|
||||
env.GIT_COMMIT = revision.GIT_COMMIT
|
||||
env.GIT_BRANCH = revision.GIT_BRANCH
|
||||
}
|
||||
sh 'PYTHONWARNINGS=default ./setup.sh'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('jungle tests') {
|
||||
stage('reset hardware') {
|
||||
steps {
|
||||
script {
|
||||
retry (3) {
|
||||
docker_run("reset hardware", 3, "python3 ./tests/hitl/reset_jungles.py")
|
||||
timeout(time: 3, unit: 'MINUTES') {
|
||||
sh script: """#!/usr/bin/env bash
|
||||
set -e
|
||||
source .venv/bin/activate
|
||||
python3 ./tests/hitl/reset_jungles.py
|
||||
""", label: "reset hardware"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,25 +107,23 @@ pipeline {
|
||||
stage('parallel tests') {
|
||||
parallel {
|
||||
stage('test cuatro') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root'; reuseNode true } }
|
||||
steps {
|
||||
phone_steps("panda-cuatro", [
|
||||
["build", "scons"],
|
||||
["flash", "cd scripts/ && ./reflash_internal_panda.py"],
|
||||
["flash jungle", "cd board/jungle && ./flash.py --all"],
|
||||
["test", "cd tests/hitl && pytest -o 'addopts=' --durations=0 2*.py [5-9]*.py"],
|
||||
["test", "cd tests/hitl && HITL=1 python -m unittest -v test_2*.py test_[5-9]*.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('test tres') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root'; reuseNode true } }
|
||||
steps {
|
||||
phone_steps("panda-tres", [
|
||||
["build", "scons"],
|
||||
["flash", "cd scripts/ && ./reflash_internal_panda.py"],
|
||||
["flash jungle", "cd board/jungle && ./flash.py --all"],
|
||||
["test", "cd tests/hitl && pytest -o 'addopts=' --durations=0 2*.py [5-9]*.py"],
|
||||
["test", "cd tests/hitl && HITL=1 python -m unittest -v test_2*.py test_[5-9]*.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -139,4 +133,9 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +76,6 @@ EOF
|
||||
sudo udevadm control --reload-rules && sudo udevadm trigger
|
||||
```
|
||||
|
||||
The panda jungle uses different udev rules. See [the repo](https://github.com/commaai/panda_jungle#udev-rules) for instructions.
|
||||
|
||||
## Licensing
|
||||
|
||||
panda software is released under the MIT license unless otherwise specified.
|
||||
|
||||
+6
-14
@@ -16,12 +16,9 @@ if os.getenv("RELEASE"):
|
||||
assert os.path.exists(cert_fn), 'Certificate file not found. Please specify absolute path'
|
||||
else:
|
||||
BUILD_TYPE = "DEBUG"
|
||||
cert_fn = File("./board/certs/debug").srcnode().relpath
|
||||
cert_fn = File("./board/crypto/certs/debug").srcnode().relpath
|
||||
common_flags += ["-DALLOW_DEBUG"]
|
||||
|
||||
if os.getenv("DEBUG"):
|
||||
common_flags += ["-DDEBUG"]
|
||||
|
||||
def objcopy(source, target, env, for_signature):
|
||||
return '$OBJCOPY -O binary %s %s' % (source[0], target[0])
|
||||
|
||||
@@ -33,7 +30,7 @@ def get_version(builder, build_type):
|
||||
return f"{builder}-{git}-{build_type}"
|
||||
|
||||
def get_key_header(name):
|
||||
public_fn = File(f'./board/certs/{name}.pub').srcnode().get_path()
|
||||
public_fn = File(f'./board/crypto/certs/{name}.pub').srcnode().get_path()
|
||||
with open(public_fn, "rb") as f:
|
||||
key = base64.b64decode(f.read().split()[1])
|
||||
values = []
|
||||
@@ -146,6 +143,7 @@ base_project_h7 = {
|
||||
# Common autogenerated includes
|
||||
with open("board/obj/gitversion.h", "w") as f:
|
||||
version = get_version(BUILDER, BUILD_TYPE)
|
||||
f.write("#pragma once\n\n")
|
||||
f.write(f'extern const uint8_t gitversion[{len(version)+1}];\n')
|
||||
f.write(f'const uint8_t gitversion[{len(version)+1}] = "{version}";\n')
|
||||
|
||||
@@ -154,6 +152,7 @@ with open("board/obj/version", "w") as f:
|
||||
|
||||
certs = [get_key_header(n) for n in ["debug", "release"]]
|
||||
with open("board/obj/cert.h", "w") as f:
|
||||
f.write("#pragma once\n\n")
|
||||
for cert in certs:
|
||||
f.write("\n".join(cert) + "\n")
|
||||
|
||||
@@ -162,19 +161,12 @@ def version_hash(path):
|
||||
with open(path, "rb") as f:
|
||||
# Normalize line endings on Windows
|
||||
return int.from_bytes(hashlib.sha256(f.read().replace(b'\r', b'')).digest()[:4], 'little')
|
||||
hh, ch, jh = version_hash("board/health.h"), version_hash(os.path.join(opendbc.INCLUDE_PATH, "opendbc/safety/can.h")), version_hash("board/jungle/jungle_health.h")
|
||||
common_flags += [f"-DHEALTH_PACKET_VERSION=0x{hh:08X}U", f"-DCAN_PACKET_VERSION_HASH=0x{ch:08X}U",
|
||||
f"-DJUNGLE_HEALTH_PACKET_VERSION=0x{jh:08X}U"]
|
||||
hh, ch = version_hash("board/health.h"), version_hash(os.path.join(opendbc.INCLUDE_PATH, "opendbc/safety/can.h"))
|
||||
common_flags += [f"-DHEALTH_PACKET_VERSION=0x{hh:08X}U", f"-DCAN_PACKET_VERSION_HASH=0x{ch:08X}U"]
|
||||
|
||||
# panda fw
|
||||
build_project("panda_h7", base_project_h7, "./board/main.c", [])
|
||||
|
||||
# panda jungle fw
|
||||
flags = [
|
||||
"-DPANDA_JUNGLE",
|
||||
]
|
||||
build_project("panda_jungle_h7", base_project_h7, "./board/jungle/main.c", flags)
|
||||
|
||||
# body fw
|
||||
build_project("body_h7", base_project_h7, "./board/body/main.c", ["-DPANDA_BODY"])
|
||||
|
||||
|
||||
+1
-2
@@ -1,13 +1,12 @@
|
||||
from .python.constants import McuType, BASEDIR, FW_PATH, USBPACKET_MAX_SIZE # noqa: F401
|
||||
from .python.spi import PandaSpiException, PandaProtocolMismatch, STBootloaderSPIHandle # noqa: F401
|
||||
from .python.serial import PandaSerial # noqa: F401
|
||||
from .python.utils import logger # noqa: F401
|
||||
from .python import (Panda, PandaDFU, # noqa: F401
|
||||
pack_can_buffer, unpack_can_buffer, calculate_checksum,
|
||||
DLC_TO_LEN, LEN_TO_DLC, CANPACKET_HEAD_SIZE)
|
||||
|
||||
# panda jungle
|
||||
from .board.jungle import PandaJungle, PandaJungleDFU # noqa: F401
|
||||
from .python.jungle import PandaJungle # noqa: F401
|
||||
|
||||
# panda body
|
||||
from .board.body import PandaBody # noqa: F401
|
||||
|
||||
@@ -11,7 +11,6 @@ typedef enum {
|
||||
} BootState;
|
||||
|
||||
typedef void (*board_init)(void);
|
||||
typedef void (*board_init_bootloader)(void);
|
||||
typedef void (*board_enable_can_transceiver)(uint8_t transceiver, bool enabled);
|
||||
typedef void (*board_set_can_mode)(uint8_t mode);
|
||||
typedef uint32_t (*board_read_voltage_mV)(void);
|
||||
@@ -33,7 +32,6 @@ struct board {
|
||||
const uint16_t avdd_mV;
|
||||
const uint8_t fan_enable_cooldown_time;
|
||||
board_init init;
|
||||
board_init_bootloader init_bootloader;
|
||||
board_enable_can_transceiver enable_can_transceiver;
|
||||
board_set_can_mode set_can_mode;
|
||||
board_read_voltage_mV read_voltage_mV;
|
||||
|
||||
@@ -77,10 +77,6 @@ static void cuatro_init(void) {
|
||||
// SOM bootkick + reset lines
|
||||
cuatro_set_bootkick(BOOT_BOOTKICK);
|
||||
|
||||
// SOM debugging UART
|
||||
gpio_uart7_init();
|
||||
uart_init(&uart_ring_som_debug, 115200);
|
||||
|
||||
// fan setup
|
||||
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
|
||||
register_set_bits(&(GPIOC->OTYPER), GPIO_OTYPER_OT8); // open drain
|
||||
@@ -120,7 +116,6 @@ board board_cuatro = {
|
||||
.avdd_mV = 1800U,
|
||||
.fan_enable_cooldown_time = 3U,
|
||||
.init = cuatro_init,
|
||||
.init_bootloader = unused_init_bootloader,
|
||||
.enable_can_transceiver = cuatro_enable_can_transceiver,
|
||||
.led_GPIO = {GPIOC, GPIOC, GPIOC},
|
||||
.led_pin = {6, 7, 9},
|
||||
|
||||
@@ -119,7 +119,6 @@ board board_red = {
|
||||
.avdd_mV = 3300U,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = red_init,
|
||||
.init_bootloader = unused_init_bootloader,
|
||||
.enable_can_transceiver = red_enable_can_transceiver,
|
||||
.led_GPIO = {GPIOE, GPIOE, GPIOE},
|
||||
.led_pin = {4, 3, 2},
|
||||
|
||||
@@ -118,10 +118,6 @@ static void tres_init(void) {
|
||||
tres_set_bootkick(BOOT_BOOTKICK);
|
||||
set_gpio_mode(GPIOC, 12, MODE_OUTPUT);
|
||||
|
||||
// SOM debugging UART
|
||||
gpio_uart7_init();
|
||||
uart_init(&uart_ring_som_debug, 115200);
|
||||
|
||||
// fan setup
|
||||
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
|
||||
|
||||
@@ -159,7 +155,6 @@ board board_tres = {
|
||||
.avdd_mV = 1800U,
|
||||
.fan_enable_cooldown_time = 3U,
|
||||
.init = tres_init,
|
||||
.init_bootloader = unused_init_bootloader,
|
||||
.enable_can_transceiver = tres_enable_can_transceiver,
|
||||
.led_GPIO = {GPIOE, GPIOE, GPIOE},
|
||||
.led_pin = {4, 3, 2},
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void unused_init_bootloader(void) {
|
||||
}
|
||||
|
||||
void unused_set_ir_power(uint8_t percentage) {
|
||||
UNUSED(percentage);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef BLDC_H
|
||||
#define BLDC_H
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/body/body.h"
|
||||
|
||||
#include "board/body/bldc/bldc_defs.h"
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
|
||||
@@ -64,6 +67,10 @@ const adc_signal_t adc_curR_phaC = ADC_CHANNEL_BLDC(ADC1, 15);
|
||||
const adc_signal_t adc_curR_DC = ADC_CHANNEL_BLDC(ADC1, 5);
|
||||
const adc_signal_t adc_batVoltage = ADC_CHANNEL_BLDC(ADC1, 4);
|
||||
|
||||
uint8_t motor_get_error_code(uint8_t motor) {
|
||||
return (motor == BODY_MOTOR_LEFT) ? rtY_Left.z_errCode : rtY_Right.z_errCode;
|
||||
}
|
||||
|
||||
void motor_set_enable(bool enable) {
|
||||
enable_motors = enable;
|
||||
}
|
||||
@@ -308,4 +315,4 @@ void bldc_step(void) {
|
||||
RIGHT_TIM->CCR3 = (uint16_t)CLAMP((wr + pwm_res / 2), PWM_MARGIN, pwm_res - PWM_MARGIN);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -50,7 +50,4 @@
|
||||
#define BAT_CALIB_REAL_VOLTAGE 1260U // multimeter voltage
|
||||
#define BAT_CALIB_ADC 1275U // adc reading voltage
|
||||
|
||||
void bldc_init(void);
|
||||
void bldc_step(void);
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/body/body.h"
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
|
||||
void board_body_init(void) {
|
||||
@@ -43,4 +47,4 @@ board board_body = {
|
||||
.led_GPIO = {GPIOA, GPIOA, GPIOA},
|
||||
.led_pin = {10, 10, 10},
|
||||
.init = board_body_init,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "stm32h7xx.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "board/body/bldc/bldc_defs.h"
|
||||
|
||||
// ******************** Prototypes ********************
|
||||
typedef void (*board_init)(void);
|
||||
typedef void (*board_init_bootloader)(void);
|
||||
typedef void (*board_enable_can_transceiver)(uint8_t transceiver, bool enabled);
|
||||
|
||||
struct board {
|
||||
@@ -14,7 +15,6 @@ struct board {
|
||||
const uint8_t led_pin[3];
|
||||
const uint8_t led_pwm_channels[3]; // leave at 0 to disable PWM
|
||||
board_init init;
|
||||
board_init_bootloader init_bootloader;
|
||||
const bool has_spi;
|
||||
};
|
||||
|
||||
@@ -53,3 +53,5 @@ struct board {
|
||||
// Ignition On
|
||||
#define OBDC_IGNITION_ON_PORT GPIOB
|
||||
#define OBDC_IGNITION_ON_PIN 11
|
||||
|
||||
extern struct board board_body;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "board/can.h"
|
||||
#include "board/body/bldc/bldc_defs.h"
|
||||
|
||||
// Motor control
|
||||
extern volatile uint16_t batt_voltage_raw;
|
||||
extern volatile uint16_t batt_percentage;
|
||||
extern volatile int rpm_left;
|
||||
extern volatile int rpm_right;
|
||||
extern volatile bool enable_motors;
|
||||
|
||||
void motor_set_enable(bool enable);
|
||||
float motor_encoder_get_speed_rpm(uint8_t motor);
|
||||
uint8_t motor_get_error_code(uint8_t motor);
|
||||
void bldc_init(void);
|
||||
void bldc_step(void);
|
||||
|
||||
// CAN communication
|
||||
void body_can_rx(CANPacket_t *msg);
|
||||
void body_can_init(void);
|
||||
void body_can_periodic(uint32_t now, bool ignition, bool plug_charging);
|
||||
|
||||
// Status LEDs
|
||||
typedef struct {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} dotstar_rgb_t;
|
||||
|
||||
void dotstar_init(void);
|
||||
void dotstar_show(void);
|
||||
void dotstar_run_rainbow(uint32_t now_us);
|
||||
void dotstar_apply_breathe(dotstar_rgb_t color, uint32_t now_us, uint32_t cycle_us);
|
||||
|
||||
#ifndef BOOTSTUB
|
||||
extern int _app_start[0xc000];
|
||||
#endif
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/body/body.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -8,7 +10,6 @@
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
#include "opendbc/safety/declarations.h"
|
||||
#include "board/body/bldc/bldc.h"
|
||||
|
||||
#define BODY_CAN_ADDR_MOTOR_SPEED 0x201U
|
||||
#define BODY_CAN_ADDR_VAR_VALUES 0x202U
|
||||
@@ -101,7 +102,7 @@ void body_can_periodic(uint32_t now, bool ignition, bool plug_charging) {
|
||||
float left_speed_rpm = motor_encoder_get_speed_rpm(BODY_MOTOR_LEFT);
|
||||
float right_speed_rpm = motor_encoder_get_speed_rpm(BODY_MOTOR_RIGHT);
|
||||
body_can_send_motor_speeds(BODY_BUS_NUMBER, left_speed_rpm, right_speed_rpm);
|
||||
body_can_send_var_values(BODY_BUS_NUMBER, ignition, enable_motors, 0U, rtY_Left.z_errCode, rtY_Right.z_errCode);
|
||||
body_can_send_var_values(BODY_BUS_NUMBER, ignition, enable_motors, 0U, motor_get_error_code(BODY_MOTOR_LEFT), motor_get_error_code(BODY_MOTOR_RIGHT));
|
||||
body_can_send_body_data(BODY_BUS_NUMBER, 0U, batt_voltage_raw, batt_percentage, plug_charging);
|
||||
|
||||
// Send message on 0x222 to identify as body v2
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/body/body.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
|
||||
#define DOTSTAR_LED_COUNT 10U
|
||||
#define DOTSTAR_GLOBAL_BRIGHTNESS_MAX 31U
|
||||
|
||||
typedef struct {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} dotstar_rgb_t;
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
uint8_t global_brightness;
|
||||
@@ -74,7 +69,7 @@ static inline void dotstar_send_end_frame(uint16_t led_count) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_show(void) {
|
||||
void dotstar_show(void) {
|
||||
if (!dotstar_state.initialized) {
|
||||
return;
|
||||
}
|
||||
@@ -93,7 +88,7 @@ static inline void dotstar_show(void) {
|
||||
dotstar_send_end_frame(DOTSTAR_LED_COUNT);
|
||||
}
|
||||
|
||||
static inline void dotstar_init(void) {
|
||||
void dotstar_init(void) {
|
||||
set_gpio_pullup(DOTSTAR_CLK_PORT, DOTSTAR_CLK_PIN, PULL_NONE);
|
||||
set_gpio_output_type(DOTSTAR_CLK_PORT, DOTSTAR_CLK_PIN, OUTPUT_TYPE_PUSH_PULL);
|
||||
set_gpio_mode(DOTSTAR_CLK_PORT, DOTSTAR_CLK_PIN, MODE_OUTPUT);
|
||||
@@ -161,7 +156,7 @@ static inline void dotstar_hue_to_rgb(uint16_t hue, uint8_t *r, uint8_t *g, uint
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_run_rainbow(uint32_t now_us) {
|
||||
void dotstar_run_rainbow(uint32_t now_us) {
|
||||
uint32_t brightness_phase = (now_us / 40000U) % 62U;
|
||||
uint8_t brightness = (brightness_phase <= 31U) ? (uint8_t)(brightness_phase + 1U) : (uint8_t)(62U - brightness_phase);
|
||||
if (brightness == 0U) {
|
||||
@@ -178,7 +173,7 @@ static inline void dotstar_run_rainbow(uint32_t now_us) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_apply_breathe(dotstar_rgb_t color, uint32_t now_us, uint32_t cycle_us) {
|
||||
void dotstar_apply_breathe(dotstar_rgb_t color, uint32_t now_us, uint32_t cycle_us) {
|
||||
if (!dotstar_state.initialized) {
|
||||
return;
|
||||
}
|
||||
@@ -207,4 +202,4 @@ static inline void dotstar_apply_breathe(dotstar_rgb_t color, uint32_t now_us, u
|
||||
|
||||
dotstar_set_global_brightness(DOTSTAR_GLOBAL_BRIGHTNESS_MAX);
|
||||
dotstar_fill(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
#include "board/body/dotstar.h"
|
||||
#include "bldc/bldc.h"
|
||||
|
||||
extern int _app_start[0xc000];
|
||||
|
||||
#include "board/body/main_comms.h"
|
||||
|
||||
static volatile uint32_t tick_count = 0U;
|
||||
@@ -24,12 +22,6 @@ static volatile uint32_t ignition_press_timestamp_us = 0U;
|
||||
static volatile bool ignition = false;
|
||||
static volatile bool plug_charging = false;
|
||||
|
||||
void debug_ring_callback(uart_ring *ring) {
|
||||
char rcv;
|
||||
while (get_char(ring, &rcv)) {
|
||||
(void)injectc(ring, rcv);
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__ ((noinline)) enable_fpu(void) {
|
||||
SCB->CPACR |= ((3UL << (10U * 2U)) | (3UL << (11U * 2U)));
|
||||
@@ -96,6 +88,8 @@ int main(void) {
|
||||
current_board = &board_body;
|
||||
hw_type = HW_TYPE_BODY;
|
||||
|
||||
print("MCU UID: "); hexdump((const uint8_t *)UID_BASE, 12);
|
||||
|
||||
current_board->init();
|
||||
|
||||
REGISTER_INTERRUPT(EXTI15_10_IRQn, exti15_10_handler, 10000U, FAULT_INTERRUPT_RATE_EXTI);
|
||||
@@ -141,4 +135,4 @@ int main(void) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/body/body.h"
|
||||
|
||||
void comms_endpoint2_write(const uint8_t *data, uint32_t len) {
|
||||
UNUSED(data);
|
||||
UNUSED(len);
|
||||
@@ -7,6 +12,12 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
unsigned int resp_len = 0;
|
||||
|
||||
switch (req->request) {
|
||||
// **** 0xb6: read debug logs
|
||||
case 0xb6:
|
||||
while ((resp_len < req->length) && (resp_len < USBPACKET_MAX_SIZE) && debug_get_char((char*)&resp[resp_len])) {
|
||||
++resp_len;
|
||||
}
|
||||
break;
|
||||
// **** 0xc1: get hardware type
|
||||
case 0xc1:
|
||||
resp[0] = hw_type;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/body/body.h"
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
#include "board/body/boards/board_body.h"
|
||||
|
||||
extern board *current_board;
|
||||
extern uint8_t hw_type;
|
||||
|
||||
void detect_board_type(void) {
|
||||
// Board type set explicitly in main()
|
||||
}
|
||||
|
||||
@@ -38,9 +38,6 @@ int main(void) {
|
||||
clock_init();
|
||||
detect_board_type();
|
||||
|
||||
#ifdef PANDA_JUNGLE
|
||||
current_board->set_panda_power(true);
|
||||
#endif
|
||||
|
||||
if (enter_bootloader_mode == ENTER_SOFTLOADER_MAGIC) {
|
||||
enter_bootloader_mode = 0;
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
// ******************** Prototypes ********************
|
||||
void print(const char *a){ UNUSED(a); }
|
||||
void puth(unsigned int i){ UNUSED(i); }
|
||||
void puth2(unsigned int i){ UNUSED(i); }
|
||||
static void hexdump(const void *a, int l){ UNUSED(a); UNUSED(l); }
|
||||
__attribute__((unused)) static void puth4(unsigned int i){ UNUSED(i); }
|
||||
void hexdump(const void *a, int l){ UNUSED(a); UNUSED(l); }
|
||||
typedef struct board board;
|
||||
typedef struct harness_configuration harness_configuration;
|
||||
void pwm_init(TIM_TypeDef *TIM, uint8_t channel);
|
||||
void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage);
|
||||
// No UART support in bootloader
|
||||
typedef struct uart_ring uart_ring;
|
||||
void uart_init(uart_ring *q, int baud) { UNUSED(q); UNUSED(baud); }
|
||||
|
||||
// ********************* Globals **********************
|
||||
uint8_t hw_type = 0;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
CAN transactions to and from the host come in the form of
|
||||
a certain number of CANPacket_t. The transaction is split
|
||||
|
||||
+3
-19
@@ -2,14 +2,6 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
//#define DEBUG
|
||||
//#define DEBUG_UART
|
||||
//#define DEBUG_USB
|
||||
//#define DEBUG_SPI
|
||||
//#define DEBUG_FAULTS
|
||||
//#define DEBUG_COMMS
|
||||
//#define DEBUG_FAN
|
||||
|
||||
#define CAN_INIT_TIMEOUT_MS 500U
|
||||
#define USBPACKET_MAX_SIZE 0x40U
|
||||
#define MAX_CAN_MSGS_PER_USB_BULK_TRANSFER 51U
|
||||
@@ -18,18 +10,10 @@
|
||||
// USB definitions
|
||||
#define USB_VID 0x3801U
|
||||
|
||||
#ifdef PANDA_JUNGLE
|
||||
#ifdef BOOTSTUB
|
||||
#define USB_PID 0xDDEFU
|
||||
#else
|
||||
#define USB_PID 0xDDCFU
|
||||
#endif
|
||||
#ifdef BOOTSTUB
|
||||
#define USB_PID 0xDDEEU
|
||||
#else
|
||||
#ifdef BOOTSTUB
|
||||
#define USB_PID 0xDDEEU
|
||||
#else
|
||||
#define USB_PID 0xDDCCU
|
||||
#endif
|
||||
#define USB_PID 0xDDCCU
|
||||
#endif
|
||||
|
||||
// platform includes
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQC948lnRo4x44Rd7Y8bQAML4aKDC4XRx958fHV8K6+FbCaP1Z42
|
||||
U2kX0yygak0LjoDutpgObmGHZA+Iz3HeUD6VGjr/teN24vPk+A95cRsjt8rgmGQ9
|
||||
6HNjaNgjR+gl1F9XxFimMzir82Xpl1ekTueJNXa7ia5HVH1nFdiksOKHGQIDAQAB
|
||||
AoGAQuPw2I6EHJLW1/eNB75e1FqhUqRGeYV8nEGDaUBCTi+wzc4kM2LijF/5QnDv
|
||||
vvht9qkfm0XK2VSoHDtnEzcVM/l1ksb68n4R/1nUooAWY6cQI7dCSk/A6yS1EJFg
|
||||
BXsgGbT/65khw9pzBW2zVtMVcVNWFayqfCO1I9WcDdA1x1kCQQDfrhoZTZNoDEUE
|
||||
JKM4fiUdWr1h3Aw8KLJFFexSWeGDwo+qqnujYcKWkHa9qaH1RG5x8Kir9s9Oi4Js
|
||||
mzKwov8fAkEA2VPJPWxJ4vVQpXle6wC1nyoL7s739yxMWFcabvkzDDhlIVBNdVJd
|
||||
gZKsFWV7QnVNdDMjn9D27FwKu3i2D+kKxwJBANp1SMojqO765MEKI1t+YDNONx6H
|
||||
cm+i85Fjuv4nCIjOEdCGVuCYDxtMFpxgO2y3HAMuHx5sm8XDnWsDHLvFRdMCQD7V
|
||||
XqWHnYUk8AAnqy2+ssQl3/VXmZG5GQmhhV74Za3u0C5ljT+SZL6FrYMyKAT67T3f
|
||||
WzllrT6BDglNyTWoZxkCQQCt0XSoGM3603GGYNt6AUlGSgtXSo/2Px7odGUtQoKA
|
||||
FH9q6FVMYpQJ38spZxIGufZJmLP8LLg6YIWJj1F+akxr
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC948lnRo4x44Rd7Y8bQAML4aKDC4XRx958fHV8K6+FbCaP1Z42U2kX0yygak0LjoDutpgObmGHZA+Iz3HeUD6VGjr/teN24vPk+A95cRsjt8rgmGQ96HNjaNgjR+gl1F9XxFimMzir82Xpl1ekTueJNXa7ia5HVH1nFdiksOKHGQ== batman@y840
|
||||
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDGN9GU2nOc0kKq6vdZI5qUMzHt234ngqofrgCFFxL0D2Whex0zACp9gar0HZp+bvtpoSgU/Ev8wexNKr+A9QTradljiuxi5ctrOra9k+wxqNj63Wrcu4+wU5UnJEVf/buV4jCOFffMT8z3PO4imt8LzHuEIC/m/ASKVYyvuvBRQQ== batman@y840
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
bool bootkick_reset_triggered = false;
|
||||
|
||||
void bootkick_tick(bool ignition, bool recent_heartbeat) {
|
||||
static uint16_t bootkick_last_serial_ptr = 0;
|
||||
static uint8_t waiting_to_boot_countdown = 0;
|
||||
static uint8_t boot_reset_countdown = 0;
|
||||
static uint8_t bootkick_harness_status_prev = HARNESS_STATUS_NC;
|
||||
@@ -33,8 +34,7 @@ void bootkick_tick(bool ignition, bool recent_heartbeat) {
|
||||
waiting_to_boot_countdown = 20U;
|
||||
}
|
||||
if (waiting_to_boot_countdown > 0U) {
|
||||
bool serial_activity = uart_ring_som_debug.w_ptr_tx != bootkick_last_serial_ptr;
|
||||
if (serial_activity || current_board->read_som_gpio() || (boot_state != BOOT_BOOTKICK)) {
|
||||
if (current_board->read_som_gpio() || (boot_state != BOOT_BOOTKICK)) {
|
||||
waiting_to_boot_countdown = 0U;
|
||||
} else {
|
||||
// try a reset
|
||||
@@ -57,7 +57,6 @@ void bootkick_tick(bool ignition, bool recent_heartbeat) {
|
||||
// update state
|
||||
bootkick_ign_prev = ignition;
|
||||
bootkick_harness_status_prev = harness.status;
|
||||
bootkick_last_serial_ptr = uart_ring_som_debug.w_ptr_tx;
|
||||
if (waiting_to_boot_countdown > 0U) {
|
||||
waiting_to_boot_countdown--;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
#include "opendbc/safety/ignition.h"
|
||||
|
||||
@@ -72,21 +74,7 @@ bool can_push(can_ring *q, const CANPacket_t *elem) {
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
if (!ret) {
|
||||
#ifdef DEBUG
|
||||
print("can_push to ");
|
||||
if (q == &can_rx_q) {
|
||||
print("can_rx_q");
|
||||
} else if (q == &can_tx1_q) {
|
||||
print("can_tx1_q");
|
||||
} else if (q == &can_tx2_q) {
|
||||
print("can_tx2_q");
|
||||
} else if (q == &can_tx3_q) {
|
||||
print("can_tx3_q");
|
||||
} else {
|
||||
print("unknown");
|
||||
}
|
||||
print(" failed!\n");
|
||||
#endif
|
||||
print("can_push failed!\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -126,9 +114,9 @@ void can_clear(can_ring *q) {
|
||||
// Helpers
|
||||
// Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3
|
||||
bus_config_t bus_config[PANDA_CAN_CNT] = {
|
||||
{ .bus_lookup = 0U, .can_num_lookup = 0U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 1U, .can_num_lookup = 1U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 2U, .can_num_lookup = 2U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 0U, .can_num_lookup = 0U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 1U, .can_num_lookup = 1U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 2U, .can_num_lookup = 2U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
};
|
||||
|
||||
void can_init_all(void) {
|
||||
@@ -146,12 +134,6 @@ void can_set_orientation(bool flipped) {
|
||||
bus_config[2].can_num_lookup = flipped ? 0U : 2U;
|
||||
}
|
||||
|
||||
#ifdef PANDA_JUNGLE
|
||||
void can_set_forwarding(uint8_t from, uint8_t to) {
|
||||
bus_config[from].forwarding_bus = to;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool can_tx_check_min_slots_free(uint32_t min) {
|
||||
return
|
||||
(can_slots_empty(&can_tx1_q) >= min) &&
|
||||
@@ -159,7 +141,7 @@ bool can_tx_check_min_slots_free(uint32_t min) {
|
||||
(can_slots_empty(&can_tx3_q) >= min);
|
||||
}
|
||||
|
||||
uint8_t calculate_checksum(const uint8_t *dat, uint32_t len) {
|
||||
static uint8_t calculate_checksum(const uint8_t *dat, uint32_t len) {
|
||||
uint8_t checksum = 0U;
|
||||
for (uint32_t i = 0U; i < len; i++) {
|
||||
checksum ^= dat[i];
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
#define CLOCK_SOURCE_PERIOD_MS 50U
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
#define DEBUG_BUFFER_SIZE 0x400U
|
||||
|
||||
static char debug_buffer[DEBUG_BUFFER_SIZE];
|
||||
static volatile uint16_t debug_write_ptr = 0;
|
||||
static volatile uint16_t debug_read_ptr = 0;
|
||||
|
||||
bool debug_get_char(char *elem) {
|
||||
bool ret = false;
|
||||
|
||||
ENTER_CRITICAL();
|
||||
if (debug_write_ptr != debug_read_ptr) {
|
||||
if (elem != NULL) *elem = debug_buffer[debug_read_ptr];
|
||||
debug_read_ptr = (debug_read_ptr + 1U) % DEBUG_BUFFER_SIZE;
|
||||
ret = true;
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void putch(const char a) {
|
||||
ENTER_CRITICAL();
|
||||
uint16_t next_write_ptr = (debug_write_ptr + 1U) % DEBUG_BUFFER_SIZE;
|
||||
if (next_write_ptr == debug_read_ptr) {
|
||||
// Drop the oldest byte when the buffer is full.
|
||||
debug_read_ptr = (debug_read_ptr + 1U) % DEBUG_BUFFER_SIZE;
|
||||
}
|
||||
debug_buffer[debug_write_ptr] = a;
|
||||
debug_write_ptr = next_write_ptr;
|
||||
EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
void print(const char *a) {
|
||||
for (const char *in = a; *in; in++) {
|
||||
if (*in == '\n') putch('\r');
|
||||
putch(*in);
|
||||
}
|
||||
}
|
||||
|
||||
static void puthx(uint32_t i, uint8_t len) {
|
||||
const char c[] = "0123456789abcdef";
|
||||
for (int pos = ((int)len * 4) - 4; pos > -4; pos -= 4) {
|
||||
putch(c[(i >> (unsigned int)(pos)) & 0xFU]);
|
||||
}
|
||||
}
|
||||
|
||||
void puth(unsigned int i) {
|
||||
puthx(i, 8U);
|
||||
}
|
||||
|
||||
static void hexdump(const void *a, int l) {
|
||||
if (a != NULL) {
|
||||
for (int i=0; i < l; i++) {
|
||||
if ((i != 0) && ((i & 0xf) == 0)) print("\n");
|
||||
puthx(((const unsigned char*)a)[i], 2U);
|
||||
print(" ");
|
||||
}
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
|
||||
static inline void puth4(unsigned int i) {
|
||||
puthx(i, 4U);
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/stm32h7/lli2c.h"
|
||||
|
||||
#define CODEC_I2C_ADDR 0x10
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
struct fan_state_t fan_state;
|
||||
@@ -25,13 +27,6 @@ void fan_tick(void) {
|
||||
fan_state.tach_counter = 0U;
|
||||
fan_state.rpm = (fan_rpm_fast + (3U * fan_state.rpm)) / 4U;
|
||||
|
||||
#ifdef DEBUG_FAN
|
||||
puth(fan_state.target_rpm);
|
||||
print(" "); puth(fan_rpm_fast);
|
||||
print(" "); puth(fan_state.power);
|
||||
print("\n");
|
||||
#endif
|
||||
|
||||
// Cooldown counter to prevent noise on tachometer line.
|
||||
if (fan_state.power > 0U) {
|
||||
fan_state.cooldown_counter = current_board->fan_enable_cooldown_time * FAN_TICK_FREQ;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
FDCAN_GlobalTypeDef *cans[PANDA_CAN_CNT] = {FDCAN1, FDCAN2, FDCAN3};
|
||||
@@ -149,7 +151,7 @@ void process_can(uint8_t can_number) {
|
||||
|
||||
// FDFDCANx_IT0 IRQ Handler (RX and errors)
|
||||
// blink blue when we are receiving CAN messages
|
||||
void can_rx(uint8_t can_number) {
|
||||
static void can_rx(uint8_t can_number) {
|
||||
FDCAN_GlobalTypeDef *FDCANx = CANIF_FROM_CAN_NUM(can_number);
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
|
||||
@@ -193,12 +195,9 @@ void can_rx(uint8_t can_number) {
|
||||
}
|
||||
can_set_checksum(&to_push);
|
||||
|
||||
// forwarding (panda only)
|
||||
// forwarding
|
||||
int bus_fwd_num = safety_fwd_hook(bus_number, to_push.addr);
|
||||
if (bus_fwd_num < 0) {
|
||||
bus_fwd_num = bus_config[can_number].forwarding_bus;
|
||||
}
|
||||
if (bus_fwd_num != -1) {
|
||||
if (bus_fwd_num >= 0) {
|
||||
CANPacket_t to_send;
|
||||
|
||||
to_send.fd = to_push.fd;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define MODE_INPUT 0
|
||||
#define MODE_OUTPUT 1
|
||||
#define MODE_ALTERNATE 2
|
||||
@@ -70,24 +72,6 @@ int get_gpio_input(const GPIO_TypeDef *GPIO, unsigned int pin) {
|
||||
return (GPIO->IDR & (1UL << pin)) == (1UL << pin);
|
||||
}
|
||||
|
||||
#ifdef PANDA_JUNGLE
|
||||
typedef struct {
|
||||
GPIO_TypeDef * const bank;
|
||||
uint8_t pin;
|
||||
} gpio_t;
|
||||
|
||||
void gpio_set_all_output(gpio_t *pins, uint8_t num_pins, bool enabled) {
|
||||
for (uint8_t i = 0; i < num_pins; i++) {
|
||||
set_gpio_output(pins[i].bank, pins[i].pin, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_set_bitmask(gpio_t *pins, uint8_t num_pins, uint32_t bitmask) {
|
||||
for (uint8_t i = 0; i < num_pins; i++) {
|
||||
set_gpio_output(pins[i].bank, pins[i].pin, (bitmask >> i) & 1U);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Detection with internal pullup
|
||||
#define PULL_EFFECTIVE_DELAY 4096
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
struct harness_t harness;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
void unused_interrupt_handler(void) {
|
||||
static void unused_interrupt_handler(void) {
|
||||
// Something is wrong if this handler is called!
|
||||
print("Unused interrupt handler called!\n");
|
||||
fault_occurred(FAULT_UNUSED_INTERRUPT_HANDLED);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#define LED_RED 0U
|
||||
#define LED_GREEN 1U
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define PWM_COUNTER_OVERFLOW 4800U // To get ~25kHz
|
||||
|
||||
// TODO: Implement for 32-bit timers
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
typedef struct reg {
|
||||
@@ -33,9 +35,7 @@ void register_set(volatile uint32_t *addr, uint32_t val, uint32_t mask){
|
||||
register_map[hash].value = (register_map[hash].value & (~mask)) | (val & mask);
|
||||
register_map[hash].check_mask |= mask;
|
||||
} else {
|
||||
#ifdef DEBUG_FAULTS
|
||||
print("Hash collision: address 0x"); puth((uint32_t) addr); print("!\n");
|
||||
#endif
|
||||
print("Hash collision: address 0x"); puth((uint32_t) addr); print("!\n");
|
||||
}
|
||||
EXIT_CRITICAL()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
static simple_watchdog_state_t wd_state;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
static void timer_init(TIM_TypeDef *TIM, int psc) {
|
||||
register_set(&(TIM->PSC), (psc-1), 0xFFFFU);
|
||||
register_set(&(TIM->DIER), TIM_DIER_UIE, 0x5F5FU);
|
||||
|
||||
+4
-129
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
// IRQs: OTG_FS
|
||||
@@ -108,11 +110,6 @@ static void *USB_ReadPacket(void *dest, uint16_t len) {
|
||||
}
|
||||
|
||||
static void USB_WritePacket(const void *src, uint16_t len, uint32_t ep) {
|
||||
#ifdef DEBUG_USB
|
||||
print("writing ");
|
||||
hexdump(src, len);
|
||||
#endif
|
||||
|
||||
uint32_t numpacket = ((uint32_t)len + (USBPACKET_MAX_SIZE - 1U)) / USBPACKET_MAX_SIZE;
|
||||
uint32_t count32b = 0;
|
||||
count32b = ((uint32_t)len + 3U) / 4U;
|
||||
@@ -135,11 +132,6 @@ static void USB_WritePacket(const void *src, uint16_t len, uint32_t ep) {
|
||||
// IN EP 0 TX FIFO has a max size of 127 bytes (much smaller than the rest)
|
||||
// so use TX FIFO empty interrupt to send larger amounts of data
|
||||
static void USB_WritePacket_EP0(uint8_t *src, uint16_t len) {
|
||||
#ifdef DEBUG_USB
|
||||
print("writing ");
|
||||
hexdump(src, len);
|
||||
#endif
|
||||
|
||||
uint16_t wplen = MIN(len, 0x40);
|
||||
USB_WritePacket(src, wplen, 0);
|
||||
|
||||
@@ -239,7 +231,7 @@ static void usb_setup(void) {
|
||||
ENDPOINT_RCV | 1, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type
|
||||
TOUSBORDER(0x0040U), // Max Packet (0x0040)
|
||||
0x00, // Polling Interval (NA)
|
||||
// endpoint 2, send serial
|
||||
// endpoint 2, bootstub flashing
|
||||
DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type
|
||||
ENDPOINT_SND | 2, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type
|
||||
TOUSBORDER(0x0040U), // Max Packet (0x0040)
|
||||
@@ -259,7 +251,7 @@ static void usb_setup(void) {
|
||||
ENDPOINT_RCV | 1, ENDPOINT_TYPE_INT, // Endpoint Num/Direction, Type
|
||||
TOUSBORDER(0x0040U), // Max Packet (0x0040)
|
||||
0x05, // Polling Interval (5 frames)
|
||||
// endpoint 2, send serial
|
||||
// endpoint 2, bootstub flashing
|
||||
DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type
|
||||
ENDPOINT_SND | 2, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type
|
||||
TOUSBORDER(0x0040U), // Max Packet (0x0040)
|
||||
@@ -463,10 +455,6 @@ static void usb_setup(void) {
|
||||
// set now?
|
||||
USBx_DEVICE->DCFG |= ((setup.b.wValue.w & 0x7fU) << 4);
|
||||
|
||||
#ifdef DEBUG_USB
|
||||
print(" set address\n");
|
||||
#endif
|
||||
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
|
||||
@@ -601,75 +589,24 @@ void usb_irqhandler(void) {
|
||||
unsigned int gotgint = USBx->GOTGINT;
|
||||
unsigned int daint = USBx_DEVICE->DAINT;
|
||||
|
||||
// gintsts SUSPEND? 04008428
|
||||
#ifdef DEBUG_USB
|
||||
puth(gintsts);
|
||||
print(" ");
|
||||
/*puth(USBx->GCCFG);
|
||||
print(" ");*/
|
||||
puth(gotgint);
|
||||
print(" ep ");
|
||||
puth(daint);
|
||||
print(" USB interrupt!\n");
|
||||
#endif
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_CIDSCHG) != 0U) {
|
||||
print("connector ID status change\n");
|
||||
}
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_USBRST) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print("USB reset\n");
|
||||
#endif
|
||||
usb_reset();
|
||||
}
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_ENUMDNE) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print("enumeration done\n");
|
||||
#endif
|
||||
// Full speed, ENUMSPD
|
||||
//puth(USBx_DEVICE->DSTS);
|
||||
}
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_OTGINT) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print("OTG int:");
|
||||
puth(USBx->GOTGINT);
|
||||
print("\n");
|
||||
#endif
|
||||
|
||||
// getting ADTOCHG
|
||||
//USBx->GOTGINT = USBx->GOTGINT;
|
||||
}
|
||||
|
||||
// RX FIFO first
|
||||
if ((gintsts & USB_OTG_GINTSTS_RXFLVL) != 0U) {
|
||||
// 1. Read the Receive status pop register
|
||||
volatile unsigned int rxst = USBx->GRXSTSP;
|
||||
int status = (rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17;
|
||||
|
||||
#ifdef DEBUG_USB
|
||||
print(" RX FIFO:");
|
||||
puth(rxst);
|
||||
print(" status: ");
|
||||
puth(status);
|
||||
print(" len: ");
|
||||
puth((rxst & USB_OTG_GRXSTSP_BCNT) >> 4);
|
||||
print("\n");
|
||||
#endif
|
||||
|
||||
if (status == STS_DATA_UPDT) {
|
||||
int endpoint = (rxst & USB_OTG_GRXSTSP_EPNUM);
|
||||
int len = (rxst & USB_OTG_GRXSTSP_BCNT) >> 4;
|
||||
(void)USB_ReadPacket(&usbdata, len);
|
||||
#ifdef DEBUG_USB
|
||||
print(" data ");
|
||||
puth(len);
|
||||
print("\n");
|
||||
hexdump(&usbdata, len);
|
||||
#endif
|
||||
|
||||
if (endpoint == 2) {
|
||||
comms_endpoint2_write((uint8_t *) usbdata, len);
|
||||
}
|
||||
@@ -680,11 +617,6 @@ void usb_irqhandler(void) {
|
||||
}
|
||||
} else if (status == STS_SETUP_UPDT) {
|
||||
(void)USB_ReadPacket(&setup, 8);
|
||||
#ifdef DEBUG_USB
|
||||
print(" setup ");
|
||||
hexdump(&setup, 8);
|
||||
print("\n");
|
||||
#endif
|
||||
} else {
|
||||
// status is neither STS_DATA_UPDT or STS_SETUP_UPDT, skip
|
||||
}
|
||||
@@ -704,9 +636,6 @@ void usb_irqhandler(void) {
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_BOUTNAKEFF) || (gintsts & USB_OTG_GINTSTS_GINAKEFF)) {
|
||||
// no global NAK, why is this getting set?
|
||||
#ifdef DEBUG_USB
|
||||
print("GLOBAL NAK\n");
|
||||
#endif
|
||||
USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK | USB_OTG_DCTL_CGINAK;
|
||||
}
|
||||
|
||||
@@ -722,51 +651,15 @@ void usb_irqhandler(void) {
|
||||
|
||||
// out endpoint hit
|
||||
if ((gintsts & USB_OTG_GINTSTS_OEPINT) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print(" 0:");
|
||||
puth(USBx_OUTEP(0U)->DOEPINT);
|
||||
print(" 2:");
|
||||
puth(USBx_OUTEP(2U)->DOEPINT);
|
||||
print(" 3:");
|
||||
puth(USBx_OUTEP(3U)->DOEPINT);
|
||||
print(" ");
|
||||
puth(USBx_OUTEP(3U)->DOEPCTL);
|
||||
print(" 4:");
|
||||
puth(USBx_OUTEP(4)->DOEPINT);
|
||||
print(" OUT ENDPOINT\n");
|
||||
#endif
|
||||
|
||||
if ((USBx_OUTEP(2U)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print(" OUT2 PACKET XFRC\n");
|
||||
#endif
|
||||
USBx_OUTEP(2U)->DOEPTSIZ = (1UL << 19) | 0x40U;
|
||||
USBx_OUTEP(2U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
|
||||
}
|
||||
|
||||
if ((USBx_OUTEP(3U)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print(" OUT3 PACKET XFRC\n");
|
||||
#endif
|
||||
// NAK cleared by process_can (if tx buffers have room)
|
||||
outep3_processing = false;
|
||||
refresh_can_tx_slots_available();
|
||||
} else if ((USBx_OUTEP(3U)->DOEPINT & 0x2000U) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print(" OUT3 PACKET WTF\n");
|
||||
#endif
|
||||
// if NAK was set trigger this, unknown interrupt
|
||||
// TODO: why was this here? fires when TX buffers when we can't clear NAK
|
||||
// USBx_OUTEP(3U)->DOEPTSIZ = (1U << 19) | 0x40U;
|
||||
// USBx_OUTEP(3U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
} else if ((USBx_OUTEP(3U)->DOEPINT) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print("OUTEP3 error ");
|
||||
puth(USBx_OUTEP(3U)->DOEPINT);
|
||||
print("\n");
|
||||
#endif
|
||||
} else {
|
||||
// USBx_OUTEP(3U)->DOEPINT is 0, ok to skip
|
||||
}
|
||||
|
||||
if ((USBx_OUTEP(0U)->DOEPINT & USB_OTG_DIEPINT_XFRC) != 0U) {
|
||||
@@ -786,14 +679,6 @@ void usb_irqhandler(void) {
|
||||
|
||||
// interrupt endpoint hit (Page 1221)
|
||||
if ((gintsts & USB_OTG_GINTSTS_IEPINT) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print(" ");
|
||||
puth(USBx_INEP(0U)->DIEPINT);
|
||||
print(" ");
|
||||
puth(USBx_INEP(1U)->DIEPINT);
|
||||
print(" IN ENDPOINT\n");
|
||||
#endif
|
||||
|
||||
// Should likely check the EP of the IN request even if there is
|
||||
// only one IN endpoint.
|
||||
|
||||
@@ -811,9 +696,6 @@ void usb_irqhandler(void) {
|
||||
case 0: ////// Bulk config
|
||||
// *** IN token received when TxFIFO is empty
|
||||
if ((USBx_INEP(1U)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print(" IN PACKET QUEUE\n");
|
||||
#endif
|
||||
// TODO: always assuming max len, can we get the length?
|
||||
USB_WritePacket((void *)response, comms_can_read(response, 0x40), 1);
|
||||
}
|
||||
@@ -822,9 +704,6 @@ void usb_irqhandler(void) {
|
||||
case 1: ////// Interrupt config
|
||||
// *** IN token received when TxFIFO is empty
|
||||
if ((USBx_INEP(1U)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print(" IN PACKET QUEUE\n");
|
||||
#endif
|
||||
// TODO: always assuming max len, can we get the length?
|
||||
int len = comms_can_read(response, 0x40);
|
||||
if (len > 0) {
|
||||
@@ -838,10 +717,6 @@ void usb_irqhandler(void) {
|
||||
}
|
||||
|
||||
if ((USBx_INEP(0U)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0U) {
|
||||
#ifdef DEBUG_USB
|
||||
print(" IN PACKET QUEUE\n");
|
||||
#endif
|
||||
|
||||
if ((ep0_txlen != 0U) && ((USBx_INEP(0U)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40U)) {
|
||||
uint16_t len = MIN(ep0_txlen, 0x40);
|
||||
USB_WritePacket(ep0_txdata, len, 0);
|
||||
|
||||
@@ -24,7 +24,6 @@ typedef struct {
|
||||
|
||||
TIM_TypeDef timer;
|
||||
TIM_TypeDef *MICROSECOND_TIMER = &timer;
|
||||
uint32_t microsecond_timer_get(void);
|
||||
|
||||
uint32_t microsecond_timer_get(void) {
|
||||
return MICROSECOND_TIMER->CNT;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// from the linker script
|
||||
#define APP_START_ADDRESS 0x8020000U
|
||||
|
||||
@@ -119,12 +121,12 @@ void comms_endpoint2_write(const uint8_t *data, uint32_t len) {
|
||||
|
||||
void soft_flasher_start(void) {
|
||||
print("\n\n\n************************ FLASHER START ************************\n");
|
||||
print("MCU UID: "); hexdump((const uint8_t *)UID_BASE, 12);
|
||||
|
||||
enter_bootloader_mode = 0;
|
||||
|
||||
flasher_peripherals_init();
|
||||
|
||||
gpio_usart2_init();
|
||||
gpio_usb_init();
|
||||
led_init();
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// **** libc ****
|
||||
|
||||
__attribute__((aligned(32), noinline)) void delay(uint32_t a) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// this is where we manage the dongle ID assigned during our
|
||||
// manufacturing. aside from this, there's a UID for the MCU
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// ///////////////////////////////////////////////////////////// //
|
||||
// Hardware abstraction layer for all different supported boards //
|
||||
// ///////////////////////////////////////////////////////////// //
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
HSE: 25MHz
|
||||
PLL1Q: 80MHz (for FDCAN)
|
||||
|
||||
+2725
-2725
File diff suppressed because it is too large
Load Diff
+24740
-24740
File diff suppressed because it is too large
Load Diff
+24740
-24740
File diff suppressed because it is too large
Load Diff
+243
-243
@@ -1,243 +1,243 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7xx.h
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS STM32H7xx Device Peripheral Access Layer Header File.
|
||||
*
|
||||
* The file is the unique include file that the application programmer
|
||||
* is using in the C source code, usually in main.c. This file contains:
|
||||
* - Configuration section that allows to select:
|
||||
* - The STM32H7xx device used in the target application
|
||||
* - To use or not the peripheral’s drivers in application code(i.e.
|
||||
* code will be based on direct access to peripheral’s registers
|
||||
* rather than drivers API), this option is controlled by
|
||||
* "#define USE_HAL_DRIVER"
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32h7xx
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef STM32H7xx_H
|
||||
#define STM32H7xx_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** @addtogroup Library_configuration_section
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief STM32 Family
|
||||
*/
|
||||
#if !defined (STM32H7)
|
||||
#define STM32H7
|
||||
#endif /* STM32H7 */
|
||||
|
||||
|
||||
/* Uncomment the line below according to the target STM32H7 device used in your
|
||||
application
|
||||
*/
|
||||
|
||||
/* #if !defined (STM32H743xx) && !defined (STM32H753xx) && !defined (STM32H750xx) && !defined (STM32H742xx) && \
|
||||
!defined (STM32H745xx) && !defined (STM32H755xx) && !defined (STM32H747xx) && !defined (STM32H757xx) && \
|
||||
!defined (STM32H7A3xx) && !defined (STM32H7A3xxQ) && !defined (STM32H7B3xx) && !defined (STM32H7B3xxQ) && !defined (STM32H7B0xx) && !defined (STM32H7B0xxQ) && \
|
||||
!defined (STM32H735xx) && !defined (STM32H733xx) && !defined (STM32H730xx) && !defined (STM32H730xxQ) && !defined (STM32H725xx) && !defined (STM32H723xx) */
|
||||
/* #define STM32H742xx */ /*!< STM32H742VI, STM32H742ZI, STM32H742AI, STM32H742II, STM32H742BI, STM32H742XI Devices */
|
||||
/* #define STM32H743xx */ /*!< STM32H743VI, STM32H743ZI, STM32H743AI, STM32H743II, STM32H743BI, STM32H743XI Devices */
|
||||
/* #define STM32H753xx */ /*!< STM32H753VI, STM32H753ZI, STM32H753AI, STM32H753II, STM32H753BI, STM32H753XI Devices */
|
||||
/* #define STM32H750xx */ /*!< STM32H750V, STM32H750I, STM32H750X Devices */
|
||||
/* #define STM32H747xx */ /*!< STM32H747ZI, STM32H747AI, STM32H747II, STM32H747BI, STM32H747XI Devices */
|
||||
/* #define STM32H757xx */ /*!< STM32H757ZI, STM32H757AI, STM32H757II, STM32H757BI, STM32H757XI Devices */
|
||||
/* #define STM32H745xx */ /*!< STM32H745ZI, STM32H745II, STM32H745BI, STM32H745XI Devices */
|
||||
/* #define STM32H755xx */ /*!< STM32H755ZI, STM32H755II, STM32H755BI, STM32H755XI Devices */
|
||||
/* #define STM32H7B0xx */ /*!< STM32H7B0ABIxQ, STM32H7B0IBTx, STM32H7B0RBTx, STM32H7B0VBTx, STM32H7B0ZBTx, STM32H7B0IBKxQ */
|
||||
/* #define STM32H7A3xx */ /*!< STM32H7A3IIK6, STM32H7A3IIT6, STM32H7A3NIH6, STM32H7A3RIT6, STM32H7A3VIH6, STM32H7A3VIT6, STM32H7A3ZIT6 */
|
||||
/* #define STM32H7A3xxQ */ /*!< STM32H7A3QIY6Q, STM32H7A3IIK6Q, STM32H7A3IIT6Q, STM32H7A3LIH6Q, STM32H7A3VIH6Q, STM32H7A3VIT6Q, STM32H7A3AII6Q, STM32H7A3ZIT6Q */
|
||||
/* #define STM32H7B3xx */ /*!< STM32H7B3IIK6, STM32H7B3IIT6, STM32H7B3NIH6, STM32H7B3RIT6, STM32H7B3VIH6, STM32H7B3VIT6, STM32H7B3ZIT6 */
|
||||
/* #define STM32H7B3xxQ */ /*!< STM32H7B3QIY6Q, STM32H7B3IIK6Q, STM32H7B3IIT6Q, STM32H7B3LIH6Q, STM32H7B3VIH6Q, STM32H7B3VIT6Q, STM32H7B3AII6Q, STM32H7B3ZIT6Q */
|
||||
/* #define STM32H735xx */ /*!< STM32H735AGI6, STM32H735IGK6, STM32H735RGV6, STM32H735VGT6, STM32H735VGY6, STM32H735ZGT6 Devices */
|
||||
/* #define STM32H733xx */ /*!< STM32H733VGH6, STM32H733VGT6, STM32H733ZGI6, STM32H733ZGT6, Devices */
|
||||
/* #define STM32H730xx */ /*!< STM32H730VBH6, STM32H730VBT6, STM32H730ZBT6, STM32H730ZBI6 Devices */
|
||||
/* #define STM32H730xxQ */ /*!< STM32H730IBT6Q, STM32H730ABI6Q, STM32H730IBK6Q Devices */
|
||||
/* #define STM32H725xx */ /*!< STM32H725AGI6, STM32H725IGK6, STM32H725IGT6, STM32H725RGV6, STM32H725VGT6, STM32H725VGY6, STM32H725ZGT6, STM32H725REV6, SM32H725VET6, STM32H725ZET6, STM32H725AEI6, STM32H725IET6, STM32H725IEK6 Devices */
|
||||
/* #define STM32H723xx */ /*!< STM32H723VGH6, STM32H723VGT6, STM32H723ZGI6, STM32H723ZGT6, STM32H723VET6, STM32H723VEH6, STM32H723ZET6, STM32H723ZEI6 Devices */
|
||||
/* #endif */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to switch between these
|
||||
devices, you can define the device in your toolchain compiler preprocessor.
|
||||
*/
|
||||
|
||||
#if defined(DUAL_CORE) && !defined(CORE_CM4) && !defined(CORE_CM7)
|
||||
#error "Dual core device, please select CORE_CM4 or CORE_CM7"
|
||||
#endif
|
||||
|
||||
#if !defined (USE_HAL_DRIVER)
|
||||
/**
|
||||
* @brief Comment the line below if you will not use the peripherals drivers.
|
||||
In this case, these drivers will not be included and the application code will
|
||||
be based on direct access to peripherals registers
|
||||
*/
|
||||
/*#define USE_HAL_DRIVER */
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
/**
|
||||
* @brief CMSIS Device version number V1.10.0
|
||||
*/
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_MAIN (0x01) /*!< [31:24] main version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_SUB1 (0x0A) /*!< [23:16] sub1 version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION ((__STM32H7xx_CMSIS_DEVICE_VERSION_MAIN << 24)\
|
||||
|(__STM32H7xx_CMSIS_DEVICE_VERSION_SUB1 << 16)\
|
||||
|(__STM32H7xx_CMSIS_DEVICE_VERSION_SUB2 << 8 )\
|
||||
|(__STM32H7xx_CMSIS_DEVICE_VERSION_RC))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Device_Included
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32H743xx)
|
||||
#include "stm32h743xx.h"
|
||||
// #elif defined(STM32H753xx)
|
||||
// #include "stm32h753xx.h"
|
||||
// #elif defined(STM32H750xx)
|
||||
// #include "stm32h750xx.h"
|
||||
// #elif defined(STM32H742xx)
|
||||
// #include "stm32h742xx.h"
|
||||
// #elif defined(STM32H745xx)
|
||||
// #include "stm32h745xx.h"
|
||||
// #elif defined(STM32H755xx)
|
||||
// #include "stm32h755xx.h"
|
||||
// #elif defined(STM32H747xx)
|
||||
// #include "stm32h747xx.h"
|
||||
// #elif defined(STM32H757xx)
|
||||
// #include "stm32h757xx.h"
|
||||
// #elif defined(STM32H7B0xx)
|
||||
// #include "stm32h7b0xx.h"
|
||||
// #elif defined(STM32H7B0xxQ)
|
||||
// #include "stm32h7b0xxq.h"
|
||||
// #elif defined(STM32H7A3xx)
|
||||
// #include "stm32h7a3xx.h"
|
||||
// #elif defined(STM32H7B3xx)
|
||||
// #include "stm32h7b3xx.h"
|
||||
// #elif defined(STM32H7A3xxQ)
|
||||
// #include "stm32h7a3xxq.h"
|
||||
// #elif defined(STM32H7B3xxQ)
|
||||
// #include "stm32h7b3xxq.h"
|
||||
#elif defined(STM32H735xx)
|
||||
#include "stm32h735xx.h"
|
||||
// #elif defined(STM32H733xx)
|
||||
// #include "stm32h733xx.h"
|
||||
// #elif defined(STM32H730xx)
|
||||
// #include "stm32h730xx.h"
|
||||
// #elif defined(STM32H730xxQ)
|
||||
// #include "stm32h730xxq.h"
|
||||
#elif defined(STM32H725xx)
|
||||
#include "stm32h725xx.h"
|
||||
// #elif defined(STM32H723xx)
|
||||
// #include "stm32h723xx.h"
|
||||
#else
|
||||
#error "Please select first the target STM32H7xx device used in your application (in stm32h7xx.h file)"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Exported_types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RESET = 0,
|
||||
SET = !RESET
|
||||
} FlagStatus, ITStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DISABLE = 0,
|
||||
ENABLE = !DISABLE
|
||||
} FunctionalState;
|
||||
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SUCCESS = 0,
|
||||
ERROR = !SUCCESS
|
||||
} ErrorStatus;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup Exported_macros
|
||||
* @{
|
||||
*/
|
||||
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
|
||||
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
#define READ_BIT(REG, BIT) ((REG) & (BIT))
|
||||
|
||||
#define CLEAR_REG(REG) ((REG) = (0x0))
|
||||
|
||||
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||
|
||||
#define READ_REG(REG) ((REG))
|
||||
|
||||
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
|
||||
|
||||
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined (USE_HAL_DRIVER)
|
||||
#include "stm32h7xx_hal.h"
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* STM32H7xx_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7xx.h
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS STM32H7xx Device Peripheral Access Layer Header File.
|
||||
*
|
||||
* The file is the unique include file that the application programmer
|
||||
* is using in the C source code, usually in main.c. This file contains:
|
||||
* - Configuration section that allows to select:
|
||||
* - The STM32H7xx device used in the target application
|
||||
* - To use or not the peripheral’s drivers in application code(i.e.
|
||||
* code will be based on direct access to peripheral’s registers
|
||||
* rather than drivers API), this option is controlled by
|
||||
* "#define USE_HAL_DRIVER"
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32h7xx
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef STM32H7xx_H
|
||||
#define STM32H7xx_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** @addtogroup Library_configuration_section
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief STM32 Family
|
||||
*/
|
||||
#if !defined (STM32H7)
|
||||
#define STM32H7
|
||||
#endif /* STM32H7 */
|
||||
|
||||
|
||||
/* Uncomment the line below according to the target STM32H7 device used in your
|
||||
application
|
||||
*/
|
||||
|
||||
/* #if !defined (STM32H743xx) && !defined (STM32H753xx) && !defined (STM32H750xx) && !defined (STM32H742xx) && \
|
||||
!defined (STM32H745xx) && !defined (STM32H755xx) && !defined (STM32H747xx) && !defined (STM32H757xx) && \
|
||||
!defined (STM32H7A3xx) && !defined (STM32H7A3xxQ) && !defined (STM32H7B3xx) && !defined (STM32H7B3xxQ) && !defined (STM32H7B0xx) && !defined (STM32H7B0xxQ) && \
|
||||
!defined (STM32H735xx) && !defined (STM32H733xx) && !defined (STM32H730xx) && !defined (STM32H730xxQ) && !defined (STM32H725xx) && !defined (STM32H723xx) */
|
||||
/* #define STM32H742xx */ /*!< STM32H742VI, STM32H742ZI, STM32H742AI, STM32H742II, STM32H742BI, STM32H742XI Devices */
|
||||
/* #define STM32H743xx */ /*!< STM32H743VI, STM32H743ZI, STM32H743AI, STM32H743II, STM32H743BI, STM32H743XI Devices */
|
||||
/* #define STM32H753xx */ /*!< STM32H753VI, STM32H753ZI, STM32H753AI, STM32H753II, STM32H753BI, STM32H753XI Devices */
|
||||
/* #define STM32H750xx */ /*!< STM32H750V, STM32H750I, STM32H750X Devices */
|
||||
/* #define STM32H747xx */ /*!< STM32H747ZI, STM32H747AI, STM32H747II, STM32H747BI, STM32H747XI Devices */
|
||||
/* #define STM32H757xx */ /*!< STM32H757ZI, STM32H757AI, STM32H757II, STM32H757BI, STM32H757XI Devices */
|
||||
/* #define STM32H745xx */ /*!< STM32H745ZI, STM32H745II, STM32H745BI, STM32H745XI Devices */
|
||||
/* #define STM32H755xx */ /*!< STM32H755ZI, STM32H755II, STM32H755BI, STM32H755XI Devices */
|
||||
/* #define STM32H7B0xx */ /*!< STM32H7B0ABIxQ, STM32H7B0IBTx, STM32H7B0RBTx, STM32H7B0VBTx, STM32H7B0ZBTx, STM32H7B0IBKxQ */
|
||||
/* #define STM32H7A3xx */ /*!< STM32H7A3IIK6, STM32H7A3IIT6, STM32H7A3NIH6, STM32H7A3RIT6, STM32H7A3VIH6, STM32H7A3VIT6, STM32H7A3ZIT6 */
|
||||
/* #define STM32H7A3xxQ */ /*!< STM32H7A3QIY6Q, STM32H7A3IIK6Q, STM32H7A3IIT6Q, STM32H7A3LIH6Q, STM32H7A3VIH6Q, STM32H7A3VIT6Q, STM32H7A3AII6Q, STM32H7A3ZIT6Q */
|
||||
/* #define STM32H7B3xx */ /*!< STM32H7B3IIK6, STM32H7B3IIT6, STM32H7B3NIH6, STM32H7B3RIT6, STM32H7B3VIH6, STM32H7B3VIT6, STM32H7B3ZIT6 */
|
||||
/* #define STM32H7B3xxQ */ /*!< STM32H7B3QIY6Q, STM32H7B3IIK6Q, STM32H7B3IIT6Q, STM32H7B3LIH6Q, STM32H7B3VIH6Q, STM32H7B3VIT6Q, STM32H7B3AII6Q, STM32H7B3ZIT6Q */
|
||||
/* #define STM32H735xx */ /*!< STM32H735AGI6, STM32H735IGK6, STM32H735RGV6, STM32H735VGT6, STM32H735VGY6, STM32H735ZGT6 Devices */
|
||||
/* #define STM32H733xx */ /*!< STM32H733VGH6, STM32H733VGT6, STM32H733ZGI6, STM32H733ZGT6, Devices */
|
||||
/* #define STM32H730xx */ /*!< STM32H730VBH6, STM32H730VBT6, STM32H730ZBT6, STM32H730ZBI6 Devices */
|
||||
/* #define STM32H730xxQ */ /*!< STM32H730IBT6Q, STM32H730ABI6Q, STM32H730IBK6Q Devices */
|
||||
/* #define STM32H725xx */ /*!< STM32H725AGI6, STM32H725IGK6, STM32H725IGT6, STM32H725RGV6, STM32H725VGT6, STM32H725VGY6, STM32H725ZGT6, STM32H725REV6, SM32H725VET6, STM32H725ZET6, STM32H725AEI6, STM32H725IET6, STM32H725IEK6 Devices */
|
||||
/* #define STM32H723xx */ /*!< STM32H723VGH6, STM32H723VGT6, STM32H723ZGI6, STM32H723ZGT6, STM32H723VET6, STM32H723VEH6, STM32H723ZET6, STM32H723ZEI6 Devices */
|
||||
/* #endif */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to switch between these
|
||||
devices, you can define the device in your toolchain compiler preprocessor.
|
||||
*/
|
||||
|
||||
#if defined(DUAL_CORE) && !defined(CORE_CM4) && !defined(CORE_CM7)
|
||||
#error "Dual core device, please select CORE_CM4 or CORE_CM7"
|
||||
#endif
|
||||
|
||||
#if !defined (USE_HAL_DRIVER)
|
||||
/**
|
||||
* @brief Comment the line below if you will not use the peripherals drivers.
|
||||
In this case, these drivers will not be included and the application code will
|
||||
be based on direct access to peripherals registers
|
||||
*/
|
||||
/*#define USE_HAL_DRIVER */
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
/**
|
||||
* @brief CMSIS Device version number V1.10.0
|
||||
*/
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_MAIN (0x01) /*!< [31:24] main version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_SUB1 (0x0A) /*!< [23:16] sub1 version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION ((__STM32H7xx_CMSIS_DEVICE_VERSION_MAIN << 24)\
|
||||
|(__STM32H7xx_CMSIS_DEVICE_VERSION_SUB1 << 16)\
|
||||
|(__STM32H7xx_CMSIS_DEVICE_VERSION_SUB2 << 8 )\
|
||||
|(__STM32H7xx_CMSIS_DEVICE_VERSION_RC))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Device_Included
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32H743xx)
|
||||
#include "stm32h743xx.h"
|
||||
// #elif defined(STM32H753xx)
|
||||
// #include "stm32h753xx.h"
|
||||
// #elif defined(STM32H750xx)
|
||||
// #include "stm32h750xx.h"
|
||||
// #elif defined(STM32H742xx)
|
||||
// #include "stm32h742xx.h"
|
||||
// #elif defined(STM32H745xx)
|
||||
// #include "stm32h745xx.h"
|
||||
// #elif defined(STM32H755xx)
|
||||
// #include "stm32h755xx.h"
|
||||
// #elif defined(STM32H747xx)
|
||||
// #include "stm32h747xx.h"
|
||||
// #elif defined(STM32H757xx)
|
||||
// #include "stm32h757xx.h"
|
||||
// #elif defined(STM32H7B0xx)
|
||||
// #include "stm32h7b0xx.h"
|
||||
// #elif defined(STM32H7B0xxQ)
|
||||
// #include "stm32h7b0xxq.h"
|
||||
// #elif defined(STM32H7A3xx)
|
||||
// #include "stm32h7a3xx.h"
|
||||
// #elif defined(STM32H7B3xx)
|
||||
// #include "stm32h7b3xx.h"
|
||||
// #elif defined(STM32H7A3xxQ)
|
||||
// #include "stm32h7a3xxq.h"
|
||||
// #elif defined(STM32H7B3xxQ)
|
||||
// #include "stm32h7b3xxq.h"
|
||||
#elif defined(STM32H735xx)
|
||||
#include "stm32h735xx.h"
|
||||
// #elif defined(STM32H733xx)
|
||||
// #include "stm32h733xx.h"
|
||||
// #elif defined(STM32H730xx)
|
||||
// #include "stm32h730xx.h"
|
||||
// #elif defined(STM32H730xxQ)
|
||||
// #include "stm32h730xxq.h"
|
||||
#elif defined(STM32H725xx)
|
||||
#include "stm32h725xx.h"
|
||||
// #elif defined(STM32H723xx)
|
||||
// #include "stm32h723xx.h"
|
||||
#else
|
||||
#error "Please select first the target STM32H7xx device used in your application (in stm32h7xx.h file)"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Exported_types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RESET = 0,
|
||||
SET = !RESET
|
||||
} FlagStatus, ITStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DISABLE = 0,
|
||||
ENABLE = !DISABLE
|
||||
} FunctionalState;
|
||||
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SUCCESS = 0,
|
||||
ERROR = !SUCCESS
|
||||
} ErrorStatus;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup Exported_macros
|
||||
* @{
|
||||
*/
|
||||
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
|
||||
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
#define READ_BIT(REG, BIT) ((REG) & (BIT))
|
||||
|
||||
#define CLEAR_REG(REG) ((REG) = (0x0))
|
||||
|
||||
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||
|
||||
#define READ_REG(REG) ((REG))
|
||||
|
||||
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
|
||||
|
||||
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined (USE_HAL_DRIVER)
|
||||
#include "stm32h7xx_hal.h"
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* STM32H7xx_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -1,221 +1,221 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7xx_hal_def.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains HAL common defines, enumeration, macros and
|
||||
* structures definitions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32H7xx_HAL_DEF
|
||||
#define STM32H7xx_HAL_DEF
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32h7xx.h"
|
||||
//#include "Legacy/stm32_hal_legacy.h"
|
||||
//#include <stddef.h>
|
||||
//#include <math.h>
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief HAL Status structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_OK = 0x00,
|
||||
HAL_ERROR = 0x01,
|
||||
HAL_BUSY = 0x02,
|
||||
HAL_TIMEOUT = 0x03
|
||||
} HAL_StatusTypeDef;
|
||||
|
||||
/**
|
||||
* @brief HAL Lock structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_UNLOCKED = 0x00,
|
||||
HAL_LOCKED = 0x01
|
||||
} HAL_LockTypeDef;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
#define HAL_MAX_DELAY 0xFFFFFFFFU
|
||||
|
||||
#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT))
|
||||
#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U)
|
||||
|
||||
#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \
|
||||
do{ \
|
||||
(__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
|
||||
(__DMA_HANDLE__).Parent = (__HANDLE__); \
|
||||
} while(0)
|
||||
|
||||
#define UNUSED(x) ((void)(x))
|
||||
|
||||
/** @brief Reset the Handle's State field.
|
||||
* @param __HANDLE__: specifies the Peripheral Handle.
|
||||
* @note This macro can be used for the following purpose:
|
||||
* - When the Handle is declared as local variable; before passing it as parameter
|
||||
* to HAL_PPP_Init() for the first time, it is mandatory to use this macro
|
||||
* to set to 0 the Handle's "State" field.
|
||||
* Otherwise, "State" field may have any random value and the first time the function
|
||||
* HAL_PPP_Init() is called, the low level hardware initialization will be missed
|
||||
* (i.e. HAL_PPP_MspInit() will not be executed).
|
||||
* - When there is a need to reconfigure the low level hardware: instead of calling
|
||||
* HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init().
|
||||
* In this later function, when the Handle's "State" field is set to 0, it will execute the function
|
||||
* HAL_PPP_MspInit() which will reconfigure the low level hardware.
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0)
|
||||
|
||||
#if (USE_RTOS == 1)
|
||||
#error " USE_RTOS should be 0 in the current HAL release "
|
||||
#else
|
||||
#define __HAL_LOCK(__HANDLE__) \
|
||||
do{ \
|
||||
if((__HANDLE__)->Lock == HAL_LOCKED) \
|
||||
{ \
|
||||
return HAL_BUSY; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(__HANDLE__)->Lock = HAL_LOCKED; \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
#define __HAL_UNLOCK(__HANDLE__) \
|
||||
do{ \
|
||||
(__HANDLE__)->Lock = HAL_UNLOCKED; \
|
||||
}while (0)
|
||||
#endif /* USE_RTOS */
|
||||
|
||||
|
||||
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((packed))
|
||||
#endif
|
||||
#elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif /* __weak */
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif /* __packed */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */
|
||||
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
|
||||
#ifndef __ALIGN_BEGIN
|
||||
#define __ALIGN_BEGIN
|
||||
#endif
|
||||
#ifndef __ALIGN_END
|
||||
#define __ALIGN_END __attribute__ ((aligned (4)))
|
||||
#endif
|
||||
#elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
|
||||
#ifndef __ALIGN_END
|
||||
#define __ALIGN_END __attribute__ ((aligned (4)))
|
||||
#endif /* __ALIGN_END */
|
||||
#ifndef __ALIGN_BEGIN
|
||||
#define __ALIGN_BEGIN
|
||||
#endif /* __ALIGN_BEGIN */
|
||||
#else
|
||||
#ifndef __ALIGN_END
|
||||
#define __ALIGN_END
|
||||
#endif /* __ALIGN_END */
|
||||
#ifndef __ALIGN_BEGIN
|
||||
#if defined (__CC_ARM) /* ARM Compiler V5 */
|
||||
#define __ALIGN_BEGIN __align(4)
|
||||
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||
#define __ALIGN_BEGIN
|
||||
#endif /* __CC_ARM */
|
||||
#endif /* __ALIGN_BEGIN */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/* Macro to get variable aligned on 32-bytes,needed for cache maintenance purpose */
|
||||
#if defined (__GNUC__) /* GNU Compiler */
|
||||
#define ALIGN_32BYTES(buf) buf __attribute__ ((aligned (32)))
|
||||
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||
#define ALIGN_32BYTES(buf) _Pragma("data_alignment=32") buf
|
||||
#elif defined (__CC_ARM) /* ARM Compiler */
|
||||
#define ALIGN_32BYTES(buf) __align(32) buf
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief __RAM_FUNC definition
|
||||
*/
|
||||
#if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/* ARM Compiler V4/V5 and V6
|
||||
--------------------------
|
||||
RAM functions are defined using the toolchain options.
|
||||
Functions that are executed in RAM should reside in a separate source module.
|
||||
Using the 'Options for File' dialog you can simply change the 'Code / Const'
|
||||
area of a module to a memory space in physical RAM.
|
||||
Available memory areas are declared in the 'Target' tab of the 'Options for Target'
|
||||
dialog.
|
||||
*/
|
||||
#define __RAM_FUNC
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
/* ICCARM Compiler
|
||||
---------------
|
||||
RAM functions are defined using a specific toolchain keyword "__ramfunc".
|
||||
*/
|
||||
#define __RAM_FUNC __ramfunc
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
/* GNU Compiler
|
||||
------------
|
||||
RAM functions are defined using a specific toolchain attribute
|
||||
"__attribute__((section(".RamFunc")))".
|
||||
*/
|
||||
#define __RAM_FUNC __attribute__((section(".RamFunc")))
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief __NOINLINE definition
|
||||
*/
|
||||
#if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || defined ( __GNUC__ )
|
||||
/* ARM V4/V5 and V6 & GNU Compiler
|
||||
-------------------------------
|
||||
*/
|
||||
#define __NOINLINE __attribute__ ( (noinline) )
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
/* ICCARM Compiler
|
||||
---------------
|
||||
*/
|
||||
#define __NOINLINE _Pragma("optimize = no_inline")
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32H7xx_HAL_DEF */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7xx_hal_def.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains HAL common defines, enumeration, macros and
|
||||
* structures definitions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32H7xx_HAL_DEF
|
||||
#define STM32H7xx_HAL_DEF
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32h7xx.h"
|
||||
//#include "Legacy/stm32_hal_legacy.h"
|
||||
//#include <stddef.h>
|
||||
//#include <math.h>
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief HAL Status structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_OK = 0x00,
|
||||
HAL_ERROR = 0x01,
|
||||
HAL_BUSY = 0x02,
|
||||
HAL_TIMEOUT = 0x03
|
||||
} HAL_StatusTypeDef;
|
||||
|
||||
/**
|
||||
* @brief HAL Lock structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_UNLOCKED = 0x00,
|
||||
HAL_LOCKED = 0x01
|
||||
} HAL_LockTypeDef;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
#define HAL_MAX_DELAY 0xFFFFFFFFU
|
||||
|
||||
#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT))
|
||||
#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U)
|
||||
|
||||
#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \
|
||||
do{ \
|
||||
(__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
|
||||
(__DMA_HANDLE__).Parent = (__HANDLE__); \
|
||||
} while(0)
|
||||
|
||||
#define UNUSED(x) ((void)(x))
|
||||
|
||||
/** @brief Reset the Handle's State field.
|
||||
* @param __HANDLE__: specifies the Peripheral Handle.
|
||||
* @note This macro can be used for the following purpose:
|
||||
* - When the Handle is declared as local variable; before passing it as parameter
|
||||
* to HAL_PPP_Init() for the first time, it is mandatory to use this macro
|
||||
* to set to 0 the Handle's "State" field.
|
||||
* Otherwise, "State" field may have any random value and the first time the function
|
||||
* HAL_PPP_Init() is called, the low level hardware initialization will be missed
|
||||
* (i.e. HAL_PPP_MspInit() will not be executed).
|
||||
* - When there is a need to reconfigure the low level hardware: instead of calling
|
||||
* HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init().
|
||||
* In this later function, when the Handle's "State" field is set to 0, it will execute the function
|
||||
* HAL_PPP_MspInit() which will reconfigure the low level hardware.
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0)
|
||||
|
||||
#if (USE_RTOS == 1)
|
||||
#error " USE_RTOS should be 0 in the current HAL release "
|
||||
#else
|
||||
#define __HAL_LOCK(__HANDLE__) \
|
||||
do{ \
|
||||
if((__HANDLE__)->Lock == HAL_LOCKED) \
|
||||
{ \
|
||||
return HAL_BUSY; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(__HANDLE__)->Lock = HAL_LOCKED; \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
#define __HAL_UNLOCK(__HANDLE__) \
|
||||
do{ \
|
||||
(__HANDLE__)->Lock = HAL_UNLOCKED; \
|
||||
}while (0)
|
||||
#endif /* USE_RTOS */
|
||||
|
||||
|
||||
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((packed))
|
||||
#endif
|
||||
#elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif /* __weak */
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif /* __packed */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */
|
||||
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
|
||||
#ifndef __ALIGN_BEGIN
|
||||
#define __ALIGN_BEGIN
|
||||
#endif
|
||||
#ifndef __ALIGN_END
|
||||
#define __ALIGN_END __attribute__ ((aligned (4)))
|
||||
#endif
|
||||
#elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
|
||||
#ifndef __ALIGN_END
|
||||
#define __ALIGN_END __attribute__ ((aligned (4)))
|
||||
#endif /* __ALIGN_END */
|
||||
#ifndef __ALIGN_BEGIN
|
||||
#define __ALIGN_BEGIN
|
||||
#endif /* __ALIGN_BEGIN */
|
||||
#else
|
||||
#ifndef __ALIGN_END
|
||||
#define __ALIGN_END
|
||||
#endif /* __ALIGN_END */
|
||||
#ifndef __ALIGN_BEGIN
|
||||
#if defined (__CC_ARM) /* ARM Compiler V5 */
|
||||
#define __ALIGN_BEGIN __align(4)
|
||||
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||
#define __ALIGN_BEGIN
|
||||
#endif /* __CC_ARM */
|
||||
#endif /* __ALIGN_BEGIN */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/* Macro to get variable aligned on 32-bytes,needed for cache maintenance purpose */
|
||||
#if defined (__GNUC__) /* GNU Compiler */
|
||||
#define ALIGN_32BYTES(buf) buf __attribute__ ((aligned (32)))
|
||||
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||
#define ALIGN_32BYTES(buf) _Pragma("data_alignment=32") buf
|
||||
#elif defined (__CC_ARM) /* ARM Compiler */
|
||||
#define ALIGN_32BYTES(buf) __align(32) buf
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief __RAM_FUNC definition
|
||||
*/
|
||||
#if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/* ARM Compiler V4/V5 and V6
|
||||
--------------------------
|
||||
RAM functions are defined using the toolchain options.
|
||||
Functions that are executed in RAM should reside in a separate source module.
|
||||
Using the 'Options for File' dialog you can simply change the 'Code / Const'
|
||||
area of a module to a memory space in physical RAM.
|
||||
Available memory areas are declared in the 'Target' tab of the 'Options for Target'
|
||||
dialog.
|
||||
*/
|
||||
#define __RAM_FUNC
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
/* ICCARM Compiler
|
||||
---------------
|
||||
RAM functions are defined using a specific toolchain keyword "__ramfunc".
|
||||
*/
|
||||
#define __RAM_FUNC __ramfunc
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
/* GNU Compiler
|
||||
------------
|
||||
RAM functions are defined using a specific toolchain attribute
|
||||
"__attribute__((section(".RamFunc")))".
|
||||
*/
|
||||
#define __RAM_FUNC __attribute__((section(".RamFunc")))
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief __NOINLINE definition
|
||||
*/
|
||||
#if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || defined ( __GNUC__ )
|
||||
/* ARM V4/V5 and V6 & GNU Compiler
|
||||
-------------------------------
|
||||
*/
|
||||
#define __NOINLINE __attribute__ ( (noinline) )
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
/* ICCARM Compiler
|
||||
---------------
|
||||
*/
|
||||
#define __NOINLINE _Pragma("optimize = no_inline")
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32H7xx_HAL_DEF */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -1,489 +1,489 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7xx_hal_gpio_ex.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of GPIO HAL Extension module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32H7xx_HAL_GPIO_EX_H
|
||||
#define STM32H7xx_HAL_GPIO_EX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32h7xx_hal_def.h"
|
||||
|
||||
/** @addtogroup STM32H7xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIOEx GPIOEx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Exported_Constants GPIO Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO_Alternate_function_selection GPIO Alternate Function Selection
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief AF 0 selection
|
||||
*/
|
||||
#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */
|
||||
#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */
|
||||
#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */
|
||||
#define GPIO_AF0_LCDBIAS ((uint8_t)0x00) /* LCDBIAS Alternate Function mapping */
|
||||
#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */
|
||||
#if defined (PWR_CPUCR_PDDS_D2) /* PWR D1 and D2 domains exists */
|
||||
#define GPIO_AF0_C1DSLEEP ((uint8_t)0x00) /* Cortex-M7 Deep Sleep Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#define GPIO_AF0_C1SLEEP ((uint8_t)0x00) /* Cortex-M7 Sleep Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#define GPIO_AF0_D1PWREN ((uint8_t)0x00) /* Domain 1 PWR enable Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#define GPIO_AF0_D2PWREN ((uint8_t)0x00) /* Domain 2 PWR enable Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#if defined(DUAL_CORE)
|
||||
#define GPIO_AF0_C2DSLEEP ((uint8_t)0x00) /* Cortex-M4 Deep Sleep Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#define GPIO_AF0_C2SLEEP ((uint8_t)0x00) /* Cortex-M4 Sleep Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#endif /* DUAL_CORE */
|
||||
#endif /* PWR_CPUCR_PDDS_D2 */
|
||||
|
||||
/**
|
||||
* @brief AF 1 selection
|
||||
*/
|
||||
#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */
|
||||
#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */
|
||||
#define GPIO_AF1_TIM16 ((uint8_t)0x01) /* TIM16 Alternate Function mapping */
|
||||
#define GPIO_AF1_TIM17 ((uint8_t)0x01) /* TIM17 Alternate Function mapping */
|
||||
#define GPIO_AF1_LPTIM1 ((uint8_t)0x01) /* LPTIM1 Alternate Function mapping */
|
||||
#if defined(HRTIM1)
|
||||
#define GPIO_AF1_HRTIM1 ((uint8_t)0x01) /* HRTIM1 Alternate Function mapping */
|
||||
#endif /* HRTIM1 */
|
||||
#if defined(SAI4)
|
||||
#define GPIO_AF1_SAI4 ((uint8_t)0x01) /* SAI4 Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
#endif /* SAI4 */
|
||||
#define GPIO_AF1_FMC ((uint8_t)0x01) /* FMC Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
|
||||
|
||||
/**
|
||||
* @brief AF 2 selection
|
||||
*/
|
||||
#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */
|
||||
#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */
|
||||
#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */
|
||||
#define GPIO_AF2_TIM12 ((uint8_t)0x02) /* TIM12 Alternate Function mapping */
|
||||
#define GPIO_AF2_SAI1 ((uint8_t)0x02) /* SAI1 Alternate Function mapping */
|
||||
#if defined(HRTIM1)
|
||||
#define GPIO_AF2_HRTIM1 ((uint8_t)0x02) /* HRTIM1 Alternate Function mapping */
|
||||
#endif /* HRTIM1 */
|
||||
#define GPIO_AF2_TIM15 ((uint8_t)0x02) /* TIM15 Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
#if defined(FDCAN3)
|
||||
#define GPIO_AF2_FDCAN3 ((uint8_t)0x02) /* FDCAN3 Alternate Function mapping */
|
||||
#endif /*FDCAN3*/
|
||||
|
||||
/**
|
||||
* @brief AF 3 selection
|
||||
*/
|
||||
#define GPIO_AF3_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */
|
||||
#define GPIO_AF3_LPTIM2 ((uint8_t)0x03) /* LPTIM2 Alternate Function mapping */
|
||||
#define GPIO_AF3_DFSDM1 ((uint8_t)0x03) /* DFSDM Alternate Function mapping */
|
||||
#define GPIO_AF3_LPTIM3 ((uint8_t)0x03) /* LPTIM3 Alternate Function mapping */
|
||||
#define GPIO_AF3_LPTIM4 ((uint8_t)0x03) /* LPTIM4 Alternate Function mapping */
|
||||
#define GPIO_AF3_LPTIM5 ((uint8_t)0x03) /* LPTIM5 Alternate Function mapping */
|
||||
#define GPIO_AF3_LPUART ((uint8_t)0x03) /* LPUART Alternate Function mapping */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF3_OCTOSPIM_P1 ((uint8_t)0x03) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#define GPIO_AF3_OCTOSPIM_P2 ((uint8_t)0x03) /* OCTOSPI Manager Port 2 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
#if defined(HRTIM1)
|
||||
#define GPIO_AF3_HRTIM1 ((uint8_t)0x03) /* HRTIM1 Alternate Function mapping */
|
||||
#endif /* HRTIM1 */
|
||||
#define GPIO_AF3_LTDC ((uint8_t)0x03) /* LTDC Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
|
||||
/**
|
||||
* @brief AF 4 selection
|
||||
*/
|
||||
#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */
|
||||
#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */
|
||||
#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */
|
||||
#define GPIO_AF4_I2C4 ((uint8_t)0x04) /* I2C4 Alternate Function mapping */
|
||||
#if defined(I2C5)
|
||||
#define GPIO_AF4_I2C5 ((uint8_t)0x04) /* I2C5 Alternate Function mapping */
|
||||
#endif /* I2C5*/
|
||||
#define GPIO_AF4_TIM15 ((uint8_t)0x04) /* TIM15 Alternate Function mapping */
|
||||
#define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */
|
||||
#define GPIO_AF4_LPTIM2 ((uint8_t)0x04) /* LPTIM2 Alternate Function mapping */
|
||||
#define GPIO_AF4_USART1 ((uint8_t)0x04) /* USART1 Alternate Function mapping */
|
||||
#if defined(USART10)
|
||||
#define GPIO_AF4_USART10 ((uint8_t)0x04) /* USART10 Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
#endif /*USART10*/
|
||||
#define GPIO_AF4_DFSDM1 ((uint8_t)0x04) /* DFSDM Alternate Function mapping */
|
||||
#if defined(DFSDM2_BASE)
|
||||
#define GPIO_AF4_DFSDM2 ((uint8_t)0x04) /* DFSDM2 Alternate Function mapping */
|
||||
#endif /* DFSDM2_BASE */
|
||||
#define GPIO_AF4_DCMI ((uint8_t)0x04) /* DCMI Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
#if defined(PSSI)
|
||||
#define GPIO_AF4_PSSI ((uint8_t)0x04) /* PSSI Alternate Function mapping */
|
||||
#endif /* PSSI */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF4_OCTOSPIM_P1 ((uint8_t)0x04) /* OCTOSPI Manager Port 1 Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 5 selection
|
||||
*/
|
||||
#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI4 ((uint8_t)0x05) /* SPI4 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */
|
||||
#define GPIO_AF5_CEC ((uint8_t)0x05) /* CEC Alternate Function mapping */
|
||||
#if defined(FDCAN3)
|
||||
#define GPIO_AF5_FDCAN3 ((uint8_t)0x05) /* FDCAN3 Alternate Function mapping */
|
||||
#endif /*FDCAN3*/
|
||||
|
||||
/**
|
||||
* @brief AF 6 selection
|
||||
*/
|
||||
#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping */
|
||||
#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3 Alternate Function mapping */
|
||||
#define GPIO_AF6_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */
|
||||
#define GPIO_AF6_I2C4 ((uint8_t)0x06) /* I2C4 Alternate Function mapping */
|
||||
#if defined(I2C5)
|
||||
#define GPIO_AF6_I2C5 ((uint8_t)0x06) /* I2C5 Alternate Function mapping */
|
||||
#endif /* I2C5*/
|
||||
#define GPIO_AF6_DFSDM1 ((uint8_t)0x06) /* DFSDM Alternate Function mapping */
|
||||
#define GPIO_AF6_UART4 ((uint8_t)0x06) /* UART4 Alternate Function mapping */
|
||||
#if defined(DFSDM2_BASE)
|
||||
#define GPIO_AF6_DFSDM2 ((uint8_t)0x06) /* DFSDM2 Alternate Function mapping */
|
||||
#endif /* DFSDM2_BASE */
|
||||
#if defined(SAI3)
|
||||
#define GPIO_AF6_SAI3 ((uint8_t)0x06) /* SAI3 Alternate Function mapping */
|
||||
#endif /* SAI3 */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF6_OCTOSPIM_P1 ((uint8_t)0x06) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 7 selection
|
||||
*/
|
||||
#define GPIO_AF7_SPI2 ((uint8_t)0x07) /* SPI2 Alternate Function mapping */
|
||||
#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3 Alternate Function mapping */
|
||||
#define GPIO_AF7_SPI6 ((uint8_t)0x07) /* SPI6 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART6 ((uint8_t)0x07) /* USART6 Alternate Function mapping */
|
||||
#define GPIO_AF7_UART7 ((uint8_t)0x07) /* UART7 Alternate Function mapping */
|
||||
#define GPIO_AF7_SDMMC1 ((uint8_t)0x07) /* SDMMC1 Alternate Function mapping */
|
||||
|
||||
/**
|
||||
* @brief AF 8 selection
|
||||
*/
|
||||
#define GPIO_AF8_SPI6 ((uint8_t)0x08) /* SPI6 Alternate Function mapping */
|
||||
#if defined(SAI2)
|
||||
#define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */
|
||||
#endif /*SAI2*/
|
||||
#define GPIO_AF8_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */
|
||||
#define GPIO_AF8_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */
|
||||
#define GPIO_AF8_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */
|
||||
#define GPIO_AF8_SPDIF ((uint8_t)0x08) /* SPDIF Alternate Function mapping */
|
||||
#define GPIO_AF8_LPUART ((uint8_t)0x08) /* LPUART Alternate Function mapping */
|
||||
#define GPIO_AF8_SDMMC1 ((uint8_t)0x08) /* SDMMC1 Alternate Function mapping */
|
||||
#if defined(SAI4)
|
||||
#define GPIO_AF8_SAI4 ((uint8_t)0x08) /* SAI4 Alternate Function mapping */
|
||||
#endif /* SAI4 */
|
||||
|
||||
/**
|
||||
* @brief AF 9 selection
|
||||
*/
|
||||
#define GPIO_AF9_FDCAN1 ((uint8_t)0x09) /* FDCAN1 Alternate Function mapping */
|
||||
#define GPIO_AF9_FDCAN2 ((uint8_t)0x09) /* FDCAN2 Alternate Function mapping */
|
||||
#define GPIO_AF9_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */
|
||||
#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */
|
||||
#define GPIO_AF9_SDMMC2 ((uint8_t)0x09) /* SDMMC2 Alternate Function mapping */
|
||||
#define GPIO_AF9_LTDC ((uint8_t)0x09) /* LTDC Alternate Function mapping */
|
||||
#define GPIO_AF9_SPDIF ((uint8_t)0x09) /* SPDIF Alternate Function mapping */
|
||||
#define GPIO_AF9_FMC ((uint8_t)0x09) /* FMC Alternate Function mapping */
|
||||
#if defined(QUADSPI)
|
||||
#define GPIO_AF9_QUADSPI ((uint8_t)0x09) /* QUADSPI Alternate Function mapping */
|
||||
#endif /* QUADSPI */
|
||||
#if defined(SAI4)
|
||||
#define GPIO_AF9_SAI4 ((uint8_t)0x09) /* SAI4 Alternate Function mapping */
|
||||
#endif /* SAI4 */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF9_OCTOSPIM_P1 ((uint8_t)0x09) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#define GPIO_AF9_OCTOSPIM_P2 ((uint8_t)0x09) /* OCTOSPI Manager Port 2 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 10 selection
|
||||
*/
|
||||
#if defined(SAI2)
|
||||
#define GPIO_AF10_SAI2 ((uint8_t)0x0A) /* SAI2 Alternate Function mapping */
|
||||
#endif /*SAI2*/
|
||||
#define GPIO_AF10_SDMMC2 ((uint8_t)0x0A) /* SDMMC2 Alternate Function mapping */
|
||||
#if defined(USB2_OTG_FS)
|
||||
#define GPIO_AF10_OTG2_FS ((uint8_t)0x0A) /* OTG2_FS Alternate Function mapping */
|
||||
#endif /*USB2_OTG_FS*/
|
||||
#define GPIO_AF10_COMP1 ((uint8_t)0x0A) /* COMP1 Alternate Function mapping */
|
||||
#define GPIO_AF10_COMP2 ((uint8_t)0x0A) /* COMP2 Alternate Function mapping */
|
||||
#if defined(LTDC)
|
||||
#define GPIO_AF10_LTDC ((uint8_t)0x0A) /* LTDC Alternate Function mapping */
|
||||
#endif /*LTDC*/
|
||||
#define GPIO_AF10_CRS_SYNC ((uint8_t)0x0A) /* CRS Sync Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#if defined(QUADSPI)
|
||||
#define GPIO_AF10_QUADSPI ((uint8_t)0x0A) /* QUADSPI Alternate Function mapping */
|
||||
#endif /* QUADSPI */
|
||||
#if defined(SAI4)
|
||||
#define GPIO_AF10_SAI4 ((uint8_t)0x0A) /* SAI4 Alternate Function mapping */
|
||||
#endif /* SAI4 */
|
||||
#if !defined(USB2_OTG_FS)
|
||||
#define GPIO_AF10_OTG1_FS ((uint8_t)0x0A) /* OTG1_FS Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
#endif /* !USB2_OTG_FS */
|
||||
#define GPIO_AF10_OTG1_HS ((uint8_t)0x0A) /* OTG1_HS Alternate Function mapping */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF10_OCTOSPIM_P1 ((uint8_t)0x0A) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
#define GPIO_AF10_TIM8 ((uint8_t)0x0A) /* TIM8 Alternate Function mapping */
|
||||
#define GPIO_AF10_FMC ((uint8_t)0x0A) /* FMC Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
|
||||
/**
|
||||
* @brief AF 11 selection
|
||||
*/
|
||||
#define GPIO_AF11_SWP ((uint8_t)0x0B) /* SWP Alternate Function mapping */
|
||||
#define GPIO_AF11_MDIOS ((uint8_t)0x0B) /* MDIOS Alternate Function mapping */
|
||||
#define GPIO_AF11_UART7 ((uint8_t)0x0B) /* UART7 Alternate Function mapping */
|
||||
#define GPIO_AF11_SDMMC2 ((uint8_t)0x0B) /* SDMMC2 Alternate Function mapping */
|
||||
#define GPIO_AF11_DFSDM1 ((uint8_t)0x0B) /* DFSDM1 Alternate Function mapping */
|
||||
#define GPIO_AF11_COMP1 ((uint8_t)0x0B) /* COMP1 Alternate Function mapping */
|
||||
#define GPIO_AF11_COMP2 ((uint8_t)0x0B) /* COMP2 Alternate Function mapping */
|
||||
#define GPIO_AF11_TIM1 ((uint8_t)0x0B) /* TIM1 Alternate Function mapping */
|
||||
#define GPIO_AF11_TIM8 ((uint8_t)0x0B) /* TIM8 Alternate Function mapping */
|
||||
#define GPIO_AF11_I2C4 ((uint8_t)0x0B) /* I2C4 Alternate Function mapping */
|
||||
#if defined(DFSDM2_BASE)
|
||||
#define GPIO_AF11_DFSDM2 ((uint8_t)0x0B) /* DFSDM2 Alternate Function mapping */
|
||||
#endif /* DFSDM2_BASE */
|
||||
#if defined(USART10)
|
||||
#define GPIO_AF11_USART10 ((uint8_t)0x0B) /* USART10 Alternate Function mapping */
|
||||
#endif /* USART10 */
|
||||
#if defined(UART9)
|
||||
#define GPIO_AF11_UART9 ((uint8_t)0x0B) /* UART9 Alternate Function mapping */
|
||||
#endif /* UART9 */
|
||||
#if defined(ETH)
|
||||
#define GPIO_AF11_ETH ((uint8_t)0x0B) /* ETH Alternate Function mapping */
|
||||
#endif /* ETH */
|
||||
#if defined(LTDC)
|
||||
#define GPIO_AF11_LTDC ((uint8_t)0x0B) /* LTDC Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
#endif /*LTDC*/
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF11_OCTOSPIM_P1 ((uint8_t)0x0B) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 12 selection
|
||||
*/
|
||||
#define GPIO_AF12_FMC ((uint8_t)0x0C) /* FMC Alternate Function mapping */
|
||||
#define GPIO_AF12_SDMMC1 ((uint8_t)0x0C) /* SDMMC1 Alternate Function mapping */
|
||||
#define GPIO_AF12_MDIOS ((uint8_t)0x0C) /* MDIOS Alternate Function mapping */
|
||||
#define GPIO_AF12_COMP1 ((uint8_t)0x0C) /* COMP1 Alternate Function mapping */
|
||||
#define GPIO_AF12_COMP2 ((uint8_t)0x0C) /* COMP2 Alternate Function mapping */
|
||||
#define GPIO_AF12_TIM1 ((uint8_t)0x0C) /* TIM1 Alternate Function mapping */
|
||||
#define GPIO_AF12_TIM8 ((uint8_t)0x0C) /* TIM8 Alternate Function mapping */
|
||||
#if defined(LTDC)
|
||||
#define GPIO_AF12_LTDC ((uint8_t)0x0C) /* LTDC Alternate Function mapping */
|
||||
#endif /*LTDC*/
|
||||
#if defined(USB2_OTG_FS)
|
||||
#define GPIO_AF12_OTG1_FS ((uint8_t)0x0C) /* OTG1_FS Alternate Function mapping */
|
||||
#endif /* USB2_OTG_FS */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF12_OCTOSPIM_P1 ((uint8_t)0x0C) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 13 selection
|
||||
*/
|
||||
#define GPIO_AF13_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */
|
||||
#define GPIO_AF13_COMP1 ((uint8_t)0x0D) /* COMP1 Alternate Function mapping */
|
||||
#define GPIO_AF13_COMP2 ((uint8_t)0x0D) /* COMP2 Alternate Function mapping */
|
||||
#if defined(LTDC)
|
||||
#define GPIO_AF13_LTDC ((uint8_t)0x0D) /* LTDC Alternate Function mapping */
|
||||
#endif /*LTDC*/
|
||||
#if defined(DSI)
|
||||
#define GPIO_AF13_DSI ((uint8_t)0x0D) /* DSI Alternate Function mapping */
|
||||
#endif /* DSI */
|
||||
#if defined(PSSI)
|
||||
#define GPIO_AF13_PSSI ((uint8_t)0x0D) /* PSSI Alternate Function mapping */
|
||||
#endif /* PSSI */
|
||||
#define GPIO_AF13_TIM1 ((uint8_t)0x0D) /* TIM1 Alternate Function mapping */
|
||||
#if defined(TIM23)
|
||||
#define GPIO_AF13_TIM23 ((uint8_t)0x0D) /* TIM23 Alternate Function mapping */
|
||||
#endif /*TIM23*/
|
||||
|
||||
/**
|
||||
* @brief AF 14 selection
|
||||
*/
|
||||
#define GPIO_AF14_LTDC ((uint8_t)0x0E) /* LTDC Alternate Function mapping */
|
||||
#define GPIO_AF14_UART5 ((uint8_t)0x0E) /* UART5 Alternate Function mapping */
|
||||
#if defined(TIM24)
|
||||
#define GPIO_AF14_TIM24 ((uint8_t)0x0E) /* TIM24 Alternate Function mapping */
|
||||
#endif /*TIM24*/
|
||||
|
||||
/**
|
||||
* @brief AF 15 selection
|
||||
*/
|
||||
#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */
|
||||
|
||||
#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x0F)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Exported_Macros GPIO Exported Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Exported_Functions GPIO Exported Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Private_Constants GPIO Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief GPIO pin available on the platform
|
||||
*/
|
||||
/* Defines the available pins per GPIOs */
|
||||
#define GPIOA_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOB_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOC_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOD_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOE_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOF_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOG_PIN_AVAILABLE GPIO_PIN_All
|
||||
#if defined(GPIOI)
|
||||
#define GPIOI_PIN_AVAILABLE GPIO_PIN_All
|
||||
#endif /*GPIOI*/
|
||||
#if defined(GPIOI)
|
||||
#define GPIOJ_PIN_AVAILABLE GPIO_PIN_All
|
||||
#else
|
||||
#define GPIOJ_PIN_AVAILABLE (GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 )
|
||||
#endif /* GPIOI */
|
||||
#define GPIOH_PIN_AVAILABLE GPIO_PIN_All
|
||||
#if defined(GPIOI)
|
||||
#define GPIOK_PIN_AVAILABLE (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | \
|
||||
GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7)
|
||||
#else
|
||||
#define GPIOK_PIN_AVAILABLE (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 )
|
||||
#endif /* GPIOI */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Private_Macros GPIO Private Macros
|
||||
* @{
|
||||
*/
|
||||
/** @defgroup GPIOEx_Get_Port_Index GPIO Get Port Index
|
||||
* @{
|
||||
*/
|
||||
#if defined(GPIOI)
|
||||
#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0UL :\
|
||||
((__GPIOx__) == (GPIOB))? 1UL :\
|
||||
((__GPIOx__) == (GPIOC))? 2UL :\
|
||||
((__GPIOx__) == (GPIOD))? 3UL :\
|
||||
((__GPIOx__) == (GPIOE))? 4UL :\
|
||||
((__GPIOx__) == (GPIOF))? 5UL :\
|
||||
((__GPIOx__) == (GPIOG))? 6UL :\
|
||||
((__GPIOx__) == (GPIOH))? 7UL :\
|
||||
((__GPIOx__) == (GPIOI))? 8UL :\
|
||||
((__GPIOx__) == (GPIOJ))? 9UL : 10UL)
|
||||
#else
|
||||
#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0UL :\
|
||||
((__GPIOx__) == (GPIOB))? 1UL :\
|
||||
((__GPIOx__) == (GPIOC))? 2UL :\
|
||||
((__GPIOx__) == (GPIOD))? 3UL :\
|
||||
((__GPIOx__) == (GPIOE))? 4UL :\
|
||||
((__GPIOx__) == (GPIOF))? 5UL :\
|
||||
((__GPIOx__) == (GPIOG))? 6UL :\
|
||||
((__GPIOx__) == (GPIOH))? 7UL :\
|
||||
((__GPIOx__) == (GPIOJ))? 9UL : 10UL)
|
||||
#endif /* GPIOI */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup GPIOEx_IS_Alternat_function_selection GPIO Check Alternate Function
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Private_Functions GPIO Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32H7xx_HAL_GPIO_EX_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7xx_hal_gpio_ex.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of GPIO HAL Extension module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32H7xx_HAL_GPIO_EX_H
|
||||
#define STM32H7xx_HAL_GPIO_EX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32h7xx_hal_def.h"
|
||||
|
||||
/** @addtogroup STM32H7xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIOEx GPIOEx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Exported_Constants GPIO Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO_Alternate_function_selection GPIO Alternate Function Selection
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief AF 0 selection
|
||||
*/
|
||||
#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */
|
||||
#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */
|
||||
#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */
|
||||
#define GPIO_AF0_LCDBIAS ((uint8_t)0x00) /* LCDBIAS Alternate Function mapping */
|
||||
#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */
|
||||
#if defined (PWR_CPUCR_PDDS_D2) /* PWR D1 and D2 domains exists */
|
||||
#define GPIO_AF0_C1DSLEEP ((uint8_t)0x00) /* Cortex-M7 Deep Sleep Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#define GPIO_AF0_C1SLEEP ((uint8_t)0x00) /* Cortex-M7 Sleep Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#define GPIO_AF0_D1PWREN ((uint8_t)0x00) /* Domain 1 PWR enable Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#define GPIO_AF0_D2PWREN ((uint8_t)0x00) /* Domain 2 PWR enable Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#if defined(DUAL_CORE)
|
||||
#define GPIO_AF0_C2DSLEEP ((uint8_t)0x00) /* Cortex-M4 Deep Sleep Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#define GPIO_AF0_C2SLEEP ((uint8_t)0x00) /* Cortex-M4 Sleep Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#endif /* DUAL_CORE */
|
||||
#endif /* PWR_CPUCR_PDDS_D2 */
|
||||
|
||||
/**
|
||||
* @brief AF 1 selection
|
||||
*/
|
||||
#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */
|
||||
#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */
|
||||
#define GPIO_AF1_TIM16 ((uint8_t)0x01) /* TIM16 Alternate Function mapping */
|
||||
#define GPIO_AF1_TIM17 ((uint8_t)0x01) /* TIM17 Alternate Function mapping */
|
||||
#define GPIO_AF1_LPTIM1 ((uint8_t)0x01) /* LPTIM1 Alternate Function mapping */
|
||||
#if defined(HRTIM1)
|
||||
#define GPIO_AF1_HRTIM1 ((uint8_t)0x01) /* HRTIM1 Alternate Function mapping */
|
||||
#endif /* HRTIM1 */
|
||||
#if defined(SAI4)
|
||||
#define GPIO_AF1_SAI4 ((uint8_t)0x01) /* SAI4 Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
#endif /* SAI4 */
|
||||
#define GPIO_AF1_FMC ((uint8_t)0x01) /* FMC Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
|
||||
|
||||
/**
|
||||
* @brief AF 2 selection
|
||||
*/
|
||||
#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */
|
||||
#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */
|
||||
#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */
|
||||
#define GPIO_AF2_TIM12 ((uint8_t)0x02) /* TIM12 Alternate Function mapping */
|
||||
#define GPIO_AF2_SAI1 ((uint8_t)0x02) /* SAI1 Alternate Function mapping */
|
||||
#if defined(HRTIM1)
|
||||
#define GPIO_AF2_HRTIM1 ((uint8_t)0x02) /* HRTIM1 Alternate Function mapping */
|
||||
#endif /* HRTIM1 */
|
||||
#define GPIO_AF2_TIM15 ((uint8_t)0x02) /* TIM15 Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
#if defined(FDCAN3)
|
||||
#define GPIO_AF2_FDCAN3 ((uint8_t)0x02) /* FDCAN3 Alternate Function mapping */
|
||||
#endif /*FDCAN3*/
|
||||
|
||||
/**
|
||||
* @brief AF 3 selection
|
||||
*/
|
||||
#define GPIO_AF3_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */
|
||||
#define GPIO_AF3_LPTIM2 ((uint8_t)0x03) /* LPTIM2 Alternate Function mapping */
|
||||
#define GPIO_AF3_DFSDM1 ((uint8_t)0x03) /* DFSDM Alternate Function mapping */
|
||||
#define GPIO_AF3_LPTIM3 ((uint8_t)0x03) /* LPTIM3 Alternate Function mapping */
|
||||
#define GPIO_AF3_LPTIM4 ((uint8_t)0x03) /* LPTIM4 Alternate Function mapping */
|
||||
#define GPIO_AF3_LPTIM5 ((uint8_t)0x03) /* LPTIM5 Alternate Function mapping */
|
||||
#define GPIO_AF3_LPUART ((uint8_t)0x03) /* LPUART Alternate Function mapping */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF3_OCTOSPIM_P1 ((uint8_t)0x03) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#define GPIO_AF3_OCTOSPIM_P2 ((uint8_t)0x03) /* OCTOSPI Manager Port 2 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
#if defined(HRTIM1)
|
||||
#define GPIO_AF3_HRTIM1 ((uint8_t)0x03) /* HRTIM1 Alternate Function mapping */
|
||||
#endif /* HRTIM1 */
|
||||
#define GPIO_AF3_LTDC ((uint8_t)0x03) /* LTDC Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
|
||||
/**
|
||||
* @brief AF 4 selection
|
||||
*/
|
||||
#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */
|
||||
#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */
|
||||
#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */
|
||||
#define GPIO_AF4_I2C4 ((uint8_t)0x04) /* I2C4 Alternate Function mapping */
|
||||
#if defined(I2C5)
|
||||
#define GPIO_AF4_I2C5 ((uint8_t)0x04) /* I2C5 Alternate Function mapping */
|
||||
#endif /* I2C5*/
|
||||
#define GPIO_AF4_TIM15 ((uint8_t)0x04) /* TIM15 Alternate Function mapping */
|
||||
#define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */
|
||||
#define GPIO_AF4_LPTIM2 ((uint8_t)0x04) /* LPTIM2 Alternate Function mapping */
|
||||
#define GPIO_AF4_USART1 ((uint8_t)0x04) /* USART1 Alternate Function mapping */
|
||||
#if defined(USART10)
|
||||
#define GPIO_AF4_USART10 ((uint8_t)0x04) /* USART10 Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
#endif /*USART10*/
|
||||
#define GPIO_AF4_DFSDM1 ((uint8_t)0x04) /* DFSDM Alternate Function mapping */
|
||||
#if defined(DFSDM2_BASE)
|
||||
#define GPIO_AF4_DFSDM2 ((uint8_t)0x04) /* DFSDM2 Alternate Function mapping */
|
||||
#endif /* DFSDM2_BASE */
|
||||
#define GPIO_AF4_DCMI ((uint8_t)0x04) /* DCMI Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
#if defined(PSSI)
|
||||
#define GPIO_AF4_PSSI ((uint8_t)0x04) /* PSSI Alternate Function mapping */
|
||||
#endif /* PSSI */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF4_OCTOSPIM_P1 ((uint8_t)0x04) /* OCTOSPI Manager Port 1 Alternate Function mapping : available on STM32H72xxx/STM32H73xxx */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 5 selection
|
||||
*/
|
||||
#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI4 ((uint8_t)0x05) /* SPI4 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */
|
||||
#define GPIO_AF5_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */
|
||||
#define GPIO_AF5_CEC ((uint8_t)0x05) /* CEC Alternate Function mapping */
|
||||
#if defined(FDCAN3)
|
||||
#define GPIO_AF5_FDCAN3 ((uint8_t)0x05) /* FDCAN3 Alternate Function mapping */
|
||||
#endif /*FDCAN3*/
|
||||
|
||||
/**
|
||||
* @brief AF 6 selection
|
||||
*/
|
||||
#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping */
|
||||
#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3 Alternate Function mapping */
|
||||
#define GPIO_AF6_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */
|
||||
#define GPIO_AF6_I2C4 ((uint8_t)0x06) /* I2C4 Alternate Function mapping */
|
||||
#if defined(I2C5)
|
||||
#define GPIO_AF6_I2C5 ((uint8_t)0x06) /* I2C5 Alternate Function mapping */
|
||||
#endif /* I2C5*/
|
||||
#define GPIO_AF6_DFSDM1 ((uint8_t)0x06) /* DFSDM Alternate Function mapping */
|
||||
#define GPIO_AF6_UART4 ((uint8_t)0x06) /* UART4 Alternate Function mapping */
|
||||
#if defined(DFSDM2_BASE)
|
||||
#define GPIO_AF6_DFSDM2 ((uint8_t)0x06) /* DFSDM2 Alternate Function mapping */
|
||||
#endif /* DFSDM2_BASE */
|
||||
#if defined(SAI3)
|
||||
#define GPIO_AF6_SAI3 ((uint8_t)0x06) /* SAI3 Alternate Function mapping */
|
||||
#endif /* SAI3 */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF6_OCTOSPIM_P1 ((uint8_t)0x06) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 7 selection
|
||||
*/
|
||||
#define GPIO_AF7_SPI2 ((uint8_t)0x07) /* SPI2 Alternate Function mapping */
|
||||
#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3 Alternate Function mapping */
|
||||
#define GPIO_AF7_SPI6 ((uint8_t)0x07) /* SPI6 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART6 ((uint8_t)0x07) /* USART6 Alternate Function mapping */
|
||||
#define GPIO_AF7_UART7 ((uint8_t)0x07) /* UART7 Alternate Function mapping */
|
||||
#define GPIO_AF7_SDMMC1 ((uint8_t)0x07) /* SDMMC1 Alternate Function mapping */
|
||||
|
||||
/**
|
||||
* @brief AF 8 selection
|
||||
*/
|
||||
#define GPIO_AF8_SPI6 ((uint8_t)0x08) /* SPI6 Alternate Function mapping */
|
||||
#if defined(SAI2)
|
||||
#define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */
|
||||
#endif /*SAI2*/
|
||||
#define GPIO_AF8_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */
|
||||
#define GPIO_AF8_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */
|
||||
#define GPIO_AF8_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */
|
||||
#define GPIO_AF8_SPDIF ((uint8_t)0x08) /* SPDIF Alternate Function mapping */
|
||||
#define GPIO_AF8_LPUART ((uint8_t)0x08) /* LPUART Alternate Function mapping */
|
||||
#define GPIO_AF8_SDMMC1 ((uint8_t)0x08) /* SDMMC1 Alternate Function mapping */
|
||||
#if defined(SAI4)
|
||||
#define GPIO_AF8_SAI4 ((uint8_t)0x08) /* SAI4 Alternate Function mapping */
|
||||
#endif /* SAI4 */
|
||||
|
||||
/**
|
||||
* @brief AF 9 selection
|
||||
*/
|
||||
#define GPIO_AF9_FDCAN1 ((uint8_t)0x09) /* FDCAN1 Alternate Function mapping */
|
||||
#define GPIO_AF9_FDCAN2 ((uint8_t)0x09) /* FDCAN2 Alternate Function mapping */
|
||||
#define GPIO_AF9_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */
|
||||
#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */
|
||||
#define GPIO_AF9_SDMMC2 ((uint8_t)0x09) /* SDMMC2 Alternate Function mapping */
|
||||
#define GPIO_AF9_LTDC ((uint8_t)0x09) /* LTDC Alternate Function mapping */
|
||||
#define GPIO_AF9_SPDIF ((uint8_t)0x09) /* SPDIF Alternate Function mapping */
|
||||
#define GPIO_AF9_FMC ((uint8_t)0x09) /* FMC Alternate Function mapping */
|
||||
#if defined(QUADSPI)
|
||||
#define GPIO_AF9_QUADSPI ((uint8_t)0x09) /* QUADSPI Alternate Function mapping */
|
||||
#endif /* QUADSPI */
|
||||
#if defined(SAI4)
|
||||
#define GPIO_AF9_SAI4 ((uint8_t)0x09) /* SAI4 Alternate Function mapping */
|
||||
#endif /* SAI4 */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF9_OCTOSPIM_P1 ((uint8_t)0x09) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#define GPIO_AF9_OCTOSPIM_P2 ((uint8_t)0x09) /* OCTOSPI Manager Port 2 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 10 selection
|
||||
*/
|
||||
#if defined(SAI2)
|
||||
#define GPIO_AF10_SAI2 ((uint8_t)0x0A) /* SAI2 Alternate Function mapping */
|
||||
#endif /*SAI2*/
|
||||
#define GPIO_AF10_SDMMC2 ((uint8_t)0x0A) /* SDMMC2 Alternate Function mapping */
|
||||
#if defined(USB2_OTG_FS)
|
||||
#define GPIO_AF10_OTG2_FS ((uint8_t)0x0A) /* OTG2_FS Alternate Function mapping */
|
||||
#endif /*USB2_OTG_FS*/
|
||||
#define GPIO_AF10_COMP1 ((uint8_t)0x0A) /* COMP1 Alternate Function mapping */
|
||||
#define GPIO_AF10_COMP2 ((uint8_t)0x0A) /* COMP2 Alternate Function mapping */
|
||||
#if defined(LTDC)
|
||||
#define GPIO_AF10_LTDC ((uint8_t)0x0A) /* LTDC Alternate Function mapping */
|
||||
#endif /*LTDC*/
|
||||
#define GPIO_AF10_CRS_SYNC ((uint8_t)0x0A) /* CRS Sync Alternate Function mapping : available on STM32H7 Rev.B and above */
|
||||
#if defined(QUADSPI)
|
||||
#define GPIO_AF10_QUADSPI ((uint8_t)0x0A) /* QUADSPI Alternate Function mapping */
|
||||
#endif /* QUADSPI */
|
||||
#if defined(SAI4)
|
||||
#define GPIO_AF10_SAI4 ((uint8_t)0x0A) /* SAI4 Alternate Function mapping */
|
||||
#endif /* SAI4 */
|
||||
#if !defined(USB2_OTG_FS)
|
||||
#define GPIO_AF10_OTG1_FS ((uint8_t)0x0A) /* OTG1_FS Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
#endif /* !USB2_OTG_FS */
|
||||
#define GPIO_AF10_OTG1_HS ((uint8_t)0x0A) /* OTG1_HS Alternate Function mapping */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF10_OCTOSPIM_P1 ((uint8_t)0x0A) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
#define GPIO_AF10_TIM8 ((uint8_t)0x0A) /* TIM8 Alternate Function mapping */
|
||||
#define GPIO_AF10_FMC ((uint8_t)0x0A) /* FMC Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
|
||||
/**
|
||||
* @brief AF 11 selection
|
||||
*/
|
||||
#define GPIO_AF11_SWP ((uint8_t)0x0B) /* SWP Alternate Function mapping */
|
||||
#define GPIO_AF11_MDIOS ((uint8_t)0x0B) /* MDIOS Alternate Function mapping */
|
||||
#define GPIO_AF11_UART7 ((uint8_t)0x0B) /* UART7 Alternate Function mapping */
|
||||
#define GPIO_AF11_SDMMC2 ((uint8_t)0x0B) /* SDMMC2 Alternate Function mapping */
|
||||
#define GPIO_AF11_DFSDM1 ((uint8_t)0x0B) /* DFSDM1 Alternate Function mapping */
|
||||
#define GPIO_AF11_COMP1 ((uint8_t)0x0B) /* COMP1 Alternate Function mapping */
|
||||
#define GPIO_AF11_COMP2 ((uint8_t)0x0B) /* COMP2 Alternate Function mapping */
|
||||
#define GPIO_AF11_TIM1 ((uint8_t)0x0B) /* TIM1 Alternate Function mapping */
|
||||
#define GPIO_AF11_TIM8 ((uint8_t)0x0B) /* TIM8 Alternate Function mapping */
|
||||
#define GPIO_AF11_I2C4 ((uint8_t)0x0B) /* I2C4 Alternate Function mapping */
|
||||
#if defined(DFSDM2_BASE)
|
||||
#define GPIO_AF11_DFSDM2 ((uint8_t)0x0B) /* DFSDM2 Alternate Function mapping */
|
||||
#endif /* DFSDM2_BASE */
|
||||
#if defined(USART10)
|
||||
#define GPIO_AF11_USART10 ((uint8_t)0x0B) /* USART10 Alternate Function mapping */
|
||||
#endif /* USART10 */
|
||||
#if defined(UART9)
|
||||
#define GPIO_AF11_UART9 ((uint8_t)0x0B) /* UART9 Alternate Function mapping */
|
||||
#endif /* UART9 */
|
||||
#if defined(ETH)
|
||||
#define GPIO_AF11_ETH ((uint8_t)0x0B) /* ETH Alternate Function mapping */
|
||||
#endif /* ETH */
|
||||
#if defined(LTDC)
|
||||
#define GPIO_AF11_LTDC ((uint8_t)0x0B) /* LTDC Alternate Function mapping : available on STM32H7A3xxx/STM32H7B3xxx/STM32H7B0xxx and STM32H72xxx/STM32H73xxx */
|
||||
#endif /*LTDC*/
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF11_OCTOSPIM_P1 ((uint8_t)0x0B) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 12 selection
|
||||
*/
|
||||
#define GPIO_AF12_FMC ((uint8_t)0x0C) /* FMC Alternate Function mapping */
|
||||
#define GPIO_AF12_SDMMC1 ((uint8_t)0x0C) /* SDMMC1 Alternate Function mapping */
|
||||
#define GPIO_AF12_MDIOS ((uint8_t)0x0C) /* MDIOS Alternate Function mapping */
|
||||
#define GPIO_AF12_COMP1 ((uint8_t)0x0C) /* COMP1 Alternate Function mapping */
|
||||
#define GPIO_AF12_COMP2 ((uint8_t)0x0C) /* COMP2 Alternate Function mapping */
|
||||
#define GPIO_AF12_TIM1 ((uint8_t)0x0C) /* TIM1 Alternate Function mapping */
|
||||
#define GPIO_AF12_TIM8 ((uint8_t)0x0C) /* TIM8 Alternate Function mapping */
|
||||
#if defined(LTDC)
|
||||
#define GPIO_AF12_LTDC ((uint8_t)0x0C) /* LTDC Alternate Function mapping */
|
||||
#endif /*LTDC*/
|
||||
#if defined(USB2_OTG_FS)
|
||||
#define GPIO_AF12_OTG1_FS ((uint8_t)0x0C) /* OTG1_FS Alternate Function mapping */
|
||||
#endif /* USB2_OTG_FS */
|
||||
#if defined(OCTOSPIM)
|
||||
#define GPIO_AF12_OCTOSPIM_P1 ((uint8_t)0x0C) /* OCTOSPI Manager Port 1 Alternate Function mapping */
|
||||
#endif /* OCTOSPIM */
|
||||
|
||||
/**
|
||||
* @brief AF 13 selection
|
||||
*/
|
||||
#define GPIO_AF13_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */
|
||||
#define GPIO_AF13_COMP1 ((uint8_t)0x0D) /* COMP1 Alternate Function mapping */
|
||||
#define GPIO_AF13_COMP2 ((uint8_t)0x0D) /* COMP2 Alternate Function mapping */
|
||||
#if defined(LTDC)
|
||||
#define GPIO_AF13_LTDC ((uint8_t)0x0D) /* LTDC Alternate Function mapping */
|
||||
#endif /*LTDC*/
|
||||
#if defined(DSI)
|
||||
#define GPIO_AF13_DSI ((uint8_t)0x0D) /* DSI Alternate Function mapping */
|
||||
#endif /* DSI */
|
||||
#if defined(PSSI)
|
||||
#define GPIO_AF13_PSSI ((uint8_t)0x0D) /* PSSI Alternate Function mapping */
|
||||
#endif /* PSSI */
|
||||
#define GPIO_AF13_TIM1 ((uint8_t)0x0D) /* TIM1 Alternate Function mapping */
|
||||
#if defined(TIM23)
|
||||
#define GPIO_AF13_TIM23 ((uint8_t)0x0D) /* TIM23 Alternate Function mapping */
|
||||
#endif /*TIM23*/
|
||||
|
||||
/**
|
||||
* @brief AF 14 selection
|
||||
*/
|
||||
#define GPIO_AF14_LTDC ((uint8_t)0x0E) /* LTDC Alternate Function mapping */
|
||||
#define GPIO_AF14_UART5 ((uint8_t)0x0E) /* UART5 Alternate Function mapping */
|
||||
#if defined(TIM24)
|
||||
#define GPIO_AF14_TIM24 ((uint8_t)0x0E) /* TIM24 Alternate Function mapping */
|
||||
#endif /*TIM24*/
|
||||
|
||||
/**
|
||||
* @brief AF 15 selection
|
||||
*/
|
||||
#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */
|
||||
|
||||
#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x0F)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Exported_Macros GPIO Exported Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Exported_Functions GPIO Exported Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Private_Constants GPIO Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief GPIO pin available on the platform
|
||||
*/
|
||||
/* Defines the available pins per GPIOs */
|
||||
#define GPIOA_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOB_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOC_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOD_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOE_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOF_PIN_AVAILABLE GPIO_PIN_All
|
||||
#define GPIOG_PIN_AVAILABLE GPIO_PIN_All
|
||||
#if defined(GPIOI)
|
||||
#define GPIOI_PIN_AVAILABLE GPIO_PIN_All
|
||||
#endif /*GPIOI*/
|
||||
#if defined(GPIOI)
|
||||
#define GPIOJ_PIN_AVAILABLE GPIO_PIN_All
|
||||
#else
|
||||
#define GPIOJ_PIN_AVAILABLE (GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 )
|
||||
#endif /* GPIOI */
|
||||
#define GPIOH_PIN_AVAILABLE GPIO_PIN_All
|
||||
#if defined(GPIOI)
|
||||
#define GPIOK_PIN_AVAILABLE (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | \
|
||||
GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7)
|
||||
#else
|
||||
#define GPIOK_PIN_AVAILABLE (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 )
|
||||
#endif /* GPIOI */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Private_Macros GPIO Private Macros
|
||||
* @{
|
||||
*/
|
||||
/** @defgroup GPIOEx_Get_Port_Index GPIO Get Port Index
|
||||
* @{
|
||||
*/
|
||||
#if defined(GPIOI)
|
||||
#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0UL :\
|
||||
((__GPIOx__) == (GPIOB))? 1UL :\
|
||||
((__GPIOx__) == (GPIOC))? 2UL :\
|
||||
((__GPIOx__) == (GPIOD))? 3UL :\
|
||||
((__GPIOx__) == (GPIOE))? 4UL :\
|
||||
((__GPIOx__) == (GPIOF))? 5UL :\
|
||||
((__GPIOx__) == (GPIOG))? 6UL :\
|
||||
((__GPIOx__) == (GPIOH))? 7UL :\
|
||||
((__GPIOx__) == (GPIOI))? 8UL :\
|
||||
((__GPIOx__) == (GPIOJ))? 9UL : 10UL)
|
||||
#else
|
||||
#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0UL :\
|
||||
((__GPIOx__) == (GPIOB))? 1UL :\
|
||||
((__GPIOx__) == (GPIOC))? 2UL :\
|
||||
((__GPIOx__) == (GPIOD))? 3UL :\
|
||||
((__GPIOx__) == (GPIOE))? 4UL :\
|
||||
((__GPIOx__) == (GPIOF))? 5UL :\
|
||||
((__GPIOx__) == (GPIOG))? 6UL :\
|
||||
((__GPIOx__) == (GPIOH))? 7UL :\
|
||||
((__GPIOx__) == (GPIOJ))? 9UL : 10UL)
|
||||
#endif /* GPIOI */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup GPIOEx_IS_Alternat_function_selection GPIO Check Alternate Function
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @defgroup GPIOEx_Private_Functions GPIO Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32H7xx_HAL_GPIO_EX_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -1,105 +1,105 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32h7xx.h
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-Mx Device System Source File for STM32H7xx devices.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32h7xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Define to prevent recursive inclusion
|
||||
*/
|
||||
#ifndef SYSTEM_STM32H7XX_H
|
||||
#define SYSTEM_STM32H7XX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Exported_types
|
||||
* @{
|
||||
*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock; /*!< System Domain1 Clock Frequency */
|
||||
extern uint32_t SystemD2Clock; /*!< System Domain2 Clock Frequency */
|
||||
extern const uint8_t D1CorePrescTable[16] ; /*!< D1CorePrescTable prescalers table values */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_STM32H7XX_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32h7xx.h
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-Mx Device System Source File for STM32H7xx devices.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32h7xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Define to prevent recursive inclusion
|
||||
*/
|
||||
#ifndef SYSTEM_STM32H7XX_H
|
||||
#define SYSTEM_STM32H7XX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Exported_types
|
||||
* @{
|
||||
*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock; /*!< System Domain1 Clock Frequency */
|
||||
extern uint32_t SystemD2Clock; /*!< System Domain2 Clock Frequency */
|
||||
extern const uint8_t D1CorePrescTable[16] ; /*!< D1CorePrescTable prescalers table values */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7xx_System_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_STM32H7XX_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// ********************* Bare interrupt handlers *********************
|
||||
// Interrupts for STM32H7x5
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "lladc_declarations.h"
|
||||
|
||||
static uint32_t adc_avdd_mV = 0U;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// TACH interrupt handler
|
||||
static void EXTI2_IRQ_Handler(void) {
|
||||
volatile unsigned int pr = EXTI->PR1 & (1U << 2);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "llfdcan_declarations.h"
|
||||
|
||||
// kbps multiplied by 10
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
bool flash_is_locked(void) {
|
||||
return (FLASH->CR1 & FLASH_CR_LOCK);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// TODO: this driver relies heavily on polling,
|
||||
// if we want it to be more async, we should use interrupts
|
||||
|
||||
@@ -17,7 +19,7 @@ void i2c_reset(I2C_TypeDef *I2C) {
|
||||
register_set_bits(&I2C->CR1, I2C_CR1_PE);
|
||||
}
|
||||
|
||||
bool i2c_write_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t value) {
|
||||
static bool i2c_write_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t value) {
|
||||
bool ret = false;
|
||||
|
||||
// Setup transfer and send START + addr
|
||||
@@ -63,7 +65,7 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool i2c_read_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t *value) {
|
||||
static bool i2c_read_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t *value) {
|
||||
bool ret = false;
|
||||
|
||||
// Setup transfer and send START + addr
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "llusb_declarations.h"
|
||||
|
||||
USB_OTG_GlobalTypeDef *USBx = USB_OTG_HS;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef BOOTSTUB
|
||||
void gpio_usb_init(void) {
|
||||
#else
|
||||
@@ -17,20 +19,6 @@ void gpio_spi_init(void) {
|
||||
register_set_bits(&(GPIOE->OSPEEDR), GPIO_OSPEEDR_OSPEED11 | GPIO_OSPEEDR_OSPEED12 | GPIO_OSPEEDR_OSPEED13 | GPIO_OSPEEDR_OSPEED14);
|
||||
}
|
||||
|
||||
#ifdef BOOTSTUB
|
||||
void gpio_usart2_init(void) {
|
||||
// A2,A3: USART 2 for debugging
|
||||
set_gpio_alternate(GPIOA, 2, GPIO_AF7_USART2);
|
||||
set_gpio_alternate(GPIOA, 3, GPIO_AF7_USART2);
|
||||
}
|
||||
#endif
|
||||
|
||||
void gpio_uart7_init(void) {
|
||||
// E7,E8: UART 7 for debugging
|
||||
set_gpio_alternate(GPIOE, 7, GPIO_AF7_UART7);
|
||||
set_gpio_alternate(GPIOE, 8, GPIO_AF7_UART7);
|
||||
}
|
||||
|
||||
// Common GPIO initialization
|
||||
void common_init_gpio(void) {
|
||||
//F11: VOLT_S
|
||||
@@ -104,7 +92,6 @@ void peripherals_init(void) {
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_USB1OTGHSEN; // USB
|
||||
RCC->AHB1LPENR |= RCC_AHB1LPENR_USB1OTGHSLPEN; // USB LP needed for CSleep state(__WFI())
|
||||
RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_USB1OTGHSULPILPEN); // disable USB ULPI
|
||||
RCC->APB1LENR |= RCC_APB1LENR_UART7EN; // SOM uart
|
||||
RCC->APB1HENR |= RCC_APB1HENR_FDCANEN; // FDCAN core enable
|
||||
|
||||
// Analog
|
||||
@@ -126,9 +113,6 @@ void peripherals_init(void) {
|
||||
RCC->APB1LENR |= RCC_APB1LENR_TIM12EN; // slow loop
|
||||
RCC->APB1LENR |= RCC_APB1LENR_TIM5EN; // sound trigger timer
|
||||
|
||||
#ifdef PANDA_JUNGLE
|
||||
RCC->AHB3ENR |= RCC_AHB3ENR_SDMMC1EN; // SDMMC
|
||||
#endif
|
||||
}
|
||||
|
||||
void enable_interrupt_timer(void) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "stm32h7xx.h"
|
||||
#include "stm32h7xx_hal_gpio_ex.h"
|
||||
#define MCU_IDCODE 0x483U
|
||||
@@ -60,22 +62,16 @@ separate IRQs for RX and TX.
|
||||
#include "board/drivers/registers.h"
|
||||
#include "board/drivers/interrupts.h"
|
||||
|
||||
#ifdef BOOTSTUB
|
||||
uart_ring uart_ring_som_debug;
|
||||
#endif
|
||||
#include "board/drivers/gpio.h"
|
||||
#include "board/stm32h7/peripherals.h"
|
||||
#include "board/stm32h7/interrupt_handlers.h"
|
||||
#include "board/drivers/timers.h"
|
||||
|
||||
#if !defined(BOOTSTUB)
|
||||
#include "board/drivers/uart.h"
|
||||
#include "board/stm32h7/lluart.h"
|
||||
#include "board/drivers/debug.h"
|
||||
#endif
|
||||
|
||||
#ifdef PANDA_JUNGLE
|
||||
#include "board/jungle/stm32h7/board.h"
|
||||
#elif defined(PANDA_BODY)
|
||||
#ifdef PANDA_BODY
|
||||
#include "board/body/stm32h7/board.h"
|
||||
#else
|
||||
#include "board/stm32h7/board.h"
|
||||
|
||||
@@ -1,222 +1,223 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
**
|
||||
|
||||
** File : LinkerScript.ld
|
||||
**
|
||||
** Author : Auto-generated by System Workbench for STM32
|
||||
**
|
||||
** Abstract : Linker script for STM32H735ZGTx series
|
||||
** 1024Kbytes FLASH and 560Kbytes RAM
|
||||
**
|
||||
** Set heap size, stack size and stack location according
|
||||
** to application requirements.
|
||||
**
|
||||
** Set memory bank area and size if external memory is used.
|
||||
**
|
||||
** Target : STMicroelectronics STM32
|
||||
**
|
||||
** Distribution: The file is distributed “as is,” without any warranty
|
||||
** of any kind.
|
||||
**
|
||||
*****************************************************************************
|
||||
** @attention
|
||||
**
|
||||
** <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
|
||||
**
|
||||
** 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 of STMicroelectronics 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 HOLDER 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.
|
||||
**
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
enter_bootloader_mode = 0x38001FFC;
|
||||
/*
|
||||
******************************************************************************
|
||||
**
|
||||
|
||||
** File : LinkerScript.ld
|
||||
**
|
||||
** Author : Auto-generated by System Workbench for STM32
|
||||
**
|
||||
** Abstract : Linker script for STM32H735ZGTx series
|
||||
** 1024Kbytes FLASH and 560Kbytes RAM
|
||||
**
|
||||
** Set heap size, stack size and stack location according
|
||||
** to application requirements.
|
||||
**
|
||||
** Set memory bank area and size if external memory is used.
|
||||
**
|
||||
** Target : STMicroelectronics STM32
|
||||
**
|
||||
** Distribution: The file is distributed “as is,” without any warranty
|
||||
** of any kind.
|
||||
**
|
||||
*****************************************************************************
|
||||
** @attention
|
||||
**
|
||||
** <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
|
||||
**
|
||||
** 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 of STMicroelectronics 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 HOLDER 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.
|
||||
**
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
enter_bootloader_mode = 0x38001FFC;
|
||||
fault_cookie = 0x38003FFC;
|
||||
_estack = 0x20020000; /* end of RAM */
|
||||
_app_start = 0x08020000; /* Reserve Sector 0(128K) for bootloader */
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0x200; /* required amount of heap */
|
||||
_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
/* RAM */
|
||||
BACKUP_SRAM (xrw) : ORIGIN = 0x38800000, LENGTH = 4K /* Backup SRAM(4kb) */
|
||||
SRAM4 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K /* SRAM4(16kb) best for BDMA and SDMMC1*/
|
||||
SRAM12 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K /* SRAM1(16kb) + SRAM2(16kb), not for BDMA or SDMMC1 */
|
||||
AXISRAM (xrw) : ORIGIN = 0x24000000, LENGTH = 320K /* AXI SRAM */
|
||||
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* DTCM */
|
||||
|
||||
/* Code */
|
||||
SYSTEM (rx) : ORIGIN = 0x1FF00000, LENGTH = 128K /* System memory */
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into FLASH */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
} >FLASH
|
||||
|
||||
/* Constant data goes into FLASH */
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
||||
.ARM : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >FLASH
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} >FLASH
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array*))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* create a global symbol at data start */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end */
|
||||
} >DTCMRAM AT> FLASH
|
||||
|
||||
|
||||
/* Uninitialized data section */
|
||||
. = ALIGN(4);
|
||||
.bss :
|
||||
{
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
_sbss = .; /* define a global symbol at bss start */
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end */
|
||||
__bss_end__ = _ebss;
|
||||
} >DTCMRAM
|
||||
|
||||
/* User_heap_stack section, used to check that there is enough RAM left */
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE ( end = . );
|
||||
PROVIDE ( _end = . );
|
||||
. = . + _Min_Heap_Size;
|
||||
. = . + _Min_Stack_Size;
|
||||
. = ALIGN(8);
|
||||
} >DTCMRAM
|
||||
|
||||
.itcmram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.itcmram*)
|
||||
} >ITCMRAM
|
||||
|
||||
.axisram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.axisram*)
|
||||
} >AXISRAM
|
||||
|
||||
.sram12 (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.sram12*)
|
||||
} >SRAM12
|
||||
|
||||
.sram4 (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.sram4*)
|
||||
} >SRAM4
|
||||
|
||||
.backup_sram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.backup_sram*)
|
||||
} >BACKUP_SRAM
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
||||
|
||||
|
||||
_estack = 0x20020000; /* end of RAM */
|
||||
_app_start = 0x08020000; /* Reserve Sector 0(128K) for bootloader */
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0x200; /* required amount of heap */
|
||||
_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
/* RAM */
|
||||
BACKUP_SRAM (xrw) : ORIGIN = 0x38800000, LENGTH = 4K /* Backup SRAM(4kb) */
|
||||
SRAM4 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K /* SRAM4(16kb) best for BDMA and SDMMC1*/
|
||||
SRAM12 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K /* SRAM1(16kb) + SRAM2(16kb), not for BDMA or SDMMC1 */
|
||||
AXISRAM (xrw) : ORIGIN = 0x24000000, LENGTH = 320K /* AXI SRAM */
|
||||
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* DTCM */
|
||||
|
||||
/* Code */
|
||||
SYSTEM (rx) : ORIGIN = 0x1FF00000, LENGTH = 128K /* System memory */
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into FLASH */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
} >FLASH
|
||||
|
||||
/* Constant data goes into FLASH */
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
||||
.ARM : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >FLASH
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} >FLASH
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array*))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* create a global symbol at data start */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end */
|
||||
} >DTCMRAM AT> FLASH
|
||||
|
||||
|
||||
/* Uninitialized data section */
|
||||
. = ALIGN(4);
|
||||
.bss :
|
||||
{
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
_sbss = .; /* define a global symbol at bss start */
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end */
|
||||
__bss_end__ = _ebss;
|
||||
} >DTCMRAM
|
||||
|
||||
/* User_heap_stack section, used to check that there is enough RAM left */
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE ( end = . );
|
||||
PROVIDE ( _end = . );
|
||||
. = . + _Min_Heap_Size;
|
||||
. = . + _Min_Stack_Size;
|
||||
. = ALIGN(8);
|
||||
} >DTCMRAM
|
||||
|
||||
.itcmram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.itcmram*)
|
||||
} >ITCMRAM
|
||||
|
||||
.axisram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.axisram*)
|
||||
} >AXISRAM
|
||||
|
||||
.sram12 (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.sram12*)
|
||||
} >SRAM12
|
||||
|
||||
.sram4 (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.sram4*)
|
||||
} >SRAM4
|
||||
|
||||
.backup_sram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.backup_sram*)
|
||||
} >BACKUP_SRAM
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/sys/sys.h"
|
||||
|
||||
// ********************* Critical section helpers *********************
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/sys/sys.h"
|
||||
|
||||
uint8_t fault_status = FAULT_STATUS_NONE;
|
||||
|
||||
@@ -42,7 +42,6 @@ extern uint8_t global_critical_depth;
|
||||
#define FAULT_INTERRUPT_RATE_TICK (1UL << 21)
|
||||
#define FAULT_INTERRUPT_RATE_EXTI (1UL << 22)
|
||||
#define FAULT_INTERRUPT_RATE_SPI (1UL << 23)
|
||||
#define FAULT_INTERRUPT_RATE_UART_7 (1UL << 24)
|
||||
#define FAULT_SIREN_MALFUNCTION (1UL << 25)
|
||||
#define FAULT_HEARTBEAT_LOOP_WATCHDOG (1UL << 26)
|
||||
#define FAULT_INTERRUPT_RATE_SOUND_DMA (1UL << 27)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// cppcheck-suppress-macro [misra-c2012-1.2, misra-c2012-17.3]; allow __typeof__ extension
|
||||
#define MIN(a, b) ({ \
|
||||
__typeof__ (a) _a = (a); \
|
||||
|
||||
+4
-21
@@ -3,7 +3,7 @@ name = "pandacan"
|
||||
version = "0.0.10"
|
||||
description = "Code powering the comma.ai panda"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11,<3.13" # macOS doesn't work with 3.13 due to pycapnp from opendbc
|
||||
requires-python = ">= 3.12.3, < 3.13" # macOS doesn't work with 3.13 due to pycapnp from opendbc
|
||||
license = {text = "MIT"}
|
||||
authors = [{name = "comma.ai"}]
|
||||
classifiers = [
|
||||
@@ -16,21 +16,16 @@ dependencies = [
|
||||
"libusb-package",
|
||||
"opendbc @ git+https://github.com/sunnypilot/opendbc.git@master#egg=opendbc",
|
||||
"spidev; platform_system == 'Linux'", # runtime dependency on comma four
|
||||
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"scons",
|
||||
"cffi",
|
||||
"flaky",
|
||||
"pytest",
|
||||
"pytest-xdist",
|
||||
"pytest-mock",
|
||||
"pytest-timeout",
|
||||
"ruff",
|
||||
"setuptools",
|
||||
"gcc-arm-none-eabi @ git+https://github.com/commaai/dependencies.git@release-gcc-arm-none-eabi#subdirectory=gcc-arm-none-eabi",
|
||||
"cppcheck @ git+https://github.com/commaai/dependencies.git@release-cppcheck#subdirectory=cppcheck",
|
||||
"comma-deps-gcc-arm-none-eabi",
|
||||
"comma-deps-cppcheck",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
@@ -43,12 +38,10 @@ packages = [
|
||||
"panda.python",
|
||||
"panda.board",
|
||||
"panda.board.body",
|
||||
"panda.board.jungle",
|
||||
]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
"panda.board" = ["health.h"]
|
||||
"panda.board.jungle" = ["jungle_health.h"]
|
||||
|
||||
[tool.setuptools.package-dir]
|
||||
panda = "."
|
||||
@@ -62,13 +55,3 @@ target-version="py311"
|
||||
select = ["E", "F", "W", "PIE", "C4", "ISC", "RUF100", "A"]
|
||||
ignore = ["W292", "E741", "E402", "C408", "ISC003"]
|
||||
flake8-implicit-str-concat.allow-multiline=false
|
||||
|
||||
[tool.ruff.lint.flake8-tidy-imports.banned-api]
|
||||
"pytest.main".msg = "pytest.main requires special handling that is easy to mess up!"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
addopts = "-Werror --strict-config --strict-markers --maxprocesses=8 -nauto --durations=10 --ignore-glob='*.sh' --ignore=tests/som --ignore=tests/hitl"
|
||||
python_files = "test_*.py"
|
||||
testpaths = [
|
||||
"tests/"
|
||||
]
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# Python interface for the preflashed Jungle fixtures used by HITL tests.
|
||||
import struct
|
||||
from functools import wraps
|
||||
|
||||
from panda import Panda
|
||||
|
||||
|
||||
def ensure_jungle_health_packet_version(fn):
|
||||
@wraps(fn)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if self.health_version != self.HEALTH_PACKET_VERSION:
|
||||
raise RuntimeError(f"Jungle firmware ({self.health_version}) doesn't match the \
|
||||
library's health packet version ({self.HEALTH_PACKET_VERSION}).")
|
||||
return fn(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
class PandaJungle(Panda):
|
||||
USB_PIDS = (0xddef, 0xddcf)
|
||||
|
||||
HW_TYPE_UNKNOWN = b'\x00'
|
||||
HW_TYPE_V2 = b'\x02'
|
||||
|
||||
H7_DEVICES = [HW_TYPE_V2, ]
|
||||
SUPPORTED_DEVICES = H7_DEVICES
|
||||
|
||||
# Frozen protocol hash of the health packet in the installed Jungle firmware.
|
||||
HEALTH_PACKET_VERSION = 0xDD322770
|
||||
HEALTH_STRUCT = struct.Struct("<IffffffHHHHHHHHHHHH")
|
||||
|
||||
HARNESS_ORIENTATION_NONE = 0
|
||||
HARNESS_ORIENTATION_1 = 1
|
||||
HARNESS_ORIENTATION_2 = 2
|
||||
|
||||
@classmethod
|
||||
def spi_connect(cls, serial):
|
||||
return None, None, None, None
|
||||
|
||||
def flash(self, fn=None, code=None, reconnect=True):
|
||||
raise NotImplementedError("Jungle firmware flashing is no longer supported")
|
||||
|
||||
def recover(self, timeout: int | None = 60, reset: bool = True) -> bool:
|
||||
raise NotImplementedError("Jungle firmware recovery is no longer supported")
|
||||
|
||||
def up_to_date(self, fn=None) -> bool:
|
||||
raise NotImplementedError("Jungle firmware is no longer distributed")
|
||||
|
||||
# ******************* health *******************
|
||||
|
||||
@ensure_jungle_health_packet_version
|
||||
def health(self):
|
||||
dat = self._handle.controlRead(PandaJungle.REQUEST_IN, 0xd2, 0, 0, self.HEALTH_STRUCT.size)
|
||||
a = self.HEALTH_STRUCT.unpack(dat)
|
||||
return {
|
||||
"uptime": a[0],
|
||||
"ch1_power": a[1],
|
||||
"ch2_power": a[2],
|
||||
"ch3_power": a[3],
|
||||
"ch4_power": a[4],
|
||||
"ch5_power": a[5],
|
||||
"ch6_power": a[6],
|
||||
"ch1_sbu1_voltage": a[7] / 1000.0,
|
||||
"ch1_sbu2_voltage": a[8] / 1000.0,
|
||||
"ch2_sbu1_voltage": a[9] / 1000.0,
|
||||
"ch2_sbu2_voltage": a[10] / 1000.0,
|
||||
"ch3_sbu1_voltage": a[11] / 1000.0,
|
||||
"ch3_sbu2_voltage": a[12] / 1000.0,
|
||||
"ch4_sbu1_voltage": a[13] / 1000.0,
|
||||
"ch4_sbu2_voltage": a[14] / 1000.0,
|
||||
"ch5_sbu1_voltage": a[15] / 1000.0,
|
||||
"ch5_sbu2_voltage": a[16] / 1000.0,
|
||||
"ch6_sbu1_voltage": a[17] / 1000.0,
|
||||
"ch6_sbu2_voltage": a[18] / 1000.0,
|
||||
}
|
||||
|
||||
# ******************* control *******************
|
||||
|
||||
def get_packets_versions(self):
|
||||
dat = self._handle.controlRead(PandaJungle.REQUEST_IN, 0xdd, 0, 0, 8)
|
||||
if dat and len(dat) == 8:
|
||||
return struct.unpack("<II", dat)
|
||||
return (0, 0)
|
||||
|
||||
# ******************* jungle stuff *******************
|
||||
|
||||
def set_panda_power(self, enabled):
|
||||
self._handle.controlWrite(PandaJungle.REQUEST_OUT, 0xa0, int(enabled), 0, b'')
|
||||
|
||||
def set_harness_orientation(self, mode):
|
||||
self._handle.controlWrite(PandaJungle.REQUEST_OUT, 0xa1, int(mode), 0, b'')
|
||||
|
||||
def set_ignition(self, enabled):
|
||||
self._handle.controlWrite(PandaJungle.REQUEST_OUT, 0xa2, int(enabled), 0, b'')
|
||||
|
||||
def set_can_silent(self, silent):
|
||||
self._handle.controlWrite(PandaJungle.REQUEST_OUT, 0xf5, int(silent), 0, b'')
|
||||
@@ -3,7 +3,6 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import select
|
||||
import codecs
|
||||
|
||||
from panda import Panda
|
||||
@@ -11,7 +10,6 @@ from panda import Panda
|
||||
setcolor = ["\033[1;32;40m", "\033[1;31;40m"]
|
||||
unsetcolor = "\033[00m"
|
||||
|
||||
port_number = int(os.getenv("PORT", "0"))
|
||||
claim = os.getenv("CLAIM") is not None
|
||||
no_color = os.getenv("NO_COLOR") is not None
|
||||
no_reconnect = os.getenv("NO_RECONNECT") is not None
|
||||
@@ -33,14 +31,10 @@ if __name__ == "__main__":
|
||||
time.sleep(1)
|
||||
continue
|
||||
|
||||
if os.getenv("BAUD") is not None:
|
||||
for panda in pandas:
|
||||
panda.set_uart_baud(port_number, int(os.getenv("BAUD"))) # type: ignore
|
||||
|
||||
while True:
|
||||
for i, panda in enumerate(pandas):
|
||||
while True:
|
||||
ret = panda.serial_read(port_number)
|
||||
ret = panda.debug_read()
|
||||
if len(ret) > 0:
|
||||
decoded = decoders[i].decode(ret)
|
||||
if no_color:
|
||||
@@ -50,10 +44,6 @@ if __name__ == "__main__":
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
break
|
||||
if select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []):
|
||||
ln = sys.stdin.readline()
|
||||
if claim:
|
||||
panda.serial_write(port_number, ln)
|
||||
time.sleep(0.01)
|
||||
except KeyboardInterrupt:
|
||||
break
|
||||
|
||||
@@ -32,7 +32,7 @@ if __name__ == "__main__":
|
||||
p.get_type() # get_type has no processing on panda side
|
||||
except PandaSpiException:
|
||||
print(f"ERROR after {datetime.now() - start}\n\n")
|
||||
sys.stdout.write("\033[1;32;40m" + p.serial_read(0).decode('utf8') + "\033[00m" + "\n")
|
||||
sys.stdout.write("\033[1;32;40m" + p.debug_read().decode('utf8') + "\033[00m" + "\n")
|
||||
sys.stdout.flush()
|
||||
sys.exit()
|
||||
cnt += 1
|
||||
|
||||
@@ -4,25 +4,6 @@ set -e
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd $DIR
|
||||
|
||||
PLATFORM=$(uname -s)
|
||||
|
||||
echo "installing dependencies"
|
||||
if [[ $PLATFORM == "Darwin" ]]; then
|
||||
# pass
|
||||
:
|
||||
elif [[ $PLATFORM == "Linux" ]]; then
|
||||
# for AGNOS since we clear the apt lists
|
||||
if [[ ! -d /"var/lib/apt/" ]]; then
|
||||
sudo apt update
|
||||
fi
|
||||
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
curl ca-certificates gcc git \
|
||||
python3-dev
|
||||
else
|
||||
echo "WARNING: unsupported platform. skipping apt/brew install."
|
||||
fi
|
||||
|
||||
if ! command -v uv &>/dev/null; then
|
||||
echo "'uv' is not installed. Installing 'uv'..."
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
+1
-1
@@ -12,4 +12,4 @@ scons
|
||||
|
||||
# *** lint + test ***
|
||||
ruff check .
|
||||
pytest
|
||||
python -W error -m unittest discover -s tests -v
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
import atexit
|
||||
import os
|
||||
import signal
|
||||
import unittest
|
||||
|
||||
from panda import Panda, PandaDFU, PandaJungle
|
||||
from panda.tests.hitl.helpers import clear_can_buffers
|
||||
|
||||
SPEED_NORMAL = 500
|
||||
BUS_SPEEDS = [(0, SPEED_NORMAL), (1, SPEED_NORMAL), (2, SPEED_NORMAL)]
|
||||
|
||||
# test options
|
||||
NO_JUNGLE = os.environ.get("NO_JUNGLE", "0") == "1"
|
||||
|
||||
# Find all pandas connected
|
||||
_panda_jungle = None
|
||||
_panda_type = None
|
||||
_panda_serial = None
|
||||
def init_devices():
|
||||
if not NO_JUNGLE:
|
||||
global _panda_jungle
|
||||
_panda_jungle = PandaJungle()
|
||||
_panda_jungle.set_panda_power(True)
|
||||
|
||||
with Panda(serial=None, claim=False) as p:
|
||||
global _panda_type
|
||||
global _panda_serial
|
||||
_panda_serial = p.get_usb_serial()
|
||||
_panda_type = bytes(p.get_type())
|
||||
assert _panda_serial is not None, "No panda found!"
|
||||
|
||||
def init_jungle():
|
||||
if _panda_jungle is None:
|
||||
return
|
||||
clear_can_buffers(_panda_jungle)
|
||||
_panda_jungle.set_panda_power(True)
|
||||
_panda_jungle.set_can_loopback(False)
|
||||
_panda_jungle.set_obd(False)
|
||||
_panda_jungle.set_harness_orientation(PandaJungle.HARNESS_ORIENTATION_1)
|
||||
for bus, speed in BUS_SPEEDS:
|
||||
_panda_jungle.set_can_speed_kbps(bus, speed)
|
||||
|
||||
|
||||
def panda_test(**options):
|
||||
def decorate(test):
|
||||
test.panda_options = {**getattr(test, "panda_options", {}), **options}
|
||||
return test
|
||||
return decorate
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get("HITL") == "1", "hardware tests require HITL=1")
|
||||
class PandaTestCase(unittest.TestCase):
|
||||
panda_types = None
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
if _panda_serial is None:
|
||||
init_devices()
|
||||
if _panda_jungle is not None:
|
||||
atexit.register(_panda_jungle.close)
|
||||
# init jungle
|
||||
init_jungle()
|
||||
|
||||
# init panda
|
||||
assert Panda.wait_for_panda(_panda_serial, timeout=10), "panda not found"
|
||||
p = Panda(serial=_panda_serial)
|
||||
cls.addClassCleanup(p.close)
|
||||
cls.p = p
|
||||
p.reset(reconnect=True)
|
||||
|
||||
p.set_can_loopback(False)
|
||||
p.set_power_save(False)
|
||||
for bus, speed in BUS_SPEEDS:
|
||||
p.set_can_speed_kbps(bus, speed)
|
||||
clear_can_buffers(p)
|
||||
p.set_power_save(False)
|
||||
|
||||
def setUp(self):
|
||||
self.options = getattr(getattr(self, self._testMethodName), "panda_options", {})
|
||||
panda_types = self.options.get("panda_types", self.panda_types)
|
||||
if panda_types is not None and _panda_type not in panda_types:
|
||||
self.skipTest(f"Not applicable, {panda_types} pandas only")
|
||||
if self.options.get("needs_jungle", False) and NO_JUNGLE:
|
||||
self.skipTest("skipping tests that require a jungle")
|
||||
|
||||
previous_handler = signal.signal(signal.SIGALRM, self._timeout)
|
||||
self.addCleanup(signal.signal, signal.SIGALRM, previous_handler)
|
||||
self.addCleanup(signal.setitimer, signal.ITIMER_REAL, 0)
|
||||
signal.setitimer(signal.ITIMER_REAL, self.options.get("timeout", 60))
|
||||
|
||||
if self.options.get("needs_jungle", False):
|
||||
init_jungle()
|
||||
self.panda_jungle = _panda_jungle
|
||||
self.p.reset()
|
||||
assert self.p.up_to_date()
|
||||
|
||||
def _timeout(self, signum, frame):
|
||||
raise TimeoutError(f"{self.id()} exceeded its test timeout")
|
||||
|
||||
def tearDown(self):
|
||||
p = self.p
|
||||
# reconnect
|
||||
if p.get_dfu_serial() in PandaDFU.list():
|
||||
PandaDFU(p.get_dfu_serial()).reset()
|
||||
p.reconnect()
|
||||
if not p.connected:
|
||||
p.reconnect()
|
||||
if p.bootstub:
|
||||
p.reset()
|
||||
|
||||
assert not p.bootstub
|
||||
|
||||
# Check for faults
|
||||
assert p.health()['faults'] == 0
|
||||
assert p.health()['fault_status'] == 0
|
||||
|
||||
# Check for SPI errors
|
||||
#assert p.health()['spi_error_count'] == 0
|
||||
|
||||
# Check health of each CAN core after test, normal to fail for test_gen2_loopback on OBD bus, so skipping
|
||||
if not self.options.get("expect_can_error", False):
|
||||
for i in range(3):
|
||||
can_health = p.can_health(i)
|
||||
assert can_health['bus_off_cnt'] == 0
|
||||
assert can_health['receive_error_cnt'] < 127
|
||||
assert can_health['transmit_error_cnt'] < 255
|
||||
assert can_health['error_passive'] == 0
|
||||
assert can_health['error_warning'] == 0
|
||||
assert can_health['total_rx_lost_cnt'] == 0
|
||||
assert can_health['total_tx_lost_cnt'] == 0
|
||||
assert can_health['total_error_cnt'] == 0
|
||||
assert can_health['total_tx_checksum_error_cnt'] == 0
|
||||
|
||||
@@ -1,44 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
import concurrent.futures
|
||||
|
||||
from panda import PandaJungle, PandaJungleDFU, McuType
|
||||
from panda.tests.libs.resetter import Resetter
|
||||
|
||||
SERIALS = {
|
||||
'180019001451313236343430', # jungle v2
|
||||
}
|
||||
|
||||
def recover(s):
|
||||
with PandaJungleDFU(s) as pd:
|
||||
pd.recover()
|
||||
|
||||
def flash(s):
|
||||
with PandaJungle(s) as p:
|
||||
p.flash()
|
||||
|
||||
# Reset + flash all CI hardware to get it into a consistent state
|
||||
# * port 1: jungles-under-test
|
||||
# * port 1: unused jungles-under-test
|
||||
# * port 2: USB hubs
|
||||
# * port 3: HITL pandas and their jungles
|
||||
if __name__ == "__main__":
|
||||
with Resetter() as r:
|
||||
# everything off
|
||||
for i in range(1, 4):
|
||||
r.enable_power(i, 0)
|
||||
r.cycle_power(ports=[1, 2], dfu=True)
|
||||
for s in SERIALS:
|
||||
assert PandaJungle.wait_for_dfu(PandaJungleDFU.st_serial_to_dfu_serial(s, McuType.H7), timeout=10)
|
||||
dfu_serials = PandaJungleDFU.list()
|
||||
assert len(dfu_serials) == len(SERIALS)
|
||||
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=len(dfu_serials)) as exc:
|
||||
list(exc.map(recover, dfu_serials, timeout=30))
|
||||
|
||||
# power cycle for H7 bootloader bug
|
||||
r.cycle_power(ports=[1, 2])
|
||||
|
||||
# wait for them to come back up
|
||||
for s in SERIALS:
|
||||
assert PandaJungle.wait_for_panda(s, timeout=10)
|
||||
assert set(PandaJungle.list()) >= SERIALS
|
||||
list(exc.map(flash, SERIALS, timeout=20))
|
||||
r.enable_power(1, False)
|
||||
r.cycle_power(ports=[2, 3])
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
from panda.tests.hitl.base import PandaTestCase, panda_test
|
||||
from panda import Panda, PandaDFU, McuType, BASEDIR
|
||||
|
||||
|
||||
def check_signature(p):
|
||||
assert not p.bootstub, "Flashed firmware not booting. Stuck in bootstub."
|
||||
assert p.up_to_date()
|
||||
|
||||
|
||||
class TestProgram(PandaTestCase):
|
||||
def test_dfu(self):
|
||||
p = self.p
|
||||
dfu_serial = p.get_dfu_serial()
|
||||
|
||||
p.reset(enter_bootstub=True)
|
||||
p.reset(enter_bootloader=True)
|
||||
assert Panda.wait_for_dfu(dfu_serial, timeout=19), "failed to enter DFU"
|
||||
|
||||
dfu = PandaDFU(dfu_serial)
|
||||
assert dfu.get_mcu_type() == McuType.H7
|
||||
|
||||
assert dfu_serial in PandaDFU.list()
|
||||
|
||||
dfu._handle.clear_status()
|
||||
dfu.reset()
|
||||
p.reconnect()
|
||||
|
||||
# TODO: make more comprehensive bootstub tests and run on a few production ones + current
|
||||
# TODO: also test release-signed app
|
||||
@panda_test(timeout=30)
|
||||
def test_known_bootstub(self):
|
||||
"""
|
||||
Test that compiled app can work with known production bootstub
|
||||
"""
|
||||
p = self.p
|
||||
known_bootstubs = {
|
||||
McuType.H7: ["bootstub.panda_h7.bin"],
|
||||
}
|
||||
|
||||
for kb in known_bootstubs[McuType.H7]:
|
||||
app_serial = p.get_usb_serial()
|
||||
assert app_serial is not None
|
||||
|
||||
p.reset(enter_bootstub=True)
|
||||
p.reset(enter_bootloader=True)
|
||||
|
||||
dfu_serial = p.get_dfu_serial()
|
||||
assert Panda.wait_for_dfu(dfu_serial, timeout=30)
|
||||
|
||||
dfu = PandaDFU(dfu_serial)
|
||||
with open(os.path.join(BASEDIR, "tests/hitl/known_bootstub", kb), "rb") as f:
|
||||
code = f.read()
|
||||
|
||||
dfu.program_bootstub(code)
|
||||
dfu.reset()
|
||||
|
||||
p.connect(claim=False, wait=True)
|
||||
|
||||
# check for serial mismatch
|
||||
with Panda(p._serial, claim=False) as np:
|
||||
assert np.get_usb_serial() == app_serial
|
||||
|
||||
# ensure we can flash app and it jumps to app
|
||||
p.flash()
|
||||
check_signature(p)
|
||||
assert not p.bootstub
|
||||
|
||||
@panda_test(timeout=25)
|
||||
def test_recover(self):
|
||||
p = self.p
|
||||
assert p.recover(timeout=30)
|
||||
check_signature(p)
|
||||
|
||||
@panda_test(timeout=25)
|
||||
def test_flash(self):
|
||||
p = self.p
|
||||
# test flash from bootstub
|
||||
serial = p._serial
|
||||
assert serial is not None
|
||||
p.reset(enter_bootstub=True)
|
||||
p.close()
|
||||
time.sleep(2)
|
||||
|
||||
with Panda(serial) as np:
|
||||
assert np.bootstub
|
||||
assert np._serial == serial
|
||||
np.flash()
|
||||
|
||||
p.reconnect()
|
||||
p.reset()
|
||||
check_signature(p)
|
||||
|
||||
# test flash from app
|
||||
p.flash()
|
||||
check_signature(p)
|
||||
@@ -0,0 +1,70 @@
|
||||
import time
|
||||
|
||||
from opendbc.car.hyundai.values import HyundaiSafetyFlags
|
||||
from opendbc.car.structs import CarParams
|
||||
from panda.tests.hitl.base import PandaTestCase, panda_test
|
||||
from panda import Panda
|
||||
|
||||
|
||||
class TestHealth(PandaTestCase):
|
||||
def test_voltage(self):
|
||||
p = self.p
|
||||
for _ in range(10):
|
||||
voltage = p.health()['voltage']
|
||||
assert ((voltage > 11000) and (voltage < 13000))
|
||||
time.sleep(0.1)
|
||||
|
||||
def test_hw_type(self):
|
||||
"""
|
||||
hw type should be same in bootstub as application
|
||||
"""
|
||||
p = self.p
|
||||
|
||||
hw_type = p.get_type()
|
||||
|
||||
app_uid = p.get_uid()
|
||||
usb_serial = p.get_usb_serial()
|
||||
assert app_uid == usb_serial
|
||||
|
||||
p.reset(enter_bootstub=True, reconnect=True)
|
||||
p.close()
|
||||
time.sleep(3)
|
||||
with Panda(p.get_usb_serial()) as pp:
|
||||
assert pp.bootstub
|
||||
assert pp.get_type() == hw_type, "Bootstub and app hw type mismatch"
|
||||
assert pp.get_uid() == app_uid
|
||||
|
||||
@panda_test(needs_jungle=True)
|
||||
def test_heartbeat(self):
|
||||
p = self.p
|
||||
panda_jungle = self.panda_jungle
|
||||
panda_jungle.set_ignition(True)
|
||||
# TODO: add more cases here once the tests aren't super slow
|
||||
p.set_safety_mode(mode=CarParams.SafetyModel.hyundai, param=HyundaiSafetyFlags.LONG)
|
||||
p.send_heartbeat()
|
||||
assert p.health()['safety_mode'] == CarParams.SafetyModel.hyundai
|
||||
assert p.health()['safety_param'] == HyundaiSafetyFlags.LONG
|
||||
|
||||
# shouldn't do anything once we're in a car safety mode
|
||||
p.set_heartbeat_disabled()
|
||||
|
||||
time.sleep(6.)
|
||||
|
||||
h = p.health()
|
||||
assert h['heartbeat_lost']
|
||||
assert h['safety_mode'] == CarParams.SafetyModel.silent
|
||||
assert h['safety_param'] == 0
|
||||
assert h['controls_allowed'] == 0
|
||||
|
||||
def test_microsecond_timer(self):
|
||||
p = self.p
|
||||
start_time = p.get_microsecond_timer()
|
||||
time.sleep(1)
|
||||
end_time = p.get_microsecond_timer()
|
||||
|
||||
# account for uint32 overflow
|
||||
if end_time < start_time:
|
||||
end_time += 2**32
|
||||
|
||||
time_diff = (end_time - start_time) / 1e6
|
||||
assert 0.98 < time_diff < 1.02, f"Timer not running at the correct speed! (got {time_diff:.2f}s instead of 1.0s)"
|
||||
@@ -0,0 +1,93 @@
|
||||
import time
|
||||
|
||||
from opendbc.car.structs import CarParams
|
||||
from panda.tests.hitl.base import PandaTestCase
|
||||
from panda import Panda
|
||||
from panda.tests.hitl.helpers import time_many_sends
|
||||
|
||||
|
||||
class TestUsb(PandaTestCase):
|
||||
panda_types = (Panda.HW_TYPE_RED_PANDA, )
|
||||
|
||||
def test_can_loopback(self):
|
||||
p = self.p
|
||||
p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
p.set_can_loopback(True)
|
||||
|
||||
for bus in (0, 1, 2):
|
||||
# set bus 0 speed to 5000
|
||||
p.set_can_speed_kbps(bus, 500)
|
||||
|
||||
# send a message on bus 0
|
||||
p.can_send(0x1aa, b"message", bus)
|
||||
|
||||
# confirm receive both on loopback and send receipt
|
||||
time.sleep(0.05)
|
||||
r = p.can_recv()
|
||||
sr = [x for x in r if x[2] == 0x80 | bus]
|
||||
lb = [x for x in r if x[2] == bus]
|
||||
assert len(sr) == 1
|
||||
assert len(lb) == 1
|
||||
|
||||
# confirm data is correct
|
||||
assert 0x1aa == sr[0][0] == lb[0][0]
|
||||
assert b"message" == sr[0][1] == lb[0][1]
|
||||
|
||||
def test_reliability(self):
|
||||
p = self.p
|
||||
MSG_COUNT = 100
|
||||
|
||||
p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
p.set_can_loopback(True)
|
||||
p.set_can_speed_kbps(0, 1000)
|
||||
|
||||
addrs = list(range(100, 100 + MSG_COUNT))
|
||||
ts = [(j, b"\xaa" * 8, 0) for j in addrs]
|
||||
|
||||
for _ in range(100):
|
||||
st = time.monotonic()
|
||||
|
||||
p.can_send_many(ts)
|
||||
|
||||
r = []
|
||||
while len(r) < 200 and (time.monotonic() - st) < 0.5:
|
||||
r.extend(p.can_recv())
|
||||
|
||||
sent_echo = [x for x in r if x[2] == 0x80]
|
||||
loopback_resp = [x for x in r if x[2] == 0]
|
||||
|
||||
assert sorted([x[0] for x in loopback_resp]) == addrs
|
||||
assert sorted([x[0] for x in sent_echo]) == addrs
|
||||
assert len(r) == 200
|
||||
|
||||
# take sub 20ms
|
||||
et = (time.monotonic() - st) * 1000.0
|
||||
assert et < 20
|
||||
|
||||
def test_throughput(self):
|
||||
p = self.p
|
||||
# enable output mode
|
||||
p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
|
||||
# enable CAN loopback mode
|
||||
p.set_can_loopback(True)
|
||||
|
||||
for speed in [10, 20, 50, 100, 125, 250, 500, 1000]:
|
||||
# set bus 0 speed to speed
|
||||
p.set_can_speed_kbps(0, speed)
|
||||
time.sleep(0.05)
|
||||
|
||||
comp_kbps = time_many_sends(p, 0)
|
||||
|
||||
# bit count from https://en.wikipedia.org/wiki/CAN_bus
|
||||
saturation_pct = (comp_kbps / speed) * 100.0
|
||||
assert saturation_pct > 80
|
||||
assert saturation_pct < 100
|
||||
|
||||
print("loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct))
|
||||
|
||||
def test_debug_logs(self):
|
||||
p = self.p
|
||||
_ = p.debug_read() # junk
|
||||
p.call_control_api(0x01)
|
||||
assert p.debug_read().startswith(b"NO HANDLER")
|
||||
@@ -0,0 +1,211 @@
|
||||
import os
|
||||
import time
|
||||
import random
|
||||
import threading
|
||||
from collections import defaultdict
|
||||
|
||||
from opendbc.car.structs import CarParams
|
||||
from panda.tests.hitl.base import PandaTestCase, panda_test
|
||||
from panda.tests.hitl.helpers import time_many_sends, get_random_can_messages, clear_can_buffers
|
||||
|
||||
class TestCanLoopback(PandaTestCase):
|
||||
@panda_test(needs_jungle=True)
|
||||
@panda_test(timeout=35)
|
||||
def test_send_recv(self):
|
||||
p = self.p
|
||||
panda_jungle = self.panda_jungle
|
||||
def test(p_send, p_recv):
|
||||
for bus in (0, 1, 2):
|
||||
for speed in (10, 20, 50, 100, 125, 250, 500, 1000):
|
||||
clear_can_buffers(p_send, speed)
|
||||
clear_can_buffers(p_recv, speed)
|
||||
|
||||
comp_kbps = time_many_sends(p_send, bus, p_recv, two_pandas=True)
|
||||
|
||||
saturation_pct = (comp_kbps / speed) * 100.0
|
||||
assert 80 < saturation_pct < 100
|
||||
|
||||
print(f"two pandas bus {bus}, 100 messages at speed {speed:4d}, comp speed is {comp_kbps:7.2f}, {saturation_pct:6.2f}%")
|
||||
|
||||
# Run tests in both directions
|
||||
p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
test(p, panda_jungle)
|
||||
test(panda_jungle, p)
|
||||
|
||||
|
||||
@panda_test(needs_jungle=True)
|
||||
@panda_test(timeout=30)
|
||||
def test_latency(self):
|
||||
p = self.p
|
||||
panda_jungle = self.panda_jungle
|
||||
def test(p_send, p_recv):
|
||||
for bus in (0, 1, 2):
|
||||
for speed in (10, 20, 50, 100, 125, 250, 500, 1000):
|
||||
clear_can_buffers(p_send, speed)
|
||||
clear_can_buffers(p_recv, speed)
|
||||
|
||||
latencies = []
|
||||
comp_kbps_list = []
|
||||
saturation_pcts = []
|
||||
|
||||
num_messages = 100
|
||||
|
||||
for _ in range(num_messages):
|
||||
st = time.monotonic()
|
||||
p_send.can_send(0x1ab, b"message", bus)
|
||||
r = []
|
||||
while len(r) < 1 and (time.monotonic() - st) < 5:
|
||||
r = p_recv.can_recv()
|
||||
et = time.monotonic()
|
||||
r_echo = []
|
||||
while len(r_echo) < 1 and (time.monotonic() - st) < 10:
|
||||
r_echo = p_send.can_recv()
|
||||
|
||||
if len(r) == 0 or len(r_echo) == 0:
|
||||
print(f"r: {r}, r_echo: {r_echo}")
|
||||
|
||||
assert len(r) == 1
|
||||
assert len(r_echo) == 1
|
||||
|
||||
et = (et - st) * 1000.0
|
||||
comp_kbps = (1 + 11 + 1 + 1 + 1 + 4 + 8 * 8 + 15 + 1 + 1 + 1 + 7) / et
|
||||
latency = et - ((1 + 11 + 1 + 1 + 1 + 4 + 8 * 8 + 15 + 1 + 1 + 1 + 7) / speed)
|
||||
|
||||
assert latency < 5.0
|
||||
|
||||
saturation_pct = (comp_kbps / speed) * 100.0
|
||||
latencies.append(latency)
|
||||
comp_kbps_list.append(comp_kbps)
|
||||
saturation_pcts.append(saturation_pct)
|
||||
|
||||
average_latency = sum(latencies) / num_messages
|
||||
assert average_latency < 1.0
|
||||
average_comp_kbps = sum(comp_kbps_list) / num_messages
|
||||
average_saturation_pct = sum(saturation_pcts) / num_messages
|
||||
|
||||
print("two pandas bus {}, {} message average at speed {:4d}, latency is {:5.3f}ms, comp speed is {:7.2f}, percent {:6.2f}"
|
||||
.format(bus, num_messages, speed, average_latency, average_comp_kbps, average_saturation_pct))
|
||||
|
||||
# Run tests in both directions
|
||||
p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
test(p, panda_jungle)
|
||||
test(panda_jungle, p)
|
||||
|
||||
|
||||
@panda_test(needs_jungle=True)
|
||||
@panda_test(expect_can_error=True)
|
||||
def test_gen2_loopback(self):
|
||||
p = self.p
|
||||
panda_jungle = self.panda_jungle
|
||||
def test(p_send, p_recv, address=None):
|
||||
for bus in range(4):
|
||||
obd = False
|
||||
if bus == 3:
|
||||
obd = True
|
||||
bus = 1
|
||||
|
||||
# Clear buses
|
||||
clear_can_buffers(p_send)
|
||||
clear_can_buffers(p_recv)
|
||||
|
||||
# Send a random string
|
||||
addr = address if address else random.randint(1, 2000)
|
||||
string = b"test" + os.urandom(4)
|
||||
p_send.set_obd(obd)
|
||||
p_recv.set_obd(obd)
|
||||
time.sleep(0.2)
|
||||
p_send.can_send(addr, string, bus)
|
||||
time.sleep(0.2)
|
||||
|
||||
content = p_recv.can_recv()
|
||||
|
||||
# Check amount of messages
|
||||
assert len(content) == 1
|
||||
|
||||
# Check content
|
||||
assert content[0][0] == addr and content[0][1] == string
|
||||
|
||||
# Check bus
|
||||
assert content[0][2] == bus
|
||||
|
||||
print("Bus:", bus, "address:", addr, "OBD:", obd, "OK")
|
||||
|
||||
# Run tests in both directions
|
||||
p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
test(p, panda_jungle)
|
||||
test(panda_jungle, p)
|
||||
|
||||
# Test extended frame address with ELM327 mode
|
||||
p.set_safety_mode(CarParams.SafetyModel.elm327)
|
||||
test(p, panda_jungle, 0x18DB33F1)
|
||||
test(panda_jungle, p, 0x18DB33F1)
|
||||
|
||||
# TODO: why it's not being reset by fixtures reinit?
|
||||
p.set_obd(False)
|
||||
panda_jungle.set_obd(False)
|
||||
|
||||
@panda_test(needs_jungle=True)
|
||||
def test_bulk_write(self):
|
||||
p = self.p
|
||||
panda_jungle = self.panda_jungle
|
||||
# The TX buffers on pandas is 0x100 in length.
|
||||
NUM_MESSAGES_PER_BUS = 10000
|
||||
|
||||
def flood_tx(panda):
|
||||
print('Sending!')
|
||||
msg = b"\xaa" * 8
|
||||
packet = []
|
||||
# start with many messages on a single bus (higher contention for single TX ring buffer)
|
||||
packet += [[0xaa, msg, 0]] * NUM_MESSAGES_PER_BUS
|
||||
# end with many messages on multiple buses
|
||||
packet += [[0xaa, msg, 0], [0xaa, msg, 1], [0xaa, msg, 2]] * NUM_MESSAGES_PER_BUS
|
||||
|
||||
# Disable timeout
|
||||
panda.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
panda.can_send_many(packet, timeout=0)
|
||||
print(f"Done sending {4 * NUM_MESSAGES_PER_BUS} messages!", time.monotonic())
|
||||
print(panda.health())
|
||||
|
||||
# Start transmisson
|
||||
threading.Thread(target=flood_tx, args=(p,)).start()
|
||||
|
||||
# Receive as much as we can in a few second time period
|
||||
rx = []
|
||||
old_len = 0
|
||||
start_time = time.monotonic()
|
||||
while time.monotonic() - start_time < 5 or len(rx) > old_len:
|
||||
old_len = len(rx)
|
||||
rx.extend(panda_jungle.can_recv())
|
||||
print(f"Received {len(rx)} messages", time.monotonic())
|
||||
|
||||
# All messages should have been received
|
||||
if len(rx) != 4 * NUM_MESSAGES_PER_BUS:
|
||||
raise Exception("Did not receive all messages!")
|
||||
|
||||
def test_message_integrity(self):
|
||||
p = self.p
|
||||
p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
p.set_can_loopback(True)
|
||||
for i in range(250):
|
||||
sent_msgs = defaultdict(set)
|
||||
for _ in range(random.randrange(10)):
|
||||
to_send = get_random_can_messages(random.randrange(100))
|
||||
for m in to_send:
|
||||
sent_msgs[m[2]].add((m[0], m[1]))
|
||||
p.can_send_many(to_send, timeout=0)
|
||||
|
||||
start_time = time.monotonic()
|
||||
while time.monotonic() - start_time < 2 and any(len(sent_msgs[bus]) for bus in range(3)):
|
||||
recvd = p.can_recv()
|
||||
for msg in recvd:
|
||||
if msg[2] >= 128:
|
||||
k = (msg[0], bytes(msg[1]))
|
||||
bus = msg[2]-128
|
||||
assert k in sent_msgs[bus], f"message {k} was never sent on bus {bus}"
|
||||
sent_msgs[msg[2]-128].discard(k)
|
||||
|
||||
# if a set isn't empty, messages got dropped
|
||||
for bus in range(3):
|
||||
assert not len(sent_msgs[bus]), f"loop {i}: bus {bus} missing {len(sent_msgs[bus])} messages"
|
||||
|
||||
print("Got all messages intact")
|
||||
@@ -0,0 +1,158 @@
|
||||
import binascii
|
||||
import random
|
||||
import struct
|
||||
import threading
|
||||
import time
|
||||
from unittest.mock import patch
|
||||
|
||||
from opendbc.car.structs import CarParams
|
||||
from panda.tests.hitl.base import PandaTestCase
|
||||
from panda import Panda
|
||||
from panda.python.spi import PandaSpiNackResponse, PandaSpiMissingAck, REQ_HEADER, CRC, SLAVE_READY, ACK, NACK, POLL
|
||||
|
||||
|
||||
class TestSpi(PandaTestCase):
|
||||
def _ping(self, panda):
|
||||
# should work with no retries
|
||||
with patch.object(panda._handle, '_transfer_spidev', wraps=panda._handle._transfer_spidev) as spy:
|
||||
panda.health()
|
||||
assert spy.call_count == 1
|
||||
|
||||
def test_info(self):
|
||||
p = self.p
|
||||
for bootstub in (False, True):
|
||||
p.reset(enter_bootstub=bootstub)
|
||||
v = p._handle.get_info()
|
||||
|
||||
uid = binascii.hexlify(v[:12]).decode()
|
||||
assert uid == p.get_uid()
|
||||
|
||||
hwtype = v[12]
|
||||
assert hwtype == ord(p.get_type())
|
||||
|
||||
bstub = v[13]
|
||||
assert bstub == (0xEE if bootstub else 0xCC)
|
||||
|
||||
def test_all_comm_types(self):
|
||||
p = self.p
|
||||
spy = self.enterContext(patch.object(p._handle, '_transfer_spidev', wraps=p._handle._transfer_spidev))
|
||||
|
||||
# controlRead + controlWrite
|
||||
p.health()
|
||||
p.can_clear(0)
|
||||
assert spy.call_count == 2
|
||||
|
||||
# bulkRead + bulkWrite
|
||||
p.can_recv()
|
||||
p.can_send(0x123, b"somedata", 0)
|
||||
assert spy.call_count == 4
|
||||
|
||||
def test_bad_crc(self):
|
||||
# dropped, and the panda is ready for the next request
|
||||
p = self.p
|
||||
cnt = p.health()['spi_error_count']
|
||||
with p._handle.dev.acquire() as spi:
|
||||
pkt = REQ_HEADER.pack(0, 1, 8, 72) + b"\xd2" + b"\x00"*7
|
||||
pkt += CRC.pack(binascii.crc32(pkt) ^ 1)
|
||||
while spi.xfer(pkt)[0] != SLAVE_READY:
|
||||
pass
|
||||
while (dat := spi.xfer(bytes([POLL, ]) * 72))[0] not in (ACK, NACK, SLAVE_READY):
|
||||
pass
|
||||
assert dat[0] == SLAVE_READY
|
||||
self._ping(p)
|
||||
assert (p.health()['spi_error_count'] - cnt) == 1
|
||||
|
||||
def test_garbage(self):
|
||||
# random bytes, of random lengths, at any point in the protocol
|
||||
p = self.p
|
||||
for _ in range(100):
|
||||
with p._handle.dev.acquire() as spi:
|
||||
for _ in range(random.randint(1, 5)):
|
||||
spi.xfer(random.randbytes(random.randint(1, 4096)))
|
||||
self._ping(p)
|
||||
|
||||
def test_abandoned_transfers(self):
|
||||
# host gives up at every stage of a transfer
|
||||
p = self.p
|
||||
with p._handle.dev.acquire() as spi:
|
||||
pkt = REQ_HEADER.pack(0, 1, 8, 72) + b"\xd2" + b"\x00"*7
|
||||
pkt += CRC.pack(binascii.crc32(pkt))
|
||||
while spi.xfer(pkt)[0] != SLAVE_READY:
|
||||
pass
|
||||
self._ping(p)
|
||||
|
||||
# read only part of the response
|
||||
with p._handle.dev.acquire() as spi:
|
||||
while spi.xfer(pkt)[0] != SLAVE_READY:
|
||||
pass
|
||||
for _ in range(100):
|
||||
if spi.xfer(bytes([POLL, ]) * 8)[0] == ACK:
|
||||
break
|
||||
else:
|
||||
raise AssertionError("no response")
|
||||
self._ping(p)
|
||||
|
||||
def test_timeout(self):
|
||||
p = self.p
|
||||
# never equal to a byte, unlike 0xFF which MISO reads while the panda queues the next transfer
|
||||
with patch('panda.python.spi.SLAVE_READY', 0x100), self.assertRaises(PandaSpiMissingAck):
|
||||
p._handle.controlRead(Panda.REQUEST_IN, 0xd2, 0, 0, p.HEALTH_STRUCT.size, timeout=50)
|
||||
self._ping(p)
|
||||
|
||||
def test_non_existent_endpoint(self):
|
||||
p = self.p
|
||||
for _ in range(10):
|
||||
ep = random.randint(4, 20)
|
||||
with self.assertRaises(PandaSpiNackResponse):
|
||||
p._handle.bulkRead(ep, random.randint(1, 1000), timeout=50)
|
||||
|
||||
self._ping(p)
|
||||
|
||||
with self.assertRaises(PandaSpiNackResponse):
|
||||
p._handle.bulkWrite(ep, b"abc", timeout=50)
|
||||
|
||||
self._ping(p)
|
||||
|
||||
def test_multiple_clients(self):
|
||||
# every client's request runs, even when it's identical to another client's
|
||||
self.p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
self.p.set_can_loopback(True)
|
||||
with Panda(self.p._serial) as p1, Panda(self.p._serial) as p2:
|
||||
for _ in range(100):
|
||||
p1.can_send(0x123, b"\x01" * 8, 0)
|
||||
p2.can_send(0x123, b"\x01" * 8, 0)
|
||||
time.sleep(0.1)
|
||||
assert len([m for m in self.p.can_recv() if m[2] == 0]) == 200
|
||||
|
||||
def test_can_exactly_once(self):
|
||||
# more than a full transfer each way, so writes and reads are split into chunks
|
||||
self.p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
self.p.set_can_loopback(True)
|
||||
sent = [struct.pack(">Q", i) for i in range(600)]
|
||||
self.p.can_send_many([(0x123, dat, 0) for dat in sent], timeout=0)
|
||||
time.sleep(0.5)
|
||||
got = []
|
||||
while len(r := self.p.can_recv()):
|
||||
got += [m[1] for m in r if m[2] == 0]
|
||||
assert sorted(got) == sent
|
||||
|
||||
def test_thread_safe(self):
|
||||
# one handle shared by threads, like pandad
|
||||
errors = []
|
||||
def hammer():
|
||||
try:
|
||||
for _ in range(200):
|
||||
self.p.health()
|
||||
except Exception as e:
|
||||
errors.append(e)
|
||||
threads = [threading.Thread(target=hammer) for _ in range(4)]
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
assert errors == []
|
||||
|
||||
def test_max_sizes(self):
|
||||
# around the first read size and the max transfer size
|
||||
for n in (1, 1013, 1014, 4032):
|
||||
assert len(self.p._handle.bulkRead(0xAB, n)) == n
|
||||
@@ -0,0 +1,21 @@
|
||||
import time
|
||||
|
||||
from opendbc.car.structs import CarParams
|
||||
from panda.tests.hitl.base import PandaTestCase
|
||||
|
||||
|
||||
class TestSafety(PandaTestCase):
|
||||
def test_safety_nooutput(self):
|
||||
p = self.p
|
||||
p.set_safety_mode(CarParams.SafetyModel.silent)
|
||||
p.set_can_loopback(True)
|
||||
|
||||
# send a message on bus 0
|
||||
p.can_send(0x1aa, b"message", 0)
|
||||
|
||||
# confirm receive nothing
|
||||
time.sleep(0.05)
|
||||
r = p.can_recv()
|
||||
# bus 192 is messages blocked by TX safety hook on bus 0
|
||||
assert len([x for x in r if x[2] != 192]) == 0
|
||||
assert len([x for x in r if x[2] == 192]) == 1
|
||||
@@ -0,0 +1,43 @@
|
||||
import time
|
||||
|
||||
from panda.tests.hitl.base import PandaTestCase, panda_test
|
||||
from panda import Panda
|
||||
|
||||
|
||||
MAX_RPM = 5000
|
||||
|
||||
class TestInternal(PandaTestCase):
|
||||
panda_types = Panda.INTERNAL_DEVICES
|
||||
|
||||
@panda_test(timeout=2*60)
|
||||
def test_fan_curve(self):
|
||||
p = self.p
|
||||
# ensure fan curve is (roughly) linear
|
||||
|
||||
rpms = []
|
||||
for power in (30, 70, 100):
|
||||
# wait until fan spins up
|
||||
p.set_fan_power(power)
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
if p.get_fan_rpm() > 1000:
|
||||
break
|
||||
time.sleep(2) # wait for RPM to converge
|
||||
rpms.append(p.get_fan_rpm())
|
||||
|
||||
print(rpms)
|
||||
diffs = [b - a for a, b in zip(rpms, rpms[1:])]
|
||||
assert all(x > 0 for x in diffs), f"Fan RPMs not strictly increasing: {rpms=}"
|
||||
assert rpms[-1] > (0.75*MAX_RPM)
|
||||
|
||||
|
||||
def test_fan_cooldown(self):
|
||||
p = self.p
|
||||
# if the fan cooldown doesn't work, we get high frequency noise on the tach line
|
||||
# while the rotor spins down. this makes sure it never goes beyond the expected max RPM
|
||||
p.set_fan_power(100)
|
||||
time.sleep(3)
|
||||
p.set_fan_power(0)
|
||||
for _ in range(5):
|
||||
assert p.get_fan_rpm() <= MAX_RPM*2
|
||||
time.sleep(0.5)
|
||||
@@ -0,0 +1,49 @@
|
||||
import time
|
||||
|
||||
from panda.tests.hitl.base import PandaTestCase, panda_test
|
||||
from panda import Panda
|
||||
|
||||
class TestMisc(PandaTestCase):
|
||||
def test_boot_time(self):
|
||||
p = self.p
|
||||
# boot time should be instant
|
||||
st = time.monotonic()
|
||||
p.reset(reconnect=False)
|
||||
assert Panda.wait_for_panda(p.get_usb_serial(), timeout=3.0)
|
||||
|
||||
# USB enumeration is slow, so SPI is faster
|
||||
assert time.monotonic() - st < (1.0 if p.spi else 5.0)
|
||||
|
||||
@panda_test(needs_jungle=True)
|
||||
@panda_test(expect_can_error=True)
|
||||
@panda_test(panda_types=(Panda.HW_TYPE_CUATRO, ))
|
||||
def test_stop_mode(self):
|
||||
p = self.p
|
||||
panda_jungle = self.panda_jungle
|
||||
serial = p.get_usb_serial()
|
||||
panda_jungle.set_obd(True)
|
||||
|
||||
for orientation in (Panda.HARNESS_STATUS_FLIPPED, Panda.HARNESS_STATUS_NORMAL):
|
||||
panda_jungle.set_harness_orientation(orientation)
|
||||
time.sleep(0.25) # wait for orientation detection
|
||||
|
||||
for wakeup in ("ign", "0", "1", "2"):
|
||||
panda_jungle.set_ignition(False)
|
||||
print(f"orientation={orientation} wakeup={wakeup}")
|
||||
|
||||
p.enter_stop_mode()
|
||||
p.close()
|
||||
# wait for panda to enter stop mode
|
||||
time.sleep(1.5)
|
||||
|
||||
# wake via ignition or CAN activity
|
||||
if wakeup == "ign":
|
||||
panda_jungle.set_ignition(True)
|
||||
else:
|
||||
panda_jungle.can_send(0x123, b'\x01\x02', int(wakeup))
|
||||
|
||||
# panda should reset and come back
|
||||
assert Panda.wait_for_panda(serial, timeout=10)
|
||||
|
||||
p.reconnect()
|
||||
assert p.health()['uptime'] < 3
|
||||
@@ -0,0 +1,80 @@
|
||||
import time
|
||||
import itertools
|
||||
|
||||
from opendbc.car.structs import CarParams
|
||||
from panda.tests.hitl.base import PandaTestCase, panda_test
|
||||
from panda import Panda
|
||||
|
||||
# TODO: test relay
|
||||
|
||||
class TestHarness(PandaTestCase):
|
||||
@panda_test(needs_jungle=True)
|
||||
@panda_test(expect_can_error=True)
|
||||
def test_harness_status(self):
|
||||
p = self.p
|
||||
panda_jungle = self.panda_jungle
|
||||
# map from jungle orientations to panda orientations
|
||||
orientation_map = {
|
||||
Panda.HARNESS_STATUS_NC: Panda.HARNESS_STATUS_NC,
|
||||
}
|
||||
|
||||
# this shouldn't be parameterized since we don't want the panda to be reset
|
||||
# between the tests.
|
||||
for ignition, orientation in itertools.product([True, False], [Panda.HARNESS_STATUS_NC, Panda.HARNESS_STATUS_NORMAL, Panda.HARNESS_STATUS_FLIPPED]):
|
||||
print()
|
||||
p.set_safety_mode(CarParams.SafetyModel.elm327)
|
||||
panda_jungle.set_harness_orientation(orientation)
|
||||
panda_jungle.set_ignition(ignition)
|
||||
|
||||
# wait for orientation detection
|
||||
time.sleep(0.25)
|
||||
|
||||
health = p.health()
|
||||
detected_orientation = health['car_harness_status']
|
||||
print(f"orientation set: {orientation} detected: {detected_orientation}")
|
||||
|
||||
if detected_orientation not in orientation_map:
|
||||
assert detected_orientation != Panda.HARNESS_STATUS_NC
|
||||
other = {Panda.HARNESS_STATUS_NORMAL: Panda.HARNESS_STATUS_FLIPPED, Panda.HARNESS_STATUS_FLIPPED: Panda.HARNESS_STATUS_NORMAL}
|
||||
orientation_map.update({
|
||||
orientation: detected_orientation,
|
||||
other[orientation]: other[detected_orientation],
|
||||
})
|
||||
|
||||
# Orientation
|
||||
assert orientation_map[detected_orientation] == orientation
|
||||
|
||||
# Line ignition
|
||||
assert health['ignition_line'] == (False if orientation == Panda.HARNESS_STATUS_NC else ignition)
|
||||
|
||||
# CAN traffic
|
||||
if orientation != Panda.HARNESS_STATUS_NC:
|
||||
for bus in range(3):
|
||||
panda_jungle.can_send(0x123, f"{bus}".encode(), bus)
|
||||
time.sleep(0.5)
|
||||
|
||||
msgs = p.can_recv()
|
||||
buses = {int(dat): bus for _, dat, bus in msgs if bus <= 3}
|
||||
print(msgs)
|
||||
|
||||
# jungle doesn't actually switch buses when switching orientation
|
||||
flipped = orientation == Panda.HARNESS_STATUS_FLIPPED
|
||||
assert buses[0] == (2 if flipped else 0)
|
||||
assert buses[2] == (0 if flipped else 2)
|
||||
|
||||
# SBU voltages
|
||||
supply_voltage_mV = 1800 if p.get_type() in [Panda.HW_TYPE_TRES, Panda.HW_TYPE_CUATRO] else 3300
|
||||
|
||||
if orientation == Panda.HARNESS_STATUS_NC:
|
||||
assert health['sbu1_voltage_mV'] > 0.9 * supply_voltage_mV
|
||||
assert health['sbu2_voltage_mV'] > 0.9 * supply_voltage_mV
|
||||
else:
|
||||
relay_line = 'sbu1_voltage_mV' if (detected_orientation == Panda.HARNESS_STATUS_FLIPPED) else 'sbu2_voltage_mV'
|
||||
ignition_line = 'sbu2_voltage_mV' if (detected_orientation == Panda.HARNESS_STATUS_FLIPPED) else 'sbu1_voltage_mV'
|
||||
|
||||
assert health[relay_line] < 0.1 * supply_voltage_mV
|
||||
assert health[ignition_line] > health[relay_line]
|
||||
if ignition:
|
||||
assert health[ignition_line] < 0.3 * supply_voltage_mV
|
||||
else:
|
||||
assert health[ignition_line] > 0.9 * supply_voltage_mV
|
||||
@@ -1,6 +1,8 @@
|
||||
import opendbc
|
||||
|
||||
import os
|
||||
env = Environment(
|
||||
ENV=os.environ,
|
||||
CFLAGS=[
|
||||
'-nostdlib',
|
||||
'-fno-builtin',
|
||||
|
||||
@@ -1,87 +1,83 @@
|
||||
import ctypes
|
||||
import os
|
||||
from cffi import FFI
|
||||
from typing import Any, Protocol
|
||||
|
||||
from panda import LEN_TO_DLC
|
||||
|
||||
libpanda_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
libpanda_fn = os.path.join(libpanda_dir, "libpanda.so")
|
||||
|
||||
ffi = FFI()
|
||||
|
||||
ffi.cdef("""
|
||||
typedef struct {
|
||||
unsigned char fd : 1;
|
||||
unsigned char bus : 3;
|
||||
unsigned char data_len_code : 4;
|
||||
unsigned char rejected : 1;
|
||||
unsigned char returned : 1;
|
||||
unsigned char extended : 1;
|
||||
unsigned int addr : 29;
|
||||
unsigned char checksum;
|
||||
unsigned char data[64];
|
||||
} CANPacket_t;
|
||||
""", packed=True)
|
||||
|
||||
ffi.cdef("""
|
||||
int set_safety_hooks(uint16_t mode, uint16_t param);
|
||||
""")
|
||||
|
||||
ffi.cdef("""
|
||||
typedef struct {
|
||||
volatile uint32_t w_ptr;
|
||||
volatile uint32_t r_ptr;
|
||||
uint32_t fifo_size;
|
||||
CANPacket_t *elems;
|
||||
} can_ring;
|
||||
|
||||
extern can_ring *rx_q;
|
||||
extern can_ring *tx1_q;
|
||||
extern can_ring *tx2_q;
|
||||
extern can_ring *tx3_q;
|
||||
|
||||
bool can_pop(can_ring *q, CANPacket_t *elem);
|
||||
bool can_push(can_ring *q, CANPacket_t *elem);
|
||||
void can_set_checksum(CANPacket_t *packet);
|
||||
int comms_can_read(uint8_t *data, uint32_t max_len);
|
||||
void comms_can_write(uint8_t *data, uint32_t len);
|
||||
void comms_can_reset(void);
|
||||
uint32_t can_slots_empty(can_ring *q);
|
||||
""")
|
||||
|
||||
class CANPacket:
|
||||
reserved: int
|
||||
bus: int
|
||||
data_len_code: int
|
||||
rejected: int
|
||||
returned: int
|
||||
extended: int
|
||||
addr: int
|
||||
data: list[int]
|
||||
|
||||
class Panda(Protocol):
|
||||
# CAN
|
||||
tx1_q: Any
|
||||
tx2_q: Any
|
||||
tx3_q: Any
|
||||
def can_set_checksum(self, p: CANPacket) -> None: ...
|
||||
|
||||
# safety
|
||||
def set_safety_hooks(self, mode: int, param: int) -> int: ...
|
||||
class CANPacketHeader(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("fd", ctypes.c_uint8, 1),
|
||||
("bus", ctypes.c_uint8, 3),
|
||||
("data_len_code", ctypes.c_uint8, 4),
|
||||
]
|
||||
|
||||
|
||||
libpanda: Panda = ffi.dlopen(libpanda_fn)
|
||||
class CANPacketAddress(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("rejected", ctypes.c_uint32, 1),
|
||||
("returned", ctypes.c_uint32, 1),
|
||||
("extended", ctypes.c_uint32, 1),
|
||||
("addr", ctypes.c_uint32, 29),
|
||||
]
|
||||
|
||||
|
||||
# helpers
|
||||
class CANPacketFields(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_anonymous_ = ("header", "address")
|
||||
_fields_ = [
|
||||
("header", CANPacketHeader),
|
||||
("address", CANPacketAddress),
|
||||
("checksum", ctypes.c_uint8),
|
||||
("data", ctypes.c_uint8 * 64),
|
||||
]
|
||||
|
||||
def make_CANPacket(addr: int, bus: int, dat):
|
||||
ret = ffi.new('CANPacket_t *')
|
||||
ret[0].extended = 1 if addr >= 0x800 else 0
|
||||
ret[0].addr = addr
|
||||
ret[0].data_len_code = LEN_TO_DLC[len(dat)]
|
||||
ret[0].bus = bus
|
||||
ret[0].data = bytes(dat)
|
||||
|
||||
class CANPacket(ctypes.Union):
|
||||
# Match CANPacket_t's packed fields and aligned(4) attribute.
|
||||
_anonymous_ = ("packet",)
|
||||
_fields_ = [("packet", CANPacketFields), ("_alignment", ctypes.c_uint32)]
|
||||
|
||||
|
||||
class CANRing(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("w_ptr", ctypes.c_uint32),
|
||||
("r_ptr", ctypes.c_uint32),
|
||||
("fifo_size", ctypes.c_uint32),
|
||||
("elems", ctypes.POINTER(CANPacket)),
|
||||
]
|
||||
|
||||
|
||||
libpanda = ctypes.CDLL(libpanda_fn)
|
||||
|
||||
for name in ("rx_q", "tx1_q", "tx2_q", "tx3_q"):
|
||||
setattr(libpanda, name, ctypes.POINTER(CANRing).in_dll(libpanda, name))
|
||||
|
||||
for name, argtypes, restype in (
|
||||
("set_safety_hooks", [ctypes.c_uint16, ctypes.c_uint16], ctypes.c_int),
|
||||
("can_pop", [ctypes.POINTER(CANRing), ctypes.POINTER(CANPacket)], ctypes.c_bool),
|
||||
("can_push", [ctypes.POINTER(CANRing), ctypes.POINTER(CANPacket)], ctypes.c_bool),
|
||||
("can_set_checksum", [ctypes.POINTER(CANPacket)], None),
|
||||
("comms_can_read", [ctypes.POINTER(ctypes.c_uint8), ctypes.c_uint32], ctypes.c_int),
|
||||
("comms_can_write", [ctypes.c_char_p, ctypes.c_uint32], None),
|
||||
("comms_can_reset", [], None),
|
||||
("can_slots_empty", [ctypes.POINTER(CANRing)], ctypes.c_uint32),
|
||||
):
|
||||
func = getattr(libpanda, name)
|
||||
func.argtypes = argtypes
|
||||
func.restype = restype
|
||||
|
||||
|
||||
def make_CANPacket(addr: int, bus: int, dat) -> CANPacket:
|
||||
ret = CANPacket()
|
||||
ret.extended = 1 if addr >= 0x800 else 0
|
||||
ret.addr = addr
|
||||
ret.data_len_code = LEN_TO_DLC[len(dat)]
|
||||
ret.bus = bus
|
||||
ret.data[:len(dat)] = bytes(dat)
|
||||
libpanda.can_set_checksum(ret)
|
||||
|
||||
return ret
|
||||
|
||||
@@ -7,7 +7,6 @@ void process_can(uint8_t can_number) { }
|
||||
//int safety_tx_hook(CANPacket_t *to_send) { return 1; }
|
||||
|
||||
typedef struct harness_configuration harness_configuration;
|
||||
void refresh_can_tx_slots_available(void);
|
||||
void can_tx_comms_resume_usb(void) { };
|
||||
void can_tx_comms_resume_spi(void) { };
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ echo "Cppcheck checkers list from test_misra.sh:" > $CHECKLIST
|
||||
|
||||
cppcheck() {
|
||||
# get all gcc defines: arm-none-eabi-gcc -dM -E - < /dev/null
|
||||
COMMON_DEFINES="-D__GNUC__=9 -UCMSIS_NVIC_VIRTUAL -UCMSIS_VECTAB_VIRTUAL -UPANDA_JUNGLE -UBOOTSTUB"
|
||||
COMMON_DEFINES="-D__GNUC__=9 -UCMSIS_NVIC_VIRTUAL -UCMSIS_VECTAB_VIRTUAL -UBOOTSTUB"
|
||||
|
||||
# note that cppcheck build cache results in inconsistent results as of v2.13.0
|
||||
OUTPUT=$DIR/.output.log
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import glob
|
||||
import pytest
|
||||
import unittest
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import random
|
||||
from concurrent.futures import ProcessPoolExecutor
|
||||
|
||||
HERE = os.path.abspath(os.path.dirname(__file__))
|
||||
ROOT = os.path.join(HERE, "../../")
|
||||
@@ -13,7 +14,6 @@ ROOT = os.path.join(HERE, "../../")
|
||||
# skip mutating these paths
|
||||
IGNORED_PATHS = (
|
||||
'board/obj',
|
||||
'board/jungle',
|
||||
'board/body',
|
||||
'board/stm32h7/inc',
|
||||
'board/fake_stm.h',
|
||||
@@ -57,7 +57,7 @@ all_files = glob.glob('board/**', root_dir=ROOT, recursive=True)
|
||||
files = sorted(f for f in all_files if f.endswith(('.c', '.h')) and not f.startswith(IGNORED_PATHS))
|
||||
assert len(files) > 50, all(d in files for d in ('board/main.c', 'board/stm32h7/llfdcan.h'))
|
||||
|
||||
# fixed seed so every xdist worker collects the same test params
|
||||
# fixed seed for reproducible mutation selection
|
||||
rng = random.Random(len(files))
|
||||
for p in patterns:
|
||||
mutations.append((rng.choice(files), p, True))
|
||||
@@ -65,10 +65,9 @@ for p in patterns:
|
||||
# sample to keep CI fast, but always include the no-mutation case
|
||||
mutations = [mutations[0]] + rng.sample(mutations[1:], min(2, len(mutations) - 1))
|
||||
|
||||
@pytest.mark.parametrize("fn, patch, should_fail", mutations)
|
||||
def test_misra_mutation(fn, patch, should_fail):
|
||||
def run_mutation(fn, patch, should_fail):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
shutil.copytree(ROOT, tmp + "/panda", dirs_exist_ok=True)
|
||||
shutil.copytree(ROOT, tmp + "/panda", ignore=shutil.ignore_patterns(".git", ".venv", "__pycache__"))
|
||||
|
||||
# apply patch
|
||||
if fn is not None:
|
||||
@@ -83,7 +82,26 @@ def test_misra_mutation(fn, patch, should_fail):
|
||||
with open(fpath, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
# run test
|
||||
r = subprocess.run("SKIP_TABLES_DIFF=1 panda/tests/misra/test_misra.sh", cwd=tmp, shell=True)
|
||||
failed = r.returncode != 0
|
||||
assert failed == should_fail
|
||||
return subprocess.run("SKIP_TABLES_DIFF=1 panda/tests/misra/test_misra.sh", cwd=tmp, shell=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
||||
|
||||
|
||||
class TestMisraMutation(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
# Each mutation has its own checkout and subprocess; keep the expensive checks parallel.
|
||||
executor = ProcessPoolExecutor(max_workers=len(mutations))
|
||||
cls.addClassCleanup(executor.shutdown)
|
||||
cls.results = [executor.submit(run_mutation, *mutation) for mutation in mutations]
|
||||
|
||||
|
||||
def mutation_test(index):
|
||||
def test(self):
|
||||
result = self.results[index].result()
|
||||
self.assertEqual(result.returncode != 0, mutations[index][2], result.stdout)
|
||||
test.__doc__ = f"MISRA mutation: {mutations[index]}"
|
||||
return test
|
||||
|
||||
|
||||
for index in range(len(mutations)):
|
||||
setattr(TestMisraMutation, f"test_misra_mutation_{index}", mutation_test(index))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
import ctypes
|
||||
import random
|
||||
import unittest
|
||||
|
||||
@@ -13,9 +14,9 @@ TX_QUEUES = (lpp.tx1_q, lpp.tx2_q, lpp.tx3_q)
|
||||
|
||||
|
||||
def unpackage_can_msg(pkt):
|
||||
dat_len = DLC_TO_LEN[pkt[0].data_len_code]
|
||||
dat = bytes(pkt[0].data[0:dat_len])
|
||||
return pkt[0].addr, dat, pkt[0].bus
|
||||
dat_len = DLC_TO_LEN[pkt.data_len_code]
|
||||
dat = bytes(pkt.data[0:dat_len])
|
||||
return pkt.addr, dat, pkt.bus
|
||||
|
||||
|
||||
def random_can_messages(n, bus=None):
|
||||
@@ -39,7 +40,7 @@ class TestPandaComms(unittest.TestCase):
|
||||
message = (0x100, b"test", bus)
|
||||
|
||||
can_pkt_tx = libpanda_py.make_CANPacket(message[0], message[2], message[1])
|
||||
can_pkt_rx = libpanda_py.ffi.new('CANPacket_t *')
|
||||
can_pkt_rx = libpanda_py.CANPacket()
|
||||
|
||||
assert lpp.can_push(TX_QUEUES[bus], can_pkt_tx), "CAN push failed"
|
||||
assert lpp.can_pop(TX_QUEUES[bus], can_pkt_rx), "CAN pop failed"
|
||||
@@ -55,7 +56,7 @@ class TestPandaComms(unittest.TestCase):
|
||||
|
||||
# read a small chunk such that we have some overflow
|
||||
TINY_CHUNK_SIZE = 6
|
||||
dat = libpanda_py.ffi.new(f"uint8_t[{TINY_CHUNK_SIZE}]")
|
||||
dat = (ctypes.c_uint8 * TINY_CHUNK_SIZE)()
|
||||
rx_len = lpp.comms_can_read(dat, TINY_CHUNK_SIZE)
|
||||
assert rx_len == TINY_CHUNK_SIZE, "comms_can_read returned too little data"
|
||||
|
||||
@@ -67,7 +68,7 @@ class TestPandaComms(unittest.TestCase):
|
||||
|
||||
# read a large chunk, which should now contain valid messages
|
||||
LARGE_CHUNK_SIZE = 512
|
||||
dat = libpanda_py.ffi.new(f"uint8_t[{LARGE_CHUNK_SIZE}]")
|
||||
dat = (ctypes.c_uint8 * LARGE_CHUNK_SIZE)()
|
||||
rx_len = lpp.comms_can_read(dat, LARGE_CHUNK_SIZE)
|
||||
assert rx_len == LARGE_CHUNK_SIZE, "comms_can_read returned too little data"
|
||||
|
||||
@@ -93,7 +94,7 @@ class TestPandaComms(unittest.TestCase):
|
||||
|
||||
# read the messages from the queue and make sure they're valid
|
||||
queue_msgs = []
|
||||
pkt = libpanda_py.ffi.new('CANPacket_t *')
|
||||
pkt = libpanda_py.CANPacket()
|
||||
while lpp.can_pop(TX_QUEUES[0], pkt):
|
||||
queue_msgs.append(unpackage_can_msg(pkt))
|
||||
|
||||
@@ -117,7 +118,7 @@ class TestPandaComms(unittest.TestCase):
|
||||
|
||||
# Check that they ended up in the right buffers
|
||||
queue_msgs = []
|
||||
pkt = libpanda_py.ffi.new('CANPacket_t *')
|
||||
pkt = libpanda_py.CANPacket()
|
||||
while lpp.can_pop(TX_QUEUES[bus], pkt):
|
||||
queue_msgs.append(unpackage_can_msg(pkt))
|
||||
|
||||
@@ -137,7 +138,7 @@ class TestPandaComms(unittest.TestCase):
|
||||
|
||||
# Simulate USB bulk IN chunks
|
||||
MAX_TRANSFER_SIZE = 16384
|
||||
dat = libpanda_py.ffi.new(f"uint8_t[{CHUNK_SIZE}]")
|
||||
dat = (ctypes.c_uint8 * CHUNK_SIZE)()
|
||||
while True:
|
||||
buf = b""
|
||||
while len(buf) < MAX_TRANSFER_SIZE:
|
||||
|
||||
Reference in New Issue
Block a user