Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 2 commits
  • 5 files changed
  • 0 commit comments
  • 1 contributor
Showing with 67 additions and 48 deletions.
  1. +1 −1 Makefile
  2. +2 −6 README
  3. +10 −7 host_calibrate.c
  4. +46 −28 main.c
  5. +8 −6 protocol.h
View
2 Makefile
@@ -84,7 +84,7 @@
.PHONY: clean
host_calibrate: host_calibrate.c protocol.h
- $(HOST_CC) host_calibrate.c -g -o host_calibrate
+ $(HOST_CC) host_calibrate.c -g -o host_calibrate -lm
clean:
-$(RM) $(OBJECTS)
View
8 README
@@ -2,7 +2,6 @@ When your micro's main clock frequency is software configurable, why not set it
REQUIREMENTS:
-------------
-libftdi
mspgcc
mspdebug
@@ -36,15 +35,12 @@ BACKGROUND:
This is a combination of two programs, one on the host, and one on the micro, that communicate to each other to get the DCO to a target frequency.
Supported host hardware:
-FTDI USB Serial adapters
+Any Serial interface
Supported micros:
MSP430 series
-Basically you have to modify the source to set the target frequency you want. If your FTDI adapter is not based on FT230X, you will have to change the USB ID to your adapter's ID.
-
-
-This work is based on goldilocks.cpp from Rick Kimball's fabooh project
+This work is inspired by goldilocks.cpp from Rick Kimball's fabooh project
https://github.com/RickKimball/msp430_code/blob/master/fabooh/examples/serial/dco_calibrate/goldilocks.cpp
LICENSING:
View
17 host_calibrate.c
@@ -6,6 +6,7 @@
#define _BSD_SOURCE
#include <endian.h>
+#include <math.h>
#include <termios.h>
#include <string.h>
#include <stdio.h>
@@ -72,7 +73,7 @@ int xmit_recv(int fd, char* dest, char send){
int main(int argc, char **argv) {
int ret;
- unsigned baudrate = 9600;
+ unsigned baudrate = 4800;
uint32_t target_freq = 16000000;
if(argc < 2){
@@ -284,15 +285,15 @@ int main(int argc, char **argv) {
if(ret)
return ret;
- if(OUT_INCREMENT == rx){
+ if(OUT_MOD_INCREMENT == rx){
}
- else if(OUT_DECREMENT == rx){
+ else if(OUT_MOD_DECREMENT == rx){
}
else if(OUT_FINISH == rx){
/* Read dco, bcs values. */
struct {
uint32_t estimate;
- uint32_t last_diff;
+ uint32_t variance;
uint8_t dco;
uint8_t bcs;
} result;
@@ -305,9 +306,11 @@ int main(int argc, char **argv) {
}
result.estimate = le32toh(result.estimate);
- fprintf(stderr, "DCO BCS1CTL ESTIMATE ERROR\n");
- printf("%02hhx %02hhx %8u %8u\n"
- ,result.dco ,result.bcs ,result.estimate ,result.last_diff);
+ fprintf(stderr, "DCO BCS1CTL ESTIMATE VARIANCE\n");
+ printf("%02hhx %02hhx %8u %8.1lf\n"
+ ,result.dco ,result.bcs ,result.estimate ,(double)result.variance / 10.0);
+
+ fprintf(stderr, "\n\nSTDDEV: %lf\n", sqrt((double)result.variance / 10.0));
break;
}
else{
View
74 main.c
@@ -1,4 +1,5 @@
/* This file is licensed under GPL3, as a derivative work from fabooh. */
+/* Developed by Dave Bender, https://analog10.com */
#include <stdint.h>
#include <msp430.h>
@@ -6,7 +7,7 @@
/* Configuration: */
#ifndef BAUD
-#define BAUD 9600
+#define BAUD 4800
#endif
/* The loop takes 4 cycles per iteration, so divide delay by 4. */
@@ -33,6 +34,8 @@ volatile uint16_t one_count;
/* Host configured target frequency. */
uint32_t cfg_target_frequency = (360L * 44100L);
+uint32_t last_estimate = 0;
+uint16_t last_var = 0;
/* Listening state to count cycles. */
volatile uint16_t cnts[BIT_COUNT];
@@ -47,14 +50,14 @@ uint8_t state = ST_CONFIGURE;
/* Increment the dco and bcs values. */
-uint8_t increment_values(void){
+uint8_t increment_values(uint8_t last){
/* If DCO is at maximum value, increase the RSEL. */
if(dco == 0xFF){
if((bcs & 0x0F) < 0x0F){
++bcs;
dco = 0;
- return OUT_INCREMENT;
+ return OUT_MOD_INCREMENT;
}
else{
state = ST_FINISHED;
@@ -65,18 +68,18 @@ uint8_t increment_values(void){
}
else{
++dco;
- return OUT_INCREMENT;
+ return OUT_MOD_INCREMENT;
}
}
/* Decrement the dco and bcs values. */
-uint8_t decrement_values(void){
+uint8_t decrement_values(uint8_t last){
/* If DCO is at minimum value, decrease the RSEL. */
if(dco == 0x0){
if((bcs & 0x0F) > 0x0){
--bcs;
dco = 0xFF;
- return OUT_DECREMENT;
+ return OUT_MOD_DECREMENT;
}
else{
state = ST_FINISHED;
@@ -87,7 +90,7 @@ uint8_t decrement_values(void){
}
else{
--dco;
- return OUT_DECREMENT;
+ return OUT_MOD_DECREMENT;
}
}
@@ -184,22 +187,22 @@ int main(void){
* and get out of this loop. */
if(ST_FINISHED == state){
/* Frequency estimate. */
- xmit_char(estimated_freq & 0xFF);
- estimated_freq >>= 8;
- xmit_char(estimated_freq & 0xFF);
- estimated_freq >>= 8;
- xmit_char(estimated_freq & 0xFF);
- estimated_freq >>= 8;
- xmit_char(estimated_freq & 0xFF);
+ xmit_char(last_estimate & 0xFF);
+ last_estimate >>= 8;
+ xmit_char(last_estimate & 0xFF);
+ last_estimate >>= 8;
+ xmit_char(last_estimate & 0xFF);
+ last_estimate >>= 8;
+ xmit_char(last_estimate & 0xFF);
/* Estimated error from true frequency. */
- xmit_char(last_diff & 0xFF);
- last_diff >>= 8;
- xmit_char(last_diff & 0xFF);
- last_diff >>= 8;
- xmit_char(last_diff & 0xFF);
- last_diff >>= 8;
- xmit_char(last_diff & 0xFF);
+ xmit_char(last_var & 0xFF);
+ last_var >>= 8;
+ xmit_char(last_var & 0xFF);
+ last_var >>= 8;
+ xmit_char(last_var & 0xFF);
+ last_var >>= 8;
+ xmit_char(last_var & 0xFF);
/* Output the calibrated values at 9600 baud. */
xmit_char(dco);
@@ -249,6 +252,9 @@ int main(void){
case 4:
/* Reset to 0. */
cfg_target_frequency = 0;
+ last_diff = 0xFFFFFFFFL;
+ estimated_freq = 0;
+ last_var = 0;
break;
case 5:
@@ -287,6 +293,7 @@ int main(void){
/* division filters the "noise" from time difference readings. */
avg /= BIT_COUNT - 1;
+
/* Extrapolate what target frequency would be based on this sampling. */
estimated_freq = avg;
estimated_freq *= BAUD;
@@ -298,33 +305,44 @@ int main(void){
? (estimated_freq - cfg_target_frequency)
: (cfg_target_frequency - estimated_freq);
+ uint16_t var = 0;
+ for(i = 1; i < bit_indx; i++) {
+ uint16_t d = cnts[i] - cnts[i - 1];
+ d = d > avg ? d - avg : avg - d;
+ var += d * d;
+ }
+
/* Since estimate is scaled by BAUD then
* we should be able to have an error less than BAUD.
* If last estimate was better than current estimate, declare it
* the winner.
* */
- if(diff < BAUD && diff > last_diff){
+ if(last_diff < BAUD && diff > last_diff){
/* Last estimate was better, reverse what we did. */
- if(tx == OUT_INCREMENT)
- decrement_values();
- else if(tx == OUT_DECREMENT)
- increment_values();
+ if((tx & 0xF) == OUT_MOD_INCREMENT)
+ decrement_values(tx);
+ else if((tx & 0xF) == OUT_MOD_DECREMENT)
+ increment_values(tx);
else{
/* FIXME If we didn't increment or decrement, wtf did we do? */
}
+
tx = OUT_FINISH;
state = ST_FINISHED;
}
else{
last_diff = diff;
+ last_estimate = estimated_freq;
+ last_var = var;
+
/* Getting there, take action based on sign of diff. */
if(estimate_greater){
/* Slow down the DCO. */
- tx = decrement_values();
+ tx = decrement_values(tx);
}
else{
/* Speed up the DCO. */
- tx = increment_values();
+ tx = increment_values(tx);
}
}
}
View
14 protocol.h
@@ -1,10 +1,12 @@
#define OUT_START (0xee)
-#define OUT_INCREMENT (0xb0)
-#define OUT_DECREMENT (0xa0)
-#define OUT_BIG_INCREMENT (0xb0)
-#define OUT_BIG_DECREMENT (0xa0)
-#define OUT_MAX (0xb1)
-#define OUT_MIN (0xa1)
+#define OUT_MOD_INCREMENT (0xb0)
+#define OUT_MOD_DECREMENT (0xa0)
+#define OUT_DCO_INCREMENT (0xb1)
+#define OUT_DCO_DECREMENT (0xa1)
+#define OUT_RSEL_INCREMENT (0xb2)
+#define OUT_RSEL_DECREMENT (0xa2)
+#define OUT_MAX (0xbf)
+#define OUT_MIN (0xaf)
#define OUT_FINISH (0xcc)
#define OUT_RX_ACK (0xd0)
#define OUT_RX_ERR (0xe0)

No commit comments for this range

Something went wrong with that request. Please try again.