imrishabh18/pedometer
This code defines and assembles a simple radio receiver hardware circuit using specific imported capacitors, inductors, RF connectors, and oscillator components with precise footprints and schematic attributes.
- Version
- 1.1.3
- License
- unset
- Stars
- 0
tests/bare-mcu.test.ts
import { expect, test } from "bun:test";
import { readFileSync } from "node:fs";
const c: any[]=JSON.parse(readFileSync("dist/index/circuit.json","utf8"));
const component=(name:string)=>c.find(e=>e.type==="source_component"&&e.name===name);
const port=(name:string,pin:number)=>c.find(e=>e.type==="source_port"&&e.source_component_id===component(name).source_component_id&&e.pin_number===pin);
const netOf=(name:string,pin:number)=>{
const id=port(name,pin)?.source_port_id;
const t=c.find(e=>e.type==="source_trace"&&e.connected_source_port_ids.includes(id));
return c.find(e=>e.type==="source_net"&&t?.connected_source_net_ids.includes(e.source_net_id))?.name;
};
test("bare RGE package has the TI pinout with separate internal supply rails",()=>{
expect(component("M1")).toBeUndefined();
expect(component("U1").manufacturer_part_number).toBe("CC2340R52E0RGER");
expect(component("U1").supplier_part_numbers.jlcpcb).toContain("C20416850");
const assignments:Record<number,string>={1:"RF_IC",2:"MCU_VDDR",3:"I2C_SDA",4:"PMIC_LP",5:"ACCEL_INT",6:"CHARGER_INT",7:"SWDIO",8:"SWCLK",9:"DISPLAY_ISOLATE",10:"GAUGE_INT",11:"VDD_2V5",12:"BUTTON_N",13:"RESET_N",14:"LF_P",15:"LF_N",16:"MCU_VDDD",17:"MCU_DCDC",18:"VDD_2V5",19:"I2C_SCL",20:"MCU_VDDR",21:"HF_P",22:"HF_N",23:"GND",24:"VDD_2V5",25:"GND"};
for(const [p,n] of Object.entries(assignments))expect(netOf("U1",Number(p))).toBe(n);
expect(netOf("L1",1)).toBe("MCU_DCDC");expect(netOf("L1",2)).toBe("MCU_VDDR");
expect(component("L1").inductance).toBe("10uH");
expect(netOf("C21",1)).toBe("MCU_VDDR");expect(netOf("C23",1)).toBe("MCU_VDDD");
expect(component("C21").capacitance).toBeCloseTo(10e-6,10);
expect(component("C23").capacitance).toBeCloseTo(1e-6,10);
});
test("radio clock, filter and antenna anchoring match the selected parts",()=>{
expect(component("Y2").ftype).toBe("simple_crystal");
expect(component("Y2").frequency).toBe(48e6);
expect(component("Y2").load_capacitance).toBeCloseTo(8e-12,14);
expect(netOf("Y2",1)).toBe("HF_P");expect(netOf("Y2",3)).toBe("HF_N");
for(const pin of [2,4])expect(netOf("Y2",pin)).toBe("GND");
expect(component("L2").inductance).toBe("2.8nH");
for(const ref of ["C26","C27"]){expect(component(ref).capacitance).toBeCloseTo(1.5e-12,14);expect(netOf(ref,2)).toBe("GND");}
expect(netOf("ANT1",1)).toBe("RF_ANT");expect(netOf("ANT1",2)).toBeUndefined();
expect(netOf("R14",1)).toBe("VDD_2V5");expect(netOf("R14",2)).toBe("RESET_N");expect(netOf("C24",1)).toBe("RESET_N");
});
test("RF and crystal connections are fully routed on top without vias",()=>{
const critical=new Set(c.filter(e=>e.type==="source_net"&&(/^(RF_|HF_|LF_)/).test(e.name)).map(e=>e.source_net_id));
const sources=c.filter(e=>e.type==="source_trace"&&e.connected_source_net_ids.some((n:string)=>critical.has(n)));
const ids=new Set(sources.map(e=>e.source_trace_id));
const routes=c.filter(e=>e.type==="pcb_trace"&&ids.has(e.source_trace_id));
expect(routes.length).toBeGreaterThan(8);
for(const t of routes)for(const p of t.route){expect(p.route_type).toBe("wire");expect(p.layer).toBe("top");}
expect(c.filter(e=>e.type.endsWith("_error"))).toHaveLength(0);
expect(c.filter(e=>e.type==="schematic_sheet")).toHaveLength(5);
const board=c.find(e=>e.type==="pcb_board");
expect([board.width,board.height]).toEqual([40,38]);
const gnd=c.find(e=>e.type==="source_net"&&e.name==="GND").source_net_id;
expect(c.filter(e=>e.type==="pcb_trace"&&e.connection_name!==gnd).flatMap(t=>t.route).filter(p=>p.route_type==="wire"&&p.layer==="inner1")).toHaveLength(0);
const rf=new Set(c.filter(e=>e.type==="source_net"&&e.name.startsWith("RF_")).map(e=>e.source_net_id));
for(const t of c.filter(e=>e.type==="pcb_trace"&&rf.has(e.connection_name))){
for(const p of t.route)if(p.route_type==="wire")expect(p.width).toBeCloseTo(0.2,6);
const length=t.route.slice(1).reduce((sum:number,p:any,i:number)=>sum+Math.hypot(p.x-t.route[i].x,p.y-t.route[i].y),0);
expect(length).toBeLessThan(6);
}
});