Permalink
Browse files

refactoring and target frequency is now settable at runtime

  • Loading branch information...
codehero committed Sep 30, 2013
1 parent 91531d0 commit 346a45a2c0cd83e3daf39a7f9f0dab168944d0ce
Showing with 426 additions and 89 deletions.
  1. +2 −2 Makefile
  2. +269 −41 host_calibrate.c
  3. +145 −46 main.c
  4. +10 −0 protocol.h
View
@@ -83,8 +83,8 @@
.SILENT:
.PHONY: clean
- host_calibrate: host_calibrate.c
- $(HOST_CC) host_calibrate.c -g -o host_calibrate -lftdi
+ host_calibrate: host_calibrate.c protocol.h
+ $(HOST_CC) host_calibrate.c -g -o host_calibrate
clean:
-$(RM) $(OBJECTS)
View
@@ -1,96 +1,324 @@
-/* License: Public domain. */
+/* License: Public domain.
+ *
+ * A free product developed by analog10 (http://analog10.com)
+ * Check it out!
+ * */
+
+#define _BSD_SOURCE
+#include <endian.h>
+#include <termios.h>
+#include <string.h>
#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
+#include <errno.h>
#include <signal.h>
-#include <ftdi.h>
+#include <poll.h>
+
+#include "protocol.h"
+
+enum {
+ FIVE_ONES = 0x55
+ ,FOUR_ONES = 0x15
+ ,THREE_ONES = 0x05
+ ,TWO_ONES = 0x01
+ ,ONE_ONE = 0x00
+};
static int keep_running = 1;
void sig_handler(int signum) {
keep_running = 0;
}
+int xmit_recv(int fd, char* dest, char send){
+ fprintf(stderr, "TX : %02hhx\n", send);
+
+ write(fd, &send, 1);
+
+ /* Wait for ack or err. */
+
+ struct pollfd pfd;
+ pfd.events = POLLIN;
+ pfd.fd = fd;
+
+ /* Wait 500 ms for response. */
+ int ret = poll(&pfd, 1, 1000);
+ if(-1 == ret){
+ fprintf(stderr, "err poll: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if(0 == ret){
+ fprintf(stderr, "timed out...\n");
+ return -2;
+ }
+
+ ret = read(fd, dest, 1);
+ if(-1 == ret){
+ fprintf(stderr, "read err: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if(OUT_RX_ERR == (*dest & 0xF0)){
+ fprintf(stderr, "recv err: %02hhx\n", *dest);
+ return -3;
+ }
+
+ fprintf(stderr, "RX : %02hhx\n", *dest);
+ return 0;
+}
+
int main(int argc, char **argv) {
- struct ftdi_context *ftdi;
int ret;
unsigned baudrate = 9600;
+ uint32_t target_freq = 16000000;
+
+ if(argc < 2){
+ fprintf(stderr, "Usage: TTY_DEV_NODE [BAUD_RATE] [TARGET_FREQUENCY] \n");
+ return 1;
+ }
/* Get the baudrate from the command line. */
- if(argc > 1){
+ if(argc > 2){
char* endptr;
- baudrate = strtoul(argv[1], &endptr, 0);
+ baudrate = strtoul(argv[2], &endptr, 0);
if(*endptr){
fprintf(stderr, "err invalid baud rate parameter\n");
return 1;
}
}
- if((ftdi = ftdi_new()) == 0){
- fprintf(stderr, "err ftdi_new\n");
+ if(argc > 3){
+ char* endptr;
+ target_freq = strtoul(argv[3], &endptr, 0);
+ if(*endptr || !target_freq){
+ fprintf(stderr, "err invalid target frequency parameter\n");
+ return 1;
+ }
+ }
+
+ int fd = open(argv[1], O_RDWR);
+ struct termios ser_options;
+ ret = tcgetattr(fd, &ser_options);
+ if(ret < 0){
+ fprintf(stderr, "err tcgetattr: %s\n", strerror(errno));
return 1;
}
- // Select interface
- ftdi_set_interface(ftdi, INTERFACE_ANY);
+ /* Set Baud speed. */
+ switch(baudrate){
+ case 50:
+ baudrate = B50;
+ break;
- /* Using FT230X here, obtained from lsusb. */
- ret = ftdi_usb_open(ftdi, 0x403, 0x6015);
+ case 75:
+ baudrate = B75;
+ break;
+ case 110:
+ baudrate = B110;
+ break;
+
+ case 134:
+ baudrate = B134;
+ break;
+
+ case 150:
+ baudrate = B150;
+ break;
+
+ case 200:
+ baudrate = B200;
+ break;
+
+ case 300:
+ baudrate = B300;
+ break;
+
+ case 600:
+ baudrate = B600;
+ break;
+
+ case 1200:
+ baudrate = B1200;
+ break;
+
+ case 1800:
+ baudrate = B1800;
+ break;
+
+ case 2400:
+ baudrate = B2400;
+ break;
+
+ case 4800:
+ baudrate = B4800;
+ break;
+
+ case 9600:
+ baudrate = B9600;
+ break;
+
+ case 19200:
+ baudrate = B19200;
+ break;
+
+ case 38400:
+ baudrate = B38400;
+ break;
+
+ case 57600:
+ baudrate = B57600;
+ break;
+
+ case 115200:
+ baudrate = B115200;
+ break;
+
+ case 230400:
+ baudrate = B230400;
+ break;
+
+ default:
+ fprintf(stderr, "err bad baudrate\n");
+ return 1;
+ }
+
+ ret = cfsetispeed(&ser_options, baudrate);
+ if(ret < 0){
+ fprintf(stderr, "err cfsetispeed: %s\n", strerror(errno));
+ return 1;
+ }
+
+ ret = cfsetospeed(&ser_options, baudrate);
if(ret < 0){
- fprintf(stderr, "err opening : %i %s\n", ret, ftdi_get_error_string(ftdi));
+ fprintf(stderr, "err cfsetospeed: %s\n", strerror(errno));
return 1;
}
- // Set baudrate
- ret = ftdi_set_baudrate(ftdi, baudrate);
+ /* Setup for raw binary comms. */
+ cfmakeraw(&ser_options);
+
+ /* Reset options for communications. */
+ ser_options.c_cflag &= ~(PARODD | PARENB | CS5 | CS6 | CS7 | CS8 | CSTOPB);
+
+ ret = tcsetattr(fd, TCSAFLUSH, &ser_options);
if(ret < 0){
- fprintf(stderr, "err set baudrate: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
+ fprintf(stderr, "err tcsetattr: %s\n", strerror(errno));
return 1;
}
signal(SIGINT, sig_handler);
- uint8_t output = 0x55;
- while(keep_running){
- /* Wait for init packet. */
- uint8_t rx;
- ret = ftdi_read_data(ftdi, &rx, 1);
- if(ret < 0){
- fprintf(stderr, "Read error");
- return 1;
+ /* Shift frequency up to its MSB.
+ * Reset the frequency register and assign the value. */
+ unsigned bits_remaining = 32;
+ while(!(target_freq & 0x80000000)){
+ target_freq <<= 1;
+ --bits_remaining;
+ }
+
+ /* Empty RX buffer. */
+ {
+ uint8_t buffer[1024];
+ struct pollfd pfd;
+ pfd.events = POLLIN;
+ pfd.fd = fd;
+ ret = 1024;
+ while(1024 == ret){
+ ret = poll(&pfd, 1, 500);
+ if(-1 == ret){
+ fprintf(stderr, "err poll: %s\n", strerror(errno));
+ return -1;
+ }
+
+ ret = read(fd, buffer, ret);
+ }
+ if(-1 == ret){
+ fprintf(stderr, "err emptying buff: %s\n", strerror(errno));
+ return -1;
}
+ }
+
+ uint8_t rx = 0;
+
+ /* Reset register. */
+ ret = xmit_recv(fd, &rx, FOUR_ONES);
+ if(ret)
+ return ret;
+ if(rx != (OUT_RX_ACK | 4)){
+ return -4;
+ }
+
+ /* Set register value. */
+ while(bits_remaining){
+ uint8_t xmit = (target_freq & 0x80000000)
+ ? ONE_ONE : TWO_ONES;
+ ret = xmit_recv(fd, &rx, xmit);
+ if(ret)
+ return ret;
+
+ /* Make sure we got proper ack back. */
+ if((xmit == ONE_ONE) && rx != (OUT_RX_ACK | 0x1))
+ return -4;
+
+ if((xmit == TWO_ONES) && rx != (OUT_RX_ACK | 0x2))
+ return -4;
+
+ target_freq <<= 1;
+ --bits_remaining;
+ }
+
+ /* Register is set, now initiate calibration. */
+ ret = xmit_recv(fd, &rx, THREE_ONES);
+ if(ret)
+ return ret;
+ if(rx != (OUT_RX_ACK | 0x3))
+ return -4;
- fprintf(stderr, "Got %02hhx, %i\n", rx, ret);
- if(0xcc == rx){
+ while(keep_running){
+ ret = xmit_recv(fd, &rx, 0x55);
+ if(ret)
+ return ret;
+
+ if(OUT_INCREMENT == rx){
+ }
+ else if(OUT_DECREMENT == rx){
+ }
+ else if(OUT_FINISH == rx){
/* Read dco, bcs values. */
- uint8_t vals[2];
+ struct {
+ uint32_t estimate;
+ uint32_t last_diff;
+ uint8_t dco;
+ uint8_t bcs;
+ } result;
+
unsigned count = 0;
- while(count < 2){
- ret = ftdi_read_data(ftdi, vals + count, 2 - count);
+ while(count < 10){
+ ret = read(fd, (uint8_t*)(&result) + count, sizeof(result) - count);
fprintf(stderr, "Read back %i\n", ret);
count += ret;
}
- fprintf(stderr, "DCO BCS1CTL\n");
- printf("%02hhx %02hhx\n", vals[0], vals[1]);
+
+ 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);
+ break;
+ }
+ else{
+ fprintf(stderr, "BAD RX %02hhx\n", rx);
break;
}
usleep(100);
-
- /* Write */
- ret = ftdi_write_data(ftdi, &output, 1);
- if(ret < 0){
- fprintf(stderr, "Write error");
- return 1;
- }
}
signal(SIGINT, SIG_DFL);
- ftdi_usb_close(ftdi);
-do_deinit:
- ftdi_free(ftdi);
-
return 0;
}
Oops, something went wrong.

0 comments on commit 346a45a

Please sign in to comment.