فهرست منبع

add a rotating chip when scanning
fix memory dumping

g3gg0 2 سال پیش
والد
کامیت
bb71d41672
4فایلهای تغییر یافته به همراه787 افزوده شده و 9 حذف شده
  1. 216 0
      model/chip.ply
  2. 39 0
      model/convert.py
  3. 420 0
      model/model_chip.h
  4. 112 9
      swd_probe_app.c

+ 216 - 0
model/chip.ply

@@ -0,0 +1,216 @@
+ply
+format ascii 1.0
+comment Created by Blender 3.3.1 - www.blender.org
+element vertex 136
+property float x
+property float y
+property float z
+element face 70
+property list uchar uint vertex_indices
+end_header
+1.000000 1.000000 0.152153
+-1.000000 1.000000 0.152153
+-1.000000 -1.000000 0.152153
+1.000000 -1.000000 0.152153
+1.000000 -1.000000 -0.185787
+-1.000000 -1.000000 -0.185787
+-1.000000 1.000000 -0.185787
+1.000000 1.000000 -0.185787
+-1.000043 -0.785071 -0.015780
+-1.155724 -0.785071 -0.015780
+-1.155724 -0.918718 -0.015780
+-1.000043 -0.918718 -0.015780
+-1.155724 -0.785071 0.127052
+-1.000043 -0.785071 0.127052
+-1.000043 -0.918718 0.127052
+-1.155724 -0.918718 0.127052
+-1.234192 -0.918846 -0.087021
+-1.234397 -0.785201 -0.086336
+-1.235319 -0.784943 -0.229143
+-1.235114 -0.918588 -0.229828
+-1.388133 -0.919573 -0.078673
+-1.389056 -0.919314 -0.221479
+-1.389261 -0.785669 -0.220795
+-1.388338 -0.785927 -0.077988
+-1.000043 -0.219627 -0.015780
+-1.155724 -0.219627 -0.015780
+-1.155724 -0.353273 -0.015780
+-1.000043 -0.353273 -0.015780
+-1.155724 -0.219627 0.127052
+-1.000043 -0.219627 0.127052
+-1.000043 -0.353273 0.127052
+-1.155724 -0.353273 0.127052
+-1.234192 -0.353402 -0.087021
+-1.234397 -0.219756 -0.086336
+-1.235319 -0.219498 -0.229143
+-1.235114 -0.353143 -0.229828
+-1.388133 -0.354128 -0.078673
+-1.389056 -0.353870 -0.221479
+-1.389261 -0.220224 -0.220795
+-1.388338 -0.220482 -0.077988
+-1.000043 0.345818 -0.015780
+-1.155724 0.345818 -0.015780
+-1.155724 0.212172 -0.015780
+-1.000043 0.212172 -0.015780
+-1.155724 0.345818 0.127052
+-1.000043 0.345818 0.127052
+-1.000043 0.212172 0.127052
+-1.155724 0.212172 0.127052
+-1.234192 0.212043 -0.087021
+-1.234397 0.345689 -0.086336
+-1.235319 0.345947 -0.229143
+-1.235114 0.212301 -0.229828
+-1.388133 0.211317 -0.078673
+-1.389056 0.211575 -0.221479
+-1.389261 0.345221 -0.220795
+-1.388338 0.344962 -0.077988
+-1.000043 0.911263 -0.015780
+-1.155724 0.911263 -0.015780
+-1.155724 0.777617 -0.015780
+-1.000043 0.777617 -0.015780
+-1.155724 0.911263 0.127052
+-1.000043 0.911263 0.127052
+-1.000043 0.777617 0.127052
+-1.155724 0.777617 0.127052
+-1.234192 0.777488 -0.087021
+-1.234397 0.911133 -0.086336
+-1.235319 0.911392 -0.229143
+-1.235114 0.777746 -0.229828
+-1.388133 0.776762 -0.078673
+-1.389056 0.777020 -0.221479
+-1.389261 0.910665 -0.220795
+-1.388338 0.910407 -0.077988
+1.000043 -0.785071 -0.015780
+1.000043 -0.918718 -0.015780
+1.155723 -0.918718 -0.015780
+1.155723 -0.785071 -0.015780
+1.155723 -0.785071 0.127052
+1.155723 -0.918718 0.127052
+1.000043 -0.918718 0.127052
+1.000043 -0.785071 0.127052
+1.234397 -0.785201 -0.086336
+1.234192 -0.918846 -0.087021
+1.235114 -0.918588 -0.229828
+1.235319 -0.784943 -0.229143
+1.388133 -0.919573 -0.078673
+1.388338 -0.785927 -0.077988
+1.389260 -0.785669 -0.220795
+1.389056 -0.919314 -0.221479
+1.000043 -0.219627 -0.015780
+1.000043 -0.353273 -0.015780
+1.155723 -0.353273 -0.015780
+1.155723 -0.219627 -0.015780
+1.155723 -0.219627 0.127052
+1.155723 -0.353273 0.127052
+1.000043 -0.353273 0.127052
+1.000043 -0.219627 0.127052
+1.234397 -0.219756 -0.086336
+1.234192 -0.353402 -0.087021
+1.235114 -0.353143 -0.229828
+1.235319 -0.219498 -0.229143
+1.388133 -0.354128 -0.078673
+1.388338 -0.220482 -0.077988
+1.389260 -0.220224 -0.220795
+1.389056 -0.353870 -0.221479
+1.000043 0.345818 -0.015780
+1.000043 0.212172 -0.015780
+1.155723 0.212172 -0.015780
+1.155723 0.345818 -0.015780
+1.155723 0.345818 0.127052
+1.155723 0.212172 0.127052
+1.000043 0.212172 0.127052
+1.000043 0.345818 0.127052
+1.234397 0.345689 -0.086336
+1.234192 0.212043 -0.087021
+1.235114 0.212301 -0.229828
+1.235319 0.345947 -0.229143
+1.388133 0.211317 -0.078673
+1.388338 0.344962 -0.077988
+1.389260 0.345221 -0.220795
+1.389056 0.211575 -0.221479
+1.000043 0.911263 -0.015780
+1.000043 0.777616 -0.015780
+1.155723 0.777616 -0.015780
+1.155723 0.911263 -0.015780
+1.155723 0.911263 0.127052
+1.155723 0.777616 0.127052
+1.000043 0.777616 0.127052
+1.000043 0.911263 0.127052
+1.234397 0.911133 -0.086336
+1.234192 0.777488 -0.087021
+1.235114 0.777746 -0.229828
+1.235319 0.911392 -0.229143
+1.388133 0.776762 -0.078673
+1.388338 0.910407 -0.077988
+1.389260 0.910665 -0.220795
+1.389056 0.777020 -0.221479
+4 0 1 2 3
+4 4 3 2 5
+4 5 2 1 6
+4 6 7 4 5
+4 7 0 3 4
+4 6 1 0 7
+4 8 9 10 11
+4 12 13 14 15
+4 13 8 11 14
+4 12 15 16 17
+4 10 9 18 19
+4 20 21 22 23
+4 17 16 20 23
+4 19 18 22 21
+4 24 25 26 27
+4 28 29 30 31
+4 29 24 27 30
+4 28 31 32 33
+4 26 25 34 35
+4 36 37 38 39
+4 33 32 36 39
+4 35 34 38 37
+4 40 41 42 43
+4 44 45 46 47
+4 45 40 43 46
+4 44 47 48 49
+4 42 41 50 51
+4 52 53 54 55
+4 49 48 52 55
+4 51 50 54 53
+4 56 57 58 59
+4 60 61 62 63
+4 61 56 59 62
+4 60 63 64 65
+4 58 57 66 67
+4 68 69 70 71
+4 65 64 68 71
+4 67 66 70 69
+4 72 73 74 75
+4 76 77 78 79
+4 79 78 73 72
+4 76 80 81 77
+4 74 82 83 75
+4 84 85 86 87
+4 80 85 84 81
+4 82 87 86 83
+4 88 89 90 91
+4 92 93 94 95
+4 95 94 89 88
+4 92 96 97 93
+4 90 98 99 91
+4 100 101 102 103
+4 96 101 100 97
+4 98 103 102 99
+4 104 105 106 107
+4 108 109 110 111
+4 111 110 105 104
+4 108 112 113 109
+4 106 114 115 107
+4 116 117 118 119
+4 112 117 116 113
+4 114 119 118 115
+4 120 121 122 123
+4 124 125 126 127
+4 127 126 121 120
+4 124 128 129 125
+4 122 130 131 123
+4 132 133 134 135
+4 128 133 132 129
+4 130 135 134 131

