You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Tobias Kohlbau 096fda843a
usb: unify handling of length parameters (#177)
* usb: unify handling of length parameters

The length parameters in USB packets are strict and the existing
implementation does already hardcode the length within the serialize
functions. Therefore the user should not provide these lengths during
creation time. In order to make this more verbose use defaults values
within the structs and reference these defaults values within the
serialization functions. It's not possible to remove these fields
completly as this fields are used within deserialization from the
hardware itself.

Signed-off-by: Tobias Kohlbau <tobias@kohlbau.de>

* Remove length fields as they are obsolete. The lengths is only required
during the serialization and therefore is already hardcoded. The only
other convinience is the calculation of the descriptor size, but this is
already wrong. extern structs are padded and therefore do not have the
right sizes.

Signed-off-by: Tobias Kohlbau <tobias@kohlbau.de>

* cleanup some accidentially added changes

Signed-off-by: Tobias Kohlbau <tobias@kohlbau.de>

---------

Signed-off-by: Tobias Kohlbau <tobias@kohlbau.de>
7 months ago
..
src usb: unify handling of length parameters (#177) 7 months ago
test Moves microzig to core/ 9 months ago
LICENSE Moves microzig to core/ 9 months ago
README.adoc Moves microzig to core/ 9 months ago
build.zig Fixes build script enough to make next-gen example build. 8 months ago
microzig-package.json Further improves deployment information, makes package info really useful 9 months ago
thoughts.md Moves microzig to core/ 9 months ago

README.adoc

:imagesdir: design
:toc: macro

image::logo-text-auto.svg[]

image::https://img.shields.io/discord/824493524413710336.svg?logo=discord[link=https://discord.gg/ShUWykk38X]

[NOTE]
This is in development; breaks in the API are bound to happen.

toc::[]

== What version of Zig to use

0.11.0

== Contributing

Please see the https://github.com/orgs/ZigEmbeddedGroup/projects/1/views/1[project page], it's used as a place to brainstorm and organize work in ZEG. There will be issues marked as `good first issue` or drafts for larger ideas that need scoping/breaking ground on.

== Introduction

This repo contains the infrastructure for getting started in an embedded Zig project; it "gets you to main()". Specifically, it offers:

* a single easy-to-use builder function that:
** generates your linker script
** sets up packages and startup code
* generalized interfaces for common devices, such as UART.
* device drivers for interacting with external hardware
* an uncomplicated method to define xref:interrupts[interrupts]

== Getting Started 

Visit https://github.com/ZigEmbeddedGroup/microzig-examples to find examples for your specific board. 

== Design

For MicroZig internals please see the xref:docs/design.adoc[Design Document].

== Does MicroZig support X hardware?

MicroZig is designed to cover as wide a swath of hardware as possible. The https://github.com/ZigEmbeddedGroup[Zig Embedded Group] has some repositories that contain hardware-specific code. You will find them with the `hardware-support-package` label. If you can't find your specific device, it doesn't mean that you can't run Zig on it, it's likely you're just the first! In that case, see xref:#getting-microzig-on-new-hardware[Getting MicroZig on New Hardware].

Start with an empty Zig project by running `zig init-exe`, and add the hardware support package as a submodule. We'll use `microchip-atmega` in our example:

[source,zig]
----
const std = @import("std");
const atmega = @import("deps/microchip-atmega/build.zig");

// the hardware support package should have microzig as a dependency
const microzig = @import("deps/hardware_support_package/deps/microzig/build.zig");

pub fn build(b: *std.build.Builder) !void {
    const optimize = b.standardOptimizeOption(.{});
    var exe = microzig.addEmbeddedExecutable( b, .{
        .name = "my-executable",
        .source_file = .{
            .path = "src/main.zig",
        },
        .backing = .{
            .board = atmega.boards.arduino_nano,

            // instead of a board, you can use the raw chip as well
            // .chip = atmega.chips.atmega328p,
        },
        .optimize = optimize,
    });
    exe.installArtifact(b);
}
----

`zig build` and now you have an executable for an Arduino Nano. In your application you can import `microzig` in order to interact with the hardware:

[source,zig]
----
const microzig = @import("microzig");

// `microzig.config`: comptime access to configuration
// `microzig.chip`: access to register definitions, generated code
// `microzig.board`: access to board information
// `microzig.hal`: access to hand-written code for interacting with the hardware
// `microzig.cpu`: access to AVR5 specific functions

pub fn main() !void {
    // your program here
}
----

== Getting MicroZig on New Hardware

If you have a board/chip that isn't defined in microzig, you can set it up yourself! You need to have:

* SVD or ATDF file defining registers
* flash and ram address and sizes

First, use https://github.com/ZigEmbeddedGroup/regz[Regz] to generate the register definitions for your chip and save them to a file. Then define the chip:

[source,zig]
----
const nrf52832 = Chip{
    .name = "nRF52832",
    .source = .{
        .path = "path/to/generated/file.zig",
    },
    .cpu = cpus.cortex_m4,
    .memory_regions = &.{
        MemoryRegion{ .offset = 0x00000000, .length = 0x80000, .kind = .flash },
        MemoryRegion{ .offset = 0x20000000, .length = 0x10000, .kind = .ram },
    },
};

const backing = .{
    .chip = nrf52832,
};
----

It's important that the chip name actually matches one of the entries under `devices` in the generated code.

=== Optional: JSON Register Schema

You can also invoke `regz` to generate a JSON representation of the hardware:

[source]
----
regz --json <path to svd/atdf>
----

This file could then be used by tooling. You can add it to a `Chip` like so:


[source,zig]
----
const nrf52832 = Chip{
    .name = "nRF52832",
    .json_register_schema = .{
        .path = "path/to.json",
    },
    // ...
};
----

== Interrupts

The currently supported architectures for interrupt vector generation are ARM and AVR. To define the Interrupt Service Routine (ISR) for a given interrupt, you create a function with the same name in an `interrupts` namespace, which is nested in a `microzig_options` namespace:

[source,zig]
----
pub const microzig_options = struct {
  pub const interrupts = struct {
      pub fn PCINT0() void {
        // interrupt handling code
      }
  };
}

pub fn main() !void {
    // my application
}
----

We're using compile-time checks along with the generated code to determine the list of interrupts. If a function is defined whose name is not in this list, you'll get a compiler error with the list of interrupts/valid names.