#include #include #include #include #include #include #include "usbn2mc.h" #define F_CPU 16000000UL #include #include "../usbn2mc/main/usbnapi.h" #include "usbn2mc.h" #include "common.h" #include "protocol.h" #include "wait.h" #include "93c46.h" #include "adc.h" #include "can.h" #include "eeprom.h" #include "i2c.h" #include "io.h" #include "pwm.h" #include "spi.h" #include "uart.h" #include #include "debug.h" SIGNAL (SIG_INTERRUPT4) { USBNInterrupt (); } SIGNAL (SIG_UART0_RECV) { } /* internal timer */ SIGNAL (SIG_OVERFLOW0) { common_scheduler (); TCNT0 = octopus.latency_timer; } void USBCommandRX (char *buf) { int i; debugf("receiving command: %X (length: %u)\n", buf[1]); /* a paket can be max 255 bytes */ if (octopus.long_rx_cmd == 1) { debugf("get next\n"); for (i = 0; i < 64; i++) request[octopus.long_rx_index + i] = buf[i]; octopus.long_rx_index = octopus.long_rx_index + i; if (octopus.long_rx_index >= octopus.long_rx_bytes) { octopus.long_rx_cmd = 0; USBMessageIn (request); } } else { debugf("get and execute\n"); octopus.long_rx_index = 0; for (i = 0; i < 64; i++) request[octopus.long_rx_index + i] = buf[i]; octopus.long_rx_index = i; if ((unsigned int) buf[1] < 64) { octopus.long_rx_cmd = 0; USBMessageIn (request); } else { octopus.long_rx_cmd = 1; octopus.long_rx_bytes = (unsigned int) buf[1]; } } } /* is called when received data from pc */ void USBMessageIn (char *buf) { octopus.long_index = 0; octopus.long_running = 0; if(octopus.status_led) STATUS_LED_on; int check = ((int) buf[0] >> 4) & 0x0F; debugf("parser, check: %X, command: %X\n", check, buf[0]); switch (check) { case 0: if (buf[0] == CMD_EXTERNAL_DEVICE) { switch (buf[2]) { case CMD_EXTERNAL_93C46: flash_93c46_parser(buf); break; } } else common_parser(buf); break; case 1: debugf("calling io_parser\n"); io_parser (buf); break; case 2: debugf("calling adc_parser\n"); adc_parser (buf); break; case 3: debugf("calling i2c_parser\n"); i2c_parser (buf); break; case 4: debugf("calling spi_parser\n"); spi_parser (buf); break; case 5: debugf("calling pwm_parser\n"); pwm_parser (buf); break; case 6: debugf("calling adc_parser\n"); uart_parser (buf); break; case 7: #ifdef OCTOPUS_CAN debugf("calling can_parser\n"); can_parser ((uint8_t *)buf); #else debugf("can't call can_parser - no CAN-support\n"); #endif break; case 8: debugf("calling eeprom_parser\n"); eeprom_parser(buf); break; default: debugf("unknown cmd\n"); answer[0] = buf[0]; answer[1] = RSP_UNKOWN_CMD; answer[2] = 0; CommandAnswer(3); } if(octopus.status_led) STATUS_LED_off; } unsigned int strlen(volatile unsigned char *str) { unsigned int len = 0; while (*str++) len++; return len; } void CommandAnswer(unsigned int length) { int i; // if first packet of a long message if (length > 64 && octopus.long_running == 0) { debugf("first packet of a long message (length: %d)\n", length); octopus.long_index = 0; octopus.long_bytes = length; octopus.long_running = 1; length = 64; } USBNWrite (FIFOTXC1, FLUSH); for (i = 0; i < length; i++) USBNWrite (TXD1, answer[octopus.long_index + i]); /* control togl bit */ if (octopus.datatogl == 1) { USBNWrite (FIFOTXC1, TX_LAST + TX_EN + TX_TOGL); octopus.datatogl = 0; } else { USBNWrite (FIFOTXC1, TX_LAST + TX_EN); octopus.datatogl = 1; } } void CommandAnswerRest (void) { if (octopus.long_running == 1) { debugf("octopus long running message\n"); if (octopus.long_index < octopus.long_bytes) { debugf("octopus.long_index < octopus.long_bytes\n"); int diff = octopus.long_bytes - octopus.long_index; octopus.long_index = octopus.long_index + 64; if (diff > 64) { debugf("not last packet: diff > 64\n"); CommandAnswer (64); } else { debugf("last packet\n"); /* last packet */ CommandAnswer (diff); octopus.long_running = 0; } } } } int main(void) { cli(); USBNInitMC (); USBNStartClock(); DDRB = 0xFF; PORTB = 0x00; /* use status led */ octopus.status_led = 1; int interf; int conf; STATUS_LED_off; USBNInit (); // setup your device USBNDeviceVendorID (0x1781); // 0x0400 is the number from national USBNDeviceProductID (0x0c65); // add your product id USBNDeviceBCDDevice (0x0001); // you can use it as version e.g. version 1.02 char lang[] = { 0x09, 0x04, 0x00 }; _USBNAddStringDescriptor (lang); // language descriptor /* Attention!!! Descriptors must be a factor of 8 (error in the stack) */ USBNDeviceManufacture ("EmbeddedProjects"); USBNDeviceProduct ("OctopusUSB Interface Converter and I/O Extension"); //USBNDeviceProduct ("Octopus USB v3.3"); USBNDeviceSerialNumber ("20090718"); conf = USBNAddConfiguration (); // we reserve 500mA, because users could drive LEDs and need more power USBNConfigurationPower (conf, 200); interf = USBNAddInterface (conf, 0); USBNAlternateSetting (conf, interf, 0); /* communication */ USBNAddInEndpoint (conf, interf, 1, 0x01, BULK, 64, 0, &CommandAnswerRest); USBNAddOutEndpoint (conf, interf, 1, 0x01, BULK, 64, 0, &USBCommandRX); //USBNAddOutEndpoint (conf, interf, 1, 0x02, BULK, 64, 0, NULL); octopus.datatogl = 0; octopus.long_rx_cmd = 0; /* UARTInit2(38400,8,'N',1); */ debug_init(); /* hello world led pattern */ DDRC = 0x7F; PORTC = 0x2A; delay_250ms (); PORTC = 0x55; delay_250ms (); PORTC = 0x00; common_init(); /* init connection between avr and usbn9604 */ USBNInitMC (); /* start usb chip */ USBNStart (); sei(); while (1); return 0; }