mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-02-05 18:40:21 +00:00
Boards header updates (#1724)
* Add script to automatically validate board header files * Fix small automatically-found inconsistencies in various board header files * Tweak and add board header file from abandoned PR #1174
This commit is contained in:
parent
333974fd6c
commit
0e5cef3ffa
84
src/boards/include/boards/0xcb_helios.h
Normal file
84
src/boards/include/boards/0xcb_helios.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// -----------------------------------------------------
|
||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Board definition for the 0xCB Helios
|
||||
|
||||
#ifndef _BOARDS_0XCB_HELIOS_H
|
||||
#define _BOARDS_0XCB_HELIOS_H
|
||||
|
||||
// For board detection
|
||||
#define _0XCB_HELIOS
|
||||
|
||||
#ifndef PICO_DEFAULT_UART
|
||||
#define PICO_DEFAULT_UART 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_UART_TX_PIN
|
||||
#define PICO_DEFAULT_UART_TX_PIN 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_UART_RX_PIN
|
||||
#define PICO_DEFAULT_UART_RX_PIN 1
|
||||
#endif
|
||||
|
||||
// User LED and level shifted PIN
|
||||
#ifndef PICO_DEFAULT_LED_PIN
|
||||
#define PICO_DEFAULT_LED_PIN 17
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_WS2812_PIN
|
||||
#define PICO_DEFAULT_WS2812_PIN 25
|
||||
#endif
|
||||
|
||||
// --- I2C ---
|
||||
#ifndef PICO_DEFAULT_I2C
|
||||
#define PICO_DEFAULT_I2C 1
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_I2C_SDA_PIN
|
||||
#define PICO_DEFAULT_I2C_SDA_PIN 2
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_I2C_SCL_PIN
|
||||
#define PICO_DEFAULT_I2C_SCL_PIN 3
|
||||
#endif
|
||||
|
||||
// --- SPI ---
|
||||
#ifndef PICO_DEFAULT_SPI
|
||||
#define PICO_DEFAULT_SPI 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_SCK_PIN
|
||||
#define PICO_DEFAULT_SPI_SCK_PIN 22
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_TX_PIN
|
||||
#define PICO_DEFAULT_SPI_TX_PIN 23
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_RX_PIN
|
||||
#define PICO_DEFAULT_SPI_RX_PIN 20
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_CSN_PIN
|
||||
#define PICO_DEFAULT_SPI_CSN_PIN 21
|
||||
#endif
|
||||
|
||||
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
|
||||
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 2
|
||||
#endif
|
||||
|
||||
// board has 16M onboard flash
|
||||
#ifndef PICO_FLASH_SIZE_BYTES
|
||||
#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
@ -26,8 +26,8 @@
|
||||
#define MAKER_PI_RP2040_M1B_PIN 9
|
||||
#endif
|
||||
|
||||
#ifndef MAKER_PI_RP2040_M2B_PIN
|
||||
#define MAKER_PI_RP2040_M2B_PIN 10
|
||||
#ifndef MAKER_PI_RP2040_M2A_PIN
|
||||
#define MAKER_PI_RP2040_M2A_PIN 10
|
||||
#endif
|
||||
|
||||
#ifndef MAKER_PI_RP2040_M2B_PIN
|
||||
@ -186,4 +186,4 @@
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -56,7 +56,7 @@
|
||||
|
||||
//------------- I2C -------------//
|
||||
#ifndef PICO_DEFAULT_I2C
|
||||
#define PICO_DEFAULT_I2C 0
|
||||
#define PICO_DEFAULT_I2C 1
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DEFAULT_I2C_SDA_PIN
|
||||
|
@ -9,7 +9,7 @@
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
|
||||
// This header may be included by other board headers as "boards/pico.h"
|
||||
// This header may be included by other board headers as "boards/pico_w.h"
|
||||
|
||||
#ifndef _BOARDS_PICO_W_H
|
||||
#define _BOARDS_PICO_W_H
|
||||
|
@ -13,8 +13,8 @@
|
||||
#define _BOARDS_PIMORONI_TINY2040_2MB_H
|
||||
|
||||
// For board detection
|
||||
#define PIMORONI_TINY2040
|
||||
#define PIMORONI_TINY2040_2MB
|
||||
#define PIMORONI_TINY2040
|
||||
|
||||
// --- BOARD SPECIFIC ---
|
||||
#define TINY2040_LED_R_PIN 18
|
||||
|
@ -9,8 +9,8 @@
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
|
||||
#ifndef _POLOLU_3PI_2040_ROBOT_H
|
||||
#define _POLOLU_3PI_2040_ROBOT_H
|
||||
#ifndef _BOARDS_POLOLU_3PI_2040_ROBOT_H
|
||||
#define _BOARDS_POLOLU_3PI_2040_ROBOT_H
|
||||
|
||||
// For board detection
|
||||
#define POLOLU_3PI_2040_ROBOT
|
||||
|
@ -9,8 +9,8 @@
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
|
||||
#ifndef _POLOLU_ZUMO_2040_ROBOT_H
|
||||
#define _POLOLU_ZUMO_2040_ROBOT_H
|
||||
#ifndef _BOARDS_POLOLU_ZUMO_2040_ROBOT_H
|
||||
#define _BOARDS_POLOLU_ZUMO_2040_ROBOT_H
|
||||
|
||||
// For board detection
|
||||
#define POLOLU_ZUMO_2040_ROBOT
|
||||
|
@ -9,13 +9,13 @@
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
|
||||
// This header may be included by other board headers as "boards/weact_studio_rp2040_16mb.h"
|
||||
// This header may be included by other board headers as "boards/weact_studio_rp2040_2mb.h"
|
||||
|
||||
#ifndef _BOARDS_WEACT_STUDIO_RP2040_16MB_H
|
||||
#define _BOARDS_WEACT_STUDIO_RP2040_16MB_H
|
||||
#ifndef _BOARDS_WEACT_STUDIO_RP2040_2MB_H
|
||||
#define _BOARDS_WEACT_STUDIO_RP2040_2MB_H
|
||||
|
||||
// For board detection
|
||||
#define WEACT_STUDIO_RP2040_16MB
|
||||
#define WEACT_STUDIO_RP2040_2MB
|
||||
|
||||
// --- UART ---
|
||||
#ifndef PICO_DEFAULT_UART
|
||||
|
@ -9,13 +9,13 @@
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
|
||||
// This header may be included by other board headers as "boards/weact_studio_rp2040_16mb.h"
|
||||
// This header may be included by other board headers as "boards/weact_studio_rp2040_4mb.h"
|
||||
|
||||
#ifndef _BOARDS_WEACT_STUDIO_RP2040_16MB_H
|
||||
#define _BOARDS_WEACT_STUDIO_RP2040_16MB_H
|
||||
#ifndef _BOARDS_WEACT_STUDIO_RP2040_4MB_H
|
||||
#define _BOARDS_WEACT_STUDIO_RP2040_4MB_H
|
||||
|
||||
// For board detection
|
||||
#define WEACT_STUDIO_RP2040_16MB
|
||||
#define WEACT_STUDIO_RP2040_4MB
|
||||
|
||||
// --- UART ---
|
||||
#ifndef PICO_DEFAULT_UART
|
||||
|
@ -9,13 +9,13 @@
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
|
||||
// This header may be included by other board headers as "boards/weact_studio_rp2040_16mb.h"
|
||||
// This header may be included by other board headers as "boards/weact_studio_rp2040_8mb.h"
|
||||
|
||||
#ifndef _BOARDS_WEACT_STUDIO_RP2040_16MB_H
|
||||
#define _BOARDS_WEACT_STUDIO_RP2040_16MB_H
|
||||
#ifndef _BOARDS_WEACT_STUDIO_RP2040_8MB_H
|
||||
#define _BOARDS_WEACT_STUDIO_RP2040_8MB_H
|
||||
|
||||
// For board detection
|
||||
#define WEACT_STUDIO_RP2040_16MB
|
||||
#define WEACT_STUDIO_RP2040_8MB
|
||||
|
||||
// --- UART ---
|
||||
#ifndef PICO_DEFAULT_UART
|
||||
|
74
src/rp2040/rp2040_interface_pins.json
Normal file
74
src/rp2040/rp2040_interface_pins.json
Normal file
@ -0,0 +1,74 @@
|
||||
{
|
||||
"UART": {
|
||||
"0": {
|
||||
"TX": [0, 12, 16, 28],
|
||||
"RX": [1, 13, 17, 29],
|
||||
"CTS": [2, 14, 18],
|
||||
"RTS": [3, 15, 19]
|
||||
},
|
||||
"1": {
|
||||
"TX": [4, 8, 20, 24],
|
||||
"RX": [5, 9, 21, 25],
|
||||
"CTS": [6, 10, 22, 26],
|
||||
"RTS": [7, 11, 23, 27]
|
||||
}
|
||||
},
|
||||
"I2C": {
|
||||
"0": {
|
||||
"SDA": [0, 4, 8, 12, 16, 20, 24, 28],
|
||||
"SCL": [1, 5, 9, 13, 17, 21, 25, 29]
|
||||
},
|
||||
"1": {
|
||||
"SDA": [2, 6, 10, 14, 18, 22, 26],
|
||||
"SCL": [3, 7, 11, 15, 19, 23, 27]
|
||||
}
|
||||
},
|
||||
"SPI": {
|
||||
"0": {
|
||||
"RX": [0, 4, 16, 20],
|
||||
"CSN": [1, 5, 17, 21],
|
||||
"SCK": [2, 6, 18, 22],
|
||||
"TX": [3, 7, 19, 23]
|
||||
},
|
||||
"1": {
|
||||
"RX": [8, 12, 24, 28],
|
||||
"CSN": [9, 13, 25, 29],
|
||||
"SCK": [10, 14, 26],
|
||||
"TX": [11, 15, 27]
|
||||
}
|
||||
},
|
||||
"PWM": {
|
||||
"0": {
|
||||
"A": [0, 16],
|
||||
"B": [1, 17]
|
||||
},
|
||||
"1": {
|
||||
"A": [2, 18],
|
||||
"B": [3, 19]
|
||||
},
|
||||
"2": {
|
||||
"A": [4, 20],
|
||||
"B": [5, 21]
|
||||
},
|
||||
"3": {
|
||||
"A": [6, 22],
|
||||
"B": [7, 23]
|
||||
},
|
||||
"4": {
|
||||
"A": [8, 24],
|
||||
"B": [9, 25]
|
||||
},
|
||||
"5": {
|
||||
"A": [10, 26],
|
||||
"B": [11, 27]
|
||||
},
|
||||
"6": {
|
||||
"A": [12, 28],
|
||||
"B": [13, 29]
|
||||
},
|
||||
"7": {
|
||||
"A": [14],
|
||||
"B": [15]
|
||||
}
|
||||
}
|
||||
}
|
7
tools/check_all_board_headers.sh
Executable file
7
tools/check_all_board_headers.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
for HEADER in src/boards/include/boards/*.h; do
|
||||
tools/check_board_header.py $HEADER
|
||||
if [[ $? -ne 0 ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
183
tools/check_board_header.py
Executable file
183
tools/check_board_header.py
Executable file
@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Raspberry Pi Ltd.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
#
|
||||
# Simple script to check basic validity of a board-header-file
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# tools/check_board_header.py src/boards/include/boards/<board.h>
|
||||
|
||||
|
||||
import re
|
||||
import sys
|
||||
import os.path
|
||||
import json
|
||||
import warnings
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
# warnings off by default, because some boards use the same pin for multiple purposes
|
||||
show_warnings = False
|
||||
|
||||
interfaces_json = "src/rp2040/rp2040_interface_pins.json"
|
||||
if not os.path.isfile(interfaces_json):
|
||||
raise Exception("{} doesn't exist".format(interfaces_json))
|
||||
|
||||
board_header = sys.argv[1]
|
||||
if not os.path.isfile(board_header):
|
||||
raise Exception("{} doesn't exist".format(board_header))
|
||||
|
||||
with open(interfaces_json) as interfaces_fh:
|
||||
interfaces = json.load(interfaces_fh)
|
||||
# convert instance-keys to integers (allowed by Python but not by JSON)
|
||||
for interface in interfaces:
|
||||
for instance in list(interfaces[interface]):
|
||||
interfaces[interface][int(instance)] = interfaces[interface].pop(instance)
|
||||
|
||||
DefineType = namedtuple("DefineType", ["name", "value", "resolved_value", "lineno"])
|
||||
|
||||
defines = dict()
|
||||
pins = dict() # dict of lists
|
||||
has_include_guard = False
|
||||
has_board_detection = False
|
||||
has_include_suggestion = False
|
||||
expected_include_suggestion = "/".join(board_header.split("/")[-2:])
|
||||
expected_include_guard = "_" + re.sub(r"\W", "_", expected_include_suggestion.upper())
|
||||
expected_board_detection = re.sub(r"\W", "_", expected_include_suggestion.split("/")[-1].upper()[:-2])
|
||||
|
||||
with open(board_header) as header_fh:
|
||||
last_ifndef = None
|
||||
last_ifndef_lineno = -1
|
||||
board_detection_is_next = False
|
||||
for lineno, line in enumerate(header_fh.readlines()):
|
||||
lineno += 1
|
||||
# strip trailing comments
|
||||
line = re.sub(r"(?<=\S)\s*//.*$", "", line)
|
||||
|
||||
# look for board-detection comment
|
||||
if re.match("// For board detection", line):
|
||||
board_detection_is_next = True
|
||||
continue
|
||||
# check include-suggestion
|
||||
m = re.match(r"^// This header may be included by other board headers as \"(.+?)\"", line)
|
||||
if m:
|
||||
include_suggestion = m.group(1)
|
||||
if include_suggestion == expected_include_suggestion:
|
||||
has_include_suggestion = True
|
||||
else:
|
||||
raise Exception("{}:{} Suggests including \"{}\" but file is named \"{}\"".format(board_header, lineno, include_suggestion, expected_include_suggestion))
|
||||
# look for "#ifndef BLAH_BLAH"
|
||||
m = re.match(r"^#ifndef (\w+)\s*$", line)
|
||||
if m:
|
||||
last_ifndef = m.group(1)
|
||||
last_ifndef_lineno = lineno
|
||||
# look for "#define BLAH_BLAH" or "#define BLAH_BLAH 42"
|
||||
m = re.match(r"^#define (\w+)(?:\s+(.+?))?\s*$", line)
|
||||
if m:
|
||||
#print(m.groups())
|
||||
name = m.group(1)
|
||||
value = m.group(2)
|
||||
# check all uppercase
|
||||
if name != name.upper():
|
||||
raise Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name))
|
||||
# check that adjacent #ifndef and #define lines match up
|
||||
if last_ifndef_lineno + 1 == lineno:
|
||||
if last_ifndef != name:
|
||||
raise Exception("{}:{} #ifndef {} / #define {} mismatch".format(board_header, last_ifndef_lineno, last_ifndef, name))
|
||||
if value:
|
||||
try:
|
||||
# most board-defines are integer values
|
||||
value = int(value, 0)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# resolve nested defines
|
||||
resolved_value = value
|
||||
while resolved_value in defines:
|
||||
resolved_value = defines[resolved_value].resolved_value
|
||||
else:
|
||||
resolved_value = None
|
||||
|
||||
define = DefineType(name, value, resolved_value, lineno)
|
||||
|
||||
# check the include-guard define
|
||||
if re.match(r"^_BOARDS_(\w+)_H$", name):
|
||||
# check it has an #ifndef
|
||||
if last_ifndef_lineno +1 != lineno:
|
||||
raise Exception("{}:{} Include-guard #define {} is missing an #ifndef".format(board_header, lineno, name))
|
||||
if value:
|
||||
raise Exception("{}:{} Include-guard #define {} shouldn't have a value".format(board_header, lineno, name))
|
||||
if len(defines):
|
||||
raise Exception("{}:{} Include-guard #define {} should be the first define".format(board_header, lineno, name))
|
||||
if name == expected_include_guard:
|
||||
has_include_guard = True
|
||||
else:
|
||||
raise Exception("{}:{} Found include-guard #define {} but expected {}".format(board_header, lineno, name, expected_include_guard))
|
||||
# check board-detection define
|
||||
if board_detection_is_next:
|
||||
board_detection_is_next = False
|
||||
if value:
|
||||
raise Exception("{}:{} Board-detection #define {} shouldn't have a value".format(board_header, lineno, name))
|
||||
# this is a bit messy because pico.h does "#define RASPBERRYPI_PICO" and metrotech_xerxes_rp2040.h does "#define XERXES_RP2040"
|
||||
if name.endswith(expected_board_detection) or expected_board_detection.endswith(name):
|
||||
has_board_detection = True
|
||||
else:
|
||||
raise Exception("{}:{} Board-detection #define {} should end with {}".format(board_header, lineno, name, expected_board_detection))
|
||||
# check for multiply-defined values
|
||||
if name in defines:
|
||||
raise Exception("{}:{} Multiple definitions for {} ({} and {})".format(board_header, lineno, name, defines[name].value, value))
|
||||
else:
|
||||
defines[name] = define
|
||||
|
||||
# check for pin-conflicts
|
||||
if name.endswith("_PIN"):
|
||||
if resolved_value is None:
|
||||
raise Exception("{}:{} {} is set to an undefined value".format(board_header, lineno, name))
|
||||
elif not isinstance(resolved_value, int):
|
||||
raise Exception("{}:{} {} resolves to a non-integer value {}".format(board_header, lineno, name, resolved_value))
|
||||
else:
|
||||
if resolved_value in pins and resolved_value == value:
|
||||
if show_warnings:
|
||||
warnings.warn("{}:{} Both {} and {} claim to be pin {}".format(board_header, lineno, pins[resolved_value][0].name, name, resolved_value))
|
||||
pins[resolved_value].append(define)
|
||||
else:
|
||||
if not (0 <= resolved_value <= 29):
|
||||
raise Exception("{}:{} Pin {} for {} is outside of the allowed range".foramt(board_header, lineno, resolved_value, name))
|
||||
pins[resolved_value] = [define]
|
||||
|
||||
#import pprint; pprint.pprint(dict(sorted(defines.items(), key=lambda x: x[1].lineno)))
|
||||
|
||||
# check for invalid DEFAULT mappings
|
||||
for name, define in defines.items():
|
||||
m = re.match(r"^(PICO_DEFAULT_(\w+))_(\w+)_PIN$", name)
|
||||
if m:
|
||||
instance_name = m.group(1)
|
||||
interface = m.group(2)
|
||||
function = m.group(3)
|
||||
if interface == "WS2812":
|
||||
continue
|
||||
if interface not in interfaces:
|
||||
raise Exception("{}:{} {} is defined but {} isn't in {}".format(board_header, define.lineno, name, interface, interfaces_json))
|
||||
if instance_name not in defines:
|
||||
raise Exception("{}:{} {} is defined but {} isn't defined".format(board_header, define.lineno, name, instance_name))
|
||||
instance_define = defines[instance_name]
|
||||
instance = instance_define.resolved_value
|
||||
if instance not in interfaces[interface]:
|
||||
raise Exception("{}:{} {} is set to an invalid instance {}".format(board_header, instance_define.lineno, instance_define, instance))
|
||||
if function not in interfaces[interface][instance]:
|
||||
raise Exception("{}:{} {} is defined but {} isn't a valid function for {}".format(board_header, define.lineno, name, function, instance_define))
|
||||
if define.resolved_value not in interfaces[interface][instance][function]:
|
||||
raise Exception("{}:{} {} is set to {} which isn't a valid pin for {} on {} {}".format(board_header, define.lineno, name, define.resolved_value, function, interface, instance))
|
||||
|
||||
if not has_include_guard:
|
||||
raise Exception("{} has no include-guard (expected {})".format(board_header, expected_include_guard))
|
||||
if not has_board_detection and expected_board_detection != "NONE":
|
||||
raise Exception("{} has no board-detection #define (expected {})".format(board_header, expected_board_detection))
|
||||
# lots of headers don't have this
|
||||
#if not has_include_suggestion:
|
||||
# raise Exception("{} has no include-suggestion (expected {})".format(board_header, expected_include_suggestion))
|
||||
|
Loading…
x
Reference in New Issue
Block a user