board-id scripts

This commit is contained in:
andreika-git 2022-02-07 16:28:06 +02:00
parent 5be3bdde28
commit 10c80f51ca
8 changed files with 266 additions and 0 deletions

3
board_id/board_ids.csv Normal file
View File

@ -0,0 +1,3 @@
# board_id | R1 | R2 | board_name
"0","510","510","unknown"
"1","510","620","72_NB2-e"
Can't render this file because it has a wrong number of fields in line 2.

View File

@ -0,0 +1,142 @@
#!/usr/bin/env python
############################################################################################
# Hellen-One: A new Board-ID generation script. The result is stored in 'generated' folder.
# (c) andreika <prometheus.pcb@gmail.com>
############################################################################################
import csv, sys, re
if len(sys.argv) < 2:
print ("Error! Please specify a Board+rev name.")
sys.exit(1)
boardName = sys.argv[1]
board_ids_csv = "board_ids.csv"
resistor_list_csv = "resistors.csv"
# todo: these should match used in gen_hellen_board_id_resistors.py, the firmware and mcu modules
r1 = "R133"
r2 = "R134"
r1_mult = 100
repl_csv = "generated/board_id_" + boardName + ".csv"
def getBoardIdFromResistorIndices(rIdx1, rIdx2):
global r1_mult
return rIdx1 * r1_mult + rIdx2
# board_id = R1_IDX * 100 + R2_IDX
def getResistorIndicesFromBoardId(board_id):
global r1_mult
rIdx1 = int(board_id / r1_mult)
rIdx2 = int(board_id % r1_mult)
return [rIdx1, rIdx2]
def getResistorFromIndex(idx):
global resistorList
return resistorList[idx][1]
def getIndexFromResistor(r):
global resistorList
for i,row in enumerate(resistorList):
if (int(row[1]) == r):
return i
return -1
def calcNextId(lastId, resistorList):
global numMajorResistors
[rIdx1, rIdx2] = getResistorIndicesFromBoardId(lastId)
rIdx2 += 1
# todo: add support for the minor resistor series
if (rIdx2 >= numMajorResistors):
rIdx1 += 1
rIdx2 = 0
if (rIdx1 >= numMajorResistors):
print ("The limit of Board IDs is reached! Cannot add a new Board ID.")
sys.exit(2)
newId = getBoardIdFromResistorIndices(rIdx1, rIdx2)
return newId
def addNew(boardIdList, boardId, boardName):
global resistorList, r1, r2
[rIdx1, rIdx2] = getResistorIndicesFromBoardId(boardId)
r1Value = getResistorFromIndex(rIdx1)
r2Value = getResistorFromIndex(rIdx2)
row = [boardId, r1Value, r2Value, boardName]
boardIdList.append(row)
r1Row = resistorList[rIdx1]
r2Row = resistorList[rIdx2]
repl = list()
repl.insert(0, ["# resistor | value | footprint | part_number"])
repl.append([ r1, r1Row[1], r1Row[2], r1Row[3] ])
repl.append([ r2, r2Row[1], r2Row[2], r2Row[3] ])
return repl
def readCsv(fileName):
rows = list()
with open(fileName, 'rt') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
# skip empty lines and comments (this is not strictly CSV-compliant, but useful for our purposes)
if (len(row) < 1 or row[0].startswith("#")):
continue
rows.append(row)
return rows
def saveCsv(fileName, rows):
rowIdx = 0
with open (fileName, 'wt') as new_f:
for row in rows:
if rowIdx == 0:
writer = csv.writer(new_f, quoting=csv.QUOTE_NONE, quotechar='"', delimiter=',', lineterminator='\n')
elif rowIdx == 1:
writer = csv.writer(new_f, quoting=csv.QUOTE_ALL, quotechar='"', delimiter=',', lineterminator='\n')
writer.writerow(row)
rowIdx += 1
print ("Reading board ID list from " + board_ids_csv + "...")
boardIdList = readCsv(board_ids_csv)
print ("Reading resistor list " + resistor_list_csv + "...")
resistorList = readCsv(resistor_list_csv)
numMajorResistors = 0
for row in resistorList:
# count major resistors
if (int(row[0]) == 0):
numMajorResistors += 1
print ("Searching for board IDs...")
lastId = 0
for row in boardIdList:
bid = int(row[0].strip())
r1Value = int(row[1].strip())
r2Value = int(row[2].strip())
bname = row[3].strip()
rIdx1 = getIndexFromResistor(r1Value)
rIdx2 = getIndexFromResistor(r2Value)
checkBoardId = getBoardIdFromResistorIndices(rIdx1, rIdx2)
# check integrity & validate resistors
if (rIdx1 < 0 or rIdx2 < 0 or bid != checkBoardId):
print ("Wrong boardId #" + str(bid) + " found in the stored list! Please fix the list before adding new records. Aborting...")
sys.exit(3)
# maintain uniqueness
if (bname.lower() == boardName.lower()):
print ("The board name " + boardName + " already exists in the list! Aborting...")
sys.exit(4)
if (bid > lastId):
lastId = bid
newId = calcNextId(lastId, resistorList)
print ("Created a new board id for " + boardName + ": #" + str(newId))
print ("Adding a new board id to the list...")
repl = addNew(boardIdList, newId, boardName)
print ("Saving the list...")
boardIdList.insert(0, ["# board_id | R1 | R2 | board_name"])
saveCsv(board_ids_csv, boardIdList)
print ("Saving the replacement board id file...")
saveCsv(repl_csv, repl)
print ("Done!")

View File

