Mercurial > ~darius > hgwebdir.cgi > tempctrl
changeset 72:13f8e6eb5c01
Create a new repo for temperature control to make hacking on other things easier.
Rename main file, remove USB stuff & fix makefiles, etc..
author | darius@Inchoate |
---|---|
date | Wed, 21 Jan 2009 16:37:32 +1030 |
parents | 553c061fda7c |
children | 56165caf744b |
files | main.c testavr.c testugen.c testugen2.c usb.c usb.h |
diffstat | 6 files changed, 572 insertions(+), 2053 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.c Wed Jan 21 16:37:32 2009 +1030 @@ -0,0 +1,572 @@ +/* + * Test various AVR bits and pieces + * + * Copyright (c) 2008 + * Daniel O'Connor <darius@dons.net.au>. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <avr/io.h> +#include <avr/interrupt.h> +#include <avr/pgmspace.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include <util/delay.h> +#include <avr/wdt.h> + +#include "cons.h" +#include "1wire.h" +#ifdef WITHUSB +#include "usb.h" +#endif +#include "tempctrl.h" +#include "ds1307.h" + +/* + * Mirror of the MCUCSR register, taken early during startup. + */ +uint8_t mcucsr __attribute__((section(".noinit"))); + +void process_cmd(void); + +/* + * Read out and reset MCUCSR early during startup. + */ +void handle_mcucsr(void) + __attribute__((section(".init3"))) + __attribute__((naked)); +void handle_mcucsr(void) { + wdt_disable(); + mcucsr = MCUCSR; + MCUCSR = 0; +} + +int +main(void) { + /* Disable interrupts while we frob stuff */ + cli(); + +#if 0 + /* Disable JTAG (yes twice) */ + MCUCSR |= _BV(JTD); + MCUCSR |= _BV(JTD); +#endif + +#ifdef WITHUSB + /* USB data bus (7:0) */ + DDRA = 0x00; + PORTA = 0x00; + + /* USB control (4:0) */ + DDRB = 0x0d; + PORTB = 0x00; +#else + DDRA = 0xff; + PORTA = 0x00; + + DDRB = 0x00; + PORTB = 0x00; + +#endif + /* GPIO (0:7) */ + DDRC = 0xff; + PORTC = 0x00; + + /* USART (0:1), IDBus (2:5), 485 (6:6), GPIO (7:7) */ + DDRD = 0xf7; + PORTD = 0xf7; + +#ifndef WITHUSB + /* Beep + * + * Fpwm = Fclk / (N * 510) + * = 16e6 / (8 * 510) + * = 3921Hz + * + * Behind ifndef because PB3 is A0 on PDI chip + * + * Phase correct PWM, non-inverted output, divide by 8 */ + TCCR0 = _BV(WGM00) | _BV(WGM11) | _BV(COM00) | _BV(COM01) | _BV(CS01); + OCR0 = 128; +#endif + + /* Set up the one wire stuff */ + OWInit(); + + /* Setup IIC */ + ds1307_init(); + + /* Init UART */ + cons_init(); + + /* Init temperature control stuff */ + tempctrl_init(); + + printf_P(PSTR("\r\n\r\n===============\r\n" + "Inited!\r\n\r\n")); + + if ((mcucsr & _BV(PORF)) == _BV(PORF)) + printf_P(PSTR("Power on reset\r\n")); + + if ((mcucsr & _BV(EXTRF)) == _BV(EXTRF)) + printf_P(PSTR("External reset\r\n")); + + if ((mcucsr & _BV(BORF)) == _BV(BORF)) + printf_P(PSTR("Brown-out reset\r\n")); + + if ((mcucsr & _BV(WDRF)) == _BV(WDRF)) + printf_P(PSTR("Watchdog reset\r\n")); + + if ((mcucsr & _BV(JTRF)) == _BV(JTRF)) + printf_P(PSTR("JTAG reset\r\n")); + + /* Ready to go! */ + sei(); + + /* + * Enable the watchdog with the largest prescaler. Will cause a + * watchdog reset after approximately 2 s @ Vcc = 5 V + * + * Gets reset in the loop below and in the tempctrl.c timer IRQ + */ + wdt_enable(WDTO_2S); + +#ifdef WITHUSB + printf_P(PSTR("Calling usb_init\r\n")); + usb_init(); + printf_P(PSTR("done\r\n")); + _delay_us(1000); +#endif + printf_P(PSTR("> ")); + cmd.state = 0; + + /* Wait for user input or an "interrupt" */ + while (1) { + wdt_reset(); + + tempctrl_update(); + + if (cmd.state == 255) { + process_cmd(); + printf_P(PSTR("> ")); + /* Allow new characters to be processed */ + cmd.state = 0; + } + +#ifdef WITHUSB + if (!(PDICTL & _BV(PDIINT))) + usb_intr(); +#endif + } +} + +void +process_cmd(void) { + uint8_t ROM[8], crc, buf[9], temp; + int8_t i, arg; + int16_t t; + + /* User just pressed enter */ + if (cmd.len == 0) + return; + + if (!strcasecmp_P((char *)cmd.buf, PSTR("?")) || + !strcasecmp_P((char *)cmd.buf, PSTR("help"))) { + printf_P(PSTR("rs Reset and check for presence\r\n" + "sr Search the bus for ROMs\r\n" + "re Read a bit\r\n" + "rb Read a byte\r\n" + "wr bit Write a bit\r\n" + "wb byte Write a byte (hex)\r\n" + "wc cmd [ROMID] Write command\r\n" + "te ROMID Read the temperature from a DS1820\r\n" + "in port Read from a port\r\n" + "ou port val Write to a port (val in hex)\r\n" + "dd port [val] Read/write DDR for a port (val in hex)\r\n" + "rt ROMID Read DS2502 status page\r\n" + "we ROMID adr val Write data into a DS2502 PROM (adr & val in hex)\r\n" + "rr ROMID Read DS2502 PROM\r\n" + "zz Reset MCU\r\n" + "gc Get time of day\r\n" + "sc time Set time of day (time is YYYY/MM/DD HH:MM:SS)\r\n" +#ifdef WITHUSB + "us Generate USB data\r\n" +#endif + "tc ... Temperature control related (tc help for more)\r\n")); + + return; + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("zz"), 2)) { + cli(); + wdt_enable(WDTO_15MS); + for (;;) + ; + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rs"), 2)) { + printf_P(PSTR("Resetting... ")); + + if (OWTouchReset() == 1) + printf_P(PSTR("No presence pulse found\r\n")); + else + printf_P(PSTR("Presence pulse found\r\n")); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("re"), 2)) { + if (OWReadBit()) + printf_P(PSTR("Read a 1\r\n")); + else + printf_P(PSTR("Read a 0\r\n")); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rb"), 2)) { + printf_P(PSTR("Read a 0x%02x\r\n"), OWReadByte()); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wr"), 2)) { + arg = strtol((char *)cmd.buf + 3, (char **)NULL, 10); + OWWriteBit(arg); + printf_P(PSTR("Wrote a %c\r\n"), arg ? '1' : '0'); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wb"), 2)) { + arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16); + OWWriteByte(arg); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rt"), 2)) { + if (sscanf_P((char *)cmd.buf, PSTR("rt %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), + &ROM[0], &ROM[1], &ROM[2], &ROM[3], + &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { + printf_P(PSTR("Unable to parse ROM ID\r\n")); + return; + } + + if (ROM[0] != OW_FAMILY_ROM) { + printf_P(PSTR("ROM specified isn't a DS2502\r\n")); + return; + } + + if (OWTouchReset() != 0) { + printf_P(PSTR("No presence\r\n")); + return; + } + + crc = 0; + + OWCRC(OW_READ_STATUS, &crc); + OWSendCmd(ROM, OW_READ_STATUS); + + OWWriteByte(0x00); + OWCRC(0x00, &crc); + + OWWriteByte(0x00); + OWCRC(0x00, &crc); + + if (crc != OWReadByte()) { + printf_P(PSTR("CRC mismatch on command & address\r\n")); + return; + } + + crc = 0; + for (i = 0; i < 8; i++) { + temp = OWReadByte(); + printf_P(PSTR("%02x "), temp); + OWCRC(temp, &crc); + } + printf_P(PSTR("\r\n")); + if (crc != OWReadByte()) { + printf_P(PSTR("CRC mismatch on data\r\n")); + return; + } + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("we"), 2)) { + uint8_t adr, data; + + if (sscanf_P((char *)cmd.buf, PSTR("we %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhx %hhx"), + &ROM[0], &ROM[1], &ROM[2], &ROM[3], + &ROM[4], &ROM[5], &ROM[6], &ROM[7], + &adr, &data) != 10) { + printf_P(PSTR("Unable to parse ROM ID\r\n")); + return; + } + + if (ROM[0] != OW_FAMILY_ROM) { + printf_P(PSTR("ID specified isn't a ROM\r\n")); + return; + } + + if (OWTouchReset() != 0) { + printf_P(PSTR("No presence\r\n")); + return; + } + + printf_P(PSTR("OWProgROM returned %S\r\n"), OWProgROM_Status[OWProgROM(ROM, buf[0], 2, &buf[1], 0, 0)]); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rr"), 2)) { + if (sscanf_P((char *)cmd.buf, PSTR("rr %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), + &ROM[0], &ROM[1], &ROM[2], &ROM[3], + &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { + printf_P(PSTR("Unable to parse ROM ID\r\n")); + return; + } + + if (ROM[0] != OW_FAMILY_ROM) { + printf_P(PSTR("ROM specified isn't a ROM\r\n")); + return; + } + + crc = 0; + OWSendCmd(ROM, OW_READ_MEMORY); + OWCRC(OW_READ_MEMORY, &crc); + + OWWriteByte(0x00); + OWCRC(0x00, &crc); + + OWWriteByte(0x00); + OWCRC(0x00, &crc); + + if (crc != OWReadByte()) { + printf_P(PSTR("CRC mismatch on command & address\r\n")); + return; + } + + crc = 0; + for (buf[0] = 0; buf[0] < 128; buf[0]++) { + buf[1] = OWReadByte(); + if (buf[0] > 0) { + if (buf[0] % 16 != 0) + printf_P(PSTR(" ")); + else + printf_P(PSTR("\r\n")); + } + + printf_P(PSTR("%02x"), buf[1]); + OWCRC(buf[1], &crc); + } + printf_P(PSTR("\r\n")); + if (crc != OWReadByte()) { + printf_P(PSTR("CRC mismatch on data\r\n")); + return; + } + + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wc"), 2)) { + uint8_t c; + + i = sscanf_P((char *)cmd.buf, PSTR("wc %hhx %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), + &ROM[0], &ROM[1], &ROM[2], &ROM[3], + &ROM[4], &ROM[5], &ROM[6], &ROM[7], + &c); + + if (i != 1 && i != 9) { + printf_P(PSTR("Incorrect usage\r\n")); + return; + } + + if (i == 1) { + OWSendCmd(i == 1 ? NULL : ROM, c); + return; + } + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("te"), 2)) { + if (sscanf_P((char *)cmd.buf, PSTR("te %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), + &ROM[0], &ROM[1], &ROM[2], &ROM[3], + &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { + printf_P(PSTR("Unable to parse ROM ID\r\n")); + return; + } + + t = OWGetTemp(ROM); + switch (t) { + case OW_TEMP_WRONG_FAM: + printf_P(PSTR("ROM specified isn't a temperature sensor\r\n")); + break; + + case OW_TEMP_CRC_ERR: + printf_P(PSTR("CRC mismatch\r\n")); + break; + + case OW_TEMP_NO_ROM: + printf_P(PSTR("No ROM found\r\n")); + break; + + default: + printf_P(PSTR("%d.%02d\r\n"), GETWHOLE(t), GETFRAC(t)); + break; + } + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("sr"), 2)) { + memset(ROM, 0, 8); + + i = OWFirst(ROM, 1, 0); + do { + switch (i) { + case OW_BADWIRE: + printf_P(PSTR("Presence pulse, but no module found, bad module/cabling?\r\n")); + break; + + case OW_NOPRESENCE: + printf_P(PSTR("No presence pulse found\r\n")); + break; + + case OW_BADCRC: + printf_P(PSTR("Bad CRC\r\n")); + break; + + case OW_NOMODULES: + case OW_FOUND: + break; + + default: + printf_P(PSTR("Unknown error from 1 wire library\r\n")); + break; + } + + if (i != OW_FOUND) + break; + + for (i = 0; i < 8; i++) + printf_P(PSTR("%02x%S"), ROM[i], i == 7 ? PSTR("\r\n") : PSTR(":")); + + i = OWNext(ROM, 1, 0); + } while (1); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("in"), 2)) { + uint8_t inp; + + switch (tolower(cmd.buf[3])) { + case 'a': + inp = PINA; + break; + + case 'b': + inp = PINB; + break; + + case 'c': + inp = PINC; + break; + + case 'd': + inp = PIND; + break; + + default: + printf_P(PSTR("Unknown port\r\n")); + return; + } + printf_P(PSTR("0x%02x\r\n"), inp); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("ou"), 2)) { + char port; + int val; + + if (sscanf_P((char *)cmd.buf, PSTR("ou %c %x"), &port, &val) != 2) { + printf_P(PSTR("Unable to parse ou arguments\r\n")); + return; + } + + switch (port) { + case 'a': + PORTA = val & 0xff; + break; + + case 'b': + PORTB = val & 0xff; + break; + + case 'c': + PORTC = val & 0xff; + break; + + case 'd': + PORTD = val & 0xff; + break; + + default: + printf_P(PSTR("Unknown port\r\n")); + return; + } + printf_P(PSTR("PORT%c <= 0x%02x\r\n"), toupper(port), val); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("dd"), 2)) { + char port; + uint8_t val; + int num; + + num = sscanf_P((char *)cmd.buf, PSTR("dd %c %x"), &port, &val); + + if (num != 2 && num != 3) { + printf_P(PSTR("Unable to parse dd arguments\r\n")); + return; + } + + if (num == 2) { + switch (port) { + case 'a': + val = DDRA; + break; + + case 'b': + val = DDRB; + break; + + case 'c': + val = DDRC; + break; + + case 'd': + val = DDRD; + break; + + default: + printf_P(PSTR("Unknown port\r\n")); + return; + } + printf_P(PSTR("DDR%c => 0x%02x\r\n"), toupper(port), val); + } else { + switch (port) { + case 'a': + DDRA = val & 0xff; + break; + + case 'b': + DDRB = val & 0xff; + break; + + case 'c': + DDRC = val & 0xff; + break; + + case 'd': + DDRD = val & 0xff; + break; + + default: + printf_P(PSTR("Unknown port\r\n")); + return; + } + printf_P(PSTR("DDR%c <= 0x%02x\r\n"), toupper(port), val); + } + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("tc"), 2)) { + tempctrl_cmd((char *)cmd.buf); +#ifdef WITHUSB + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("us"), 2)) { + usb_gendata(); +#endif + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("gc"), 2)) { + ds1307_printtime(PSTR(""), PSTR("\r\n")); + } else if (!strncasecmp_P((char *)cmd.buf, PSTR("sc"), 2)) { + if (cmd.len < 17) { + printf_P(PSTR("Command not long enough\r\n")); + } else { + if (ds1307_settod((char *)cmd.buf + 3) != 1) + printf_P(PSTR("Unable to set time of day\r\n")); + } + } else { + printf_P(PSTR("Unknown command, help for a list\r\n")); + } +} +
--- a/testavr.c Mon Jan 19 22:54:19 2009 +1030 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,572 +0,0 @@ -/* - * Test various AVR bits and pieces - * - * Copyright (c) 2008 - * Daniel O'Connor <darius@dons.net.au>. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <avr/io.h> -#include <avr/interrupt.h> -#include <avr/pgmspace.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#include <util/delay.h> -#include <avr/wdt.h> - -#include "cons.h" -#include "1wire.h" -#ifdef WITHUSB -#include "usb.h" -#endif -#include "tempctrl.h" -#include "ds1307.h" - -/* - * Mirror of the MCUCSR register, taken early during startup. - */ -uint8_t mcucsr __attribute__((section(".noinit"))); - -void process_cmd(void); - -/* - * Read out and reset MCUCSR early during startup. - */ -void handle_mcucsr(void) - __attribute__((section(".init3"))) - __attribute__((naked)); -void handle_mcucsr(void) { - wdt_disable(); - mcucsr = MCUCSR; - MCUCSR = 0; -} - -int -main(void) { - /* Disable interrupts while we frob stuff */ - cli(); - -#if 0 - /* Disable JTAG (yes twice) */ - MCUCSR |= _BV(JTD); - MCUCSR |= _BV(JTD); -#endif - -#ifdef WITHUSB - /* USB data bus (7:0) */ - DDRA = 0x00; - PORTA = 0x00; - - /* USB control (4:0) */ - DDRB = 0x0d; - PORTB = 0x00; -#else - DDRA = 0xff; - PORTA = 0x00; - - DDRB = 0x00; - PORTB = 0x00; - -#endif - /* GPIO (0:7) */ - DDRC = 0xff; - PORTC = 0x00; - - /* USART (0:1), IDBus (2:5), 485 (6:6), GPIO (7:7) */ - DDRD = 0xf7; - PORTD = 0xf7; - -#ifndef WITHUSB - /* Beep - * - * Fpwm = Fclk / (N * 510) - * = 16e6 / (8 * 510) - * = 3921Hz - * - * Behind ifndef because PB3 is A0 on PDI chip - * - * Phase correct PWM, non-inverted output, divide by 8 */ - TCCR0 = _BV(WGM00) | _BV(WGM11) | _BV(COM00) | _BV(COM01) | _BV(CS01); - OCR0 = 128; -#endif - - /* Set up the one wire stuff */ - OWInit(); - - /* Setup IIC */ - ds1307_init(); - - /* Init UART */ - cons_init(); - - /* Init temperature control stuff */ - tempctrl_init(); - - printf_P(PSTR("\r\n\r\n===============\r\n" - "Inited!\r\n\r\n")); - - if ((mcucsr & _BV(PORF)) == _BV(PORF)) - printf_P(PSTR("Power on reset\r\n")); - - if ((mcucsr & _BV(EXTRF)) == _BV(EXTRF)) - printf_P(PSTR("External reset\r\n")); - - if ((mcucsr & _BV(BORF)) == _BV(BORF)) - printf_P(PSTR("Brown-out reset\r\n")); - - if ((mcucsr & _BV(WDRF)) == _BV(WDRF)) - printf_P(PSTR("Watchdog reset\r\n")); - - if ((mcucsr & _BV(JTRF)) == _BV(JTRF)) - printf_P(PSTR("JTAG reset\r\n")); - - /* Ready to go! */ - sei(); - - /* - * Enable the watchdog with the largest prescaler. Will cause a - * watchdog reset after approximately 2 s @ Vcc = 5 V - * - * Gets reset in the loop below and in the tempctrl.c timer IRQ - */ - wdt_enable(WDTO_2S); - -#ifdef WITHUSB - printf_P(PSTR("Calling usb_init\r\n")); - usb_init(); - printf_P(PSTR("done\r\n")); - _delay_us(1000); -#endif - printf_P(PSTR("> ")); - cmd.state = 0; - - /* Wait for user input or an "interrupt" */ - while (1) { - wdt_reset(); - - tempctrl_update(); - - if (cmd.state == 255) { - process_cmd(); - printf_P(PSTR("> ")); - /* Allow new characters to be processed */ - cmd.state = 0; - } - -#ifdef WITHUSB - if (!(PDICTL & _BV(PDIINT))) - usb_intr(); -#endif - } -} - -void -process_cmd(void) { - uint8_t ROM[8], crc, buf[9], temp; - int8_t i, arg; - int16_t t; - - /* User just pressed enter */ - if (cmd.len == 0) - return; - - if (!strcasecmp_P((char *)cmd.buf, PSTR("?")) || - !strcasecmp_P((char *)cmd.buf, PSTR("help"))) { - printf_P(PSTR("rs Reset and check for presence\r\n" - "sr Search the bus for ROMs\r\n" - "re Read a bit\r\n" - "rb Read a byte\r\n" - "wr bit Write a bit\r\n" - "wb byte Write a byte (hex)\r\n" - "wc cmd [ROMID] Write command\r\n" - "te ROMID Read the temperature from a DS1820\r\n" - "in port Read from a port\r\n" - "ou port val Write to a port (val in hex)\r\n" - "dd port [val] Read/write DDR for a port (val in hex)\r\n" - "rt ROMID Read DS2502 status page\r\n" - "we ROMID adr val Write data into a DS2502 PROM (adr & val in hex)\r\n" - "rr ROMID Read DS2502 PROM\r\n" - "zz Reset MCU\r\n" - "gc Get time of day\r\n" - "sc time Set time of day (time is YYYY/MM/DD HH:MM:SS)\r\n" -#ifdef WITHUSB - "us Generate USB data\r\n" -#endif - "tc ... Temperature control related (tc help for more)\r\n")); - - return; - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("zz"), 2)) { - cli(); - wdt_enable(WDTO_15MS); - for (;;) - ; - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rs"), 2)) { - printf_P(PSTR("Resetting... ")); - - if (OWTouchReset() == 1) - printf_P(PSTR("No presence pulse found\r\n")); - else - printf_P(PSTR("Presence pulse found\r\n")); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("re"), 2)) { - if (OWReadBit()) - printf_P(PSTR("Read a 1\r\n")); - else - printf_P(PSTR("Read a 0\r\n")); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rb"), 2)) { - printf_P(PSTR("Read a 0x%02x\r\n"), OWReadByte()); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wr"), 2)) { - arg = strtol((char *)cmd.buf + 3, (char **)NULL, 10); - OWWriteBit(arg); - printf_P(PSTR("Wrote a %c\r\n"), arg ? '1' : '0'); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wb"), 2)) { - arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16); - OWWriteByte(arg); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rt"), 2)) { - if (sscanf_P((char *)cmd.buf, PSTR("rt %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), - &ROM[0], &ROM[1], &ROM[2], &ROM[3], - &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { - printf_P(PSTR("Unable to parse ROM ID\r\n")); - return; - } - - if (ROM[0] != OW_FAMILY_ROM) { - printf_P(PSTR("ROM specified isn't a DS2502\r\n")); - return; - } - - if (OWTouchReset() != 0) { - printf_P(PSTR("No presence\r\n")); - return; - } - - crc = 0; - - OWCRC(OW_READ_STATUS, &crc); - OWSendCmd(ROM, OW_READ_STATUS); - - OWWriteByte(0x00); - OWCRC(0x00, &crc); - - OWWriteByte(0x00); - OWCRC(0x00, &crc); - - if (crc != OWReadByte()) { - printf_P(PSTR("CRC mismatch on command & address\r\n")); - return; - } - - crc = 0; - for (i = 0; i < 8; i++) { - temp = OWReadByte(); - printf_P(PSTR("%02x "), temp); - OWCRC(temp, &crc); - } - printf_P(PSTR("\r\n")); - if (crc != OWReadByte()) { - printf_P(PSTR("CRC mismatch on data\r\n")); - return; - } - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("we"), 2)) { - uint8_t adr, data; - - if (sscanf_P((char *)cmd.buf, PSTR("we %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhx %hhx"), - &ROM[0], &ROM[1], &ROM[2], &ROM[3], - &ROM[4], &ROM[5], &ROM[6], &ROM[7], - &adr, &data) != 10) { - printf_P(PSTR("Unable to parse ROM ID\r\n")); - return; - } - - if (ROM[0] != OW_FAMILY_ROM) { - printf_P(PSTR("ID specified isn't a ROM\r\n")); - return; - } - - if (OWTouchReset() != 0) { - printf_P(PSTR("No presence\r\n")); - return; - } - - printf_P(PSTR("OWProgROM returned %S\r\n"), OWProgROM_Status[OWProgROM(ROM, buf[0], 2, &buf[1], 0, 0)]); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rr"), 2)) { - if (sscanf_P((char *)cmd.buf, PSTR("rr %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), - &ROM[0], &ROM[1], &ROM[2], &ROM[3], - &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { - printf_P(PSTR("Unable to parse ROM ID\r\n")); - return; - } - - if (ROM[0] != OW_FAMILY_ROM) { - printf_P(PSTR("ROM specified isn't a ROM\r\n")); - return; - } - - crc = 0; - OWSendCmd(ROM, OW_READ_MEMORY); - OWCRC(OW_READ_MEMORY, &crc); - - OWWriteByte(0x00); - OWCRC(0x00, &crc); - - OWWriteByte(0x00); - OWCRC(0x00, &crc); - - if (crc != OWReadByte()) { - printf_P(PSTR("CRC mismatch on command & address\r\n")); - return; - } - - crc = 0; - for (buf[0] = 0; buf[0] < 128; buf[0]++) { - buf[1] = OWReadByte(); - if (buf[0] > 0) { - if (buf[0] % 16 != 0) - printf_P(PSTR(" ")); - else - printf_P(PSTR("\r\n")); - } - - printf_P(PSTR("%02x"), buf[1]); - OWCRC(buf[1], &crc); - } - printf_P(PSTR("\r\n")); - if (crc != OWReadByte()) { - printf_P(PSTR("CRC mismatch on data\r\n")); - return; - } - - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wc"), 2)) { - uint8_t c; - - i = sscanf_P((char *)cmd.buf, PSTR("wc %hhx %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), - &ROM[0], &ROM[1], &ROM[2], &ROM[3], - &ROM[4], &ROM[5], &ROM[6], &ROM[7], - &c); - - if (i != 1 && i != 9) { - printf_P(PSTR("Incorrect usage\r\n")); - return; - } - - if (i == 1) { - OWSendCmd(i == 1 ? NULL : ROM, c); - return; - } - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("te"), 2)) { - if (sscanf_P((char *)cmd.buf, PSTR("te %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), - &ROM[0], &ROM[1], &ROM[2], &ROM[3], - &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { - printf_P(PSTR("Unable to parse ROM ID\r\n")); - return; - } - - t = OWGetTemp(ROM); - switch (t) { - case OW_TEMP_WRONG_FAM: - printf_P(PSTR("ROM specified isn't a temperature sensor\r\n")); - break; - - case OW_TEMP_CRC_ERR: - printf_P(PSTR("CRC mismatch\r\n")); - break; - - case OW_TEMP_NO_ROM: - printf_P(PSTR("No ROM found\r\n")); - break; - - default: - printf_P(PSTR("%d.%02d\r\n"), GETWHOLE(t), GETFRAC(t)); - break; - } - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("sr"), 2)) { - memset(ROM, 0, 8); - - i = OWFirst(ROM, 1, 0); - do { - switch (i) { - case OW_BADWIRE: - printf_P(PSTR("Presence pulse, but no module found, bad module/cabling?\r\n")); - break; - - case OW_NOPRESENCE: - printf_P(PSTR("No presence pulse found\r\n")); - break; - - case OW_BADCRC: - printf_P(PSTR("Bad CRC\r\n")); - break; - - case OW_NOMODULES: - case OW_FOUND: - break; - - default: - printf_P(PSTR("Unknown error from 1 wire library\r\n")); - break; - } - - if (i != OW_FOUND) - break; - - for (i = 0; i < 8; i++) - printf_P(PSTR("%02x%S"), ROM[i], i == 7 ? PSTR("\r\n") : PSTR(":")); - - i = OWNext(ROM, 1, 0); - } while (1); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("in"), 2)) { - uint8_t inp; - - switch (tolower(cmd.buf[3])) { - case 'a': - inp = PINA; - break; - - case 'b': - inp = PINB; - break; - - case 'c': - inp = PINC; - break; - - case 'd': - inp = PIND; - break; - - default: - printf_P(PSTR("Unknown port\r\n")); - return; - } - printf_P(PSTR("0x%02x\r\n"), inp); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("ou"), 2)) { - char port; - int val; - - if (sscanf_P((char *)cmd.buf, PSTR("ou %c %x"), &port, &val) != 2) { - printf_P(PSTR("Unable to parse ou arguments\r\n")); - return; - } - - switch (port) { - case 'a': - PORTA = val & 0xff; - break; - - case 'b': - PORTB = val & 0xff; - break; - - case 'c': - PORTC = val & 0xff; - break; - - case 'd': - PORTD = val & 0xff; - break; - - default: - printf_P(PSTR("Unknown port\r\n")); - return; - } - printf_P(PSTR("PORT%c <= 0x%02x\r\n"), toupper(port), val); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("dd"), 2)) { - char port; - uint8_t val; - int num; - - num = sscanf_P((char *)cmd.buf, PSTR("dd %c %x"), &port, &val); - - if (num != 2 && num != 3) { - printf_P(PSTR("Unable to parse dd arguments\r\n")); - return; - } - - if (num == 2) { - switch (port) { - case 'a': - val = DDRA; - break; - - case 'b': - val = DDRB; - break; - - case 'c': - val = DDRC; - break; - - case 'd': - val = DDRD; - break; - - default: - printf_P(PSTR("Unknown port\r\n")); - return; - } - printf_P(PSTR("DDR%c => 0x%02x\r\n"), toupper(port), val); - } else { - switch (port) { - case 'a': - DDRA = val & 0xff; - break; - - case 'b': - DDRB = val & 0xff; - break; - - case 'c': - DDRC = val & 0xff; - break; - - case 'd': - DDRD = val & 0xff; - break; - - default: - printf_P(PSTR("Unknown port\r\n")); - return; - } - printf_P(PSTR("DDR%c <= 0x%02x\r\n"), toupper(port), val); - } - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("tc"), 2)) { - tempctrl_cmd((char *)cmd.buf); -#ifdef WITHUSB - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("us"), 2)) { - usb_gendata(); -#endif - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("gc"), 2)) { - ds1307_printtime(PSTR(""), PSTR("\r\n")); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("sc"), 2)) { - if (cmd.len < 17) { - printf_P(PSTR("Command not long enough\r\n")); - } else { - if (ds1307_settod((char *)cmd.buf + 3) != 1) - printf_P(PSTR("Unable to set time of day\r\n")); - } - } else { - printf_P(PSTR("Unknown command, help for a list\r\n")); - } -} -
--- a/testugen.c Mon Jan 19 22:54:19 2009 +1030 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -#include <sys/types.h> -#include <sys/ioctl.h> -#include <dev/usb/usb.h> -#include <sys/errno.h> -#include <sys/uio.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdio.h> - -int -main(int argc, char **argv) { - int endpt2fd, i, len; - char *endpt2name = "/dev/ugen0.2"; - uint8_t data[256]; - - if ((endpt2fd = open(endpt2name, O_RDWR)) == -1) { - fprintf(stderr, "Unable to open %s: %s\n", endpt2name, strerror(errno)); - exit(1); - } - - i = 1; - if (ioctl(endpt2fd, USB_SET_SHORT_XFER, &i) == -1) { - fprintf(stderr, "Unable to set short xfer on end point 2: %s\n", strerror(errno)); - exit(1); - } - - while(1) { - len = read(endpt2fd, data, 256); - printf("len = %d\n", len); - if (len == 0) { - printf("EOF\n"); - continue; - } - if (len == -1) { - printf("read error: %s\n", strerror(errno)); - exit(1); - } - - for (i = 0; i < len; i++) - printf("0x%02x ", data[i]); - printf("\n"); - } -} -
--- a/testugen2.c Mon Jan 19 22:54:19 2009 +1030 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -#include <sys/types.h> -#include <sys/ioctl.h> -#include <dev/usb/usb.h> -#include <sys/errno.h> -#include <sys/uio.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -/* Return codes for OWFirst()/OWNext() */ -#define OW_BADWIRE -3 -#define OW_BADCRC -2 -#define OW_NOPRESENCE -1 -#define OW_NOMODULES 0 -#define OW_FOUND 1 - -void docmd(int fd, uint8_t *buffer, int rlen, int wlen); - -int -main(int argc, char **argv) { - int endptfd, i; - char *endptname = "/dev/ugen0.2"; - uint8_t buffer[9]; - - if (argc < 2) { - fprintf(stderr, - "Bad usage:\n" - "\t%s cmd\n", argv[0]); - exit(1); - } - - if ((endptfd = open(endptname, O_RDWR)) == -1) { - fprintf(stderr, "Unable to open %s: %s\n", endptname, strerror(errno)); - exit(1); - } - - i = 1; - if (ioctl(endptfd, USB_SET_SHORT_XFER, &i) == -1) { - fprintf(stderr, "Unable to set short xfer on end point 1: %s\n", strerror(errno)); - exit(1); - } - - bzero(buffer, 9); - - if (!strcmp(argv[1], "reset")) { - buffer[0] = 0x00; - docmd(endptfd, buffer, 1, 1); - printf("OWTouchReset() reported %d\n", buffer[0]); - } else if (!strcmp(argv[1], "first")) { - buffer[0] = 0x01; - docmd(endptfd, buffer, 1, 9); - printf("OWFirst() = %d\n", buffer[0]); - if (buffer[0] == OW_FOUND) - printf("Found module %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - buffer[1], buffer[2], buffer[3], buffer[4], - buffer[5], buffer[6], buffer[7], buffer[8]); - } else if (!strcmp(argv[1], "next")) { - if (scanf(argv[2], "%hh:%hh:%hh:%hh:%hh:%hh:%hh:%hh", &buffer[1], &buffer[2], &buffer[3], - &buffer[4], &buffer[5], &buffer[6], &buffer[7], &buffer[8]) != 8) { - fprintf(stderr, "Unable to parse ROM ID\n"); - exit(1); - } - buffer[0] = 0x02; - fprintf(stderr, "About to OWNext()\n"); - docmd(endptfd, buffer, 9, 9); - fprintf(stderr, "OWNext() = %d\n", buffer[0]); - if (buffer[0] == OW_FOUND) - printf("Found module %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - buffer[1], buffer[2], buffer[3], buffer[4], - buffer[5], buffer[6], buffer[7], buffer[8]); - - } else if (!strcmp(argv[1], "scan")) { - buffer[0] = 0x00; - fprintf(stderr, "About to reset\n"); - docmd(endptfd, buffer, 1, 1); - printf("OWReset() reported %d\n", buffer[0]); - if (buffer[0] != 0) - exit(1); - - bzero(buffer, 9); - buffer[0] = 0x01; - fprintf(stderr, "About to OWFirst()\n"); - docmd(endptfd, buffer, 1, 9); - printf("OWFirst() = %d\n", buffer[0]); - - do { - switch (buffer[0]) { - case OW_BADWIRE: - printf("Bad wiring, either bus is held low, or a presence pulse was detected but no module found\n"); - break; - - case OW_NOPRESENCE: - printf("No presence pulse detected\n"); - break; - - case OW_BADCRC: - printf("Bad CRC\n"); - break; - - case OW_NOMODULES: - case OW_FOUND: - break; - - default: - printf("Unknown return code %d\n", buffer[0]); - break; - } - - if (buffer[0] != OW_FOUND) { - printf("No more modules\n"); - break; - } else { - printf("Found module %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - buffer[1], buffer[2], buffer[3], buffer[4], - buffer[5], buffer[6], buffer[7], buffer[8]); - } - - buffer[0] = 0x02; - fprintf(stderr, "About to OWNext()\n"); - docmd(endptfd, buffer, 9, 9); - } while(1); - } else { - printf("Unknown command: %s\n", argv[1]); - exit(1); - } - - - exit(0); -} - -void -docmd(int fd, uint8_t *buffer, int wlen, int rlen) { - char blah[20]; - int i; - - fprintf(stderr, "About to write\n"); - gets(blah); - - if ((i = write(fd, buffer, wlen)) == -1) { - fprintf(stderr, "Unable to write end point: %s\n", strerror(errno)); - exit(1); - } - if (i != wlen) - printf("Warning, only wrote %d of %d bytes\n", i, wlen); - - fprintf(stderr, "About to read\n"); - gets(blah); - - if ((i = read(fd, buffer, rlen)) == -1) { - fprintf(stderr, "Unable to read from end point: %s\n", strerror(errno)); - exit(1); - } - if (i != rlen) - printf("Warning, only read %d of %d bytes\n", i, wlen); -} - -
--- a/usb.c Mon Jan 19 22:54:19 2009 +1030 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1058 +0,0 @@ -#include <stdlib.h> -#include <avr/io.h> -#include <avr/pgmspace.h> -#include <avr/interrupt.h> -#include <avr/eeprom.h> -#include <util/delay.h> - -#include "usb.h" -#include "1wire.h" - -/* Maximum FIFO sizes for each endpoint */ -#define EP0_FIFO_SZ 16 -#define EP1_FIFO_SZ 16 -#define EP2_FIFO_SZ 64 - -/* PDIUSBD12 mode */ -#define D12_MODE_0 0x14 /* Endpoint config = 0, SoftConnect = 1, IRQ Mode = 1, - * Clock running = 0, No Lazy Clock = 0 - */ -#define D12_MODE_1 0x02 /* SOF mode = 0, Set-to-one = 0, Clock div = 2 (16Mhz) */ - -/* Debugging stuff */ -void uart_putsP(const char *addr); -void uart_puts(const char *addr); -int uart_putc(char c); -void uart_puts_dec(uint8_t a, uint8_t l); -void uart_puts_hex(uint8_t a); - -void parsebuf(uint8_t *buffer, uint8_t ep); - -/* USB administrivia */ -uint8_t deviceaddress; -uint8_t deviceconfigured; - -/* Endpoint buffers and such */ -/* EP0 in */ -static const uint8_t *sendbuffer0; -static uint8_t sendbytes0; - -/* EP0 out */ -/* This is unbuffered as we don't handle packets > EP0_FIFO_SZ */ - -/* EP1 */ -/* Unbuffered as yet */ -static uint8_t packet1[270]; -static uint16_t packetlen1; - -/* EP2 in */ -static const uint8_t *sendbuffer2; -static uint8_t sendbytes2; - -/* EP2 out */ -static uint8_t packet2[270]; -static uint16_t packetlen2; - -/* XXX: Not actually used */ -void (*bootloader)(void) = (void*)0xe000; - -/* Device/endpoint/etc descriptions */ -const USB_DEVICE_DESCRIPTOR DeviceDescriptor = { - sizeof(USB_DEVICE_DESCRIPTOR), /* bLength */ - TYPE_DEVICE_DESCRIPTOR, /* bDescriptorType */ - 0x0110, /* bcdUSB USB Version 1.1 */ - 0, /* bDeviceClass */ - 0, /* bDeviceSubclass */ - 0, /* bDeviceProtocol */ - EP0_FIFO_SZ, /* bMaxPacketSize in Bytes */ - 0x4753, /* idVendor (unofficial GS) */ - 0x0001, /* idProduct */ - 0x0100, /* bcdDevice */ - 1, /* iManufacturer String Index */ - 2, /* iProduct String Index */ - 3, /* iSerialNumber String Index */ - 1 /* bNumberConfigurations */ -}; - -const USB_CONFIG_DATA ConfigurationDescriptor = { - { /* configuration descriptor */ - sizeof(USB_CONFIGURATION_DESCRIPTOR), /* bLength */ - TYPE_CONFIGURATION_DESCRIPTOR, /* bDescriptorType */ - sizeof(USB_CONFIG_DATA), /* wTotalLength */ - 2, /* bNumInterfaces */ - 1, /* bConfigurationValue */ - 0, /* iConfiguration String Index */ - 0x80, /* bmAttributes Bus Powered, No Remote Wakeup */ - 100/2 /* bMaxPower in mA */ - }, - { /* interface descriptor */ - sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ - TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */ - 0, /* bInterface Number */ - 0, /* bAlternateSetting */ - 2, /* bNumEndpoints */ - 0xff, /* bInterfaceClass (Vendor specific) */ - 0x02, /* bInterfaceSubClass */ - 0x00, /* bInterfaceProtocol */ - 0 /* iInterface String Index */ - }, - { /* endpoint descriptor */ - sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ - TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */ - 0x02, /* bEndpoint Address EP2 OUT */ - 0x02, /* bmAttributes - Bulk */ - 0x0040, /* wMaxPacketSize */ - 0x00 /* bInterval */ - }, - { /* endpoint descriptor */ - sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ - TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */ - 0x82, /* bEndpoint Address EP2 IN */ - 0x02, /* bmAttributes - Bulk */ - 0x0040, /* wMaxPacketSize */ - 0x00 /* bInterval */ - }, - { /* interface descriptor */ - sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ - TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */ - 1, /* bInterface Number */ - 0, /* bAlternateSetting */ - 2, /* bNumEndpoints */ - 0xff, /* bInterfaceClass (Vendor specific) */ - 0x02, /* bInterfaceSubClass */ - 0x00, /* bInterfaceProtocol */ - 0 /* iInterface String Index */ - }, - { /* endpoint descriptor */ - sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ - TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */ - 0x01, /* bEndpoint Address EP1 OUT */ - 0x02, /* bmAttributes - Bulk */ - 0x0010, /* wMaxPacketSize */ - 0x00 /* bInterval */ - }, - { /* endpoint descriptor */ - sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ - TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */ - 0x81, /* bEndpoint Address EP1 IN */ - 0x02, /* bmAttributes - Bulk */ - 0x0010, /* wMaxPacketSize */ - 0x00 /* bInterval */ - } -}; -const LANGID_DESCRIPTOR LANGID_Descriptor = { /* LANGID String Descriptor - * Zero */ - sizeof(LANGID_DESCRIPTOR), /* bLength - must match string below */ - TYPE_STRING_DESCRIPTOR, /* bDescriptorType */ - 0x0409 /* LANGID US English */ -}; - -STRING_DESCRIPTOR Manufacturer_Descriptor = { - sizeof(STRING_DESCRIPTOR) + 32, /* bLength */ - TYPE_STRING_DESCRIPTOR, /* bDescriptorType */ - "G\0e\0n\0e\0s\0i\0s\0 \0S\0o\0f\0t\0w\0a\0r\0e\0" /* ManufacturerString in - * UNICODE */ -}; - -STRING_DESCRIPTOR Product_Descriptor = { - sizeof(STRING_DESCRIPTOR) + 48, /* bLength */ - TYPE_STRING_DESCRIPTOR, /* bDescriptorType */ - /* ProductString in - * UNICODE */ - "R\0S\0""-\0""4\0""8\0""5\0"" \0M\0u\0l\0t\0i\0d\0r\0o\0p\0 \0A\0d\0a\0p\0t\0e\0r\0" - /* XXX: dunno why I need the double quote magic above.. */ -}; - -STRING_DESCRIPTOR Serial_Descriptor; -STRING_DESCRIPTOR EE_Serial_Descriptor __attribute__ ((section (".eeprom"))) = { /* SerialString 3 */ - sizeof(STRING_DESCRIPTOR) + 20, /* bLength - must match string below */ - TYPE_STRING_DESCRIPTOR, /* bDescriptorType */ - "1\02\03\0" -}; - -/******************************************************************************* -** d12_get_data -** -** Read a data byte -*/ -uint8_t -d12_get_data(void) { - uint8_t data; - - _delay_us(1); - PDICTL &= ~_BV(PDIA0); /* Data phase */ - PDIDDR = 0x00; /* Set to input */ - PDICTL &= ~_BV(PDIRD); /* Pull RD_N low */ - PDICTL &= ~_BV(PDIRD); /* Delay 40ns */ - PDICTL &= ~_BV(PDIRD); - PDICTL &= ~_BV(PDIRD); - data = PINA; /* Read the data */ - PDICTL |= _BV(PDIRD); /* Pull RD_N high */ - - return(data); -} - -/******************************************************************************* -** d12_set_data -** -** Write a data byte -*/ -void -d12_set_data(uint8_t data) { - _delay_us(1); - PDICTL &= ~_BV(PDIA0); /* Data phase */ - PDIDDR = 0xff; /* Set to output */ - PDIPORT = data; /* Put the data on the bus */ - PDICTL &= ~_BV(PDIWR); /* Pull WR_N low */ - PDICTL &= ~_BV(PDIWR); /* Delay 40ns */ - PDICTL &= ~_BV(PDIWR); - PDICTL &= ~_BV(PDIWR); - PDICTL |= _BV(PDIWR); /* Pull WR_N high */ - PDICTL |= _BV(PDIWR); /* Delay 40 ns */ - PDICTL |= _BV(PDIWR); - PDICTL |= _BV(PDIWR); - PDIDDR = 0x00; /* Back to input */ -} - -/******************************************************************************* -** d12_set_cmd -** -** Start a command -*/ -void -d12_set_cmd(uint8_t cmd) { - _delay_us(1); - PDICTL |= _BV(PDIA0); /* Command phase */ - PDIDDR = 0xff; /* Set to output */ - PDIPORT = cmd; /* Put the data on the bus */ - PDICTL &= ~_BV(PDIWR); /* Pull WR_N low */ - PDICTL &= ~_BV(PDIWR); /* Delay 40ns */ - PDICTL &= ~_BV(PDIWR); - PDICTL &= ~_BV(PDIWR); - PDICTL |= _BV(PDIWR); /* Pull WR_N high */ - PDICTL |= _BV(PDIWR); /* Delay 40ns */ - PDICTL |= _BV(PDIWR); - PDICTL |= _BV(PDIWR); - PDIDDR = 0x00; /* Back to input */ -} - -/******************************************************************************* -** d12_write_cmd -** -** Issue a command with associated data -*/ -void -d12_write_cmd(uint8_t command, const uint8_t *buffer, uint8_t count) { - uint8_t i; - - d12_set_cmd(command); - if (count) { - for (i = 0; i < count; i++) { - d12_set_data(buffer[i]); - } - } -} - -/******************************************************************************* -** d12_read_cmd -** -** Issue a command and read back the data -*/ -void -d12_read_cmd(uint8_t command, uint8_t *buffer, uint8_t count) { - uint8_t i; - - d12_set_cmd(command); - if (count) { - for (i = 0; i < count; i++) { - buffer[i] = d12_get_data(); - } - } -} - -/******************************************************************************* -** usb_init -** -** Configure the PDIUSBD12 -*/ -void -usb_init(void) { - uint8_t buffer[2]; - - /* Check the device is present */ - d12_read_cmd(D12_READ_CHIP_ID, buffer, 2); - if (buffer[0] != 0x12 || buffer[1] != 0x10) { - uart_putsP(PSTR("PDIUSBD12 does not appear to be present/working, chip ID = 0x")); - uart_puts_hex(buffer[0]); - uart_puts_hex(buffer[1]); - uart_putsP(PSTR(", expected 0x1210\r\n")); - return; - } - - /* pull EE_Serial_Descriptor into RAM */ - eeprom_read_block(&Serial_Descriptor, &EE_Serial_Descriptor, EE_Serial_Descriptor.bLength); - - /* Set Address to zero (default) and enable function */ - buffer[0] = 0x80; - d12_write_cmd(D12_SET_ADDRESS_ENABLE, buffer, 1); - - /* Enable function generic endpoints */ - buffer[0] = 0x01; - d12_write_cmd(D12_SET_ENDPOINT_ENABLE, buffer, 1); - - /* Configure the device (soft connect off) */ - buffer[0] = D12_MODE_0 & 0xef; - buffer[1] = D12_MODE_1; - d12_write_cmd(D12_SET_MODE, buffer, 2); - - /* Delay long enough for the PC to notice the disconnect */ - _delay_us(1000); - - buffer[0] |= 0x10; /* Soft connect on */ - d12_write_cmd(D12_SET_MODE, buffer, 2); - - /* Endpoint 2 IN/OUT IRQ enable */ - buffer[0] = 0xc0; - d12_write_cmd(D12_SET_DMA, buffer, 1); - -} - -/******************************************************************************* -** usb_intr -** -** Process any pending interrupts -*/ -void -usb_intr(void) { - uint8_t irq[2]; - uint8_t buffer[8]; - - d12_read_cmd(D12_READ_INTERRUPT_REGISTER, irq, 2); - - /* Why do we get interrupts when this is 0? */ - if (irq[0] == 0) - return; - - uart_putsP(PSTR("usb_intr() called\r\n")); - - if (irq[0] & D12_INT_BUS_RESET) { - uart_putsP(PSTR("Bus reset\r\n")); - usb_init(); - return; - } - - if (irq[0] & D12_INT_SUSPEND) { - uart_putsP(PSTR("Suspend change\r\n")); - } - - if (irq[0] & D12_INT_EP0_IN) { - d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_IN, buffer, 1); - if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { - uart_putsP(PSTR("EP0_IN error ")); - uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); - uart_putsP(PSTR("\r\n")); - } - - /* Handle any outgoing data for EP0 */ - d12_send_data_ep0(); - } - - /* Handle configuration and misc stuff */ - if (irq[0] & D12_INT_EP0_OUT) { - d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_OUT, buffer, 1); - if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { - uart_putsP(PSTR("EP0_OUT error ")); - uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); - uart_putsP(PSTR("\r\n")); - } - - if (buffer[0] & D12_LAST_TRAN_SETUP) - d12_handle_setup(); - else { - /* Data packet */ - } - } - - /* EPx_IN is when the host has had a packet of data and is expecting more */ - if (irq[0] & D12_INT_EP1_IN) { - d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP1_IN, buffer, 1); - if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { - uart_putsP(PSTR("EP1_IN error ")); - uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); - uart_putsP(PSTR("\r\n")); - } - - /* Select endpoint */ - d12_read_cmd(D12_ENDPOINT_EP1_IN, buffer, 1); - - if (buffer[0] & 0x01) - uart_putsP(PSTR("EP1_IN is full\r\n")); - - if (buffer[0] & 0x02) - uart_putsP(PSTR("EP1_IN is stalled\r\n")); - - d12_write_endpt(D12_ENDPOINT_EP1_IN, NULL, 0); - } - - /* EPx_OUT is when we have gotten a packet from the host */ - if (irq[0] & D12_INT_EP1_OUT) { - d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP1_OUT, buffer, 1); - if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { - uart_putsP(PSTR("EP1_OUT error ")); - uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); - uart_putsP(PSTR("\r\n")); - } - - d12_receive_data_ep1(); - } - - if (irq[0] & D12_INT_EP2_IN) { - d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_IN, buffer, 1); - if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { - uart_putsP(PSTR("EP2_IN error ")); - uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); - uart_putsP(PSTR("\r\n")); - } - - d12_send_data_ep2(); - } - - if (irq[0] & D12_INT_EP2_OUT) { - d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_OUT, buffer, 1); - if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { - uart_putsP(PSTR("EP2_OUT error ")); - uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); - uart_putsP(PSTR("\r\n")); - } - d12_receive_data_ep2(); - } -} - -/******************************************************************************* -** usb_gendata -** -** Fake up some data for testing purposes -*/ -void -usb_gendata(void) { - packet2[0] = 'a'; - packet2[1] = 'b'; - packet2[2] = 'c'; - packet2[3] = '\n'; - packet2[4] = '\r'; - sendbytes2 = 5; - sendbuffer2 = (uint8_t *)&packet2[0]; - - /* Kick off the data transfer */ - d12_send_data_ep2(); -} - -/******************************************************************************* -** d12_handle_setup -** -** Handle setup packet stuff for endpoint 0 -*/ -void -d12_handle_setup(void) { - uint8_t buffer[2]; - USB_SETUP_REQUEST setuppkt; - - /* Read the setup packet */ - d12_read_endpt(D12_ENDPOINT_EP0_OUT, (uint8_t *)&setuppkt); - - /* Ack the packet to EP0_OUT */ - d12_write_cmd(D12_ENDPOINT_EP0_OUT, NULL, 0); - d12_write_cmd(D12_ACK_SETUP, NULL, 0); - d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); - - /* Ack the packet to EP0_IN */ - d12_write_cmd(D12_ENDPOINT_EP0_IN, NULL, 0); - d12_write_cmd(D12_ACK_SETUP, NULL, 0); - - /* Parse request type */ - switch (setuppkt.bmRequestType & 0x7f) { - case STANDARD_DEVICE_REQUEST: - switch (setuppkt.bRequest) { - case GET_STATUS: - /* Get status request should return remote - * wakeup and self powered status - */ - buffer[0] = 0x01; - buffer[1] = 0x00; - d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2); - break; - case CLEAR_FEATURE: - case SET_FEATURE: - /* We don't support DEVICE_REMOTE_WAKEUP or - * TEST_MODE - */ - - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - - case SET_ADDRESS: - deviceaddress = setuppkt.wValue | 0x80; - d12_write_cmd(D12_SET_ADDRESS_ENABLE, &deviceaddress, 1); - d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); - break; - - case GET_DESCRIPTOR: - d12_getdescriptor(&setuppkt); - break; - - case GET_CONFIGURATION: - d12_write_endpt(D12_ENDPOINT_EP0_IN, &deviceconfigured, 1); - break; - - case SET_CONFIGURATION: - deviceconfigured = setuppkt.wValue & 0xff; - d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); - break; - - - case SET_DESCRIPTOR: - default: - /* Unsupported, stall */ - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } - break; - - case STANDARD_INTERFACE_REQUEST: - switch (setuppkt.bRequest) { - case GET_STATUS: - /* Should return 0, 0 (reserved) */ - buffer[0] = 0x00; - buffer[1] = 0x00; - d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2); - break; - - case SET_INTERFACE: - if (setuppkt.wIndex == 0 && setuppkt.wValue == 0) - d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); - else { - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - } - - break; - - case GET_INTERFACE: - /* Can only handle interface 0 ... */ - if (setuppkt.wIndex == 0) { - buffer[0] = 0; - d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 1); - break; - } - /* .. otherwise fall through to error */ - - case CLEAR_FEATURE: - case SET_FEATURE: - default: - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } - break; - - case STANDARD_ENDPOINT_REQUEST: - switch (setuppkt.bRequest) { - case CLEAR_FEATURE: - case SET_FEATURE: - /* Halt(stall) is required to be implemented on - * interrupt and bulk endpoints. - */ - if (setuppkt.wValue == ENDPOINT_HALT) { - if (setuppkt.bRequest == CLEAR_FEATURE) - buffer[0] = 0x00; - else - buffer[0] = 0x01; - switch (setuppkt.wIndex & 0xFF) { - case 0x01: - d12_write_cmd(D12_SET_ENDPOINT_STATUS + \ - D12_ENDPOINT_EP1_OUT, buffer, 1); - break; - case 0x81: - d12_write_cmd(D12_SET_ENDPOINT_STATUS + \ - D12_ENDPOINT_EP1_IN, buffer, 1); - break; - case 0x02: - d12_write_cmd(D12_SET_ENDPOINT_STATUS + \ - D12_ENDPOINT_EP2_OUT, buffer, 1); - break; - case 0x82: - d12_write_cmd(D12_SET_ENDPOINT_STATUS + \ - D12_ENDPOINT_EP2_IN, buffer, 1); - break; - default: /* Invalid Endpoint - - * RequestError */ - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } - d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); - } else { - /* - * No other Features for Endpoint - - * Request Error - */ - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - } - break; - - case GET_STATUS: - /* - * Get Status Request to Endpoint should - * return Halt Status in D0 for Interrupt and Bulk - */ - switch (setuppkt.wIndex & 0xFF) { - case 0x01: - d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ - D12_ENDPOINT_EP1_OUT, buffer, 1); - break; - case 0x81: - d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ - D12_ENDPOINT_EP1_IN, buffer, 1); - break; - case 0x02: - d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ - D12_ENDPOINT_EP2_OUT, buffer, 1); - break; - case 0x82: - d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ - D12_ENDPOINT_EP2_IN, buffer, 1); - break; - default: /* Invalid Endpoint - - * RequestError */ - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } - if (buffer[0] & 0x08) - buffer[0] = 0x01; - else - buffer[0] = 0x00; - buffer[1] = 0x00; - d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2); - break; - - default: - /* Unsupported - Request Error - Stall */ - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } - break; - case VENDOR_DEVICE_REQUEST: - case VENDOR_ENDPOINT_REQUEST: - switch (setuppkt.bRequest) { - case VENDOR_RESET: - d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); - _delay_us(1000); - /* disconnect from USB */ - buffer[0] = D12_MODE_0 & 0xef; - buffer[1] = D12_MODE_1; - d12_write_cmd(D12_SET_MODE, buffer, 2); - _delay_us(1000); - cli(); - reset(); - /* NOT REACHED */ - break; - - case VENDOR_UPDATE: - d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); - _delay_us(1000); - /* disconnect from USB */ - buffer[0] = D12_MODE_0 & 0xef; - buffer[1] = D12_MODE_1; - d12_write_cmd(D12_SET_MODE, buffer, 2); - _delay_us(1000); - cli(); - bootloader(); - /* NOT REACHED */ - break; - - default: - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } - break; - case VENDOR_INTERFACE_REQUEST: - switch (setuppkt.bRequest) { - default: - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } - break; - default: - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } -} - - -/******************************************************************************* -** reset -** -** Reset the micro by triggering the watchdog timer. -** -*/ -void -reset(void) { - uart_putsP(PSTR("Resetting!\r\n")); - _delay_us(1000); - - /* Disable the interrupts */ - MCUCR = _BV(IVCE); - MCUCR = 0; - - /* Enable watchdog, smallest prescaler */ - WDTCR = _BV(WDE); - - /* Wait for oblivion! */ - for (;;) - ; -} - -/******************************************************************************* -** d12_getdescriptor -** -** Handle returning the various descriptor to the host -** -** Note: that we need to truncate the request because the host first -** requests the first 2 bytes to find out then size, then requests the -** rest. -*/ -void -d12_getdescriptor(USB_SETUP_REQUEST *setuppkt) { - switch ((setuppkt->wValue & 0xff00) >> 8) { - case TYPE_DEVICE_DESCRIPTOR: - sendbuffer0 = (const uint8_t *)&DeviceDescriptor; - sendbytes0 = DeviceDescriptor.bLength; - if (sendbytes0 >= setuppkt->wLength) - sendbytes0 = setuppkt->wLength; - - d12_send_data_ep0(); - break; - - case TYPE_CONFIGURATION_DESCRIPTOR: - sendbuffer0 = (const uint8_t *)&ConfigurationDescriptor; - sendbytes0 = sizeof(ConfigurationDescriptor); - if (sendbytes0 >= setuppkt->wLength) - sendbytes0 = setuppkt->wLength; - - d12_send_data_ep0(); - break; - - case TYPE_STRING_DESCRIPTOR: - switch (setuppkt->wValue & 0xFF) { - case 0: - sendbuffer0 = (const uint8_t *)&LANGID_Descriptor; - sendbytes0 = LANGID_Descriptor.bLength; - break; - - case 1: - sendbuffer0 = (const uint8_t *)&Manufacturer_Descriptor; - sendbytes0 = Manufacturer_Descriptor.bLength; - break; - - case 2: - sendbuffer0 = (const uint8_t *)&Product_Descriptor; - sendbytes0 = Product_Descriptor.bLength; - break; - - case 3: - sendbuffer0 = (const uint8_t *)&Serial_Descriptor; - sendbytes0 = Serial_Descriptor.bLength; - break; - - default: - sendbuffer0 = NULL; - sendbytes0 = 0; - } - if (sendbytes0 >= setuppkt->wLength) - sendbytes0 = setuppkt->wLength; - - d12_send_data_ep0(); - break; - - default: - d12_stallendpt(D12_ENDPOINT_EP0_IN); - d12_stallendpt(D12_ENDPOINT_EP0_OUT); - break; - } -} - -/******************************************************************************* -** d12_stallendpt -** -** Stall the nominated endpoint. -** -*/ -void -d12_stallendpt(uint8_t ep) { - uint8_t buffer[] = {0x01}; - - d12_write_cmd(D12_SET_ENDPOINT_STATUS + ep, buffer, 1); -} - -/******************************************************************************* -** d12_read_cmd -** -** Read data from the nominated endpoint if it's full. -** -*/ -uint8_t -d12_read_endpt(uint8_t endpt, uint8_t *buffer) { - uint8_t d12header[2], status, i; - - d12header[1] = 0; - - /* Select Endpoint */ - d12_read_cmd(endpt, &status, 1); - - /* Check if buffer is Full */ - if (status & 0x01) { - d12_set_cmd(D12_READ_BUFFER); - d12header[0] = d12_get_data(); - d12header[1] = d12_get_data(); - if (d12header[1]) { - for (i = 0; i < d12header[1]; i++) - buffer[i] = d12_get_data(); - } - /* Allow new packets to be accepted */ - d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); - - } - return d12header[1]; -} - -/******************************************************************************* -** d12_read_cmd -** -** Write data to the nominated endpoint. -** -*/ -void -d12_write_endpt(uint8_t endpt, const uint8_t *buffer, uint8_t bytes) { - uint8_t status, i; - - /* Select Endpoint */ - d12_read_cmd(endpt, &status, 1); - if ((status & 0x01) != 0) { - uart_putsP(PSTR("Endpoint ")); - uart_puts_dec(endpt / 2, 0); - uart_putsP(PSTR(" IN is full..\r\n")); - return; - } - - /* Write Header */ - d12_set_cmd(D12_WRITE_BUFFER); - d12_set_data(0x00); - d12_set_data(bytes); - /* Write Packet */ - if (bytes) { - for (i = 0; i < bytes; i++) - d12_set_data(buffer[i]); - } - /* Validate buffer */ - d12_write_cmd(D12_VALIDATE_BUFFER, NULL, 0); -} - -/******************************************************************************* -** d12_send_data_ep0 -** -** Send the next FIFOs worth of data to the endpoint and update the -** pointer and counters. -** -** d12_send_data_epX should be collapsed together but it's more -** complex than it looks. -** -*/ -void -d12_send_data_ep0(void) { - uint8_t status; - - /* Select endpoint */ - d12_read_cmd(D12_ENDPOINT_EP0_IN, &status, 1); - - if (status & 0x01) /* Bail if the buffer is full */ - return; - - if (sendbytes0 == 0) { - /* Nothing to do */ - } else if (sendbytes0 >= EP0_FIFO_SZ) { - /* Write another EP0_FIFO_SZ Bytes to buffer and send */ - d12_write_endpt(D12_ENDPOINT_EP0_IN, sendbuffer0, EP0_FIFO_SZ); - sendbuffer0 += EP0_FIFO_SZ; - sendbytes0 -= EP0_FIFO_SZ; - } else { - /* Buffer must have less than EP0_FIFO_SZ bytes left */ - d12_write_endpt(D12_ENDPOINT_EP0_IN, sendbuffer0, sendbytes0); - sendbytes0 = 0; - } -} - -/******************************************************************************* -** d12_send_data_ep2 -** -** Send the next FIFOs worth of data to the endpoint and update the -** pointer and counters. -** -*/ -void -d12_send_data_ep2(void) { - uint8_t status; - - /* Select endpoint */ - d12_read_cmd(D12_ENDPOINT_EP2_IN, &status, 1); - - if (status & 0x01) /* Bail if the buffer is full */ - return; - - if (sendbytes2 == 0) { - /* Nothing to do */ - } else if (sendbytes2 >= EP2_FIFO_SZ) { - /* Write another EP2_FIFO_SZ Bytes to buffer and send */ - d12_write_endpt(D12_ENDPOINT_EP2_IN, sendbuffer2, EP2_FIFO_SZ); - sendbuffer2 += EP2_FIFO_SZ; - sendbytes2 -= EP2_FIFO_SZ; - } else { - /* Buffer must have less than EP2_FIFO_SZ bytes left */ - d12_write_endpt(D12_ENDPOINT_EP2_IN, sendbuffer2, sendbytes2); - sendbytes2 = 0; - } -} - -/******************************************************************************* -** d12_receive_data_ep2 -** -** Get the next FIFOs worth of data from the endpoint -** -*/ -void -d12_receive_data_ep2(void) { - uint8_t d12header[2], bytes, i, status; - - /* Select Endpoint */ - d12_read_cmd(D12_ENDPOINT_EP2_OUT, &status, 1); - - if (!(status & 0x01)) /* Bail if the buffer is empty */ - return; - - /* Read header */ - d12_set_cmd(D12_READ_BUFFER); - d12header[0] = d12_get_data(); - d12header[1] = d12_get_data(); - bytes = d12header[1]; - - packetlen2 = 0; - - for (i = 0; i < bytes; i++) - packet2[i] = d12_get_data(); - - packetlen2 += bytes; - - /* Allow new packets to be accepted */ - d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); - - uart_putsP(PSTR("Got ")); - uart_puts_dec(bytes, 0); - uart_putsP(PSTR(" bytes from the host\r\n")); - - parsebuf(packet2, D12_ENDPOINT_EP2_IN); - -} - -/******************************************************************************* -** d12_receive_data_ep1 -** -** Get the next FIFOs worth of data from the endpoint -** -*/ -void -d12_receive_data_ep1(void) { - uint8_t d12header[2], bytes, i, status; - - /* Select Endpoint */ - d12_read_cmd(D12_ENDPOINT_EP1_OUT, &status, 1); - - /* Check if Buffer is Full */ - if (!(status & 0x01)) - return; - - /* Read header */ - d12_set_cmd(D12_READ_BUFFER); - d12header[0] = d12_get_data(); - d12header[1] = d12_get_data(); - bytes = d12header[1]; - - packetlen1 = 0; - - for (i = 0; i < bytes; i++) - packet1[i] = d12_get_data(); - - packetlen1 += bytes; - - uart_putsP(PSTR("Got ")); - uart_puts_dec(bytes, 0); - uart_putsP(PSTR(" bytes from the host\r\n")); - - /* Allow new packets to be accepted */ - d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); - - parsebuf(packet1, D12_ENDPOINT_EP1_IN); -} - -void -parsebuf(uint8_t *buffer, uint8_t ep) { - int i; - - switch (buffer[0]) { - case 0x00: - uart_putsP(PSTR("OWTouchReset()\r\n")); - buffer[0] = OWTouchReset(); - d12_write_endpt(ep, buffer, 1); - break; - - case 0x01: - uart_putsP(PSTR("OWFirst()\r\n")); - buffer[0] = OWFirst(&buffer[1], 1, 0); - for (i = 0; i < 9; i++) { - uart_puts_hex(buffer[i + 1]); - uart_putsP(PSTR(" ")); - } - uart_putsP(PSTR("\r\n")); - d12_write_endpt(ep, buffer, 9); - break; - - case 0x02: - uart_putsP(PSTR("OWNext()\r\n")); - buffer[0] = OWNext(&buffer[1], 1, 0); - d12_write_endpt(ep, buffer, 9); - break; - - case 0x03: - uart_putsP(PSTR(" bytes, asked to do temperature conversion for ")); - for (i = 0; i < 8; i++) { - uart_puts_hex(buffer[i + 1]); - if (i != 7) - uart_putsP(PSTR(":")); - } - - uart_putsP(PSTR("\r\n")); - d12_write_endpt(ep, buffer, 9); - - break; - - default: - uart_putsP(PSTR("Unknown command on endpoint 1\r\n")); - break; - } -}
--- a/usb.h Mon Jan 19 22:54:19 2009 +1030 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2003 Bernd Walter - * All rights reserved. - */ - -/* Example Source Code for USB Enumeration using a PDIUSBD11 connected to a PIC16F87x - * Copyright 2001 Craig Peacock, Craig.Peacock@beyondlogic.org - * 31th December 2001 http://www.beyondlogic.org - */ - -typedef struct { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} __attribute__ ((packed)) USB_SETUP_REQUEST; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize0; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; - uint8_t iManufacturer; - uint8_t iProduct; - uint8_t iSerialNumber; - uint8_t bNumConfigurations; -} __attribute__ ((packed)) USB_DEVICE_DESCRIPTOR; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - uint16_t wMaxPacketSize; - uint8_t bInterval; -} __attribute__ ((packed)) USB_ENDPOINT_DESCRIPTOR; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wTotalLength; - uint8_t bNumInterfaces; - uint8_t bConfigurationValue; - uint8_t iConfiguration; - uint8_t bmAttributes; - uint8_t MaxPower; -} __attribute__ ((packed)) USB_CONFIGURATION_DESCRIPTOR; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bInterfaceNumber; - uint8_t bAlternateSetting; - uint8_t bNumEndpoints; - uint8_t bInterfaceClass; - uint8_t bInterfaceSubClass; - uint8_t bInterfaceProtocol; - uint8_t iInterface; -} __attribute__ ((packed)) USB_INTERFACE_DESCRIPTOR; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wHIDClassSpecComp; - uint8_t bCountry; - uint8_t bNumDescriptors; - uint8_t b1stDescType; - uint16_t w1stDescLength; -} __attribute__ ((packed)) USB_HID_DESCRIPTOR; - -typedef struct { - USB_CONFIGURATION_DESCRIPTOR ConfigDescriptor; - USB_INTERFACE_DESCRIPTOR InterfaceDescriptor0; - USB_ENDPOINT_DESCRIPTOR EndpointDescriptor00; - USB_ENDPOINT_DESCRIPTOR EndpointDescriptor01; - USB_INTERFACE_DESCRIPTOR InterfaceDescriptor1; - USB_ENDPOINT_DESCRIPTOR EndpointDescriptor10; - USB_ENDPOINT_DESCRIPTOR EndpointDescriptor11; -} __attribute__ ((packed)) USB_CONFIG_DATA; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - char bString[]; -} __attribute__ ((packed)) STRING_DESCRIPTOR; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wLANGID0; -} __attribute__ ((packed)) LANGID_DESCRIPTOR; - -#define D12_SET_ADDRESS_ENABLE 0xd0 -#define D12_SET_ENDPOINT_ENABLE 0xd8 -#define D12_SET_MODE 0xf3 -#define D12_SET_DMA 0xfb -#define D12_READ_INTERRUPT_REGISTER 0xf4 -#define D12_READ_BUFFER 0xf0 -#define D12_WRITE_BUFFER 0xf0 -#define D12_ACK_SETUP 0xf2 -#define D12_CLEAR_BUFFER 0xf2 -#define D12_VALIDATE_BUFFER 0xfa -#define D12_READ_LAST_TRANSACTION 0x40 -#define D12_SET_ENDPOINT_STATUS 0x40 -#define D12_READ_ENDPOINT_STATUS 0x80 -#define D12_READ_CHIP_ID 0xfd - -#define D12_ENDPOINT_EP0_OUT 0x00 -#define D12_ENDPOINT_EP0_IN 0x01 -#define D12_ENDPOINT_EP1_OUT 0x02 -#define D12_ENDPOINT_EP1_IN 0x03 -#define D12_ENDPOINT_EP2_OUT 0x04 -#define D12_ENDPOINT_EP2_IN 0x05 - -#define D12_INT_EP0_OUT 0x01 -#define D12_INT_EP0_IN 0x02 -#define D12_INT_EP1_OUT 0x04 -#define D12_INT_EP1_IN 0x08 -#define D12_INT_EP2_OUT 0x10 -#define D12_INT_EP2_IN 0x20 -#define D12_INT_BUS_RESET 0x40 -#define D12_INT_SUSPEND 0x80 - -#define D12_LAST_TRAN_OK 0x01 -#define D12_LAST_TRAN_ERRMSK 0x1e -#define D12_LAST_TRAN_SETUP 0x20 -#define D12_LAST_TRAN_DATA 0x40 -#define D12_LAST_TRAN_OFLOW 0x80 - -#define STANDARD_DEVICE_REQUEST 0x00 -#define STANDARD_INTERFACE_REQUEST 0x01 -#define STANDARD_ENDPOINT_REQUEST 0x02 -#define VENDOR_DEVICE_REQUEST 0x40 -#define VENDOR_INTERFACE_REQUEST 0x41 -#define VENDOR_ENDPOINT_REQUEST 0x42 - -#define GET_STATUS 0 -#define CLEAR_FEATURE 1 -#define SET_FEATURE 3 -#define SET_ADDRESS 5 -#define GET_DESCRIPTOR 6 -#define SET_DESCRIPTOR 7 -#define GET_CONFIGURATION 8 -#define SET_CONFIGURATION 9 -#define GET_INTERFACE 10 -#define SET_INTERFACE 11 -#define SYNCH_FRAME 12 - -#define VENDOR_DOTEMP 125 -#define VENDOR_UPDATE 126 -#define VENDOR_RESET 127 - -#define ENDPOINT_HALT 0 - -#define TYPE_DEVICE_DESCRIPTOR 1 -#define TYPE_CONFIGURATION_DESCRIPTOR 2 -#define TYPE_STRING_DESCRIPTOR 3 -#define TYPE_INTERFACE_DESCRIPTOR 4 -#define TYPE_ENDPOINT_DESCRIPTOR 5 -#define TYPE_HID_DESCRIPTOR 0x21 - -#define USB_ENDPOINT_TYPE_CONTROL 0x00 -#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 -#define USB_ENDPOINT_TYPE_BULK 0x02 -#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 - -/* Function prototypes */ -uint8_t d12_get_data(void); -void d12_set_data(uint8_t data); -void d12_set_cmd(uint8_t cmd); -void d12_write_cmd(uint8_t command, const uint8_t *buffer, uint8_t count); -void d12_read_cmd(uint8_t command, uint8_t *buffer, uint8_t count); -uint8_t d12_read_endpt(uint8_t endpt, uint8_t *buffer); - -void d12_ep0_irq(void); -void d12_handle_setup(void); -void d12_getdescriptor(USB_SETUP_REQUEST *setuppkt); -void d12_stallendpt(uint8_t ep); -uint8_t d12_read_endpt(uint8_t endpt, uint8_t *buffer); -void d12_write_endpt(uint8_t endpt, const uint8_t *buffer, uint8_t bytes); -void d12_send_data_ep0(void); -void d12_receive_data_ep1(void); -void d12_send_data_ep2(void); -void d12_receive_data_ep2(void); - -void reset(void); - -void usb_init(void); -void usb_intr(void); -void usb_gendata(void); - -/* - * The PDIUSBD12 is wired up like so - * - * PDI AVR - * ====================== - * D7:0 <=> PA7:0 - * RD_N <= PB0 - * INT_N => PB1 - * WR_N <= PB2 - * A0 <= PB3 (0 = data, 1 = cmd) - * SUSPEND <=> PB4 - */ - -#define PDIPORT PORTA -#define PDIDDR PORTA -#define PDICTL PORTB -#define PDIRD PB0 -#define PDIINT PB1 -#define PDIWR PB2 -#define PDIA0 PB3 -#define PDISUSP PB4 -