~repos /rp2350

#zig#raspberry-pi

git clone https://pyrossh.dev/repos/rp2350.git

code to drive rp2350


6a7717e8 pyrossh

7 months ago
initial commit
.DS_Store ADDED
Binary file
.gitignore CHANGED
@@ -1 +1,2 @@
1
- .zig-cache
1
+ .zig-cache
2
+ zig-out
aa.zig DELETED
@@ -1,17 +0,0 @@
1
- const std = @import("std");
2
- const stdout = std.io.getStdOut().writer();
3
-
4
- pub fn main() !void {
5
- var i: usize = 1;
6
- while (i <= 16) : (i += 1) {
7
- if (i % 15 == 0) {
8
- try stdout.writeAll("ZiggZagg\n");
9
- } else if (i % 3 == 0) {
10
- try stdout.writeAll("Zigg\n");
11
- } else if (i % 5 == 0) {
12
- try stdout.writeAll("Zagg\n");
13
- } else {
14
- try stdout.print("{d}\n", .{i});
15
- }
16
- }
17
- }
blinky.zig DELETED
@@ -1,22 +0,0 @@
1
- const std = @import("std");
2
- const microzig = @import("microzig");
3
- const rp2xxx = microzig.hal;
4
- const time = rp2xxx.time;
5
-
6
- const pin_config = rp2xxx.pins.GlobalConfiguration{
7
- .GPIO25 = .{
8
- .name = "led",
9
- .direction = .out,
10
- },
11
- };
12
-
13
- const pins = pin_config.pins();
14
-
15
- pub fn main() !void {
16
- pin_config.apply();
17
-
18
- while (true) {
19
- pins.led.toggle();
20
- time.sleep_ms(250);
21
- }
22
- }
build.zig CHANGED
@@ -6,13 +6,14 @@ const MicroBuild = microzig.MicroBuild(.{
6
6
  });
7
7
 
