summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2014-09-13 20:29:11 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2014-09-13 20:29:11 +0200
commit0a618e37524a948ff78b5aa0d0d924176c7e6ebb (patch)
treee3d5cd565ae6598c9f183ba630fbc8c6c197f99c
parent3456c9e10432dd70cd1ec2f82a6a3cc19f009a15 (diff)
Tool for calculating the I2S clock register values.
-rw-r--r--tools/Makefile4
-rw-r--r--tools/clkcalc.c91
2 files changed, 95 insertions, 0 deletions
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100644
index 0000000..3cb72c9
--- /dev/null
+++ b/tools/Makefile
@@ -0,0 +1,4 @@
+all: clkcalc
+
+clkcalc: clkcalc.c
+ gcc clkcalc.c -o clkcalc \ No newline at end of file
diff --git a/tools/clkcalc.c b/tools/clkcalc.c
new file mode 100644
index 0000000..2829ca9
--- /dev/null
+++ b/tools/clkcalc.c
@@ -0,0 +1,91 @@
+#include <stdio.h>
+
+double _fabs(double a)
+{
+ return a<0?a*-1:a;
+}
+
+typedef struct {
+ int pclkdiv_idx;
+ int bitrate;
+ int x;
+ int y;
+ double err;
+} result_t;
+
+static const int pclkdiv[] = { 1, 2, 4, 8 };
+
+
+int main(int argc, char *argv[])
+{
+ result_t best;
+ best.err = 999999;
+
+ if(argc < 3) {
+ printf("Usage: %s samplerate bitwidth channelcount\n", argv[0]);
+ printf("Example: 48KHz 16bit stereo\n");
+ printf("%s 48000 16 2\n", argv[0]);
+ return 1;
+ }
+
+ int fs = atoi(argv[1]);
+ int bw = atoi(argv[2]);
+ int ch = atoi(argv[3]);
+
+ int target = fs * bw * ch;
+
+ int cclk = 100000000;
+
+ result_t res;
+ res.pclkdiv_idx = 0;
+
+ res.bitrate = 0;
+ res.x = 1;
+ res.y = 1;
+
+ for(;res.pclkdiv_idx < 4; res.pclkdiv_idx++) {
+
+ double clk = (cclk / pclkdiv[res.pclkdiv_idx]);
+
+ for(res.y = 1; res.y < 256; res.y++) {
+
+ double clk_y = clk / (double)res.y;
+
+ for(res.x = 1; res.x < 256; res.x++) {
+
+ double clk_y_x_2 = (clk_y * (double)res.x) / 2.0;
+
+ for(res.bitrate = 0; res.bitrate < 65; res.bitrate++) {
+
+ double val = clk_y_x_2 / ((double)res.bitrate + 1.0);
+
+ res.err = _fabs(val - target);
+ if(res.err < best.err) best = res;
+
+ if(res.err == 0.0) {
+ goto found;
+ }
+ }
+ }
+ }
+ }
+
+ goto not_found;
+
+ found:
+ printf("Found:\n");
+ printf(" pclkdiv: %d\n", pclkdiv[res.pclkdiv_idx]);
+ printf(" bitrate: %d\n", res.bitrate);
+ printf(" x: %d\n", res.x);
+ printf(" y: %d\n", res.y);
+ return 0;
+
+ not_found:
+ printf("Not found - best was:\n");
+ printf(" pclkdiv: %d\n", pclkdiv[best.pclkdiv_idx]);
+ printf(" bitrate: %d\n", best.bitrate);
+ printf(" x: %d\n", best.x);
+ printf(" y: %d\n", best.y);
+ printf(" err: %f\n", best.err);
+ return 1;
+}