int main(void) { CPU_PRESCALE(0); GBA_DDR &= ~(1<<MISO_BIT); GBA_DDR |= (1<<MOSI_BIT) | (1<<CLK_BIT); CLK_HIGH(); usb_init(); while (!usb_configured()); _delay_ms(1000); INIT_TIMER(); while (1) { if (usb_serial_available() >= 4) { uint32_t data = 0; data |= (uint32_t)usb_serial_getchar()<<24; data |= (uint32_t)usb_serial_getchar()<<16; data |= (uint32_t)usb_serial_getchar()<<8; data |= (uint32_t)usb_serial_getchar(); xfer(&data); usb_serial_putchar((data>>24) & 0xff); usb_serial_putchar((data>>16) & 0xff); usb_serial_putchar((data>>8) & 0xff); usb_serial_putchar(data & 0xff); usb_serial_flush_output(); } }
// USB Input buffer available inline unsigned int Output_availablechar() { #if enableVirtualSerialPort_define == 1 return usb_serial_available(); #else return 0; #endif }
void usb_serial_wait_for_key(void) { while(usb_serial_available() == 0) { usb_tasks(); service_button(); _delay_ms(10); } }
int kbhit() { // return usb_serial_available() != 0; if(USB_SERIAL_ON && (usb_serial_available() != 0)) return 1; #ifdef USE_UART return serial_available() != 0; #endif return 0; }
int getkey() { while (!kbhit()) ; // return the next character from the console input device // return usb_serial_getchar(); if(USB_SERIAL_ON && (usb_serial_available() != 0)) { return usb_serial_getchar(); } #ifdef USE_UART return serial_getchar(); #endif return 0; }
uint16_t usb_serial_readline(char *buffer, const uint16_t buffer_size, const bool obscure_input) { uint16_t end = 0; char c; while(true) { if(usb_serial_available() > 0) { c = (char)usb_serial_getchar(); switch((char) c) { case '\r': // enter buffer[end] = 0; usb_serial_putchar('\n'); usb_serial_putchar('\r'); return end; break; case '\b': // ^H case 127: // backspace end--; usb_serial_write("\b \b"); // remove the last char from the display //usb_serial_readline_refresh(buffer, end, obscure_input); break; default: if(end < buffer_size-1) { buffer[end++] = c; if(obscure_input) usb_serial_putchar('*'); else usb_serial_putchar(c); } break; } } usb_tasks(); service_button(); _delay_ms(10); } return 0; // never reached }
// Basic command interpreter for controlling port pins int main(void) { char rx_buf[8];// the buffer to store received characters uint8_t n = 0; // to store the number of bytes read from the serial port uint8_t counter = 0; //keep count of the number of cycles in the while loop // coordinates of the middle of the screen int x=LCD_X/2; int y=LCD_Y/2; //set clock speed to 8MhZ set_clock_speed(CPU_8MHz); //initialise LCD and ports Init(); // initialize the USB, and then wait for the host // to set configuration. If the Teensy is powered // without a PC connected to the USB port, this // will wait forever. usb_init(); while (!usb_configured()) /* wait */ ; _delay_ms(1000); //keep looping until the character 'q' is received while (rx_buf[0]!='q') { counter++; // wait for the user to run their terminal emulator program // which sets DTR to indicate it is ready to receive. while (!(usb_serial_get_control() & USB_SERIAL_DTR)) /* wait */ ; // discard anything that was received prior. Sometimes the // operating system or other software will send a modem // "AT command", which can still be buffered. usb_serial_flush_input(); // and then listen for commands and process them while (1) { //send some characters to the other side //send_str(PSTR("> \n")); if (usb_serial_available()) n = recv_str(rx_buf, sizeof(rx_buf)); //read serial port else break; parse_and_execute_command(rx_buf, n); clear_screen(); draw_string(x-40,y,"receiving: "); show_screen(); draw_char(x+20,y,rx_buf[0]); show_screen(); } } return 0; }
//void parse_CIM_protocol(unsigned char actbyte) void parse_CIM_protocol(void) { uint32_t checksum=0; static uint8_t transmission_mode; static uint8_t reply_status_code; static uint8_t last_serial; uint8_t actbyte; while (usb_serial_available()) { //PORTD |= (1<<6); actbyte=usb_serial_getchar(); switch (readstate) { case 0: // first sync byte reply_status_code=0; if (actbyte=='@') readstate++; break; case 1: // second sync byte if (actbyte=='T') readstate++; else readstate=0; break; // packet in sync ! case 2: // ARE-ID: SW-version low byte ARE_frame.are_id=actbyte; readstate++; break; case 3: // ARE-ID: SW-version high byte ARE_frame.are_id+=((uint16_t)actbyte)<<8; if (ARE_frame.are_id < ARE_MINIMAL_VERSION) // outdated ARE ? reply_status_code |= CIM_ERROR_INVALID_ARE_VERSION; readstate++; break; case 4: // data length low byte ARE_frame.data_size=actbyte; readstate++; break; case 5: // data length high byte ARE_frame.data_size+=((uint16_t)actbyte)<<8; if (ARE_frame.data_size > DATABUF_SIZE) { // dismiss packets of excessive length readstate=0; //ARE_frame.data_size=0; //reply_status_code |= CIM_ERROR_INVALID_FEATURE; } else readstate++; break; case 6: // serial_number ARE_frame.serial_number = actbyte; if (first_packet) // don't check first serial first_packet=0; else if (actbyte != (last_serial+1)%0x80) // check current serial number reply_status_code |= CIM_ERROR_LOST_PACKETS; last_serial=actbyte; readstate++; break; case 7: // CIM-feature low byte ARE_frame.cim_feature= actbyte; readstate++; break; case 8: // CIM-feature high byte ARE_frame.cim_feature+=((int)actbyte)<<8; readstate++; break; case 9: // Request code low byte ( command ) ARE_frame.request_code=actbyte; readstate++; break; case 10:// Request code high byte (transmission mode) transmission_mode=actbyte; // bit 0: CRC enable // reply_status_code|=(actbyte & CIM_STATUS_CRC); // remember CRC state for reply if (ARE_frame.data_size>0) { readstate++; datapos=0; } else { // no data in packet if (transmission_mode & CIM_STATUS_CRC) readstate+=2; // proceed with CRC else readstate=FRAME_DONE; // frame is finished here ! } break; case 11: // read out data ARE_frame.data[datapos]=actbyte; datapos++; if (datapos==ARE_frame.data_size) { if (transmission_mode & CIM_STATUS_CRC) // with CRC: get checksum readstate++; else readstate=FRAME_DONE; // no CRC: frame is finished here ! } break; case 12: // checksum byte 1 checksum=actbyte; readstate++; break; case 13: // checksum byte 2 checksum+=((long)actbyte)<<8; readstate++; break; case 14: // checksum byte 3 checksum+=((long)actbyte)<<16; readstate++; break; case 15: // checksum byte 4 checksum+=((long)actbyte)<<24; // check CRC now (currently not used): // if (checksum != crc32(ARE_frame.data, ARE_frame.data_size)) reply_status_code |= CIM_ERROR_CRC_MISMATCH; // frame finished here ! readstate=FRAME_DONE; break; default: readstate=0; break; } if (readstate==FRAME_DONE) { // frame finished: store command in ringbuffer process_ARE_frame(reply_status_code); readstate=0; } } }
/** The MAIN loop. */ int main(void) { // Turn off the CPU prescale. CLKPR = 0x80; CLKPR = 0x00; // PORTA are general purpose inputs. DDRA = 0x00; PORTA = 0xff; // pull-ups all enabled PORTD = 0xff; DDRD = 0x00; // pull-ups all enabled DDRF = 0x00; // These are ADC lines. PORTF = 0x00; usb_init(); // Set up Timer 0 to match compare every 1ms. OCR0A = 250; TCCR0A = 0x02; // CTC TCCR0B = 0x03; // CK/64 (64 * 250 == 16000) sei(); char line_buf[128] = {}; uint8_t line_len = 0; uint8_t usb_ready = 0; while (1) { wdt_reset(); g_main_loop_count++; if (usb_configured() && (usb_serial_get_control() & USB_SERIAL_DTR)) { if (!usb_ready) { usb_ready = 1; strcpy_P(line_buf, PSTR("!GNR WELCOME " DEV_VERSION EOL)); usb_serial_write((uint8_t*)line_buf, strlen(line_buf)); line_len = 0; } } else { stream_stop_all(); usb_serial_flush_input(); usb_ready = 0; line_len = 0; g_arm_code = 0; } if (usb_serial_available()) { int16_t c = usb_serial_getchar(); if (c == '\r' || c == '\n') { line_buf[line_len] = 0; handle_line(line_buf); if (g_arm_code) { g_arm_timer = ARM_TIMEOUT_MS; } line_len = 0; } else { line_buf[line_len++] = c & 0xff; if ((line_len + 1) >= sizeof(line_buf)) { /* Clobber the first byte so that this line will be reported as an error. */ line_buf[0] = MAGIC_OVERRUN_CODE; line_len--; } } } if (TIFR0 & (1 << OCF0A)) { TIFR0 |= (1 << OCF0A); g_timer++; stream_timer_update(); hit_timer_update(); g_main_loop_count = (uint16_t) (((uint32_t) g_main_loop_count) * 7 / 8); } stream_poll(); usb_poll(); hit_poll(); } }
// USB Input buffer available inline unsigned int Output_availablechar() { return usb_serial_available(); }
// Basic command interpreter for controlling port pins int main(void) { char rx_buf[8];// the buffer to store received characters uint8_t n=0; //number of bytes read //set clock speed to 8MhZ set_clock_speed(CPU_8MHz); //initialise LCD and ports Init(); // initialize the USB, and then wait for the host // to set configuration. If the Teensy is powered // without a PC connected to the USB port, this // will wait forever. usb_init(); while (!usb_configured()) /* wait */ ; _delay_ms(1000); //keep looping until the character 'q' is received while (rx_buf[0]!='q') { // wait for the user to run their terminal emulator program // which sets DTR to indicate it is ready to receive. while (!(usb_serial_get_control() & USB_SERIAL_DTR)) /* wait */ ; // discard anything that was received prior. Sometimes the // operating system or other software will send a modem // "AT command", which can still be buffered. usb_serial_flush_input(); // and then listen for commands and process them while (1) { if (usb_serial_available()) { n = recv_str(rx_buf, sizeof(rx_buf)); //read serial port //send a characters to the other side send_str(PSTR("> \n")); } else { break; } //check first character of the buffer and perform an action if(rx_buf[0]=='a') //turn LED0 ON PORTB = 1<<2; if(rx_buf[0]=='d') //turn LED1 ON PORTB = 1<<3; if(rx_buf[0]=='s') //turn LED0 OFF PORTB = 0x00; } } return 0; }
int main(void) { char cmd; char param1; char param2; char param3; cmd = 0; param1 = 0; param2 = 0; param3 = 0; DDRB = 0x00; PORTB |= 0x01; // set for 16 MHz clock, and make sure the LED is off CPU_PRESCALE(0); LED_CONFIG; LED_ON; SPI_SlaveInit(); ACK_CONFIG; ACK_HIGH; TEST_CONFIG; usb_init(); _delay_ms(1000); usb_serial_flush_input(); int flashCounter = 0; char LEDstate = 1; while (1) { idle: TEST_HIGH; ACK_HIGH; SPDR = 0xff; if(ATT_PIN) { timeoutCounter++; if(timeoutCounter >= 30000)//we've been disconnected { mode = 0x41; motorSetting1 = 0xff; motorSetting2 = 0xff; analogEnabled = 0; configMode = 0; timeoutCounter = 0; flashCounter++; if(flashCounter > 5) { if(LEDstate == 1) { LED_OFF; LEDstate = 0; } else { LED_ON; LEDstate = 1; } flashCounter = 0; } } if(usb_serial_available()) { LED_ON; int c = usb_serial_getchar(); if (c >= 0) { switch(parseIndex) { case 0: if(c == 0x5A) parseIndex++; else usb_serial_putchar('x'); break; case 1: buttons1 &= c;//combine this with any pending presses buttons1postReportState = c; parseIndex++; break; case 2: buttons2 &= c;//combine this with any pending presses buttons2postReportState = c; parseIndex++; break; case 3: joyRX = c; parseIndex++; break; case 4: joyRY = c; parseIndex++; break; case 5: joyLX = c; parseIndex++; break; case 6: joyLY = c; parseIndex = 0; recievedUpdate = 1; break; } } else { parseIndex = 0; usb_serial_putchar('x'); } } _delay_us(1); goto idle; } timeoutCounter = 0; if((buttons1 & 0x10) == 0) upPressure = 0xFF; else upPressure = 0x00; if((buttons1 & 0x20) == 0) rightPressure = 0xFF; else rightPressure = 0x00; if((buttons1 & 0x40) == 0) downPressure = 0xFF; else downPressure = 0x00; if((buttons1 & 0x80) == 0) leftPressure = 0xFF; else leftPressure = 0x00; if((buttons2 & 0x01) == 0) L2Pressure = 0xFF; else L2Pressure = 0x00; if((buttons2 & 0x02) == 0) R2Pressure = 0xFF; else R2Pressure = 0x00; if((buttons2 & 0x04) == 0) L1Pressure = 0xFF; else L1Pressure = 0x00; if((buttons2 & 0x08) == 0) R1Pressure = 0xFF; else R1Pressure = 0x00; if((buttons2 & 0x10) == 0) trianglePressure = 0xFF; else trianglePressure = 0x00; if((buttons2 & 0x20) == 0) circlePressure = 0xFF; else circlePressure = 0x00; if((buttons2 & 0x40) == 0) crossPressure = 0xFF; else crossPressure = 0x00; if((buttons2 & 0x80) == 0) squarePressure = 0xFF; else squarePressure = 0x00; cli();//disable usb interrupts LED_ON; TEST_LOW; cmd = SPI_SlaveReceive(0xff,1); TEST_HIGH; if(cmd != 0x01) goto finish; if(configMode) { cmd = SPI_SlaveReceive(0xF3,1); SPI_SlaveReceive(0x5A,1); switch(cmd) { case 0x40: param1 = SPI_SlaveReceive(0x00,1); // if(param1 == 0) //lots on param1 but the reponses are all the same? { SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x02,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x5A,0); } break; case 0x41://check response data if(analogEnabled==1) { //button pressures byte mask, appears after 0x44 is called SPI_SlaveReceive(0xFF,1);//use mask instead? SPI_SlaveReceive(0xFF,1); SPI_SlaveReceive(0x03,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x5A,0); } else { SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,0); } break; case 0x43://exit config mode param1 = SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,0); if(param1 == 0) { configMode = 0; } break; case 0x44://turn on analog mode param1 = SPI_SlaveReceive(0x00,1); param2 = SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,0); if(param1 == 1) { mode = 0x73;//no analog button pressures analogEnabled = 1; } else { mode = 0x41; analogEnabled = 0; } break; case 0x45://query model param1 = SPI_SlaveReceive(0x03,1); param2 = SPI_SlaveReceive(0x02,1); if(analogEnabled==1) SPI_SlaveReceive(0x01,1); else SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x02,1); SPI_SlaveReceive(0x01,1); SPI_SlaveReceive(0x00,0); break; case 0x46: param1 = SPI_SlaveReceive(0x00,1); if(param1 == 0) { param2 = SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x01,1); SPI_SlaveReceive(0x02,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x0F,0); } if(param1 == 1) { param2 = SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x01,1); SPI_SlaveReceive(0x01,1); SPI_SlaveReceive(0x01,1); SPI_SlaveReceive(0x0F,0); } break; case 0x47: SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x02,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x01,1); SPI_SlaveReceive(0x00,0); break; case 0x4C: param1 = SPI_SlaveReceive(0x00,1); if(param1 == 0) { SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x04,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,0); } if(param1 == 1) { SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x07,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,0); } break; case 0x4D://setup motors motorSetting1 = SPI_SlaveReceive(motorSetting1,1); motorSetting2 = SPI_SlaveReceive(motorSetting2,1); SPI_SlaveReceive(0xFF,1); SPI_SlaveReceive(0xFF,1); SPI_SlaveReceive(0xFF,1); SPI_SlaveReceive(0xFF,0); break; case 0x4F://set pressure byte mask, extended pressures mode = 0x79;//analog button pressures param1 = SPI_SlaveReceive(0x00,1); param2 = SPI_SlaveReceive(0x00,1); param3 = SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x00,1); SPI_SlaveReceive(0x5A,0); break; } } else { TEST_LOW; cmd = SPI_SlaveReceive(mode,1); SPI_SlaveReceive(0x5A,1); if(mode == 0x41)//digital only { param1 = SPI_SlaveReceive(buttons1,1); param2 = SPI_SlaveReceive(buttons2,0); } if(mode == 0x73)//digital buttons, analog joysticks { param1 = SPI_SlaveReceive(buttons1,1); if(param1 ==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(buttons2,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(joyRX,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(joyRY,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(joyLX,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(joyLY,0)==TIME_OUT_ERROR_CODE) goto finish; } if(mode == 0x79)//analog joysticks, analog buttons { param1 = SPI_SlaveReceive(buttons1,1); if(param1 ==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(buttons2,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(joyRX,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(joyRY,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(joyLX,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(joyLY,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(rightPressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(leftPressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(upPressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(downPressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(trianglePressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(circlePressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(crossPressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(squarePressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(L1Pressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(R1Pressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(L2Pressure,1)==TIME_OUT_ERROR_CODE) goto finish; if(SPI_SlaveReceive(R2Pressure,0)==TIME_OUT_ERROR_CODE) goto finish; } //cmd should usually be 0x42 for polling if(cmd == 0x43) { if(param1 == 0x01) configMode = 1; } } finish: TEST_HIGH; ACK_HIGH; if((buttons1 == 0xff)&&(buttons2 == 0xff)) { LED_OFF; } //copy queued releases into button state buttons1 = buttons1postReportState; buttons2 = buttons2postReportState; sei();//renable usb interrupts if(recievedUpdate == 1) { //ack the update was sent to the console usb_serial_putchar('k'); recievedUpdate = 0; } while(!ATT_PIN) { _delay_us(20); //conservative so we aren't still in ATT low at the top of the loop } counter++; } }