8
8
  pub fn build(b: *std.Build) void {
9
+ const optimize = b.standardOptimizeOption(.{});
9
10
  const mz_dep = b.dependency("microzig", .{});
10
11
  const mb = MicroBuild.init(b, mz_dep) orelse return;
11
12
 
12
13
  const firmware = mb.add_firmware(.{
13
- .name = "blinky",
14
+ .name = "rp2350",
14
- .target = mb.ports.rp2xxx.boards.raspberrypi.pico,
15
+ .target = mb.ports.rp2xxx.boards.raspberrypi.pico2_arm,
15
- .optimize = .ReleaseSmall,
16
+ .optimize = optimize,
16
17
  .root_source_file = b.path("src/main.zig"),
17
18
  });
18
19
 
@@ -21,123 +22,3 @@ pub fn build(b: *std.Build) void {
21
22
  mb.install_firmware(firmware, .{});
22
23
  mb.install_firmware(firmware, .{ .format = .elf });
23
24
  }
24
-
25
- // const std = @import("std");
26
- // const microzig = @import("microzig");
27
-
28
- // const MicroBuild = microzig.MicroBuild(.{
29
- // .rp2xxx = true,
30
- // });
31
-
32
- // pub fn build(b: *std.Build) void {
33
- // const optimize = b.standardOptimizeOption(.{});
34
- // const maybe_example = b.option([]const u8, "example", "only build matching examples");
35
-
36
- // const mz_dep = b.dependency("microzig", .{});
37
- // const mb = MicroBuild.init(b, mz_dep) orelse return;
38
-
39
- // const rp2040_only_examples: []const Example = &.{
40
- // // RaspberryPi Boards:
41
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_flash-program", .file = "src/rp2040_only/flash_program.zig" },
42
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_flash-id", .file = "src/rp2040_only/flash_id.zig" },
43
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_random", .file = "src/rp2040_only/random.zig" },
44
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_rtc", .file = "src/rp2040_only/rtc.zig" },
45
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_usb-hid", .file = "src/rp2040_only/usb_hid.zig" },
46
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_multicore", .file = "src/rp2040_only/blinky_core1.zig" },
47
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_hd44780", .file = "src/rp2040_only/hd44780.zig" },
48
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_pcf8574", .file = "src/rp2040_only/pcf8574.zig" },
49
- // .{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_i2c_slave", .file = "src/rp2040_only/i2c_slave.zig" },
50
-
51
- // // WaveShare Boards:
52
- // .{ .target = mb.ports.rp2xxx.boards.waveshare.rp2040_matrix, .name = "rp2040-matrix_tiles", .file = "src/rp2040_only/tiles.zig" },
53
- // // .{ .target = "board:waveshare/rp2040_eth", .name = "rp2040-eth" },
54
- // // .{ .target = "board:waveshare/rp2040_plus_4m", .name = "rp2040-plus-4m" },
55
- // // .{ .target = "board:waveshare/rp2040_plus_16m", .name = "rp2040-plus-16m" },
56
- // };
57
-
58
- // const rp2350_only_examples: []const Example = &.{
59
- // // TODO: No RP2350 feature specific examples to show off yet
60
- // };
61
-
62
- // const chip_agnostic_examples: []const ChipAgnosticExample = &.{
63
- // .{ .name = "adc", .file = "src/adc.zig" },
64
- // .{ .name = "i2c-bus-scan", .file = "src/i2c_bus_scan.zig" },
65
- // .{ .name = "pwm", .file = "src/pwm.zig" },
66
- // .{ .name = "uart-echo", .file = "src/uart_echo.zig" },
67
- // .{ .name = "uart-log", .file = "src/uart_log.zig" },
68
- // .{ .name = "spi-master", .file = "src/spi_master.zig" },
69
- // .{ .name = "spi-slave", .file = "src/spi_slave.zig" },
70
- // .{ .name = "squarewave", .file = "src/squarewave.zig" },
71
- // .{ .name = "ws2812", .file = "src/ws2812.zig" },
72
- // .{ .name = "blinky", .file = "src/blinky.zig" },
73
- // .{ .name = "gpio-clock-output", .file = "src/gpio_clock_output.zig" },
74
- // .{ .name = "changing-system-clocks", .file = "src/changing_system_clocks.zig" },
75
- // .{ .name = "custom-clock-config", .file = "src/custom_clock_config.zig" },
76
- // .{ .name = "watchdog-timer", .file = "src/watchdog_timer.zig" },
77
- // .{ .name = "interrupts", .file = "src/interrupts.zig" },
78
- // .{ .name = "stepper", .file = "src/stepper.zig" },
79
- // .{ .name = "usb-cdc", .file = "src/usb_cdc.zig" },
80
- // };
81
-
82
- // var available_examples = std.ArrayList(Example).init(b.allocator);
83
- // available_examples.appendSlice(rp2040_only_examples) catch @panic("out of memory");
84
- // available_examples.appendSlice(rp2350_only_examples) catch @panic("out of memory");
85
- // for (chip_agnostic_examples) |example| {
86
- // available_examples.append(.{
87
- // .target = mb.ports.rp2xxx.boards.raspberrypi.pico,
88
- // .name = b.fmt("pico_{s}", .{example.name}),
89
- // .file = example.file,
90
- // }) catch @panic("out of memory");
91
-
92
- // available_examples.append(.{
93
- // .target = mb.ports.rp2xxx.boards.raspberrypi.pico2_arm,
94
- // .name = b.fmt("pico2_arm_{s}", .{example.name}),
95
- // .file = example.file,
96
- // }) catch @panic("out of memory");
97
-
98
- // available_examples.append(.{
99
- // .target = mb.ports.rp2xxx.boards.raspberrypi.pico2_riscv,
100
- // .name = b.fmt("pico2_riscv_{s}", .{example.name}),
101
- // .file = example.file,
102
- // }) catch @panic("out of memory");
103
- // }
104
-
105
- // for (available_examples.items) |example| {
106
- // // If we specify example, only select the ones that match
107
- // if (maybe_example) |selected_example|
108
- // if (!std.mem.containsAtLeast(u8, example.name, 1, selected_example))
109
- // continue;
110
-
111
- // // `add_firmware` basically works like addExecutable, but takes a
112
- // // `microzig.Target` for target instead of a `std.zig.CrossTarget`.
113
- // //
114
- // // The target will convey all necessary information on the chip,
115
- // // cpu and potentially the board as well.
116
- // const firmware = mb.add_firmware(.{
117
- // .name = example.name,
118
- // .target = example.target,
119
- // .optimize = optimize,
120
- // .root_source_file = b.path(example.file),
121
- // });
122
-
123
- // // `install_firmware()` is the MicroZig pendant to `Build.installArtifact()`
124
- // // and allows installing the firmware as a typical firmware file.
125
- // //
126
- // // This will also install into `$prefix/firmware` instead of `$prefix/bin`.
127
- // mb.install_firmware(firmware, .{});
128
-
129
- // // For debugging, we also always install the firmware as an ELF file
130
- // mb.install_firmware(firmware, .{ .format = .elf });
131
- // }
132
- // }
133
-
134
- // const Example = struct {
135
- // target: *const microzig.Target,
136
- // name: []const u8,
137
- // file: []const u8,
138
- // };
139
-
140
- // const ChipAgnosticExample = struct {
141
- // name: []const u8,
142
- // file: []const u8,
143
- // };
build.zig.zon CHANGED
@@ -1,69 +1,17 @@
1
1
  .{
2
- // This is the default name used by packages depending on this one. For
3
- // example, when a user runs `zig fetch --save <url>`, this field is used
4
- // as the key in the `dependencies` table. Although the user can choose a
5
- // different name, most users will stick with this provided value.
6
- //
7
- // It is redundant to include "zig" in this name because it is already
8
- // within the Zig package namespace.
9
- .name = .rp2040,
2
+ .name = .rp2350,
10
-
11
- // This is a [Semantic Version](https://semver.org/).
12
- // In a future version of Zig it will be used for package deduplication.
13
3
  .version = "0.0.0",
14
-
15
- // Together with name, this represents a globally unique package
16
- // identifier. This field is generated by the Zig toolchain when the
17
- // package is first created, and then *never changes*. This allows
18
- // unambiguous detection of one package being an updated version of
19
- // another.
20
- //
21
- // When forking a Zig project, this id should be regenerated (delete the
22
- // field and run `zig build`) if the upstream project is still maintained.
23
- // Otherwise, the fork is *hostile*, attempting to take control over the
24
- // original project's identity. Thus it is recommended to leave the comment
25
- // on the following line intact, so that it shows up in code reviews that
26
- // modify the field.
4
+ .fingerprint = 0xf61d745fc6e28443,
27
- .fingerprint = 0xed40fb47bc802c59, // Changing this has security and trust implications.
28
-
29
- // Tracks the earliest Zig version that the package considers to be a
30
- // supported use case.
31
5
  .minimum_zig_version = "0.14.0",
32
-
33
- // This field is optional.
34
- // Each dependency must either provide a `url` and `hash`, or a `path`.
35
- // `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
36
- // Once all dependencies are fetched, `zig build` no longer requires
37
- // internet connectivity.
38
6
  .dependencies = .{
39
7
  .microzig = .{
40
- .url = "https://microzig.tech/downloads/microzig/0.13.2/microzig.tar.gz",
8
+ .url = "git+https://github.com/ZigEmbeddedGroup/microzig.git#36c2517dd56d675fcd64a2d6e8fc8e7a053a0f15",
41
- .hash = "microzig-0.13.2-AAAAAEAoCACJtVQID09BdlBX63hCLqdwobnQC5A_1QfO",
9
+ .hash = "microzig-0.14.0-D20YSUoZagN9r5VoCh6qtb1ljAIFSAG19ED5EiqiVhvk",
42
10
  },
43
11
  },
44
12
  .paths = .{
45
13
  "build.zig",
46
14
  "build.zig.zon",
47
15
  "src",
48
- // For example...
49
- //"LICENSE",
50
- //"README.md",
51
16
  },
52
17
  }
53
-
54
- // .{
55
- // .name = .examples_raspberrypi_rp2xxx,
56
- // .fingerprint = 0xffa4bfa151162a57,
57
- // .version = "0.0.0",
58
- // .dependencies = .{
59
- // .microzig = .{ .path = "../../.." },
60
- // },
61
- // .paths = .{
62
- // "LICENSE",
63
- // "README.md",
64
- // "build.zig",
65
- // "build.zig.zon",
66
- // "src",
67
- // "scripts",
68
- // },
69
- // }
docs/aa.zig ADDED
@@ -0,0 +1,75 @@
1
+ const std = @import("std");
2
+ const stdout = std.io.getStdOut().writer();
3
+
4
+ pub const User = struct {
5
+ power: u64,
6
+ name: []const u8,
7
+
8
+ pub const SUPER_POWER = 9000;
9
+
10
+ pub fn diagnose(self: User) void {
11
+ if (self.power >= SUPER_POWER) {
12
+ std.debug.print("it's over {d}!!!", .{SUPER_POWER});
13
+ }
14
+ }
15
+ };
16
+
17
+ const Stage = enum {
18
+ validate,
19
+ awaiting_confirmation,
20
+ confirmed,
21
+ err,
22
+
23
+ fn isComplete(self: Stage) bool {
24
+ return self == .confirmed or self == .err;
25
+ }
26
+ };
27
+
28
+ const TimestampType = enum {
29
+ unix,
30
+ datetime,
31
+ };
32
+
33
+ const Timestamp = union(TimestampType) {
34
+ unix: i32,
35
+ datetime: DateTime,
36
+
37
+ const DateTime = struct {
38
+ year: u16,
39
+ month: u8,
40
+ day: u8,
41
+ hour: u8,
42
+ minute: u8,
43
+ second: u8,
44
+ };
45
+
46
+ fn seconds(self: Timestamp) u16 {
47
+ switch (self) {
48
+ .datetime => |dt| return dt.second,
49
+ .unix => |ts| {
50
+ const seconds_since_midnight: i32 = @rem(ts, 86400);
51
+ return @intCast(@rem(seconds_since_midnight, 60));
52
+ },
53
+ }
54
+ }
55
+ };
56
+
57
+ const user = User{ .name = "Goku" };
58
+
59
+ pub fn main() !void {
60
+ var i: usize = 1;
61
+ while (i <= 16) : (i += 1) {
62
+ if (i % 15 == 0) {
63
+ try stdout.writeAll("ZiggZagg\n");
64
+ } else if (i % 3 == 0) {
65
+ try stdout.writeAll("Zigg\n");
66
+ } else if (i % 5 == 0) {
67
+ try stdout.writeAll("Zagg\n");
68
+ } else {
69
+ try stdout.print("{d}\n", .{i});
70
+ }
71
+ }
72
+ for (0..10) |j| {
73
+ std.debug.print("{d}\n", .{j});
74
+ }
75
+ }
docs/connecting-to-the-internet-with-pico-w.pdf ADDED
Binary file
docs/getting-started-with-pico.pdf ADDED
Binary file
docs/hardware-design-with-rp2350.pdf ADDED
Binary file
kaluma-rp2-pico2-w-1.2.0.uf2 → docs/kaluma-rp2-pico2-w-1.2.0.uf2 RENAMED
File without changes
docs/main.js ADDED
@@ -0,0 +1,106 @@
1
+ const { GPIO } = require('gpio');
2
+ const { SPI } = require('spi');
3
+
4
+ const ssr = new GPIO(0, OUTPUT);
5
+ const button = new GPIO(1, INPUT_PULLUP);
6
+ // pinMode(26, INPUT) // analogRead(26)
7
+ const csn = new GPIO(17, OUTPUT);
8
+ const dc = new GPIO(20, OUTPUT);
9
+ const rst = new GPIO(21, OUTPUT);
10
+ const spi0 = new SPI(0, {
11
+ mode: SPI.MODE_0,
12
+ baudrate: 800000,
13
+ bitorder: SPI.MSB,
14
+ });
15
+
16
+ // command, data, delay
17
+ const initCommands = [
18
+ [0x01, [], 150], // Software reset
19
+ // .[ 0xEF, [ 0x03, 0x80, 0x02 ] },
20
+ [0xCF, [0x00, 0xC1, 0x30]], // Pwr ctrl B
21
+ [0xED, [0x64, 0x03, 0x12, 0x81]], // # Pwr on seq. ctrl
22
+ [0xE8, [0x85, 0x00, 0x78]], // Driver timing ctrl A
23
+ [0xCB, [0x39, 0x2C, 0x00, 0x34, 0x02]], // Pwr ctrl A
24
+ [0xF7, [0x20]], // Pump ratio control
25
+ [0xEA, [0x00, 0x00]], // Driver timing ctrl B
26
+ [0xC0, [0x23]], // Pwr ctrl 1
27
+ [0xC1, [0x10]], // Pwr ctrl 2
28
+ [0xC5, [0x3E, 0x28]], // VCM control1
29
+ [0xC7, [0x86]], // VCM control2
30
+ [0x36, [0x80]], // Memory Access Control
31
+ [0x37, [0x00]], // Vertical scroll zero
32
+ [0x3A, [0x55]], // COLMOD: Pixel Format Set
33
+ [0xB1, [0x00, 0x18]], // Frame Rate Control (In Normal Mode/Full Colors)
34
+ [0xB6, [0x08, 0x82, 0x27]], // Display Function Control
35
+ [0xF2, [0x00]], // 3Gamma Function Disable
36
+ [0x26, [0x01]], // Gamma curve selected
37
+ // .[ 0xE0, [ 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00 ] ], // Set Gamma Positive Gamma Correction
38
+ // .[ 0xE1, [ 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F ] ], // Set Gamma Negative Gamma Correction
39
+ [0x11, [], 150], // Exit Sleep/Sleep Out
40
+ [0x29, [], 150], // Display
41
+ ]
42
+
43
+ function sendCommand(cmd, data) {
44
+ dc.write(LOW);
45
+ csn.write(LOW);
46
+ spi0.send(new Uint8Array([cmd]));
47
+ csn.write(HIGH);
48
+ if (data.length > 0) {
49
+ dc.write(HIGH);
50
+ csn.write(LOW);
51
+ spi0.send(data);
52
+ csn.write(HIGH);
53
+ }
54
+ }
55
+
56
+ function block(x0, y0, x1, y1, data) {
57
+ sendCommand(0x2A, [x0 >> 8, x0 & 0xFF, x1 >> 8, x1 & 0xFF]); // Column address set
58
+ sendCommand(0x2B, [y0 >> 8, y0 & 0xFF, y1 >> 8, y1 & 0xFF]); // Page address set
59
+ sendCommand(0x2C, data); // Memory write
60
+ }
61
+
62
+ function hardware_reset() {
63
+ rst.write(0);
64
+ delay(50);
65
+ rst.write(1);
66
+ delay(50);
67
+ }
68
+
69
+ function cleanup() {
70
+ clear()
71
+ // self.display_off()
72
+ // self.spi.deinit()
73
+ }
74
+
75
+
76
+ const width = 240;
77
+ const height = 320;
78
+ function clear(color) {
79
+ for (var y = 0; y < height; y += 8) {
80
+ block(0, y, width, y + 8 - 1, new Uint8Array(width * 2 * 8).fill(color));
81
+ }
82
+ }
83
+
84
+ delay(100);
85
+ csn.write(1);
86
+ dc.write(0);
87
+ rst.write(1);
88
+ delay(50);
89
+ hardware_reset();
90
+
91
+ for (const init of initCommands) {
92
+ sendCommand(init[0], init[1]);
93
+ if (init[2]) {
94
+ delay(init[2]);
95
+ }
96
+ }
97
+
98
+ button.irq((pin, mode) => {
99
+ if (button.read() === LOW) {
100
+ ssr.write(HIGH);
101
+ clear(0x00);
102
+ } else {
103
+ ssr.write(LOW);
104
+ clear(0xA0);
105
+ }
106
+ }, CHANGE);
docs/openocd.tar.gz ADDED
Binary file
docs/pico2w.png ADDED
Binary file
docs/raspberry-pi-pico-c-sdk.pdf ADDED
Binary file
docs/rp2350-datasheet.pdf ADDED
Binary file
docs/rp2350-product-brief.pdf ADDED
Binary file
docs/rp2350_explanation.svg ADDED
@@ -0,0 +1,376 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+
4
+ <svg
5
+ version="1.1"
6
+ x="0px"
7
+ y="0px"
8
+ width="145.087px"
9
+ height="80px"
10
+ viewBox="0 0 145.087 80"
11
+ style="enable-background:new 0 0 145.087 80;"
12
+ xml:space="preserve"
13
+ id="svg114"
14
+ sodipodi:docname="rp2040_explanation.svg"
15
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
16
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
17
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
18
+ xmlns="http://www.w3.org/2000/svg"
19
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
20
+ id="defs118">
21
+
22
+
23
+ </defs><sodipodi:namedview
24
+ id="namedview116"
25
+ pagecolor="#ffffff"
26
+ bordercolor="#666666"
27
+ borderopacity="1.0"
28
+ inkscape:pageshadow="2"
29
+ inkscape:pageopacity="0.0"
30
+ inkscape:pagecheckerboard="0"
31
+ showgrid="false"
32
+ inkscape:zoom="13.041952"
33
+ inkscape:cx="54.899758"
34
+ inkscape:cy="9.9678331"
35
+ inkscape:window-width="1920"
36
+ inkscape:window-height="1163"
37
+ inkscape:window-x="3840"
38
+ inkscape:window-y="0"
39
+ inkscape:window-maximized="1"
40
+ inkscape:current-layer="Layer_1" />
41
+ <style
42
+ type="text/css"
43
+ id="style2">
44
+ .st0{fill:#F6F6F6;}
45
+ .st1{fill:#CA4F62;}
46
+ .st2{fill:#4A96D2;}
47
+ .st3{fill:none;}
48
+ .st4{fill:#1D1D1B;}
49
+ .st5{font-family:'Roboto-Bold';}
50
+ .st6{font-size:15px;}
51
+ .st7{fill:none;stroke:#1D1D1B;stroke-width:0.5;stroke-miterlimit:10;}
52
+ .st8{font-size:4px;}
53
+ .st9{fill:none;stroke:#CA4F62;stroke-miterlimit:10;}
54
+ </style>
55
+ <g
56
+ id="Guides">
57
+ </g>
58
+ <g
59
+ id="BG">
60
+ <rect
61
+ class="st0"
62
+ width="145.087"
63
+ height="80"
64
+ id="rect5" />
65
+ </g>
66
+ <g
67
+ id="Ref">
68
+ </g>
69
+ <g
70
+ id="Layer_1">
71
+ <rect
72
+ x="13.694"
73
+ y="8.7620001"
74
+ class="st3"
75
+ width="70.167"
76
+ height="12.116"
77
+ id="rect9" /><text
78
+ id="text29"
79
+ x="12.593029"
80
+ y="19.9993"><tspan
81
+ x="12.593029"
82
+ y="19.9993"
83
+ class="st4 st5 st6"
84
+ id="tspan11"
85
+ dy="0 0 0">RP </tspan></text><text
86
+ id="text29-3"
87
+ x="48.967743"
88
+ y="19.9993"
89
+ style="text-align:center;text-anchor:middle"><tspan
90
+ sodipodi:role="line"
91
+ id="tspan79195"
92
+ x="40.522919"
93
+ y="19.9993"><tspan
94
+ x="40.522919"
95
+ y="19.9993"
96
+ class="st4 st5 st6"
97
+ id="tspan11-6"
98
+ style="text-align:center;text-anchor:middle">2</tspan></tspan><tspan
99
+ sodipodi:role="line"
100
+ id="tspan79197"
101
+ x="42.020721"
102
+ y="19.9993"><tspan
103
+ x="40.522919"
104
+ y="19.9993"
105
+ class="st4 st5 st6"
106
+ dy="0"
107
+ style="text-align:center;text-anchor:middle"
108
+ id="tspan79199"> </tspan></tspan></text><text
109
+ id="text29-3-3"
110
+ x="51.877296"
111
+ y="19.786898"
112
+ style="text-align:center;text-anchor:middle"><tspan
113
+ sodipodi:role="line"
114
+ id="tspan82308"
115
+ x="51.877296"
116
+ y="19.786898"><tspan
117
+ x="51.877296"
118
+ y="19.786898"
119
+ class="st4 st5 st6"
120
+ id="tspan11-6-5"
121
+ style="text-align:center;text-anchor:middle">3</tspan></tspan><tspan
122
+ sodipodi:role="line"
123
+ id="tspan82310"
124
+ x="53.375099"
125
+ y="19.786898"><tspan
126
+ x="51.877296"
127
+ y="19.786898"
128
+ class="st4 st5 st6"
129
+ dy="0"
130
+ style="text-align:center;text-anchor:middle"
131
+ id="tspan82312"> </tspan></tspan></text><text
132
+ id="text29-3-3-6"
133
+ x="63.601402"
134
+ y="19.786898"
135
+ style="text-align:center;text-anchor:middle"><tspan
136
+ sodipodi:role="line"
137
+ id="tspan85781"
138
+ x="63.601402"
139
+ y="19.786898"><tspan
140
+ x="63.601402"
141
+ y="19.786898"
142
+ class="st4 st5 st6"
143
+ id="tspan11-6-5-2"
144
+ style="text-align:center;text-anchor:middle">5</tspan></tspan><tspan
145
+ sodipodi:role="line"
146
+ id="tspan85783"
147
+ x="65.099205"
148
+ y="19.786898"><tspan
149
+ x="63.601402"
150
+ y="19.786898"
151
+ class="st4 st5 st6"
152
+ dy="0"
153
+ style="text-align:center;text-anchor:middle"
154
+ id="tspan85785"> </tspan></tspan></text><text
155
+ id="text29-3-3-6-9"
156
+ x="75.065659"
157
+ y="19.786898"
158
+ style="text-align:center;text-anchor:middle"><tspan
159
+ sodipodi:role="line"
160
+ id="tspan91420"
161
+ x="75.065659"
162
+ y="19.786898"><tspan
163
+ x="75.065659"
164
+ y="19.786898"
165
+ class="st4 st5 st6"
166
+ id="tspan11-6-5-2-1"
167
+ style="text-align:center;text-anchor:middle">0</tspan></tspan><tspan
168
+ sodipodi:role="line"
169
+ id="tspan91422"
170
+ x="76.563461"
171
+ y="19.786898"><tspan
172
+ x="75.065659"
173
+ y="19.786898"
174
+ class="st4 st5 st6"
175
+ dy="0"
176
+ style="text-align:center;text-anchor:middle"
177
+ id="tspan91424"> </tspan></tspan></text>
178
+ <g
179
+ id="g41">
180
+ <g
181
+ id="g39">
182
+ <line
183
+ class="st7"
184
+ x1="23.063"
185
+ y1="26.239"
186
+ x2="23.063"
187
+ y2="67.996"
188
+ id="line33" />
189
+ <g
190
+ id="g37">
191
+ <polygon
192
+ class="st4"
193
+ points="21.674,27.292 23.063,26.702 24.452,27.292 23.063,24 "
194
+ id="polygon35" />
195
+ </g>
196
+ </g>
197
+ </g>
198
+ <g
199
+ id="g51">
200
+ <g
201
+ id="g49">
202
+ <line
203
+ class="st7"
204
+ x1="75.14"
205
+ y1="26.239"
206
+ x2="75.14"
207
+ y2="35.998"
208
+ id="line43" />
209
+ <g
210
+ id="g47">
211
+ <polygon
212
+ class="st4"
213
+ points="73.752,27.292 75.14,26.702 76.529,27.292 75.14,24 "
214
+ id="polygon45" />
215
+ </g>
216
+ </g>
217
+ </g>
218
+ <rect
219
+ x="22.56"
220
+ y="68.995"
221
+ class="st3"
222
+ width="26.603"
223
+ height="7.001"
224
+ id="rect53" />
225
+ <text
226
+ transform="matrix(1 0 0 1 22.5606 71.995)"
227
+ class="st4 st5 st8"
228
+ id="text55">Raspberry Pi</text>
229
+ <line
230
+ class="st9"
231
+ x1="14.644"
232
+ y1="22.123"
233
+ x2="31.482"
234
+ y2="22.123"
235
+ id="line57" />
236
+ <line
237
+ class="st9"
238
+ x1="36.667"
239
+ y1="22.123"
240
+ x2="43.976"
241
+ y2="22.123"
242
+ id="line59" />
243
+ <line
244
+ class="st9"
245
+ x1="48.194"
246
+ y1="22.123"
247
+ x2="55.502"
248
+ y2="22.123"
249
+ id="line61" />
250
+ <line
251
+ class="st9"
252
+ x1="71.408"
253
+ y1="22.123"
254
+ x2="78.716"
255
+ y2="22.123"
256
+ id="line63" />
257
+ <line
258
+ class="st9"
259
+ x1="59.87"
260
+ y1="22.123"
261
+ x2="67.179"
262
+ y2="22.123"
263
+ id="line65" />
264
+ <g
265
+ id="g75">
266
+ <g
267
+ id="g73">
268
+ <line
269
+ class="st7"
270
+ x1="40.285"
271
+ y1="26.239"
272
+ x2="40.285"
273
+ y2="59.996"
274
+ id="line67" />
275
+ <g
276
+ id="g71">
277
+ <polygon
278
+ class="st4"
279
+ points="38.897,27.292 40.285,26.702 41.674,27.292 40.285,24 "
280
+ id="polygon69" />
281
+ </g>
282
+ </g>
283
+ </g>
284
+ <rect
285
+ x="39.783"
286
+ y="60.995"
287
+ class="st3"
288
+ width="30.546"
289
+ height="7.001"
290
+ id="rect77" />
291
+ <text
292
+ transform="matrix(1 0 0 1 39.783 63.995)"
293
+ class="st4 st5 st8"
294
+ id="text79">Number of cores</text>
295
+ <g
296
+ id="g89">
297
+ <g
298
+ id="g87">
299
+ <line
300
+ class="st7"
301
+ x1="51.907"
302
+ y1="26.239"
303
+ x2="51.907"
304
+ y2="51.996"
305
+ id="line81" />
306
+ <g
307
+ id="g85">
308
+ <polygon
309
+ class="st4"
310
+ points="50.518,27.292 51.907,26.702 53.296,27.292 51.907,24 "
311
+ id="polygon83" />
312
+ </g>
313
+ </g>
314
+ </g>
315
+ <rect
316
+ x="51.404"
317
+ y="52.995"
318
+ class="st3"
319
+ width="42.746"
320
+ height="7.001"
321
+ id="rect91" />
322
+ <text
323
+ transform="translate(51.4046,55.995)"
324
+ class="st4 st5 st8"
325
+ id="text93">Type of core (e.g. Cortex-M33)</text>
326
+ <g
327
+ id="g103">
328
+ <g
329
+ id="g101">
330
+ <line
331
+ class="st7"
332
+ x1="63.534"
333
+ y1="26.239"
334
+ x2="63.534"
335
+ y2="43.998"
336
+ id="line95" />
337
+ <g
338
+ id="g99">
339
+ <polygon
340
+ class="st4"
341
+ points="62.145,27.292 63.534,26.702 64.923,27.292 63.534,24 "
342
+ id="polygon97" />
343
+ </g>
344
+ </g>
345
+ </g>
346
+ <rect
347
+ x="63.031"
348
+ y="44.996"
349
+ class="st3"
350
+ width="42.746"
351
+ height="7.001"
352
+ id="rect105" />
353
+ <text
354
+ transform="translate(63.0315,47.9957)"
355
+ class="st4 st5 st8"
356
+ id="text107">floor(log2(RAM / 16 kB))</text>
357
+ <rect
358
+ x="74.635"
359
+ y="36.996"
360
+ class="st3"
361
+ width="53.622"
362
+ height="7.001"
363
+ id="rect109" />
364
+ <text
365
+ transform="translate(74.6349,39.9961)"
366
+ class="st4 st5 st8"
367
+ id="text111">floor(log2(nonvolatile / 128 kB))</text>
368
+ <text
369
+ xml:space="preserve"
370
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none"
371
+ x="38.2201"
372
+ y="18.437899"
373
+ id="text22809"><tspan
374
+ sodipodi:role="line"
375
+ id="tspan22807"></tspan></text></g>
376
+ </svg>
main.js DELETED
@@ -1,13 +0,0 @@
1
- pinMode(0, OUTPUT);
2
- pinMode(1, INPUT_PULLUP);
3
- pinMode(26, INPUT)
4
-
5
- attachInterrupt(1, (pin, mode) => {
6
- console.log(analogRead(26));
7
- if (digitalRead(1) === LOW) {
8
- digitalWrite(0, HIGH)
9
- }
10
- if (digitalRead(1) === HIGH) {
11
- digitalWrite(0, LOW)
12
- }
13
- }, CHANGE);
readme.md ADDED
@@ -0,0 +1,54 @@
1
+ # RP2350 Dev Board
2
+
3
+ ## Setup
4
+ 1. `brew install zig open-ocd arm-none-eabi-gdb`
5
+ 2. Test
6
+
7
+
8
+ If open-ocd doesn't work build from source,
9
+
10
+ `brew remove open-ocd`
11
+ `brew install pkg-config autoconf automake texinfo libfdti hidpi jimtcl`
12
+ `untar docs/openocd.tar.gz`
13
+ `./boostrap`
14
+ `./configure --enable-target=rp2350 --enable-interface=jtag`
15
+ `make`
16
+ `sudo make install`
17
+
18
+ ## Run
19
+ 1. `zig build`
20
+ 2. `picotool load -x zig-out/firmware/rp2350.uf2 -f`
21
+
22
+
23
+ # Start OCD Server
24
+
25
+ `sudo openocd -s tcl -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000"sudo openocd -s tcl -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000"`
26
+
27
+ # Flash OCD Program
28
+
29
+ `sudo openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" -c "program zig-out/firmware/rp2350.elf verify reset exit"`
30
+
31
+ ```c
32
+ // Flash allocation map 4MB for pico 2W
33
+ //
34
+ // |------------------------------------------------|
35
+ // | A | B | C | D |
36
+ // |----------------|---|-----------|---------------|
37
+ // | 1024K |64K| 1472K | 1536K |
38
+ // |------------------------------------------------|
39
+ // |----------- flash.c -----------|
40
+
41
+ // |------ 1MB -----|------------- 3MB -------------|
42
+ // |---------------------- 4MB ---------------------|
43
+ //
44
+ // - A : binary (firmware)
45
+ // - B : storage (key-value database)
46
+ // - C : user program (js)
47
+ // - D : file system (lfs)
48
+ // (Total : 4MB)
49
+
50
+ // file system on flash (1024K)
51
+ // - sector base : 400
52
+ // - sector count : 384
53
+ // - use block device : new Flash(400, 384)
54
+ ```
src/main.zig CHANGED
@@ -2,23 +2,263 @@ const std = @import("std");
2
2
  const microzig = @import("microzig");
3
3
  const rp2xxx = microzig.hal;
4
4
  const time = rp2xxx.time;
5
+ const gpio = rp2xxx.gpio;
6
+ const SPI0 = rp2xxx.spi.instance.SPI0;
5
7
 
6
- // Compile-time pin configuration
7
- const pin_config = rp2xxx.pins.GlobalConfiguration{
8
+ const uart = rp2xxx.uart.instance.num(0);
9
+ const uart_baud_rate = 115200;
10
+ const uart_tx_pin = gpio.num(0);
11
+ const uart_rx_pin = gpio.num(1);
12
+
8
- .GPIO25 = .{
13
+ const ssr = gpio.num(26);
14
+ const button = gpio.num(27);
15
+ const miso = gpio.num(16);
16
+ const csn = gpio.num(17);
17
+ const sck = gpio.num(18);
18
+ const mosi = gpio.num(19);
9
- .name = "led",
19
+ const dc = gpio.num(20);
20
+ const rst = gpio.num(21);
21
+
22
+ // spi = SPI(0, 40_000_000, sck=Pin(18), mosi=Pin(19), miso=Pin(16))
23
+ // display = Display(spi, gamma=False, bgr=False, dc=Pin(20), cs=Pin(17), rst=Pin(21))
24
+ // display.clear(color565(64, 0, 255))
25
+ // sleep(1)
26
+
27
+ const Command = struct {
28
+ code: u8,
10
- .direction = .out,
29
+ data: []const u8,
11
- },
30
+ delay_ms: ?u32 = null,
12
31
  };
13
32
 
33
+ // const initDisplayCommands = [
34
+ // Command(code: 0x01, data: [], delay_ms: 150),
35
+ // Command(code: 0x01, data: [], delay_ms: 150),
36
+ // Command(code: 0x01, data: [], delay_ms: 150),
37
+ // Command(code: 0x01, data: [], delay_ms: 150),
38
+ // Command(code: 0x01, data: [], delay_ms: 150),
39
+ // Command(code: 0x01, data: [], delay_ms: 150),
40
+ // Command(code: 0x01, data: [], delay_ms: 150),
41
+ // Command(code: 0x01, data: [], delay_ms: 150),
42
+ //]
43
+
44
+ const initDisplayCommands: []const Command = &.{
45
+ .{ .code = 0x01, .data = &.{}, .delay_ms = 150 }, // Software reset
46
+ // .{ .code = 0xEF, .data = &.{ 0x03, 0x80, 0x02 } },
47
+ .{ .code = 0xCF, .data = &.{ 0x00, 0xC1, 0x30 } }, // Pwr ctrl B
48
+ .{ .code = 0xED, .data = &.{ 0x64, 0x03, 0x12, 0x81 } }, // # Pwr on seq. ctrl
49
+ .{ .code = 0xE8, .data = &.{ 0x85, 0x00, 0x78 } }, // Driver timing ctrl A
50
+ .{ .code = 0xCB, .data = &.{ 0x39, 0x2C, 0x00, 0x34, 0x02 } }, // Pwr ctrl A
51
+ .{ .code = 0xF7, .data = &.{0x20} }, // Pump ratio control
52
+ .{ .code = 0xEA, .data = &.{ 0x00, 0x00 } }, // Driver timing ctrl B
53
+ .{ .code = 0xC0, .data = &.{0x23} }, // Pwr ctrl 1
54
+ .{ .code = 0xC1, .data = &.{0x10} }, // Pwr ctrl 2
55
+ .{ .code = 0xC5, .data = &.{ 0x3E, 0x28 } }, // VCM control1
56
+ .{ .code = 0xC7, .data = &.{0x86} }, // VCM control2
57
+ .{ .code = 0x36, .data = &.{0x80} }, // Memory Access Control
58
+ .{ .code = 0x37, .data = &.{0x00} }, // Vertical scroll zero
59
+ .{ .code = 0x3A, .data = &.{0x55} }, // COLMOD: Pixel Format Set
60
+ .{ .code = 0xB1, .data = &.{ 0x00, 0x18 } }, // Frame Rate Control (In Normal Mode/Full Colors)
61
+ .{ .code = 0xB6, .data = &.{ 0x08, 0x82, 0x27 } }, // Display Function Control
62
+ .{ .code = 0xF2, .data = &.{0x00} }, // 3Gamma Function Disable
63
+ .{ .code = 0x26, .data = &.{0x01} }, // Gamma curve selected
64
+ // .{ .code = 0xE0, .data = &.{ 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00 } }, // Set Gamma Positive Gamma Correction
65
+ // .{ .code = 0xE1, .data = &.{ 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F } }, // Set Gamma Negative Gamma Correction
66
+ .{ .code = 0x11, .data = &.{}, .delay_ms = 150 }, // Exit Sleep/Sleep Out
67
+ .{ .code = 0x29, .data = &.{}, .delay_ms = 150 }, // Display on
68
+ };
69
+
70
+ fn send(self: Command) void {
71
+ dc.put(0);
72
+ csn.put(0);
73
+ SPI0.write_blocking(u8, &.{self.code});
74
+ csn.put(1);
75
+ if (self.data.len > 0) {
76
+ sendData(self.data);
77
+ }
78
+ }
79
+
80
+ fn sendData(data: []const u8) void {
81
+ dc.put(1);
82
+ csn.put(0);
83
+ SPI0.write_blocking(u8, data);
84
+ csn.put(1);
85
+ }
86
+
87
+ // Write a block of data to display.
88
+ //
89
+ // Args:
90
+ // x0 (int): Starting X position.
91
+ // y0 (int): Starting Y position.
92
+ // x1 (int): Ending X position.
93
+ // y1 (int): Ending Y position.
94
+ // data (bytes): Data buffer to write.
95
+ fn block(x0: u16, y0: u16, x1: u16, y1: u16, data: []const u8) void {
96
+ send(.{ .code = 0x2A, .data = &.{ @intCast(x0 >> 8), @truncate(x0), @intCast(x1 >> 8), @truncate(x1) } }); // Column address set
97
+ send(.{ .code = 0x2B, .data = &.{ @intCast(y0 >> 8), @truncate(y0), @intCast(y1 >> 8), @truncate(y1) } }); // Page address set
98
+ send(.{ .code = 0x2C, .data = data });
99
+ }
100
+
101
+ fn draw_pixel(x: u16, y: u16, color: u16) void {
102
+ block(x, y, x, y, &.{color});
103
+ }
104
+
105
+ // def draw_circle(self, x0, y0, r, color):
106
+ // """Draw a circle.
107
+
108
+ // Args:
109
+ // x0 (int): X coordinate of center point.
110
+ // y0 (int): Y coordinate of center point.
111
+ // r (int): Radius.
112
+ // color (int): RGB565 color value.
113
+ // """
114
+ // f = 1 - r
115
+ // dx = 1
116
+ // dy = -r - r
117
+ // x = 0
118
+ // y = r
119
+ // self.draw_pixel(x0, y0 + r, color)
120
+ // self.draw_pixel(x0, y0 - r, color)
121
+ // self.draw_pixel(x0 + r, y0, color)
122
+ // self.draw_pixel(x0 - r, y0, color)
123
+ // while x < y:
124
+ // if f >= 0:
125
+ // y -= 1
126
+ // dy += 2
127
+ // f += dy
128
+ // x += 1
129
+ // dx += 2
130
+ // f += dx
131
+ // self.draw_pixel(x0 + x, y0 + y, color)
132
+ // self.draw_pixel(x0 - x, y0 + y, color)
133
+ // self.draw_pixel(x0 + x, y0 - y, color)
134
+ // self.draw_pixel(x0 - x, y0 - y, color)
135
+ // self.draw_pixel(x0 + y, y0 + x, color)
136
+ // self.draw_pixel(x0 - y, y0 + x, color)
137
+ // self.draw_pixel(x0 + y, y0 - x, color)
138
+ // self.draw_pixel(x0 - y, y0 - x, color)
139
+
140
+ // def draw_image(self, path, x=0, y=0, w=320, h=240):
141
+ // """Draw image from flash.
142
+
143
+ // Args:
144
+ // path (string): Image file path.
145
+ // x (int): X coordinate of image left. Default is 0.
146
+ // y (int): Y coordinate of image top. Default is 0.
147
+ // w (int): Width of image. Default is 320.
148
+ // h (int): Height of image. Default is 240.
149
+ // """
150
+ // x2 = x + w - 1
151
+ // y2 = y + h - 1
152
+ // if self.is_off_grid(x, y, x2, y2):
153
+ // return
154
+ // with open(path, "rb") as f:
155
+ // chunk_height = 1024 // w
156
+ // chunk_count, remainder = divmod(h, chunk_height)
157
+ // chunk_size = chunk_height * w * 2
158
+ // chunk_y = y
159
+ // if chunk_count:
160
+ // for c in range(0, chunk_count):
161
+ // buf = f.read(chunk_size)
162
+ // self.block(x, chunk_y,
163
+ // x2, chunk_y + chunk_height - 1,
164
+ // buf)
165
+ // chunk_y += chunk_height
166
+ // if remainder:
167
+ // buf = f.read(remainder * w * 2)
168
+ // self.block(x, chunk_y,
169
+ // x2, chunk_y + remainder - 1,
170
+ // buf)
171
+
172
+ fn color565(r: u32, g: u32, b: u32) u16 {
173
+ return (r & 0xF8) << 8 | (g & 0xFC) << 3 | b >> 3;
174
+ }
175
+
14
- const pins = pin_config.pins();
176
+ const width = 480;
177
+ const height = 320;
178
+ fn clear(color: u8) void {
179
+ // mem.zeroes([4096]u8);
180
+ var buffer: [width]u8 = undefined;
181
+ var i: usize = 0;
182
+ while (i < buffer.len) : (i += 1) {
183
+ buffer[i] = color;
184
+ }
185
+ var y: u16 = 0;
186
+ while (y < height) : (y += 1) {
187
+ block(0, y, width - 1, y + 8 - 1, &buffer);
188
+ }
189
+ }
190
+
191
+ fn hardware_reset() void {
192
+ rst.put(0);
193
+ time.sleep_ms(50);
194
+ rst.put(1);
195
+ time.sleep_ms(50);
196
+ }
15
197
 
16
198
  pub fn main() !void {
199
+ inline for (&.{ miso, mosi, sck }) |pin| {
200
+ pin.set_function(.spi);
201
+ }
202
+ uart_tx_pin.set_function(.uart);
203
+ uart_rx_pin.set_function(.uart);
17
- pin_config.apply();
204
+ uart.apply(.{
205
+ .baud_rate = uart_baud_rate,
206
+ .clock_config = rp2xxx.clock_config,
207
+ });
208
+ ssr.set_function(.sio);
209
+ ssr.set_direction(.out);
210
+ csn.set_function(.sio);
211
+ csn.set_direction(.out);
212
+ dc.set_function(.sio);
213
+ dc.set_direction(.out);
214
+ rst.set_function(.sio);
215
+ rst.set_direction(.out);
216
+ button.set_function(.sio);
217
+ button.set_direction(.in);
18
- pin_config.apply();
218
+ button.set_pull(.up);
219
+
220
+ try SPI0.apply(.{ .clock_config = rp2xxx.clock_config, .baud_rate = 40_000_000 });
221
+ csn.put(1);
222
+ dc.put(0);
223
+ rst.put(1);
224
+ hardware_reset();
225
+ for (initDisplayCommands) |cmd| {
226
+ send(cmd);
227
+ if (cmd.delay_ms) |delay_ms| {
228
+ time.sleep_ms(delay_ms);
229
+ }
230
+ }
231
+ clear(0x00);
232
+ var ascon = rp2xxx.rand.Ascon.init();
233
+ var rng = ascon.random();
234
+ var set: u1 = 0;
19
235
 
20
236
  while (true) {
21
- pins.led.toggle();
237
+ const a = button.read();
238
+ if (a == 0) {
239
+ ssr.put(1);
240
+ if (set != 1) {
241
+ clear(rng.int(u8));
242
+ }
243
+ set = 1;
244
+ } else {
245
+ ssr.put(0);
246
+ set = 0;
247
+ }
22
248
  time.sleep_ms(250);
23
249
  }
24
250
  }
251
+
252
+ const expect = std.testing.expect;
253
+
254
+ fn data2(v: u8) u8 {
255
+ return v;
256
+ }
257
+
258
+ test "truncate u16 to u6" {
259
+ const a: u16 = 320;
260
+ try expect(data2(@truncate(a)) == 64);
261
+ try expect(320 & 0xFF == 64);
262
+ try expect(320 >> 8 == 1);
263
+ try expect(data2(@intCast(a >> 8)) == 1);
264
+ }