+ 39 - 0
model/convert.py

@@ -0,0 +1,39 @@
+#!/usr/bin/python
+
+import plyfile
+import argparse
+
+parser = argparse.ArgumentParser(description='Convert a PLY file to C arrays.')
+parser.add_argument('input_file', help='the input PLY file')
+parser.add_argument('output_file', help='the output C file')
+args = parser.parse_args()
+
+# Open the PLY file
+plydata = plyfile.PlyData.read(args.input_file)
+
+# Extract the vertices
+vertices = plydata['vertex'].data
+num_vertices = len(vertices)
+
+with open(args.output_file, 'w') as f:
+    f.write('#define NUM_VERTICES %d\n' % num_vertices)
+    f.write('float vertexCoords[NUM_VERTICES][3] = {\n')
+    for i in range(num_vertices):
+        x, y, z = vertices[i][0], vertices[i][1], vertices[i][2]
+        f.write('  {%f, %f, %f},\n' % (x, y, z))
+    f.write('};')
+
+    # Extract the faces
+    faces = plydata['face'].data
+    num_faces = len(faces)
+    f.write('int edgeIndices[][3] = {\n')
+    for i in range(num_faces):
+        face = faces[i][0]
+        if len(face) == 3:
+            f.write('  {%d, %d, %d},\n' % (face[0], face[1], face[2]))
+        elif len(face) == 4:
+            # Convert 4-index face to 2-index edges
+            edges = [(face[0], face[1]), (face[1], face[2]), (face[2], face[3]), (face[3], face[0])]
+            for edge in edges:
+                f.write('  {%d, %d},\n' % (edge[0], edge[1]))
+    f.write('};\n')