@ -0,0 +1,62 @@
#!/usr/bin/env python
############################################################################################
# Hellen-One: This generates the header file needed for the firmware (stored in 'generated').
# (c) andreika <prometheus.pcb@gmail.com>
############################################################################################
import csv, sys, re, datetime
resistor_list_csv = "resistors.csv"
resistors_h = "generated/hellen_board_id_resistors.h"
#todo: maybe make capacitance & board-id multiplier configurable?
capacitance = 1.0
r1_mult = 100
def read_csv(fileName):
rows = list()
with open(fileName, 'rt') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
# skip empty lines and comments (this is not strictly CSV-compliant, but useful for our purposes)
if (len(row) < 1 or row[0].startswith("#")):
continue
rows.append(row)
return rows
date_time = datetime.datetime.now()
# flag, value, footprint, LCSC #
rows = read_csv(resistor_list_csv)
major = list()
minor = list()
for row in rows:
# (flag = 0(major)/1(minor))
flag = int(row[0])
value = int(row[1])
if (flag == 1):
minor.append(value)
else:
major.append(value)
majorLastIdx = len(major) - 1
minorLastIdx = len(minor) - 1
majorAndMinorLastIdx = len(major) + len(minor) - 1
numBoardIds = len(major) * (len(major) + len(minor))
with open(resistors_h, 'wt') as f:
f.write("//\n// was generated automatically by Hellen Board-ID generation tool gen_hellen_board_id_resistors.py " + str(date_time) + "\n//\n\n")
f.write("#pragma once\n")
f.write("\n// major_idx = 0.." + str(majorLastIdx) + "\n")
f.write("#define HELLEN_BOARD_ID_MAJOR_RESISTORS\t")
for m in major:
f.write(str(m) + ", ")
f.write("\n\n// minor_idx = 0.." + str(minorLastIdx) + "\n")
f.write("#define HELLEN_BOARD_ID_MINOR_RESISTORS\t")
for m in minor:
f.write(str(m) + ", ")
f.write("\n\n// C = " + str(capacitance) + "uF\n")
f.write("#define HELLEN_BOARD_ID_CAPACITOR " + str(capacitance) + "f\n")
f.write("\n// R1_IDX = 0.." + str(majorLastIdx) + ", R2_IDX = 0.." + str(majorAndMinorLastIdx) + " (max. " + str(numBoardIds) + " boardIds)\n")
f.write("#define HELLEN_GET_BOARD_ID(R1_IDX, R2_IDX) ((R1_IDX) * " + str(r1_mult) + " + (R2_IDX))\n")

View File

@ -0,0 +1,3 @@
# resistor | value | footprint | part_number
"R133","510","R0603","C23193"
"R134","620","R0603","C23220"
Can't render this file because it has a wrong number of fields in line 2.

View File

@ -0,0 +1,3 @@
# resistor | value | footprint | part_number
"R133","510","R0603","C23193"
"R134","510","R0603","C23193"
Can't render this file because it has a wrong number of fields in line 2.

View File

@ -0,0 +1,17 @@
//
// was generated automatically by Hellen Board-ID generation tool gen_hellen_board_id_resistors.py 2022-02-07 12:25:30.654958
//
#pragma once
// major_idx = 0..15
#define HELLEN_BOARD_ID_MAJOR_RESISTORS 510, 620, 750, 1000, 1200, 1500, 1800, 2200, 2700, 3300, 3900, 4700, 5600, 6800, 8200, 10000,
// minor_idx = 0..11
#define HELLEN_BOARD_ID_MINOR_RESISTORS 560, 680, 820, 1100, 2000, 2400, 3000, 3600, 4300, 5100, 6200, 7500,
// C = 1.0uF
#define HELLEN_BOARD_ID_CAPACITOR 1.0f
// R1_IDX = 0..15, R2_IDX = 0..27 (max. 448 boardIds)
#define HELLEN_GET_BOARD_ID(R1_IDX, R2_IDX) ((R1_IDX) * 100 + (R2_IDX))

31
board_id/resistors.csv Normal file
View File

@ -0,0 +1,31 @@
# The order of resistors is extremely important and should correspond to board ID indices
# major series: 0(major)/1(minor) flag, value, footprint, LCSC #
0,510,"R0603","C23193"
0,620,"R0603","C23220"
0,750,"R0603","C23241"
0,1000,"R0603","C21190"
0,1200,"R0603","C22765"
0,1500,"R0603","C22843"
0,1800,"R0603","C4177"
0,2200,"R0603","C4190"
0,2700,"R0603","C13167"
0,3300,"R0603","C22978"
0,3900,"R0603","C23018"
0,4700,"R0603","C23162"
0,5600,"R0603","C23189"
0,6800,"R0603","C23212"
0,8200,"R0603","C25981"
0,10000,"R0603","C25804"
# minor series (todo: currently not used...)
1,560,"R0603","C23204"
1,680,"R0603","C23228"
1,820,"R0603","C23253"
1,1100,"R0603","C22764"
1,2000,"R0603","C22975"
1,2400,"R0603","C22940"
1,3000,"R0603","C4211"
1,3600,"R0603","C22980"
1,4300,"R0603","C23159"
1,5100,"R0603","C23186"
1,6200,"R0603","C4260"
1,7500,"R0603","C23234"
Can't render this file because it has a wrong number of fields in line 2.

5
board_id/test.sh Normal file
View File

@ -0,0 +1,5 @@
#!/bin/bash
#python3 gen_hellen_board_id_resistors.py
python3 gen_hellen_board_id.py 72_NB2-e