altos: Make micropeak 'serial' interface work
authorKeith Packard <keithp@keithp.com>
Tue, 18 Dec 2012 06:58:49 +0000 (22:58 -0800)
committerKeith Packard <keithp@keithp.com>
Tue, 18 Dec 2012 06:58:49 +0000 (22:58 -0800)
I prototyped the mpserial interface on a breadboard and tuned the
circuit to register the LED correctly. Then adjusted the serial code
to send bits at the right speed and format.

The logging contents are now in hexdecimal with a CCITT CRC-16
computed to verify correct reception.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/micropeak/Makefile
src/micropeak/ao_async.c
src/micropeak/ao_async.h
src/micropeak/ao_log_micro.c
src/micropeak/ao_micropeak.c

index 82944cb1b4632e57c50b51a5a8d7dd5c2c1a699b..ff0a4499ea0ca9db0fafa6ec969b5ea9c730571f 100644 (file)
@@ -50,7 +50,7 @@ IDPRODUCT=0
 PRODUCT=MicroPeak-v0.1
 PRODUCT_DEF=-DMICROPEAK
 CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../core -I.. -I../drivers
-CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DATTINY
+CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY
 
 NICKLE=nickle
 
index 04bba9e81fa7669e5f3347b58077d7a6f68e64fc..3556f54c00d511932baabad43a3d358311233d0f 100644 (file)
 #define AO_ASYNC_BAUD  38400l
 #define AO_ASYNC_DELAY (uint8_t) (1000000l / AO_ASYNC_BAUD)
 
+#define LED_PORT       PORTB
+
+void
+ao_async_start(void)
+{
+       LED_PORT |= (1 << AO_LED_SERIAL);
+}
+
+void
+ao_async_stop(void)
+{
+       LED_PORT &= ~(1 << AO_LED_SERIAL);
+}
+
 void
 ao_async_byte(uint8_t byte)
 {
        uint8_t         b;
        uint16_t        w;
 
-       /* start bit */
-
-       /* start     data         stop */
-       w = 0x001 | (byte << 1) | 0x000;
+       /*    start           data           stop */
+       w = (0x000 << 0) | (byte << 1) | (0x001 << 9);
 
+       ao_arch_block_interrupts();
        for (b = 0; b < 10; b++) {
-               ao_led_set((w & 1) << AO_LED_SERIAL);
+               uint8_t v = LED_PORT & ~(1 << AO_LED_SERIAL);
+               v |= (w & 1) << AO_LED_SERIAL;
+               LED_PORT = v;
                w >>= 1;
-               ao_delay_us(26);
+
+               /* Carefully timed to hit around 9600 baud */
+               asm volatile ("nop");
+               asm volatile ("nop");
+
+               asm volatile ("nop");
+               asm volatile ("nop");
+               asm volatile ("nop");
+               asm volatile ("nop");
+               asm volatile ("nop");
+
+               asm volatile ("nop");
+               asm volatile ("nop");
+               asm volatile ("nop");
+               asm volatile ("nop");
+               asm volatile ("nop");
        }
+       ao_arch_release_interrupts();
 }
index a06d2e1a6bde7f07ba3d1f614960e286c5f27da9..1b239712855e3276da9b2b8d75c213f94bf9e5d3 100644 (file)
 #ifndef _AO_ASYNC_H_
 #define _AO_ASYNC_H_
 
+void
+ao_async_start(void);
+
+void
+ao_async_stop(void);
+
 void
 ao_async_byte(uint8_t byte);
 
index 40a7a35dbe32561a620a6ffcde0407c7433d0ae4..d665efb5b56f94e1123afe8df306ad02dc53bbca 100644 (file)
@@ -49,6 +49,46 @@ ao_log_micro_data(void)
        }
 }
 
+#define POLY 0x8408
+
+static uint16_t
+ao_log_micro_crc(uint16_t crc, uint8_t byte)
+{
+       uint8_t i;
+
+       for (i = 0; i < 8; i++) {
+               if ((crc & 0x0001) ^ (byte & 0x0001))
+                       crc = (crc >> 1) ^ POLY;
+               else
+                       crc = crc >> 1;
+               byte >>= 1;
+       }
+       return crc;
+}
+
+static void
+ao_log_hex_nibble(uint8_t b)
+{
+       if (b < 10)
+               ao_async_byte('0' + b);
+       else
+               ao_async_byte('a' - 10 + b);
+}
+
+static void
+ao_log_hex(uint8_t b)
+{
+       ao_log_hex_nibble(b>>4);
+       ao_log_hex_nibble(b&0xf);
+}
+
+static void
+ao_log_newline(void)
+{
+       ao_async_byte('\r');
+       ao_async_byte('\n');
+}
+
 void
 ao_log_micro_dump(void)
 {
@@ -56,13 +96,26 @@ ao_log_micro_dump(void)
        uint16_t        nbytes;
        uint8_t         byte;
        uint16_t        b;
+       uint16_t        crc = 0xffff;
 
        ao_eeprom_read(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples));
+       if (n_samples == 0xffff)
+               n_samples = 0;
        nbytes = STARTING_LOG_OFFSET + sizeof (uint16_t) * n_samples;
+       ao_async_start();
        ao_async_byte('M');
        ao_async_byte('P');
        for (b = 0; b < nbytes; b++) {
+               if ((b & 0xf) == 0)
+                       ao_log_newline();
                ao_eeprom_read(b, &byte, 1);
-               ao_async_byte(byte);
+               ao_log_hex(byte);
+               crc = ao_log_micro_crc(crc, byte);
        }
+       ao_log_newline();
+       crc = ~crc;
+       ao_log_hex(crc >> 8);
+       ao_log_hex(crc);
+       ao_log_newline();
+       ao_async_stop();
 }
index 3bbc7eea59a09c348d4c4debf4e1e019db45ea4c..f579a09a27b62fdfe4376a2022b98dbdf741f2dc 100644 (file)
@@ -19,6 +19,7 @@
 #include <ao_micropeak.h>
 #include <ao_ms5607.h>
 #include <ao_log_micro.h>
+#include <ao_async.h>
 
 static struct ao_ms5607_sample sample;
 static struct ao_ms5607_value  value;