+ 420 - 0
model/model_chip.h

@@ -0,0 +1,420 @@
+#define NUM_VERTICES 136
+float vertexCoords[NUM_VERTICES][3] = {
+  {1.000000, 1.000000, 0.152153},
+  {-1.000000, 1.000000, 0.152153},
+  {-1.000000, -1.000000, 0.152153},
+  {1.000000, -1.000000, 0.152153},
+  {1.000000, -1.000000, -0.185787},
+  {-1.000000, -1.000000, -0.185787},
+  {-1.000000, 1.000000, -0.185787},
+  {1.000000, 1.000000, -0.185787},
+  {-1.000043, -0.785071, -0.015780},
+  {-1.155724, -0.785071, -0.015780},
+  {-1.155724, -0.918718, -0.015780},
+  {-1.000043, -0.918718, -0.015780},
+  {-1.155724, -0.785071, 0.127052},
+  {-1.000043, -0.785071, 0.127052},
+  {-1.000043, -0.918718, 0.127052},
+  {-1.155724, -0.918718, 0.127052},
+  {-1.234192, -0.918846, -0.087021},
+  {-1.234397, -0.785201, -0.086336},
+  {-1.235319, -0.784943, -0.229143},
+  {-1.235114, -0.918588, -0.229828},
+  {-1.388133, -0.919573, -0.078673},
+  {-1.389056, -0.919314, -0.221479},
+  {-1.389261, -0.785669, -0.220795},
+  {-1.388338, -0.785927, -0.077988},
+  {-1.000043, -0.219627, -0.015780},
+  {-1.155724, -0.219627, -0.015780},
+  {-1.155724, -0.353273, -0.015780},
+  {-1.000043, -0.353273, -0.015780},
+  {-1.155724, -0.219627, 0.127052},
+  {-1.000043, -0.219627, 0.127052},
+  {-1.000043, -0.353273, 0.127052},
+  {-1.155724, -0.353273, 0.127052},
+  {-1.234192, -0.353402, -0.087021},
+  {-1.234397, -0.219756, -0.086336},
+  {-1.235319, -0.219498, -0.229143},
+  {-1.235114, -0.353143, -0.229828},
+  {-1.388133, -0.354128, -0.078673},
+  {-1.389056, -0.353870, -0.221479},
+  {-1.389261, -0.220224, -0.220795},
+  {-1.388338, -0.220482, -0.077988},
+  {-1.000043, 0.345818, -0.015780},
+  {-1.155724, 0.345818, -0.015780},
+  {-1.155724, 0.212172, -0.015780},
+  {-1.000043, 0.212172, -0.015780},
+  {-1.155724, 0.345818, 0.127052},
+  {-1.000043, 0.345818, 0.127052},
+  {-1.000043, 0.212172, 0.127052},
+  {-1.155724, 0.212172, 0.127052},
+  {-1.234192, 0.212043, -0.087021},
+  {-1.234397, 0.345689, -0.086336},
+  {-1.235319, 0.345947, -0.229143},
+  {-1.235114, 0.212301, -0.229828},
+  {-1.388133, 0.211317, -0.078673},
+  {-1.389056, 0.211575, -0.221479},
+  {-1.389261, 0.345221, -0.220795},
+  {-1.388338, 0.344962, -0.077988},
+  {-1.000043, 0.911263, -0.015780},
+  {-1.155724, 0.911263, -0.015780},
+  {-1.155724, 0.777617, -0.015780},
+  {-1.000043, 0.777617, -0.015780},
+  {-1.155724, 0.911263, 0.127052},
+  {-1.000043, 0.911263, 0.127052},
+  {-1.000043, 0.777617, 0.127052},
+  {-1.155724, 0.777617, 0.127052},
+  {-1.234192, 0.777488, -0.087021},
+  {-1.234397, 0.911133, -0.086336},
+  {-1.235319, 0.911392, -0.229143},
+  {-1.235114, 0.777746, -0.229828},
+  {-1.388133, 0.776762, -0.078673},
+  {-1.389056, 0.777020, -0.221479},
+  {-1.389261, 0.910665, -0.220795},
+  {-1.388338, 0.910407, -0.077988},
+  {1.000043, -0.785071, -0.015780},
+  {1.000043, -0.918718, -0.015780},
+  {1.155723, -0.918718, -0.015780},
+  {1.155723, -0.785071, -0.015780},
+  {1.155723, -0.785071, 0.127052},
+  {1.155723, -0.918718, 0.127052},
+  {1.000043, -0.918718, 0.127052},
+  {1.000043, -0.785071, 0.127052},
+  {1.234397, -0.785201, -0.086336},
+  {1.234192, -0.918846, -0.087021},
+  {1.235114, -0.918588, -0.229828},
+  {1.235319, -0.784943, -0.229143},
+  {1.388133, -0.919573, -0.078673},
+  {1.388338, -0.785927, -0.077988},
+  {1.389260, -0.785669, -0.220795},
+  {1.389056, -0.919314, -0.221479},
+  {1.000043, -0.219627, -0.015780},
+  {1.000043, -0.353273, -0.015780},
+  {1.155723, -0.353273, -0.015780},
+  {1.155723, -0.219627, -0.015780},
+  {1.155723, -0.219627, 0.127052},
+  {1.155723, -0.353273, 0.127052},
+  {1.000043, -0.353273, 0.127052},
+  {1.000043, -0.219627, 0.127052},
+  {1.234397, -0.219756, -0.086336},
+  {1.234192, -0.353402, -0.087021},
+  {1.235114, -0.353143, -0.229828},
+  {1.235319, -0.219498, -0.229143},
+  {1.388133, -0.354128, -0.078673},
+  {1.388338, -0.220482, -0.077988},
+  {1.389260, -0.220224, -0.220795},
+  {1.389056, -0.353870, -0.221479},
+  {1.000043, 0.345818, -0.015780},
+  {1.000043, 0.212172, -0.015780},
+  {1.155723, 0.212172, -0.015780},
+  {1.155723, 0.345818, -0.015780},
+  {1.155723, 0.345818, 0.127052},
+  {1.155723, 0.212172, 0.127052},
+  {1.000043, 0.212172, 0.127052},
+  {1.000043, 0.345818, 0.127052},
+  {1.234397, 0.345689, -0.086336},
+  {1.234192, 0.212043, -0.087021},
+  {1.235114, 0.212301, -0.229828},
+  {1.235319, 0.345947, -0.229143},
+  {1.388133, 0.211317, -0.078673},
+  {1.388338, 0.344962, -0.077988},
+  {1.389260, 0.345221, -0.220795},
+  {1.389056, 0.211575, -0.221479},
+  {1.000043, 0.911263, -0.015780},
+  {1.000043, 0.777616, -0.015780},
+  {1.155723, 0.777616, -0.015780},
+  {1.155723, 0.911263, -0.015780},
+  {1.155723, 0.911263, 0.127052},
+  {1.155723, 0.777616, 0.127052},
+  {1.000043, 0.777616, 0.127052},
+  {1.000043, 0.911263, 0.127052},
+  {1.234397, 0.911133, -0.086336},
+  {1.234192, 0.777488, -0.087021},
+  {1.235114, 0.777746, -0.229828},
+  {1.235319, 0.911392, -0.229143},
+  {1.388133, 0.776762, -0.078673},
+  {1.388338, 0.910407, -0.077988},
+  {1.389260, 0.910665, -0.220795},
+  {1.389056, 0.777020, -0.221479},
+};int edgeIndices[][3] = {
+  {0, 1},
+  {1, 2},
+  {2, 3},
+  {3, 0},
+  {4, 3},
+  {3, 2},
+  {2, 5},
+  {5, 4},
+  {5, 2},
+  {2, 1},
+  {1, 6},
+  {6, 5},
+  {6, 7},
+  {7, 4},
+  {4, 5},
+  {5, 6},
+  {7, 0},
+  {0, 3},
+  {3, 4},
+  {4, 7},
+  {6, 1},
+  {1, 0},
+  {0, 7},
+  {7, 6},
+  {8, 9},
+  {9, 10},
+  {10, 11},
+  {11, 8},
+  {12, 13},
+  {13, 14},
+  {14, 15},
+  {15, 12},
+  {13, 8},
+  {8, 11},
+  {11, 14},
+  {14, 13},
+  {12, 15},
+  {15, 16},
+  {16, 17},
+  {17, 12},
+  {10, 9},
+  {9, 18},
+  {18, 19},
+  {19, 10},
+  {20, 21},
+  {21, 22},
+  {22, 23},
+  {23, 20},
+  {17, 16},
+  {16, 20},
+  {20, 23},
+  {23, 17},
+  {19, 18},
+  {18, 22},
+  {22, 21},
+  {21, 19},
+  {24, 25},
+  {25, 26},
+  {26, 27},
+  {27, 24},
+  {28, 29},
+  {29, 30},
+  {30, 31},
+  {31, 28},
+  {29, 24},
+  {24, 27},
+  {27, 30},
+  {30, 29},
+  {28, 31},
+  {31, 32},
+  {32, 33},
+  {33, 28},
+  {26, 25},
+  {25, 34},
+  {34, 35},
+  {35, 26},
+  {36, 37},
+  {37, 38},
+  {38, 39},
+  {39, 36},
+  {33, 32},
+  {32, 36},
+  {36, 39},
+  {39, 33},
+  {35, 34},
+  {34, 38},
+  {38, 37},
+  {37, 35},
+  {40, 41},
+  {41, 42},
+  {42, 43},
+  {43, 40},
+  {44, 45},
+  {45, 46},
+  {46, 47},
+  {47, 44},
+  {45, 40},
+  {40, 43},
+  {43, 46},
+  {46, 45},
+  {44, 47},
+  {47, 48},
+  {48, 49},
+  {49, 44},
+  {42, 41},
+  {41, 50},
+  {50, 51},
+  {51, 42},
+  {52, 53},
+  {53, 54},
+  {54, 55},
+  {55, 52},
+  {49, 48},
+  {48, 52},
+  {52, 55},
+  {55, 49},
+  {51, 50},
+  {50, 54},
+  {54, 53},
+  {53, 51},
+  {56, 57},
+  {57, 58},
+  {58, 59},
+  {59, 56},
+  {60, 61},
+  {61, 62},
+  {62, 63},
+  {63, 60},
+  {61, 56},
+  {56, 59},
+  {59, 62},
+  {62, 61},
+  {60, 63},
+  {63, 64},
+  {64, 65},
+  {65, 60},
+  {58, 57},
+  {57, 66},
+  {66, 67},
+  {67, 58},
+  {68, 69},
+  {69, 70},
+  {70, 71},
+  {71, 68},
+  {65, 64},
+  {64, 68},
+  {68, 71},
+  {71, 65},
+  {67, 66},
+  {66, 70},
+  {70, 69},
+  {69, 67},
+  {72, 73},
+  {73, 74},
+  {74, 75},
+  {75, 72},
+  {76, 77},
+  {77, 78},
+  {78, 79},
+  {79, 76},
+  {79, 78},
+  {78, 73},
+  {73, 72},
+  {72, 79},
+  {76, 80},
+  {80, 81},
+  {81, 77},
+  {77, 76},
+  {74, 82},
+  {82, 83},
+  {83, 75},
+  {75, 74},
+  {84, 85},
+  {85, 86},
+  {86, 87},
+  {87, 84},
+  {80, 85},
+  {85, 84},
+  {84, 81},
+  {81, 80},
+  {82, 87},
+  {87, 86},
+  {86, 83},
+  {83, 82},
+  {88, 89},
+  {89, 90},
+  {90, 91},
+  {91, 88},
+  {92, 93},
+  {93, 94},
+  {94, 95},
+  {95, 92},
+  {95, 94},
+  {94, 89},
+  {89, 88},
+  {88, 95},
+  {92, 96},
+  {96, 97},
+  {97, 93},
+  {93, 92},
+  {90, 98},
+  {98, 99},
+  {99, 91},
+  {91, 90},
+  {100, 101},
+  {101, 102},
+  {102, 103},
+  {103, 100},
+  {96, 101},
+  {101, 100},
+  {100, 97},
+  {97, 96},
+  {98, 103},
+  {103, 102},
+  {102, 99},
+  {99, 98},
+  {104, 105},
+  {105, 106},
+  {106, 107},
+  {107, 104},
+  {108, 109},
+  {109, 110},
+  {110, 111},
+  {111, 108},
+  {111, 110},
+  {110, 105},
+  {105, 104},
+  {104, 111},
+  {108, 112},
+  {112, 113},
+  {113, 109},
+  {109, 108},
+  {106, 114},
+  {114, 115},
+  {115, 107},
+  {107, 106},
+  {116, 117},
+  {117, 118},
+  {118, 119},
+  {119, 116},
+  {112, 117},
+  {117, 116},
+  {116, 113},
+  {113, 112},
+  {114, 119},
+  {119, 118},
+  {118, 115},
+  {115, 114},
+  {120, 121},
+  {121, 122},
+  {122, 123},
+  {123, 120},
+  {124, 125},
+  {125, 126},
+  {126, 127},
+  {127, 124},
+  {127, 126},
+  {126, 121},
+  {121, 120},
+  {120, 127},
+  {124, 128},
+  {128, 129},
+  {129, 125},
+  {125, 124},
+  {122, 130},
+  {130, 131},
+  {131, 123},
+  {123, 122},
+  {132, 133},
+  {133, 134},
+  {134, 135},
+  {135, 132},
+  {128, 133},
+  {133, 132},
+  {132, 129},
+  {129, 128},
+  {130, 135},
+  {135, 134},
+  {134, 131},
+  {131, 130},
+};

+ 112 - 9
swd_probe_app.c

@@ -9,6 +9,8 @@
 #include <notification/notification.h>
 #include <notification/notification_messages.h>
 
+#include <math.h>
+
 #include "swd_probe_app.h"
 #include "swd_probe_icons.h"
 #include "jep106.h"
@@ -43,7 +45,6 @@ static const char* gpio_names[] = {"PC0", "PC1", "PC3", "PB2", "PB3", "PA4", "PA
 /* bit set: clock, else data */
 static const uint8_t gpio_direction_mask[6] =
     {0b10101010, 0b01010101, 0b11001100, 0b00110011, 0b11110000, 0b00001111};
-static const uint8_t gpio_direction_ind[6] = "-\\||/-";
 
 static bool has_multiple_bits(uint8_t x) {
     return (x & (x - 1)) != 0;
@@ -442,7 +443,7 @@ static uint8_t swd_read_memory_block(
     uint32_t len) {
     uint8_t ret = 0;
     uint32_t data = 0;
-    uint32_t csw = 0x23000002;
+    uint32_t csw = 0x23000012;
 
     ret |= swd_write_ap(ctx, ap, MEMAP_CSW, csw);
     ret |= swd_write_ap(ctx, ap, MEMAP_TAR, address);
@@ -582,10 +583,13 @@ static bool swd_ensure_powerup(AppFSM* const ctx) {
         swd_read_dpbank(ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat);
         ret = false;
     }
-    DBGS(" - Fetch CTRL/STAT");
-    ctx->dp_regs.ctrlstat_ok =
-        swd_read_dpbank(ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat) == 1;
-    DBG("     %08lX %s", ctx->dp_regs.ctrlstat, ctx->dp_regs.ctrlstat_ok ? "OK" : "FAIL");
+
+    if(!ret) {
+        DBGS(" - Fetch CTRL/STAT");
+        ctx->dp_regs.ctrlstat_ok =
+            swd_read_dpbank(ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat) == 1;
+        DBG("     %08lX %s", ctx->dp_regs.ctrlstat, ctx->dp_regs.ctrlstat_ok ? "OK" : "FAIL");
+    }
 
     return ret;
 }
@@ -1541,6 +1545,105 @@ static bool swd_execute_script(AppFSM* const ctx, const char* filename) {
 
 /************************** UI functions **************************/
 
+/*
+#define NUM_EDGES 12
+#define NUM_VERTICES 8
+
+const int vertexCoords[NUM_VERTICES][3] = {
+    {-1, -1, -1},
+    {1, -1, -1},
+    {1, 1, -1},
+    {-1, 1, -1},
+    {-1, -1, 1},
+    {1, -1, 1},
+    {1, 1, 1},
+    {-1, 1, 1}};
+
+const int edgeIndices[NUM_EDGES][2] =
+    {{0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 5}, {5, 6}, {6, 7}, {7, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}};
+
+*/
+
+#define CANVAS_WIDTH 128
+#define CANVAS_HEIGHT 64
+
+#define COERCE(d, min, max) \
+    do {                    \
+        if(d < (min)) {     \
+            d = (min);      \
+        }                   \
+        if(d > (max)) {     \
+            d = (max);      \
+        }                   \
+    } while(0)
+
+#define COERCE_COORDS(x1, y1, x2, y2) \
+    do {                              \
+        COERCE(x1, 0, CANVAS_WIDTH);  \
+        COERCE(x2, 0, CANVAS_WIDTH);  \
+        COERCE(y1, 0, CANVAS_HEIGHT); \
+        COERCE(y1, 0, CANVAS_HEIGHT); \
+    } while(0)
+
+#include "model/model_chip.h"
+
+static int rotatedVertexCoords[NUM_VERTICES][3];
+
+static void draw_model(Canvas* const canvas) {
+    static float xAngle = 0;
+    static float yAngle = 0;
+    static float zAngle = 0;
+    static float zoom = 0;
+    static float speed = 0.6f;
+
+    float cosXAngle = cosf(xAngle);
+    float sinXAngle = sinf(xAngle);
+    float cosYAngle = cosf(yAngle);
+    float sinYAngle = sinf(yAngle);
+    float cosZAngle = cosf(zAngle);
+    float sinZAngle = sinf(zAngle);
+    float sinZoom = 1.2f + sinf(zoom) * 0.25f;
+
+    int centerX = CANVAS_WIDTH / 2;
+    int centerY = CANVAS_HEIGHT / 2 + 5;
+
+    for(int i = 0; i < NUM_VERTICES; i++) {
+        int x = vertexCoords[i][0] * sinZoom * 16;
+        int y = vertexCoords[i][1] * sinZoom * 16;
+        int z = vertexCoords[i][2] * sinZoom * 16;
+
+        int y1 = y * cosXAngle - z * sinXAngle;
+        int z1 = y * sinXAngle + z * cosXAngle;
+
+        int x2 = x * cosYAngle + z1 * sinYAngle;
+        int z2 = -x * sinYAngle + z1 * cosYAngle;
+
+        int x3 = x2 * cosZAngle - y1 * sinZAngle;
+        int y3 = x2 * sinZAngle + y1 * cosZAngle;
+
+        rotatedVertexCoords[i][0] = x3 + centerX;
+        rotatedVertexCoords[i][1] = y3 + centerY;
+        rotatedVertexCoords[i][2] = z2;
+    }
+
+    for(size_t i = 0; i < COUNT(edgeIndices); i++) {
+        int v1Index = edgeIndices[i][0];
+        int v2Index = edgeIndices[i][1];
+        int x1 = rotatedVertexCoords[v1Index][0];
+        int y1 = rotatedVertexCoords[v1Index][1];
+        int x2 = rotatedVertexCoords[v2Index][0];
+        int y2 = rotatedVertexCoords[v2Index][1];
+
+        COERCE_COORDS(x1, y1, x2, y2);
+        canvas_draw_line(canvas, x1, y1, x2, y2);
+    }
+
+    xAngle += speed * 0.02 / sinZoom;
+    yAngle += speed * 0.023 / sinZoom;
+    zAngle += speed * 0.029 * sinZoom;
+    zoom += speed * 0.005;
+}
+
 static void render_callback(Canvas* const canvas, void* cb_ctx) {
     AppFSM* ctx = acquire_mutex((ValueMutex*)cb_ctx, 25);
     if(ctx == NULL) {
@@ -1809,9 +1912,9 @@ static void render_callback(Canvas* const canvas, void* cb_ctx) {
         } break;
         }
     } else {
-        snprintf(
-            buffer, sizeof(buffer), "Searching... %c", gpio_direction_ind[ctx->current_mask_id]);
-        canvas_draw_str(canvas, 25, 10, buffer);
+        draw_model(canvas);
+
+        canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "Searching");
         y += 14;
 
         canvas_set_font(canvas, FontSecondary);