static void usb_send(void) { usb_putc(sendcode.word.low.byte.low | 0x80); sendcode.dword <<= 1; usb_putc(sendcode.word.low.byte.high & 0x7f); sendcode.dword <<= 1; usb_putc(sendcode.word.high.byte.low & 0x7f); sendcode.dword <<= 1; usb_putc(sendcode.word.high.byte.high & 0x7f); }
/// \brief Processes a command character /// \details If the supplied character is a carriage return, the command line read so far is /// executed, otherwise the character is simply appended to a (circular!) buffer. /// If #echo_on is set, the character is also immediately sent back to the sender, /// whereby carriage return characters are replaced by #USB_NEWLINE. static inline void process_command_char(void) { // Fetch a character from the USB data buffer char data = usb_getc(); // Handle escape sequence if any and abort if (handle_escape_sequence(data)) { return; } // Echo back the received character if desired and possible if (echo_on) { if (data == '\r') { usb_puts(PSTR("")); } else if (0 <= data && data < 128) { usb_putc(data); } } // Parse and execute commands if the enter key was hit if (data == '\r') { // Ignore empty command if (strcmp(cmd_buffer, "") == 0) { return; } strncpy(cmd_history[cmd_history_index], cmd_buffer, CMD_BUFFER_SIZE); ++cmd_history_index; cmd_history_index %= CMD_HISTORY_SIZE; execute_command(cmd_buffer); return; } // Clear last character and rewind buffer index if backspace was received if (data == '\b') { usb_printf(PSTR(" \b")); if (cmd_buffer_index > 0) { --cmd_buffer_index; } cmd_buffer[cmd_buffer_index] = '\0'; return; } // Add char to command buffer; cycle on overflow cmd_buffer[cmd_buffer_index] = data; ++cmd_buffer_index; cmd_buffer_index %= CMD_BUFFER_SIZE; }
/* * \brief Services data transmission or reception on USB * * This function polls for usb for completion of reception or transmission of * a byte on USB. */ void usb_handler(void) { /* * USB Status is the upper 2 bits of Port E * PE6 - TXE write is allowed if Low * PE7 - RXF Data available if Low */ uint8_t cUSBstat = USB_CTRL_PIN; if (LOW == (cUSBstat & USB_RXF)) { /* The received data is read in the PAL USB buffer */ usb_getc(); } /* Transmit data, if any */ if (usb_tx_count > 0) { uint8_t bytes_tx = MAX_BYTES_FOR_USB_TX; while ((usb_tx_count > 0) && (bytes_tx > 0)) { /* * To avoid slow transmission (byte per pal_task), a maximum of * MAX_BYTES_FOR_USB_TX bytes or number of bytes present in USB * buffer, whichever is minimum is transmitted at one go. */ if (LOW == (cUSBstat & USB_TXE)) { if (usb_tx_busy) { /* * Reset USB busy handling variables and mark USB as not busy. */ usb_tx_busy = false; } usb_putc(); bytes_tx--; } else { break; } /* while ((usb_tx_count > 0) && (bytes_tx > 0)) */ } } /* if (usb_tx_count > 0) */ }
void serprog_handle_command(unsigned char command) { static uint8_t i; /* Loop */ static uint8_t l; /* Length */ static uint32_t slen; /* SPIOP write len */ static uint32_t rlen; /* SPIOP read len */ static uint32_t freq_req; LED0=0; switch(command) { case S_CMD_NOP: usb_putc(S_ACK); break; case S_CMD_Q_IFACE: usb_putc(S_ACK); /* little endian multibyte value to complete to 16bit */ usb_putc(S_IFACE_VERSION); usb_putc(0); break; case S_CMD_Q_CMDMAP: usb_putc(S_ACK); /* little endian */ usb_putu32(S_CMD_MAP); for(i = 0; i < 32 - sizeof(uint32_t); i++) usb_putc(0); break; case S_CMD_Q_PGMNAME: usb_putc(S_ACK); l = 0; while(S_PGM_NAME[l]) { usb_putc(S_PGM_NAME[l]); l ++; } for(i = l; i < 16; i++) usb_putc(0); break; case S_CMD_Q_SERBUF: usb_putc(S_ACK); /* Pretend to be 64K (0xffff) */ usb_putc(0xff); usb_putc(0xff); break; case S_CMD_Q_BUSTYPE: // TODO: LPC / FWH IO support via PP-Mode usb_putc(S_ACK); usb_putc(S_SUPPORTED_BUS); break; case S_CMD_Q_CHIPSIZE: break; case S_CMD_Q_OPBUF: // TODO: opbuf function 0 break; case S_CMD_Q_WRNMAXLEN: break; case S_CMD_R_BYTE: break; case S_CMD_R_NBYTES: break; case S_CMD_O_INIT: break; case S_CMD_O_WRITEB: // TODO: opbuf function 1 break; case S_CMD_O_WRITEN: // TODO: opbuf function 2 break; case S_CMD_O_DELAY: // TODO: opbuf function 3 break; case S_CMD_O_EXEC: // TODO: opbuf function 4 break; case S_CMD_SYNCNOP: usb_putc(S_NAK); usb_putc(S_ACK); break; case S_CMD_Q_RDNMAXLEN: // TODO break; case S_CMD_S_BUSTYPE: /* We do not have multiplexed bus interfaces, * so simply ack on supported types, no setup needed. */ if((usb_getc() | S_SUPPORTED_BUS) == S_SUPPORTED_BUS) usb_putc(S_ACK); else usb_putc(S_NAK); break; case S_CMD_O_SPIOP: slen = usb_getu24(); rlen = usb_getu24(); select_chip(); /* TODO: handle errors with S_NAK */ if(slen) spi_bulk_write(slen); usb_putc(S_ACK); if(rlen) spi_bulk_read(rlen); unselect_chip(); break; case S_CMD_S_SPI_FREQ: freq_req = usb_getu32(); if(freq_req == 0) usb_putc(S_NAK); else { usb_putc(S_ACK); usb_putu32(spi_conf(freq_req)); } break; default: break; // TODO: Debug malformed command } LED0=1; }
static void usb_ack_rx(void) { usbadr = R_USBIndexed_OutCSR1; usb_putc(0); }
/* Call this to start an opening process */ void loccStartOpening(void) { if(state == SLEEP) { usb_putc('|'); state_machine(POWERUP); } }