diff options
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | calibrator.c | 106 | ||||
| -rw-r--r-- | client.c | 29 | ||||
| -rw-r--r-- | host/calibrator_client.c | 82 | ||||
| -rw-r--r-- | host/client.c | 7 |
5 files changed, 227 insertions, 4 deletions
@@ -41,7 +41,7 @@ # Target file name (without extension). -TARGET = example +TARGET = calibrator # List C source files here. (C dependencies are automatically generated.) @@ -63,7 +63,7 @@ MCU = atmega32u4 # Teensy 2.0 # so your program will run at the correct speed. You should also set this # variable to same clock speed. The _delay_ms() macro uses this, and many # examples use this variable to calculate timings. Do not add a "UL" here. -F_CPU = 16000000 +F_CPU = 1000000 # Output format. (can be srec, ihex, binary) @@ -443,7 +443,8 @@ gccversion : # Program the device. program: $(TARGET).hex $(TARGET).eep - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) +# $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex # Generate avr-gdb config/init file which does the following: diff --git a/calibrator.c b/calibrator.c new file mode 100644 index 0000000..7eb9003 --- /dev/null +++ b/calibrator.c @@ -0,0 +1,106 @@ +/* Simple example for Teensy USB Development Board + * http://www.pjrc.com/teensy/ + * Copyright (c) 2008 PJRC.COM, LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <avr/io.h> +#include <avr/pgmspace.h> +#include <avr/interrupt.h> +#include <stdint.h> +#include <util/delay.h> +#include "usb_serial.h" + +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) + +void send_str(const char *s); +void send_int(unsigned int val); +uint8_t recv_str(char *buf, uint8_t size); + +volatile unsigned int system_timer = 0; + +int main(void) +{ + int changed = 0, val; + int port = 'B' - 'A'; + int pin = 1 << ('0' - '0'); + unsigned int timer_prev = 1; + + system_timer = 100; + + CPU_PRESCALE(0x00); // 16 MHz + usb_init(); + while (!usb_configured()) /* wait */ ; + _delay_ms(1000); + CPU_PRESCALE(0x04); // 1 MHz + TCCR1B |= (1 << CS10); // Set timer1 to 1 microsecond steps + TIMSK1 |= (1 << TOIE1); // enabled timer overflow interrupt; + sei(); + + while (1) { + if (system_timer != timer_prev) { + timer_prev++; +// send_int((int)system_timer); + usb_serial_putchar('\n'); + continue; + } + } +} + +ISR(TIMER1_OVF_vect) +{ + system_timer++; +} + +// Send a string to the USB serial port. The string must be in +// flash memory, using PSTR +// +void send_str(const char *s) +{ + char c; + while (1) { + c = pgm_read_byte(s++); + if (!c) break; + usb_serial_putchar(c); + } +} + +/* Write a decimal integer to the serial port + */ +void send_int(unsigned int val) +{ + char c_out[10]; + int ptr; + c_out[ptr++] = '\0'; + if (val < 0) { + c_out[ptr++] = '-'; + val = -val; + } + while (val > 0) { + c_out[ptr++] = (val % 10) + '0'; + val /= 10; + } + ptr--; + while (ptr) { + usb_serial_putchar(c_out[ptr--]); + } +} + + diff --git a/client.c b/client.c new file mode 100644 index 0000000..2b3ff4c --- /dev/null +++ b/client.c @@ -0,0 +1,29 @@ +/* Thinger to read 60hz cycle times and display diagnostics in a kind + * of stripcharty way. + */ + +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> + + +int main(int *argc, char **argv) +{ + char line[20]; + double bottom = 1/59.9; + double top = 1/60.1; + double center = 1/60; + int fd = open("/dev/ttyACM0", O_RDONLY); + + while (1) { + double current; + char* line = " | \n"; + int len = read(fd, &line, 20); + if (len == 0) { + puts("Fucked\n"); + continue; + } + current = (float)atoi(&line); + printf("%f %f\n", current - bottom, current); + } +} diff --git a/host/calibrator_client.c b/host/calibrator_client.c new file mode 100644 index 0000000..3b5eee5 --- /dev/null +++ b/host/calibrator_client.c @@ -0,0 +1,82 @@ +/* Thinger to read 60hz cycle times and display diagnostics in a kind + * of stripcharty way. + */ + +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <time.h> + +// window for reporting, in cycles +#define REPORT_FREQ 60 +// width of the bargraph +#define WIDTH 40 +// timer cycles per second +#define SCALE 1000000 +// length between nominal timer overflows, in microseconds +// (1 overflow / 65'536 microseconds) * (1'000'000 microseconds) +#define TICKSIZE (SCALE / 65536) + +#define NANOSECOND 1000000000 +#define MILLISECOND 1000 + +#define NOMINAL 60 +#define MOTION 0.2 + +int main(int *argc, char **argv) +{ + char line[WIDTH + 10]; + char blankline[] = " | "; + double bottom = SCALE/(NOMINAL-MOTION); + double top = SCALE/(NOMINAL+MOTION); + double center = SCALE/(NOMINAL); + int counter; + int qpos = 0; + int fd = open("/dev/ttyACM0", O_RDONLY); + + long int count_total = 0; // total overflows so far ever + struct timespec initial; // initial timestamp + + signed long long int initial_nsec; + signed long int initial_msec; + + strcpy(&line, &blankline); + + clock_gettime(CLOCK_REALTIME, &initial); + + initial_nsec = initial.tv_nsec; + + initial_msec = (initial.tv_sec * 1000) + (initial.tv_nsec / (1000 * 1000)); + + while (1) { + double current, average; + char inlin[20]; + int position, pos_avg, i; + int len; + + struct timespec current_time; + signed long long int cur_nsec; + signed long int cur_msec; + + long double nominal, measured; + + len = read(fd, &inlin, 1); + if (len == 0) { + puts("Fucked\n"); + continue; + } + clock_gettime(CLOCK_REALTIME, ¤t_time); + cur_nsec = (current_time.tv_nsec) + ((current_time.tv_sec - initial.tv_sec) * 1000 * 1000 * 1000); + cur_msec = (current_time.tv_nsec / (1000 * 1000)) + ((current_time.tv_sec) * 1000); + + count_total++; + + nominal = (long double) count_total / TICKSIZE; + //measured = (cur_nsec - initial_nsec) / NANOSECOND; + measured = (cur_msec - initial_msec) / MILLISECOND; + + printf("% '05.8Lf - % '05.8Lf, % '05.8Lf\n", nominal, measured, measured/nominal); + + } +} diff --git a/host/client.c b/host/client.c index 17f3fba..3752800 100644 --- a/host/client.c +++ b/host/client.c @@ -7,8 +7,13 @@ #include <string.h> #include <fcntl.h> +// window for frequency averaging, in cycles #define QUEUE 3600 +// window for reporting, in cycles +#define REPORT_FREQ 60 +// width of the bargraph #define WIDTH 40 +// timer cycles per second #define SCALE 1000000 int main(int *argc, char **argv) @@ -57,7 +62,7 @@ int main(int *argc, char **argv) line[position] = '.'; } - if (counter % 60 == 0) { + if (counter % REPORT_FREQ == 0) { if (pos_avg > WIDTH) { line[WIDTH] = '_'; } else if (pos_avg < 0) { |
