diff --git a/.github/workflows/build_calypso.yml b/.github/workflows/build_calypso.yml new file mode 100644 index 0000000..7800ebe --- /dev/null +++ b/.github/workflows/build_calypso.yml @@ -0,0 +1,22 @@ +name: Check CAN, build Calypso +on: + push: + paths: + - 'cangen/**' + +jobs: + run-build: + runs-on: ubuntu-latest + steps: + - name: Clone Calypso + uses: actions/checkout@v4 + with: + repository: Northeastern-Electric-Racing/Calypso + + - name: Clone Embedded-base + uses: actions/checkout@v4 + with: + path: "./Embedded-Base" + + - name: Build Calypso + run: cargo build --locked diff --git a/README.md b/README.md index 1b52fb9..8d5e4c0 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,22 @@ # Embedded-Base -Embedded-Base is a collection of drivers & middleware designed for use across various systems. +Embedded-Base is a collection of drivers, middlewares, and communication definitions designed for use across various systems. -This repository houses custom drivers and middleware that can be utilized in multiple projects. +Most firmware projects define Embedded-Base as a submodule. -To use this repository in any project, it should be set up as a submodule. +## Getting Started With NER Firmware -## Getting Started +All you need is on confluence [here](https://nerdocs.atlassian.net/wiki/spaces/NER/pages/1343533/Firmware+Onboarding+Embedded+Software#Development-Environment-Setup). -#### 1. Clone Embbeded-Base: - ~~~ - git clone https://github.com/Northeastern-Electric-Racing/Embedded-Base.git - ~~~ +### Notable items in this repository -#### 2. Initialize submodule - Within the application directory, run the following command to initialize the submodule: - ~~~ - git submodule update --init - ~~~ - -## Development Guidelines - -When developing in the parent directory, it's recommended to frequently run the following command to update all submodules in case changes have been made: -~~~ -git submodule update --remote -~~~ - - -**When making changes to a driver located within Embedded-Base, always make those changes directly within the Embedded-Base repository. Avoid making changes to a submodule from the parent directory.** Although it's technically possible, doing so can lead to disorganization, which we want to avoid. - -This approach ensures that changes to Embedded-Base are tracked properly and can be easily integrated into your projects using it as a submodule. +- `cangen`: All JSON definitions of in-car CAN data as well as documentation and parsing utilities. +- `dev`: The manual version of the NER build system, compatible up circuit boards in competition 22A +- `ner_environment`: The NER developer environment compatible with all boards from 22A onwards and cross platform support. +- `general`: Cross-platform C source files for all peripheral drivers used by NER. +- `middleware`: Cross-platform C source files common utilities used across various platforms. +- `platforms`: C source files specific to STM HAL versions. +- `clang-format`: The organization wide clang-format definition. +- `ftdi_flash.cfg`: An openocd script to assist in FTDI flashing. +- `openocd.cfg`: A openocd stub to load GDB onto a target. diff --git a/cangen/can-messages/bms.json b/cangen/can-messages/bms.json index d401e99..e16a22a 100644 --- a/cangen/can-messages/bms.json +++ b/cangen/can-messages/bms.json @@ -1016,5 +1016,178 @@ ] } ] - } + }, + { + "id": "0x6FF", + "desc": "BMS Fault Timers", + "sim_freq": 700, + "fields": [ + { + "name": "BMS/Fault_Timer/Start_Stop", + "unit": "", + "sim": { + "options": [ + [ + 0, + 0.5 + ], + [ + 1, + 0.25 + ], + [ + 2, + 0.25 + ] + ] + }, + "points": [ + { + "size": 8 + } + ] + }, + { + "name": "BMS/Fault_Timer/Code", + "unit": "", + "sim": { + "min": 0, + "max": 31, + "inc_min": 0, + "inc_max": 31, + "round": true + }, + "points": [ + { + "size": 8 + } + ] + }, + { + "name": "BMS/Fault_Timer/Value", + "unit": "", + "sim": { + "min": -100, + "max": 100, + "inc_min": 0.05, + "inc_max": 1 + }, + "points": [ + { + "size": 16 + } + ] + } + ] + }, + { + "id": "0x69A", + "desc": "Shepherd Version Tag", + "sim_freq": 1000, + "fields": [ + { + "name": "BMS/Version/Tag", + "unit": "major.minor.patch", + "sim": { + "min": 0, + "max": 3, + "inc_min": 1, + "inc_max": 1, + "round": true + }, + "points": [ + { + "size": 8 + }, + { + "size": 8 + }, + { + "size": 8 + } + ] + }, + { + "name": "BMS/Version/Dirty", + "unit": "bool", + "sim": { + "options": [ + [ + 0, + 0.95 + ], + [ + 1, + 0.05 + ] + ] + }, + "points": [ + { + "size": 8 + } + ] + }, + { + "name": "BMS/Version/LocalCommit", + "unit": "bool", + "sim": { + "options": [ + [ + 0, + 0.95 + ], + [ + 1, + 0.05 + ] + ] + }, + "points": [ + { + "size": 8 + } + ] + } + ] + }, + { + "id": "0x69B", + "desc": "Shepherd Version Hash", + "sim_freq": 1000, + "fields": [ + { + "name": "BMS/Version/ShortHash", + "unit": "hash", + "sim": { + "min": 0, + "max": 4294967295, + "inc_min": 1, + "inc_max": 1, + "round": true + }, + "points": [ + { + "size": 32 + } + ] + }, + { + "name": "BMS/Version/AuthorHash", + "unit": "hash", + "sim": { + "min": 0, + "max": 4294967295, + "inc_min": 1, + "inc_max": 1, + "round": true + }, + "points": [ + { + "size": 32 + } + ] + } + ] + } ] \ No newline at end of file diff --git a/cangen/can-messages/charger.json b/cangen/can-messages/charger.json index 0dea159..acd1cc7 100644 --- a/cangen/can-messages/charger.json +++ b/cangen/can-messages/charger.json @@ -218,10 +218,10 @@ "send": false, "points": [ { - "size": 24 + "size": 27 } ] } ] } -] \ No newline at end of file +] diff --git a/cangen/can-messages/mpu.json b/cangen/can-messages/mpu.json index 9a9f236..21f5d84 100644 --- a/cangen/can-messages/mpu.json +++ b/cangen/can-messages/mpu.json @@ -15,7 +15,7 @@ ], [ 1, - 0.80 + 0.78 ], [ 2, @@ -27,7 +27,7 @@ ], [ 4, - 0.00 + 0.01 ] ] }, @@ -52,7 +52,7 @@ ], [ 2, - 0.40 + 0.20 ], [ 3, @@ -370,8 +370,7 @@ }, "points": [ { - "size": 8, - "endianness": "little" + "size": 8 } ] } @@ -933,5 +932,115 @@ ] } ] + }, + { + "id": "0x698", + "desc": "Cerberus Version Tag", + "sim_freq": 1000, + "fields": [ + { + "name": "MPU/Version/Tag", + "unit": "major.minor.patch", + "sim": { + "min": 0, + "max": 3, + "inc_min": 1, + "inc_max": 1, + "round": true + }, + "points": [ + { + "size": 8 + }, + { + "size": 8 + }, + { + "size": 8 + } + ] + }, + { + "name": "MPU/Version/Dirty", + "unit": "bool", + "sim": { + "options": [ + [ + 0, + 0.95 + ], + [ + 1, + 0.05 + ] + ] + }, + "points": [ + { + "size": 8 + } + ] + }, + { + "name": "MPU/Version/LocalCommit", + "unit": "bool", + "sim": { + "options": [ + [ + 0, + 0.95 + ], + [ + 1, + 0.05 + ] + ] + }, + "points": [ + { + "size": 8 + } + ] + } + ] + }, + { + "id": "0x699", + "desc": "Cerberus Version Hash", + "sim_freq": 1000, + "fields": [ + { + "name": "MPU/Version/ShortHash", + "unit": "hash", + "sim": { + "min": 0, + "max": 4294967295, + "inc_min": 1, + "inc_max": 1, + "round": true + }, + "points": [ + { + "size": 32 + } + ] + }, + { + "name": "MPU/Version/AuthorHash", + "unit": "hash", + "sim": { + "min": 0, + "max": 4294967295, + "inc_min": 1, + "inc_max": 1, + "round": true + }, + "points": [ + { + "size": 32 + } + ] + } + ] } ] diff --git a/launchpad.py b/launchpad.py deleted file mode 100644 index b517706..0000000 --- a/launchpad.py +++ /dev/null @@ -1,115 +0,0 @@ -import subprocess -import sys -import os -import platform -import shutil - -def install_platformio(venv_path): - """Install PlatformIO package and set up aliases.""" - try: - # Install the platformio package - subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'platformio']) - - # Define aliases - aliases = [ - 'lpbuild="platformio run"', - 'lpflash="platformio run --target upload"', - 'lpinit="platformio project init"', - - ] - - os_type = platform.system() - if os_type == 'Windows': - activate_path = os.path.join(venv_path, 'Scripts', 'activate') # Bash script for Git Bash on Windows - else: - activate_path = os.path.join(venv_path, 'bin', 'activate') # bash script for Unix-like system - - - with open(activate_path, 'a') as activate_file: - activate_file.write('\n# Aliases\n') - for alias in aliases: - alias_name, alias_command = alias.strip().split('=', 1) - alias_command = alias_command.strip('"') - activate_file.write(f'alias {alias_name}="{alias_command}"\n') - - print("Aliases added to the activation script successfully.") - - except subprocess.CalledProcessError as e: - print(f"Failed to install PlatformIO: {e}", file=sys.stderr) - sys.exit(1) - -def uninstall_platformio(venv_path): - """Uninstall PlatformIO package and remove aliases.""" - try: - # Uninstall the platformio package - subprocess.check_call([sys.executable, '-m', 'pip', 'uninstall', '-y', 'platformio']) - - # Remove PlatformIO directory - remove_platformio_directory() - - # Determine OS and adjust alias handling - os_type = platform.system() - if os_type == 'Windows': - activate_path = os.path.join(venv_path, 'Scripts', 'activate') # Bash script for Git Bash on Windows - else: - activate_path = os.path.join(venv_path, 'bin', 'activate') # bash script for Unix-like system - - remove_aliases(activate_path) - - print("PlatformIO uninstalled and aliases removed. Please restart your terminal or source your profile script.") - - except subprocess.CalledProcessError as e: - print(f"Failed to uninstall PlatformIO: {e}", file=sys.stderr) - sys.exit(1) - -def remove_aliases(activate_path): - """Remove aliases from the virtual environment's activation script.""" - try: - if os.path.exists(activate_path): - with open(activate_path, 'r') as f: - lines = f.readlines() - with open(activate_path, 'w') as f: - for line in lines: - if not line.startswith('alias '): - f.write(line) - print("Aliases removed from the activation script successfully.") - else: - print("Activation script not found.", file=sys.stderr) - sys.exit(1) - except Exception as e: - print(f"Failed to remove aliases: {e}", file=sys.stderr) - sys.exit(1) - -def remove_platformio_directory(): - """Remove the PlatformIO directory.""" - platformio_dir = os.path.expanduser('~/.platformio') - if os.path.isdir(platformio_dir): - try: - shutil.rmtree(platformio_dir) - print("PlatformIO directory removed.") - except OSError as e: - print(f"Failed to remove PlatformIO directory: {e}", file=sys.stderr) - sys.exit(1) - else: - print("PlatformIO directory does not exist.") -def main(): - if len(sys.argv) != 2: - print("Usage: launchpad.py [install|uninstall]", file=sys.stderr) - sys.exit(1) - - os_type = platform.system() - current_directory = os.path.dirname(os.path.abspath(__file__)) - parent_directory = os.path.dirname(current_directory) - venv_path = os.path.join(parent_directory, 'ner-venv') - - action = sys.argv[1].lower() - if action == 'install': - install_platformio(venv_path) - elif action == 'uninstall': - uninstall_platformio(venv_path) - else: - print("Invalid action. Use 'install' or 'uninstall'.", file=sys.stderr) - sys.exit(1) - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/ner_environment/build_system/build_system.py b/ner_environment/build_system/build_system.py index 4a92a0a..a3f79a5 100644 --- a/ner_environment/build_system/build_system.py +++ b/ner_environment/build_system/build_system.py @@ -13,6 +13,7 @@ # # To see a list of available commands and additional configuration options, run `ner --help` # ============================================================================== +import shutil import typer from rich import print import platform @@ -31,9 +32,12 @@ # ============================================================================== app = typer.Typer(help="Northeastern Electric Racing Firmware Build System", - epilog="For more information, visit https://nerdocs.atlassian.net/wiki/spaces/NER/pages/611516420/NER+Build+System", + epilog="For more information, visit https://nerdocs.atlassian.net/wiki/spaces/NER/pages/524451844/2024+Firmware+Onboarding+Master", add_completion=False) +lp_app = typer.Typer(help="Install configure, and run launchpad environment items") +app.add_typer(lp_app, name="lp") + def unsupported_option_cb(value:bool): if value: print("[bold red] WARNING: the selected option is not currently implemented. This is either because is is an planned or deprecated feature") @@ -59,7 +63,7 @@ def build(profile: str = typer.Option(None, "--profile", "-p", callback=unsuppor @app.command(help="Configure autoformatter settings") def clang(disable: bool = typer.Option(False, "--disable","-d", help="Disable clang-format"), - enablrune: bool = typer.Option(False, "--enable", "-e", help="Enable clang-format"), + enable: bool = typer.Option(False, "--enable", "-e", help="Enable clang-format"), run: bool = typer.Option(False, "--run", "-r", help="Run clang-format")): if disable: @@ -239,7 +243,74 @@ def usbip(connect: bool = typer.Option(False, "--connect", help="Connect to a US elif disconnect: disconnect_usbip() - + +# ============================================================================== +# ---- Launchpad Section +# ============================================================================== + + +# ============================================================================== +# init +# ============================================================================== +@lp_app.command(help="Initialize launchpad, run before any commands") +def install(): + """Install PlatformIO package.""" + try: + # Install the platformio package + subprocess.check_call(['pip', 'install', 'platformio']) + + except subprocess.CalledProcessError as e: + print(f"Failed to install PlatformIO: {e}", file=sys.stderr) + sys.exit(1) + +# ============================================================================== +# uninstall +# ============================================================================== +@lp_app.command(help="Remove launchpad") +def uninstall(): + """Uninstall PlatformIO package.""" + try: + # Install the platformio package + subprocess.check_call(['pip', 'uninstall', '-y', 'platformio']) + + platformio_dir = os.path.expanduser('~/.platformio') + if os.path.isdir(platformio_dir): + shutil.rmtree(platformio_dir) + print("PlatformIO directory removed.") + else: + print("PlatformIO directory does not exist.") + + except subprocess.CalledProcessError as e: + print(f"Failed to uninstall PlatformIO: {e}", file=sys.stderr) + sys.exit(1) + +# ============================================================================== +# build +# ============================================================================== +@lp_app.command(help="Build your launchpad project") +def build(): + subprocess.run(['platformio', 'run']) + +# ============================================================================== +# flash +# ============================================================================== +@lp_app.command(help="Flash your launchpad project to a board") +def flash(): + subprocess.run(['platformio', 'run', '--target', 'upload']) + +# ============================================================================== +# serial +# ============================================================================== +@lp_app.command(help="View serial output from the device") +def serial(): + subprocess.run(['platformio', 'device', 'monitor']) + + +# ============================================================================== +# ---- End Launchpad Section +# ============================================================================== + + # ============================================================================== # Helper functions - not direct commands # ============================================================================== diff --git a/ner_environment/ner_setup.py b/ner_environment/ner_setup.py index 2a7045d..39d4d17 100644 --- a/ner_environment/ner_setup.py +++ b/ner_environment/ner_setup.py @@ -77,6 +77,14 @@ def install_precommit(venv_python): print(f"Failed to install pre-commit: {e}", file=sys.stderr) sys.exit(1) +def install_launchpad(venv_python): + print("Installing launchpad (platformio)...") + try: + run_command([venv_python, '-m', 'pip', 'install', 'platformio']) + except Exception as e: + print(f"Failed to install platformio: {e}", file=sys.stderr) + sys.exit(1) + def install_openocd(): os_type = platform.system() try: @@ -142,21 +150,26 @@ def main(): answer = input("Would you like to install all python packages in the venv? (yes/no)") if 'y' in answer: - # Use the venv's Python + # Use the venv's Python venv_python = os.path.join(venv_path, 'bin', 'python') # Step 4: run setup.py (installs requirements and entry points) run_setup(venv_python) # Step 5: Run pre-commit install - install_precommit(venv_python) + # disabled bc buggy as all hell + #install_precommit(venv_python) + answer = input("Would you like to install launchpad? (yes/no)") + if 'y' in answer: + # Step 5: Install launchpad + install_launchpad(venv_python) answer = input("Would you like to install openOCD? (do this manually if on a weird linux distro!) (yes/no)") if 'y' in answer: - # Step 5: Install probe-rs + # Step 6: Install openocd install_openocd() - # Step 6: Install usbip if on Linux + # Step 7: Install usbip if on Linux if os_type == "Linux" and is_wsl() == 0: answer = input("Would you like to install usbip? (yes/no)") if 'y' in answer: