component
STM32F103C8T6 - Arm Cortex-M3 MCU (Blue Pill)
Public Made by Adomby adom
STMicroelectronics mainstream Arm Cortex-M3 MCU. 72 MHz, 64 KB Flash, 20 KB SRAM, USB, CAN, LQFP-48. The workhorse Blue Pill microcontroller.
← Commit history
pinout: keep every pin inside the body, and make the JSON button work
Two fixes that shipped in adom-widget on Aug 24 (28e23c3) but never reached this
page, because sections/pinout.html carries its own inline copy of the widget.
The corner overhang: the pin run was distributed across the full inner..outer
span while the body is drawn inset from the outermost pins, so the first and
last pin of every side landed 4.33px past the corner and crossed its neighbour
(1 into 48, 12 into 13, 24 into 25, 36 into 37). Measured on this page: body
spans 76..324, the pin run spanned 71.67..328.33. With the corner keep-out the
run is 95.5..304.5, inside the body on every side.
The JSON button: it built a blob: URL, and this renders inside the readme's
sandboxed frame whose CSP has no blob:, so the button did nothing and said
nothing. Now a data: URL, verified to produce 8769 chars instead of a refused
46-char blob: href.
1 file changed
+20−10
sections/pinout.html+20−10@@ -314,22 +314,30 @@ body{margin:0;padding:4px 0 10px;background:transparent; return { ...p, x, y, side }; }); } else {+ // The body is drawn inset from the outermost pins, so a run distributed+ // across the whole inner..outer span puts the FIRST and LAST pin of each+ // side OUTSIDE the body: at 12 per side they land 4.3px past each corner+ // and cross the end pin of the neighbouring side (1 into 48, 12 into 13,+ // 24 into 25, 36 into 37). Real quad packages have a corner keep-out+ // anyway, which is why the explicit-xy path never showed this. Inset the+ // run to match the body. Ported from adom-widget 28e23c3. const N = edge.length, inner = pad, outer = S - pad, at = (a, b, t) => a + (b - a) * t;+ const CORNER = 26, runLo = inner + CORNER, runHi = outer - CORNER; const quad = forced === 'quad' || (forced !== 'dual' && /QF|BGA|LGA|LCC|QFN|QFP/i.test(pkg || '')); if (quad) { const per = Math.ceil(N / 4); laid = edge.map((p, i) => { const s = Math.floor(i / per), t = ((i % per) + 0.5) / per;- if (s === 0) return { ...p, x: inner, y: at(inner, outer, t), side: 'left' };- if (s === 1) return { ...p, x: at(inner, outer, t), y: outer, side: 'bottom' };- if (s === 2) return { ...p, x: outer, y: at(outer, inner, t), side: 'right' };- return { ...p, x: at(outer, inner, t), y: inner, side: 'top' };+ if (s === 0) return { ...p, x: inner, y: at(runLo, runHi, t), side: 'left' };+ if (s === 1) return { ...p, x: at(runLo, runHi, t), y: outer, side: 'bottom' };+ if (s === 2) return { ...p, x: outer, y: at(runHi, runLo, t), side: 'right' };+ return { ...p, x: at(runHi, runLo, t), y: inner, side: 'top' }; }); } else { const half = Math.ceil(N / 2); // DIP-style: left top→bottom, right bottom→top laid = edge.map((p, i) => i < half- ? { ...p, x: inner, y: at(inner, outer, (i + 0.5) / half), side: 'left' }- : { ...p, x: outer, y: at(outer, inner, (i - half + 0.5) / (N - half)), side: 'right' });+ ? { ...p, x: inner, y: at(runLo, runHi, (i + 0.5) / half), side: 'left' }+ : { ...p, x: outer, y: at(runHi, runLo, (i - half + 0.5) / (N - half)), side: 'right' }); } } centers.forEach(p => laid.push({ ...p, x: mid, y: mid, side: 'center' }));@@ -459,10 +467,12 @@ body{margin:0;padding:4px 0 10px;background:transparent; _exportJson() { return JSON.stringify(this.toJSON(), null, 2); } _exportName() { const d = this._data || {}; return ((d.mpn || 'pinout') + (d.package ? '-' + d.package : '')).replace(/[^\w.-]+/g, '_') + '.pins.json'; } _download() {- const blob = new Blob([this._exportJson()], { type: 'application/json' });- const url = URL.createObjectURL(blob), a = document.createElement('a');- a.href = url; a.download = this._exportName(); document.body.appendChild(a); a.click();- a.remove(); setTimeout(() => URL.revokeObjectURL(url), 1000);+ // data:, not blob:. This renders inside the readme's sandboxed frame,+ // whose CSP carries no blob:, so createObjectURL was refused and the+ // button did nothing at all without saying so.+ const a = document.createElement('a');+ a.href = 'data:application/json;charset=utf-8,' + encodeURIComponent(this._exportJson());+ a.download = this._exportName(); document.body.appendChild(a); a.click(); a.remove(); } async _copy(btn) { const txt = this._exportJson(), done = () => { if (!btn) return; const o = btn.textContent; btn.textContent = 'copied'; btn.classList.add('ok'); setTimeout(() => { btn.textContent = o; btn.classList.remove('ok'); }, 1100); };