diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..e15324f3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,7 @@ +IndentWidth: 4 +ColumnLimit: 120 +AlignEscapedNewlines: DontAlign +SortIncludes: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true \ No newline at end of file diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 00000000..9a84f5b1 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,35 @@ +# Copyright (c) 2022 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +# Author: Jannis Schönleber + +name: lint-format + +on: + workflow_dispatch: + push: + branches: + - '**' + +jobs: + lint-python: + runs-on: ubuntu-latest + steps: + - name: Check Python with black + uses: rickstaa/action-black@v1 + with: + black_args: ". --check" + + lint-cxx: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Run Clang-format + uses: DoozyX/clang-format-lint-action@v0.18.2 + with: + extensions: 'c,h,cpp' + clangFormatVersion: 17 \ No newline at end of file diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml index ccfd37b4..0d1ed533 100644 --- a/.github/workflows/license.yml +++ b/.github/workflows/license.yml @@ -22,4 +22,7 @@ jobs: SPDX-License-Identifier: (SHL-0.51|Apache-2.0) exclude_paths: | deps - include/version.h \ No newline at end of file + include/version.h + ihp13 + klayout/def2gds.sh + klayout/def2stream.py \ No newline at end of file diff --git a/Bender.yml b/Bender.yml index d312c3fe..c162ab9b 100644 --- a/Bender.yml +++ b/Bender.yml @@ -1,4 +1,4 @@ -# Copyright 2024 ETH Zurich and University of Bologna +# Copyright (c) 2024 ETH Zurich and University of Bologna # Solderpad Hardware License, Version 0.51, see LICENSE for details. # SPDX-License-Identifier: SHL-0.51 @@ -18,7 +18,7 @@ dependencies: timer_unit: { git: "https://github.com/pulp-platform/timer_unit.git", version: 1.0.3 } obi: { git: "https://github.com/pulp-platform/obi.git", version: 0.1.3 } apb_uart: { git: "https://github.com/pulp-platform/apb_uart.git", version: 0.2.1 } - cve2: { path: "rtl/cve2" } # a vendor package (no Bender.yml), see below + cve2: { path: "rtl/cve2" } # a vendor package (no Bender.yml), see below sources: @@ -53,7 +53,7 @@ sources: files: # Level 0 - rtl/croc_chip.sv - + # netlist for simulation - target: netlist_yosys files: diff --git a/Makefile b/Makefile index 1eac3c68..800c8af6 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ checkout: $(IHP_RCX_FILE) $(BENDER) checkout git submodule update --init --recursive -$(IHP_RCX_FILE): +$(IHP_RCX_FILE): curl -L -o $@ $(IHP_RCX_URL) ## Reset dependencies (without updating Bender.lock) @@ -151,13 +151,26 @@ help: Makefile .PHONY: help +########### +# Format # +########### +CLANG_FORMAT_EXECUTABLE ?= clang-format + +## Automatically format the code using clang-format and black +format: + @echo -e "\033[1m-> Formatting Python Code...\033[0m" + @black */*.py + @echo -e "\033[1m-> Formatting C Code...\033[0m" + @python scripts/run_clang_format.py -ir sw/ --clang-format-executable=$(CLANG_FORMAT_EXECUTABLE) + +.PHONY: format ########### # Cleanup # ########### ## Delete generated files and directories -clean: +clean: rm -f $(SV_FLIST) rm -f klayout/croc_chip.gds rm -rf verilator/obj_dir/ diff --git a/klayout/def2stream.py b/klayout/def2stream.py index 8d4cef79..b4ea2dce 100644 --- a/klayout/def2stream.py +++ b/klayout/def2stream.py @@ -12,7 +12,7 @@ tech.load(tech_file) layoutOptions = tech.load_layout_options if len(layer_map) > 0: - layoutOptions.lefdef_config.map_file = layer_map + layoutOptions.lefdef_config.map_file = layer_map # Load def file main_layout = pya.Layout() @@ -21,7 +21,7 @@ print("[INFO] Reporting cells after loading DEF ...") for i in main_layout.each_cell(): - print("[INFO] '{0}'".format(i.name)) + print("[INFO] '{0}'".format(i.name)) # Clear cells top_cell_index = main_layout.cell(design_name).cell_index() @@ -30,17 +30,17 @@ # - KLayout is prepending VIA_ when reading DEF that instantiates LEF's via print("[INFO] Clearing cells...") for i in main_layout.each_cell(): - if i.cell_index() != top_cell_index: - if not i.name.startswith("VIA_"): - i.clear() + if i.cell_index() != top_cell_index: + if not i.name.startswith("VIA_"): + i.clear() # Load in the gds to merge print("[INFO] Merging GDS/OAS files...") -with open(gds_flist, 'rb') as file: +with open(gds_flist, "rb") as file: in_files_list = file.read() for fil in in_files_list.split(): - print("\t{0}".format(fil)) - main_layout.read(fil) + print("\t{0}".format(fil)) + main_layout.read(fil) # Copy the top level only to a new layout print("[INFO] Copying toplevel cell '{0}'".format(design_name)) @@ -52,32 +52,38 @@ print("[INFO] Checking for missing cell from GDS/OAS...") missing_cell = False regex = None -if 'GDS_ALLOW_EMPTY' in os.environ: +if "GDS_ALLOW_EMPTY" in os.environ: print("[INFO] Found GDS_ALLOW_EMPTY variable.") - regex = os.getenv('GDS_ALLOW_EMPTY') + regex = os.getenv("GDS_ALLOW_EMPTY") for i in top_only_layout.each_cell(): - if i.is_empty(): - missing_cell = True - if regex is not None and re.match(regex, i.name): - print("[WARNING] LEF Cell '{0}' ignored. Matches GDS_ALLOW_EMPTY.".format(i.name)) - else: - print("[ERROR] LEF Cell '{0}' has no matching GDS/OAS cell." - " Cell will be empty.".format(i.name)) - errors += 1 + if i.is_empty(): + missing_cell = True + if regex is not None and re.match(regex, i.name): + print( + "[WARNING] LEF Cell '{0}' ignored. Matches GDS_ALLOW_EMPTY.".format( + i.name + ) + ) + else: + print( + "[ERROR] LEF Cell '{0}' has no matching GDS/OAS cell." + " Cell will be empty.".format(i.name) + ) + errors += 1 if not missing_cell: - print("[INFO] All LEF cells have matching GDS/OAS cells") + print("[INFO] All LEF cells have matching GDS/OAS cells") print("[INFO] Checking for orphan cell in the final layout...") orphan_cell = False for i in top_only_layout.each_cell(): - if i.name != design_name and i.parent_cells() == 0: - orphan_cell = True - print("[ERROR] Found orphan cell '{0}'".format(i.name)) - errors += 1 + if i.name != design_name and i.parent_cells() == 0: + orphan_cell = True + print("[ERROR] Found orphan cell '{0}'".format(i.name)) + errors += 1 if not orphan_cell: - print("[INFO] No orphan cells") + print("[INFO] No orphan cells") # Write out the GDS diff --git a/project.toml b/project.toml new file mode 100644 index 00000000..2d108827 --- /dev/null +++ b/project.toml @@ -0,0 +1,11 @@ +# Copyright 2025 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Philip Wiese + +[tool.black] +line-length = 120 +target-version = ['py38'] +include = '\\.pyi?$' +exclude = '' \ No newline at end of file diff --git a/rtl/soc_ctrl/soc_ctrl.h b/rtl/soc_ctrl/soc_ctrl.h index 25734899..571046d5 100644 --- a/rtl/soc_ctrl/soc_ctrl.h +++ b/rtl/soc_ctrl/soc_ctrl.h @@ -4,7 +4,7 @@ // Copyright 2024 ETH Zurich and University of Bologna // Licensing information found in source file: -// +// // SPDX-License-Identifier: SHL-0.51 #ifndef _SOC_CTRL_REG_DEFS_ @@ -31,10 +31,10 @@ extern "C" { #define SOC_CTRL_BOOTMODE_BOOTMODE_MASK 0x3 #define SOC_CTRL_BOOTMODE_BOOTMODE_OFFSET 0 #define SOC_CTRL_BOOTMODE_BOOTMODE_FIELD \ - ((bitfield_field32_t) { .mask = SOC_CTRL_BOOTMODE_BOOTMODE_MASK, .index = SOC_CTRL_BOOTMODE_BOOTMODE_OFFSET }) + ((bitfield_field32_t){.mask = SOC_CTRL_BOOTMODE_BOOTMODE_MASK, .index = SOC_CTRL_BOOTMODE_BOOTMODE_OFFSET}) #ifdef __cplusplus -} // extern "C" +} // extern "C" #endif -#endif // _SOC_CTRL_REG_DEFS_ -// End generated register defines for safety_soc_ctrl \ No newline at end of file +#endif // _SOC_CTRL_REG_DEFS_ + // End generated register defines for safety_soc_ctrl \ No newline at end of file diff --git a/scripts/run_clang_format.py b/scripts/run_clang_format.py new file mode 100644 index 00000000..4dc1e218 --- /dev/null +++ b/scripts/run_clang_format.py @@ -0,0 +1,440 @@ +#!/usr/bin/env python + +# MIT License + +# Copyright (c) 2017 Guillaume Papin + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Taken from: https://github.com/Sarcasm/run-clang-format +# SPDX-License-Identifier: MIT +"""A wrapper script around clang-format, suitable for linting multiple files +and to use for continuous integration. + +This is an alternative API for the clang-format command line. +It runs over multiple files and directories in parallel. +A diff output is produced and a sensible exit code is returned. + +""" + +from __future__ import print_function, unicode_literals + +import argparse +import codecs +import difflib +import errno +import fnmatch +import io +import multiprocessing +import os +import signal +import subprocess +import sys +import traceback +from functools import partial + +try: + from subprocess import DEVNULL # py3k +except ImportError: + DEVNULL = open(os.devnull, "wb") + +DEFAULT_EXTENSIONS = "c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx" +DEFAULT_CLANG_FORMAT_IGNORE = ".clang-format-ignore" + + +class ExitStatus: + SUCCESS = 0 + DIFF = 1 + TROUBLE = 2 + + +def excludes_from_file(ignore_file): + excludes = [] + try: + with io.open(ignore_file, "r", encoding="utf-8") as f: + for line in f: + if line.startswith("#"): + # ignore comments + continue + pattern = line.rstrip() + if not pattern: + # allow empty lines + continue + excludes.append(pattern) + except EnvironmentError as e: + if e.errno != errno.ENOENT: + raise + return excludes + + +def list_files(files, recursive=False, extensions=None, exclude=None): + if extensions is None: + extensions = [] + if exclude is None: + exclude = [] + + out = [] + for file in files: + if recursive and os.path.isdir(file): + for dirpath, dnames, fnames in os.walk(file): + fpaths = [os.path.join(dirpath, fname) for fname in fnames] + for pattern in exclude: + # os.walk() supports trimming down the dnames list + # by modifying it in-place, + # to avoid unnecessary directory listings. + dnames[:] = [ + x + for x in dnames + if not fnmatch.fnmatch(os.path.join(dirpath, x), pattern) + ] + fpaths = [x for x in fpaths if not fnmatch.fnmatch(x, pattern)] + for f in fpaths: + ext = os.path.splitext(f)[1][1:] + if ext in extensions: + out.append(f) + else: + out.append(file) + return out + + +def make_diff(file, original, reformatted): + return list( + difflib.unified_diff( + original, + reformatted, + fromfile="{}\t(original)".format(file), + tofile="{}\t(reformatted)".format(file), + n=3, + ) + ) + + +class DiffError(Exception): + def __init__(self, message, errs=None): + super(DiffError, self).__init__(message) + self.errs = errs or [] + + +class UnexpectedError(Exception): + def __init__(self, message, exc=None): + super(UnexpectedError, self).__init__(message) + self.formatted_traceback = traceback.format_exc() + self.exc = exc + + +def run_clang_format_diff_wrapper(args, file): + try: + ret = run_clang_format_diff(args, file) + return ret + except DiffError: + raise + except Exception as e: + raise UnexpectedError("{}: {}: {}".format(file, e.__class__.__name__, e), e) + + +def run_clang_format_diff(args, file): + try: + with io.open(file, "r", encoding="utf-8") as f: + original = f.readlines() + except IOError as exc: + raise DiffError(str(exc)) + + if args.in_place: + invocation = [args.clang_format_executable, "-i", file] + else: + invocation = [args.clang_format_executable, file] + + if args.style: + invocation.extend(["-style", args.style]) + + if args.dry_run: + print(" ".join(invocation)) + return [], [] + + # Use of utf-8 to decode the process output. + # + # Hopefully, this is the correct thing to do. + # + # It's done due to the following assumptions (which may be incorrect): + # - clang-format will returns the bytes read from the files as-is, + # without conversion, and it is already assumed that the files use utf-8. + # - if the diagnostics were internationalized, they would use utf-8: + # > Adding Translations to Clang + # > + # > Not possible yet! + # > Diagnostic strings should be written in UTF-8, + # > the client can translate to the relevant code page if needed. + # > Each translation completely replaces the format string + # > for the diagnostic. + # > -- http://clang.llvm.org/docs/InternalsManual.html#internals-diag-translation + # + # It's not pretty, due to Python 2 & 3 compatibility. + encoding_py3 = {} + if sys.version_info[0] >= 3: + encoding_py3["encoding"] = "utf-8" + + try: + proc = subprocess.Popen( + invocation, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + **encoding_py3 + ) + except OSError as exc: + raise DiffError( + "Command '{}' failed to start: {}".format( + subprocess.list2cmdline(invocation), exc + ) + ) + proc_stdout = proc.stdout + proc_stderr = proc.stderr + if sys.version_info[0] < 3: + # make the pipes compatible with Python 3, + # reading lines should output unicode + encoding = "utf-8" + proc_stdout = codecs.getreader(encoding)(proc_stdout) + proc_stderr = codecs.getreader(encoding)(proc_stderr) + # hopefully the stderr pipe won't get full and block the process + outs = list(proc_stdout.readlines()) + errs = list(proc_stderr.readlines()) + proc.wait() + if proc.returncode: + raise DiffError( + "Command '{}' returned non-zero exit status {}".format( + subprocess.list2cmdline(invocation), proc.returncode + ), + errs, + ) + if args.in_place: + return [], errs + return make_diff(file, original, outs), errs + + +def bold_red(s): + return "\x1b[1m\x1b[31m" + s + "\x1b[0m" + + +def colorize(diff_lines): + def bold(s): + return "\x1b[1m" + s + "\x1b[0m" + + def cyan(s): + return "\x1b[36m" + s + "\x1b[0m" + + def green(s): + return "\x1b[32m" + s + "\x1b[0m" + + def red(s): + return "\x1b[31m" + s + "\x1b[0m" + + for line in diff_lines: + if line[:4] in ["--- ", "+++ "]: + yield bold(line) + elif line.startswith("@@ "): + yield cyan(line) + elif line.startswith("+"): + yield green(line) + elif line.startswith("-"): + yield red(line) + else: + yield line + + +def print_diff(diff_lines, use_color): + if use_color: + diff_lines = colorize(diff_lines) + if sys.version_info[0] < 3: + sys.stdout.writelines((l.encode("utf-8") for l in diff_lines)) + else: + sys.stdout.writelines(diff_lines) + + +def print_trouble(prog, message, use_colors): + error_text = "error:" + if use_colors: + error_text = bold_red(error_text) + print("{}: {} {}".format(prog, error_text, message), file=sys.stderr) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--clang-format-executable", + metavar="EXECUTABLE", + help="path to the clang-format executable", + default="clang-format", + ) + parser.add_argument( + "--extensions", + help="comma separated list of file extensions (default: {})".format( + DEFAULT_EXTENSIONS + ), + default=DEFAULT_EXTENSIONS, + ) + parser.add_argument( + "-r", + "--recursive", + action="store_true", + help="run recursively over directories", + ) + parser.add_argument( + "-d", "--dry-run", action="store_true", help="just print the list of files" + ) + parser.add_argument( + "-i", + "--in-place", + action="store_true", + help="format file instead of printing differences", + ) + parser.add_argument("files", metavar="file", nargs="+") + parser.add_argument( + "-q", + "--quiet", + action="store_true", + help="disable output, useful for the exit code", + ) + parser.add_argument( + "-j", + metavar="N", + type=int, + default=0, + help="run N clang-format jobs in parallel" " (default number of cpus + 1)", + ) + parser.add_argument( + "--color", + default="auto", + choices=["auto", "always", "never"], + help="show colored diff (default: auto)", + ) + parser.add_argument( + "-e", + "--exclude", + metavar="PATTERN", + action="append", + default=[], + help="exclude paths matching the given glob-like pattern(s)" + " from recursive search", + ) + parser.add_argument( + "--style", + help="formatting style to apply (LLVM, Google, Chromium, Mozilla, WebKit)", + ) + + args = parser.parse_args() + + # use default signal handling, like diff return SIGINT value on ^C + # https://bugs.python.org/issue14229#msg156446 + signal.signal(signal.SIGINT, signal.SIG_DFL) + try: + signal.SIGPIPE + except AttributeError: + # compatibility, SIGPIPE does not exist on Windows + pass + else: + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + + colored_stdout = False + colored_stderr = False + if args.color == "always": + colored_stdout = True + colored_stderr = True + elif args.color == "auto": + colored_stdout = sys.stdout.isatty() + colored_stderr = sys.stderr.isatty() + + version_invocation = [args.clang_format_executable, str("--version")] + try: + subprocess.check_call(version_invocation, stdout=DEVNULL) + except subprocess.CalledProcessError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + return ExitStatus.TROUBLE + except OSError as e: + print_trouble( + parser.prog, + "Command '{}' failed to start: {}".format( + subprocess.list2cmdline(version_invocation), e + ), + use_colors=colored_stderr, + ) + return ExitStatus.TROUBLE + + retcode = ExitStatus.SUCCESS + + excludes = excludes_from_file(DEFAULT_CLANG_FORMAT_IGNORE) + excludes.extend(args.exclude) + + files = list_files( + args.files, + recursive=args.recursive, + exclude=excludes, + extensions=args.extensions.split(","), + ) + + if not files: + return + + njobs = args.j + if njobs == 0: + njobs = multiprocessing.cpu_count() + 1 + njobs = min(len(files), njobs) + + if njobs == 1: + # execute directly instead of in a pool, + # less overhead, simpler stacktraces + it = (run_clang_format_diff_wrapper(args, file) for file in files) + pool = None + else: + pool = multiprocessing.Pool(njobs) + it = pool.imap_unordered(partial(run_clang_format_diff_wrapper, args), files) + pool.close() + while True: + try: + outs, errs = next(it) + except StopIteration: + break + except DiffError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + retcode = ExitStatus.TROUBLE + sys.stderr.writelines(e.errs) + except UnexpectedError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + sys.stderr.write(e.formatted_traceback) + retcode = ExitStatus.TROUBLE + # stop at the first unexpected error, + # something could be very wrong, + # don't process all files unnecessarily + if pool: + pool.terminate() + break + else: + sys.stderr.writelines(errs) + if outs == []: + continue + if not args.quiet: + print_diff(outs, use_color=colored_stdout) + if retcode == ExitStatus.SUCCESS: + retcode = ExitStatus.DIFF + if pool: + pool.join() + return retcode + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/sw/config.h b/sw/config.h index 94ee1438..dedcfb6e 100644 --- a/sw/config.h +++ b/sw/config.h @@ -9,16 +9,16 @@ // Address map #define SOCCTRL_BASE_ADDR 0x03000000 -#define UART_BASE_ADDR 0x03002000 -#define GPIO_BASE_ADDR 0x03005000 -#define TIMER_BASE_ADDR 0x0300A000 +#define UART_BASE_ADDR 0x03002000 +#define GPIO_BASE_ADDR 0x03005000 +#define TIMER_BASE_ADDR 0x0300A000 // Frequencies #define TB_FREQUENCY 20000000 -#define TB_BAUDRATE 115200 +#define TB_BAUDRATE 115200 // Peripheral configs // UART #define UART_BYTE_ALIGN 4 -#define UART_FREQ TB_FREQUENCY -#define UART_BAUD TB_BAUDRATE \ No newline at end of file +#define UART_FREQ TB_FREQUENCY +#define UART_BAUD TB_BAUDRATE \ No newline at end of file diff --git a/sw/helloworld.c b/sw/helloworld.c index 8c3da8ae..7fdb4c9f 100644 --- a/sw/helloworld.c +++ b/sw/helloworld.c @@ -41,21 +41,21 @@ int main() { // toggling some GPIOs gpio_set_direction(0xFFFF, 0x000F); // lowest four as outputs - gpio_write(0x0A); // ready output pattern - gpio_enable(0xFF); // enable lowest eight + gpio_write(0x0A); // ready output pattern + gpio_enable(0xFF); // enable lowest eight // wait a few cycles to give GPIO signal time to propagate - asm volatile ("nop; nop; nop; nop; nop;"); + asm volatile("nop; nop; nop; nop; nop;"); printf("GPIO (expect 0xA0): 0x%x\n", gpio_read()); gpio_toggle(0x0F); // toggle lower 8 GPIOs - asm volatile ("nop; nop; nop; nop; nop;"); + asm volatile("nop; nop; nop; nop; nop;"); printf("GPIO (expect 0x50): 0x%x\n", gpio_read()); uart_write_flush(); // doing some compute uint32_t start = get_mcycle(); - uint32_t res = isqrt(1234567890UL); - uint32_t end = get_mcycle(); + uint32_t res = isqrt(1234567890UL); + uint32_t end = get_mcycle(); printf("Result: 0x%x, Cycles: 0x%x\n", res, end - start); uart_write_flush(); diff --git a/sw/lib/inc/gpio.h b/sw/lib/inc/gpio.h index 8e0a300e..b15c4b1b 100644 --- a/sw/lib/inc/gpio.h +++ b/sw/lib/inc/gpio.h @@ -9,19 +9,18 @@ #include #include "config.h" - -#define GPIO_DIR_REG_OFFSET 0x000 -#define GPIO_EN_REG_OFFSET 0x080 -#define GPIO_IN_REG_OFFSET 0x100 -#define GPIO_OUT_REG_OFFSET 0x180 -#define GPIO_TOGGLE_REG_OFFSET 0x200 -#define GPIO_INTRPT_EN_REG_OFFSET 0x280 +#define GPIO_DIR_REG_OFFSET 0x000 +#define GPIO_EN_REG_OFFSET 0x080 +#define GPIO_IN_REG_OFFSET 0x100 +#define GPIO_OUT_REG_OFFSET 0x180 +#define GPIO_TOGGLE_REG_OFFSET 0x200 +#define GPIO_INTRPT_EN_REG_OFFSET 0x280 #define GPIO_INTRPT_STATUS_REG_OFFSET 0x300 -#define GPIO_INTRPT_EDGE_REG_OFFSET 0x380 +#define GPIO_INTRPT_EDGE_REG_OFFSET 0x380 // functions applying to all 32 GPIOs with mask // a 1 in the mask applies action to this GPIO pin -// LSB is considered GPIO number 0 +// LSB is considered GPIO number 0 void gpio_set_direction(uint32_t mask, uint32_t direction); // 1: output void gpio_enable(uint32_t mask); void gpio_disable(uint32_t mask); diff --git a/sw/lib/inc/soc_ctrl.h b/sw/lib/inc/soc_ctrl.h index 089e58af..3f2f33b4 100644 --- a/sw/lib/inc/soc_ctrl.h +++ b/sw/lib/inc/soc_ctrl.h @@ -6,6 +6,6 @@ #pragma once -#define SOC_CTRL_BOOTADDR_REG_OFFSET 0x00 -#define SOC_CTRL_FETCHEN_REG_OFFSET 0x04 +#define SOC_CTRL_BOOTADDR_REG_OFFSET 0x00 +#define SOC_CTRL_FETCHEN_REG_OFFSET 0x04 #define SOC_CTRL_CORESTATUS_REG_OFFSET 0x08 diff --git a/sw/lib/inc/timer.h b/sw/lib/inc/timer.h index 69828bce..116369f1 100644 --- a/sw/lib/inc/timer.h +++ b/sw/lib/inc/timer.h @@ -10,33 +10,33 @@ #include "config.h" // Register offsets -#define CFG_LOW_REG_OFFSET 0x00 -#define CFG_HIGH_REG_OFFSET 0x04 -#define TIMER_VALUE_LOW_REG_OFFSET 0x08 -#define TIMER_VALUE_HIGH_REG_OFFSET 0x0C -#define TIMER_CMP_LOW_REG_OFFSET 0x10 -#define TIMER_CMP_HIGH_REG_OFFSET 0x14 -#define TIMER_START_LOW_REG_OFFSET 0x18 -#define TIMER_START_HIGH_REG_OFFSET 0x1C -#define TIMER_RESET_LOW_REG_OFFSET 0x20 -#define TIMER_RESET_HIGH_REG_OFFSET 0x24 +#define CFG_LOW_REG_OFFSET 0x00 +#define CFG_HIGH_REG_OFFSET 0x04 +#define TIMER_VALUE_LOW_REG_OFFSET 0x08 +#define TIMER_VALUE_HIGH_REG_OFFSET 0x0C +#define TIMER_CMP_LOW_REG_OFFSET 0x10 +#define TIMER_CMP_HIGH_REG_OFFSET 0x14 +#define TIMER_START_LOW_REG_OFFSET 0x18 +#define TIMER_START_HIGH_REG_OFFSET 0x1C +#define TIMER_RESET_LOW_REG_OFFSET 0x20 +#define TIMER_RESET_HIGH_REG_OFFSET 0x24 // Register fields -#define CFG_LOW_REG_ENABLE_BIT 0 -#define CFG_LOW_REG_RESET_BIT 1 -#define CFG_LOW_REG_IRQ_ENABLE_BIT 2 -#define CFG_LOW_REG_CMP_CLR_BIT 4 -#define CFG_LOW_REG_ONE_SHOT_BIT 5 +#define CFG_LOW_REG_ENABLE_BIT 0 +#define CFG_LOW_REG_RESET_BIT 1 +#define CFG_LOW_REG_IRQ_ENABLE_BIT 2 +#define CFG_LOW_REG_CMP_CLR_BIT 4 +#define CFG_LOW_REG_ONE_SHOT_BIT 5 #define CFG_LOW_REG_PRESC_ENABLE_BIT 6 #define CFG_LOW_REG_CLOCK_SOURCE_BIT 7 -#define CFG_LOW_REG_PRESC_VALUE_BIT 8 // 15:8 -#define CFG_LOW_REG_64BIT_MODE_BIT 31 +#define CFG_LOW_REG_PRESC_VALUE_BIT 8 // 15:8 +#define CFG_LOW_REG_64BIT_MODE_BIT 31 -#define CFG_HIGH_REG_ENABLE_BIT 0 -#define CFG_HIGH_REG_RESET_BIT 1 -#define CFG_HIGH_REG_IRQ_ENABLE_BIT 2 -#define CFG_HIGH_REG_CMP_CLR_BIT 4 -#define CFG_HIGH_REG_ONE_SHOT_BIT 5 +#define CFG_HIGH_REG_ENABLE_BIT 0 +#define CFG_HIGH_REG_RESET_BIT 1 +#define CFG_HIGH_REG_IRQ_ENABLE_BIT 2 +#define CFG_HIGH_REG_CMP_CLR_BIT 4 +#define CFG_HIGH_REG_ONE_SHOT_BIT 5 #define CFG_HIGH_REG_PRESC_ENABLE_BIT 6 #define CFG_HIGH_REG_CLOCK_SOURCE_BIT 7 diff --git a/sw/lib/inc/uart.h b/sw/lib/inc/uart.h index d62ff11b..7ee6dba5 100644 --- a/sw/lib/inc/uart.h +++ b/sw/lib/inc/uart.h @@ -13,20 +13,19 @@ // Registers below can be aligned to a byte, word, dword etc // UART_BYTE_ALIGN provides the number of bytes it is aligned to - // Register offsets -#define UART_RBR_REG_OFFSET (0*UART_BYTE_ALIGN) // Receive Buffer Register -#define UART_THR_REG_OFFSET (0*UART_BYTE_ALIGN) // Transmitter Holding Register -#define UART_INTR_ENABLE_REG_OFFSET (1*UART_BYTE_ALIGN) -#define UART_INTR_IDENT_REG_OFFSET (2*UART_BYTE_ALIGN) -#define UART_FIFO_CONTROL_REG_OFFSET (2*UART_BYTE_ALIGN) -#define UART_LINE_CONTROL_REG_OFFSET (3*UART_BYTE_ALIGN) -#define UART_MODEM_CONTROL_REG_OFFSET (4*UART_BYTE_ALIGN) -#define UART_LINE_STATUS_REG_OFFSET (5*UART_BYTE_ALIGN) -#define UART_MODEM_STATUS_REG_OFFSET (6*UART_BYTE_ALIGN) -#define UART_SCRATCH_REG_OFFSET (7*UART_BYTE_ALIGN) -#define UART_DLAB_LSB_REG_OFFSET (0*UART_BYTE_ALIGN) -#define UART_DLAB_MSB_REG_OFFSET (1*UART_BYTE_ALIGN) +#define UART_RBR_REG_OFFSET (0 * UART_BYTE_ALIGN) // Receive Buffer Register +#define UART_THR_REG_OFFSET (0 * UART_BYTE_ALIGN) // Transmitter Holding Register +#define UART_INTR_ENABLE_REG_OFFSET (1 * UART_BYTE_ALIGN) +#define UART_INTR_IDENT_REG_OFFSET (2 * UART_BYTE_ALIGN) +#define UART_FIFO_CONTROL_REG_OFFSET (2 * UART_BYTE_ALIGN) +#define UART_LINE_CONTROL_REG_OFFSET (3 * UART_BYTE_ALIGN) +#define UART_MODEM_CONTROL_REG_OFFSET (4 * UART_BYTE_ALIGN) +#define UART_LINE_STATUS_REG_OFFSET (5 * UART_BYTE_ALIGN) +#define UART_MODEM_STATUS_REG_OFFSET (6 * UART_BYTE_ALIGN) +#define UART_SCRATCH_REG_OFFSET (7 * UART_BYTE_ALIGN) +#define UART_DLAB_LSB_REG_OFFSET (0 * UART_BYTE_ALIGN) +#define UART_DLAB_MSB_REG_OFFSET (1 * UART_BYTE_ALIGN) // Register fields #define UART_LINE_STATUS_DATA_READY_BIT 0 diff --git a/sw/lib/src/print.c b/sw/lib/src/print.c index 4ec0883d..784ad70e 100644 --- a/sw/lib/src/print.c +++ b/sw/lib/src/print.c @@ -8,8 +8,7 @@ #include "util.h" #include "config.h" -const char hex_symbols[16] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; +const char hex_symbols[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; /// @brief format number as hexadecimal digits /// @return number of characters written to buffer @@ -30,7 +29,7 @@ uint8_t format_hex32(char *buffer, uint32_t num) { void printf(const char *fmt, ...) { va_list args; va_start(args, fmt); - char buffer[12]; // holds string while assembling + char buffer[12]; // holds string while assembling uint8_t idx; while (*fmt) { diff --git a/sw/lib/src/timer.c b/sw/lib/src/timer.c index 98883b54..18482e99 100644 --- a/sw/lib/src/timer.c +++ b/sw/lib/src/timer.c @@ -9,20 +9,19 @@ #include "config.h" void sleep_ms(uint32_t ms) { - uint32_t config = \ - (1 << CFG_LOW_REG_CLOCK_SOURCE_BIT) | // from 32.768 kHz ref clock - (1 << CFG_LOW_REG_PRESC_ENABLE_BIT) | // enable prescaler - (31 << CFG_LOW_REG_PRESC_VALUE_BIT) | // prescaler value - (1 << CFG_LOW_REG_CMP_CLR_BIT) | // auto-clear - (1 << CFG_LOW_REG_IRQ_ENABLE_BIT) | // enable IRQ - (1 << CFG_LOW_REG_ENABLE_BIT); // enable timer + uint32_t config = (1 << CFG_LOW_REG_CLOCK_SOURCE_BIT) | // from 32.768 kHz ref clock + (1 << CFG_LOW_REG_PRESC_ENABLE_BIT) | // enable prescaler + (31 << CFG_LOW_REG_PRESC_VALUE_BIT) | // prescaler value + (1 << CFG_LOW_REG_CMP_CLR_BIT) | // auto-clear + (1 << CFG_LOW_REG_IRQ_ENABLE_BIT) | // enable IRQ + (1 << CFG_LOW_REG_ENABLE_BIT); // enable timer // disable timer *reg32(TIMER_BASE_ADDR, CFG_LOW_REG_OFFSET) = 0; *reg32(TIMER_BASE_ADDR, TIMER_CMP_LOW_REG_OFFSET) = ms; - set_mtie(1); // Machine Timer Interrupt Enable + set_mtie(1); // Machine Timer Interrupt Enable set_mie(1); // Global Interrupt Enable // start timer diff --git a/sw/lib/src/uart.c b/sw/lib/src/uart.c index 25d57a0b..672d069d 100644 --- a/sw/lib/src/uart.c +++ b/sw/lib/src/uart.c @@ -9,7 +9,7 @@ #include "util.h" #include "config.h" -#define UART_DIVISOR(freq, baud) ((freq) / ((baud) << 4)) // Divisor calculation +#define UART_DIVISOR(freq, baud) ((freq) / ((baud) << 4)) // Divisor calculation void uart_init() { const uint16_t divisor = UART_DIVISOR(UART_FREQ, UART_BAUD); // Calculate from provided config