
Macdweller wrote a step by step tutorial on making Cadsoft Eagle footprints for any Microchip device, like PIC microcontrollers, using the Ultra Librarian app to generate footprints automatically.
Via the forum.

Macdweller wrote a step by step tutorial on making Cadsoft Eagle footprints for any Microchip device, like PIC microcontrollers, using the Ultra Librarian app to generate footprints automatically.
Via the forum.
Ultra Librarian is not a Microchip app, its developed by Accelerated-Designs. Other IC vendors like SiliconLaboratories have been providing footpints in .bxl format for years already.
http://www.silabs.com/support/Pages/CAD-CAE-Schematic-Footprints-and-Symbols.aspx
Thanks, sorry for the mishap
I think Analog Devices uses that software as well.
Ultra Librarian is a pretty spendy piece of software, not for the casual/hobbyist user.
Search on the web for a copy of LPC (Land Pad Calculator) from Valor,
before it was bought by Mentor (there are early, but functional copies out there).
It allows you to type in all the numbers from a datasheet and generate a footprint.
Looks like Microchip’s version is free as long as you use it with their stuff…
It’s expensive only if you want to create new vendor neutral bxl files. Most of us will most probably just want to create eagle/Altium footprints from already existing bxl files.
The Ultra Librarian version that you can download from Silabs is free and you can use it with any bxl file (even microchip’s bxl files), but you can’t create new bxl files.
The bxl file format is decodable. The first four bytes contain he encoded original file length. Next follows a Huffman encoded ASCII file.
Hi Geert! Do you have more info on BXL file format? I’m especially interested in the Huffman encoding scheme you mentioned. (Or rather its decoding:-)). You can reach me at stick (at) gk2.sk. Thanks!
Just to see what would happen, I threw together a quick extractor attempt using Ruby.
Sure, maybe the rest of the file is using Huffman encoding, but without knowing more about the compression scheme, you’ll get nothing but noise out of the thing.
I know this is an old thread, but, Geert, how do you know it’s huffman encoded? Can you share any more information about the encoding scheme?
This is the code I have lying around:
namespace bxl {
public class Decoder {
static uchar[] source_buffer;
public bool is_filled { get; private set; default = false; }
public int max_level { get; private set; default = 8; }
public int node_count { get; private set; default = -1; }
public int leaf_count { get; set; default = 0; }
public int level { get; private set; default = 0; }
public Node root { get; private set; default = null; }
protected class Node {
public int level { get; private set; default = 0; }
public Node parent { get; set; default = null; }
public Node left { get; set; default = null; }
public Node right { get; set; default = null; }
public int symbol { get; private set; default = -1; }
public int weight { get; set; default = 0; }
public Node (Node? parent, int symbol) {
if (parent != null) {
this.parent = parent;
this.level = parent.level+1;
} else {
this.level = 0;
}
if (level > 7) {
this.symbol = symbol;
}
}
public Node? add_child(int symbol){
Node ret = null;
if (level 7);
}
public Node? sibling(Node node){
if (node != right) {
return right;
} else {
return left;
}
}
public bool need_swapping() {
if (parent != null &&
parent.parent != null && // root node
weight > parent.weight) {
return true;
}
return false;
}
}
public Decoder (string filename) {
create_tree();
fill_buffer(filename);
}
private int read_next_bit(ref int source_index, ref int source_char, ref int bit) {
int result = 0;
if (bit < 0) {
// Fetch next byte from source_buffer
bit = 7;
source_char = source_buffer[source_index];
result = source_char & (1 << bit);
source_index ++;
} else {
result = source_char & (1 << bit);
}
bit–;
return result;
}
private void swap (Node n1, Node n2, Node? n3) {
if (n3 != null) { n3.parent = n1;}
if (n1.right == n2) { n1.right = n3; return; }
if (n1.left == n2) { n1.left = n3; return; }
}
private void create_tree() {
// create root node
var node = new Node (null, 0);
root = node;
// fill levels
while(node != null) {
node = root.add_child(leaf_count);
if(node != null && node.is_leaf()) { leaf_count++; }
}
}
private void update_tree(Node? current) {
if (current != null && current.need_swapping()) {
var parent = current.parent;
var grand_parent = parent.parent;
var parent_sibling = grand_parent.sibling(parent);
swap(grand_parent, parent, current);
swap(grand_parent, parent_sibling, parent);
swap(parent, current, parent_sibling);
parent.weight = parent.right.weight + parent.left.weight;
grand_parent.weight = current.weight + parent.weight;
update_tree(parent);
update_tree(grand_parent);
update_tree(current);
}
}
private int uncompressed_size () {
/* Uncompressed size =
B0b7 * 1<<0 + B0b6 * 1<<1 + … + B0b0 * 1<<7 +
B1b7 * 1<<0 + B1b6 * 1<<1 + … + B2b0 * 1<<7 +
B2b7 * 1<<0 + B2b6 * 1<<1 + … + B3b0 * 1<<7 +
B3b7 * 1<<0 + B3b6 * 1<<1 + … + B4b0 * 1<=0 ; i–) {
if ((source_buffer[0] & (1 << i)) != 0) {
size |= (1 <=0 ; i–) {
if ((source_buffer[1] & (1 << i)) != 0) {
size |= (1<=0 ; i–) {
if ((source_buffer[2] & (1 << i)) != 0) {
size |= (1<=0 ; i–) {
if ((source_buffer[3] & (1 << i)) != 0) {
size |= (1<<mask);
}
mask++;
}
return size;
}
public string decode() {
var out_file_length = uncompressed_size ();
var source_char = 0;
var bit = 0;
var source_index = 4;
var sb = new StringBuilder();
while (source_index < source_buffer.length && sb.len != out_file_length) {
var node = root;
while (!node.is_leaf()) {
// find leaf node
if (read_next_bit(ref source_index, ref source_char, ref bit) != 0) {
node = node.left;
} else {
node = node.right;
}
}
sb.append_c ((char)(node.symbol&0xff));
node.weight+=1;
update_tree(node);
}
source_buffer = null;
is_filled = false;
return sb.str;
}
public int fill_buffer(string filename) {
try {
var file = File.new_for_path (filename);
var file_info = file.query_info ("*", FileQueryInfoFlags.NONE);
source_buffer = new uchar[file_info.get_size ()];
var file_stream = file.read ();
size_t read = 0;
file_stream.read_all(source_buffer, out read, null);
if ( read == source_buffer.length) {
is_filled = true;
}
} catch (FileError e) {
stderr.printf ("FileError: %s\n", e.message);
return 1;
} catch (Error e) {
stderr.printf ("Error: %d %s\n", e.code, e.message);
return 1;
}
return 0;
}
}
}
Looks like the comment system garbled the code, e.g. truncated code at the start of uncompressed_size.
Do you have a link to a public repository (e.g. Github)? Or do you mind posting it in the Dangerous Prototypes forum?
http://users.telenet.be/geert.jordaens/geda.tgz
Sorry wrong code. The code your looking for is in decoder.vala contained in http://users.telenet.be/geert.jordaens/bxl_20140717.tar.gz
Thanks!
Did you manage to get this to work Adrain?
Geert does this code work?
At least the decoder works. I tried it on a few files, just dumping the plain text into a file.
I also tried to port it to Python, without much luck though.
It worked in 2014, for sure some bindings have changed. I generated a pile of symbols with it.
Hi Geert,
I successfully ported your vala huffman decoding algorithm to java.
Have you thought about a distribution and usage licence for your vala code and the tarballed symbols?
Would you mind if the symbols were put on gedasymbols.org with suitable attributions and licencing?
Cheers,
Erich.
Well, for those using gEDA, there is now a utility to convert BXL schematic symbols and footprints to gEDA compatible formats.
https://github.com/erichVK5/BXL2text
Thanks to Geert for publishing code that implements the adaptive Huffman Decoding.
For anyone interested, I’ve added some c++ code for adaptive huffman decoding in the git repository.
I’m not sure what kind of licensing I have to add since it is a fairly straight forward implementation of the adaptive Huffman Decoding. For the work I put in I’m happy with any lincensing that is compatible with the gEDA initiative.