int msr_iso_write(int fd, msr_tracks_t * tracks) { int i; uint8_t buf[4]; msr_cmd (fd, MSR_CMD_WRITE); buf[0] = MSR_ESC; buf[1] = MSR_RW_START; serial_write (fd, buf, 2); for (i = 0; i < MSR_MAX_TRACKS; i++) { buf[0] = MSR_ESC; buf[1] = i + 1; serial_write (fd, buf, 2); serial_write (fd, tracks->msr_tracks[i].msr_tk_data, tracks->msr_tracks[i].msr_tk_len); } buf[0] = MSR_RW_END; buf[1] = MSR_FS; serial_write (fd, buf, 2); serial_readchar (fd, &buf[0]); serial_readchar (fd, &buf[0]); if (buf[0] != MSR_STS_OK) warnx("write failed"); return (0); }
int msr_raw_write(int fd, msr_tracks_t * tracks) { int i; uint8_t buf[4]; msr_cmd (fd, MSR_CMD_RAW_WRITE); buf[0] = MSR_ESC; buf[1] = MSR_RW_START; serial_write (fd, buf, 2); for (i = 0; i < MSR_MAX_TRACKS; i++) { buf[0] = MSR_ESC; /* start delimiter */ buf[1] = i + 1; /* track number */ buf[2] = tracks->msr_tracks[i].msr_tk_len; /* data length */ serial_write (fd, buf, 3); serial_write (fd, tracks->msr_tracks[i].msr_tk_data, tracks->msr_tracks[i].msr_tk_len); } buf[0] = MSR_RW_END; buf[1] = MSR_FS; serial_write (fd, buf, 2); serial_readchar (fd, &buf[0]); serial_readchar (fd, &buf[0]); if (buf[0] != MSR_STS_OK) warnx("raw write failed"); return (0); }
static int gettrack_iso (int fd, int t, uint8_t * buf, uint8_t * len) { uint8_t b; int i = 0; int l = 0; /* Start delimiter should be ESC <track number> */ serial_readchar (fd, &b); if (b != MSR_ESC) { *len = 0; return (-1); } serial_readchar (fd, &b); if (b != t) { *len = 0; return (-1); } while (1) { serial_readchar (fd, &b); if (b == '%') continue; if (b == ';') continue; if (b == MSR_RW_END) break; if (b == MSR_ESC) break; /* Avoid overflowing the buffer */ if (i < *len) { l++; buf[i] = b; } i++; } if (b == MSR_RW_END) { *len = l; return (0); } else { *len = 0; serial_readchar (fd, &b); } return (-1); }
int serial_readline(char * buffer, const int buf_size) { int length = 0; char c = 0; while (c != '\n') { /* Read the next char */ c = serial_readchar(); /* If we haven't reached the max length yet */ if (length < buf_size) { buffer[length] = c; length++; } } /* Delete the last char if it is a new line */ if (buffer[length] == '\n') { length--; } /* Delete the last char if it is a carriage return */ if (buffer[length] == '\r') { length--; } /* Terminate the string */ buffer[length] = 0; return length; }
static int readchar (int timeout) { int c; do { c = serial_readchar (e7000_desc, timeout); } while (c > 127); if (c == SERIAL_TIMEOUT) { if (timeout == 0) return -1; echo = 0; error ("Timeout reading from remote system."); } else if (c < 0) error ("Serial communication error"); if (remote_debug) { putchar_unfiltered (c); gdb_flush (gdb_stdout); } return normal (c); }
int msr_commtest (int fd) { int r; uint8_t buf[2]; r = msr_cmd (fd, MSR_CMD_DIAG_COMM); if (r == -1) err(1, "Commtest write failed"); /* * Read the result. Note: we're supposed to get back * two characters: an escape and a 'y' character. But * with my serial USB adapter, the escape sometimes * gets lost. As a workaround, we scan only for the 'y' * and discard the escape. */ while (1) { serial_readchar (fd, &buf[0]); if (buf[0] == MSR_STS_COMM_OK) break; } if (buf[0] != MSR_STS_COMM_OK) { printf("Communications test failure\n"); return (-1); } else printf("Communications test passed.\n"); return (0); }
static int readchar (struct serial *desc, int timeout) { int ch; char s[10]; ch = serial_readchar (desc, timeout); switch (ch) { case SERIAL_EOF: error ("SPARClite remote connection closed"); case SERIAL_ERROR: perror_with_name ("SPARClite communication error"); case SERIAL_TIMEOUT: error ("SPARClite remote timeout"); default: if (remote_debug > 0) { sprintf (s, "[%02x]", ch & 0xff); puts_debug ("read -->", s, "<--"); } return ch; } }
static int gettrack_raw (int fd, int t, uint8_t * buf, uint8_t * len) { uint8_t b, s; int i = 0; int l = 0; /* Start delimiter should be ESC <track number> */ serial_readchar (fd, &b); if (b != MSR_ESC) { *len = 0; return (-1); } serial_readchar (fd, &b); if (b != t) { *len = 0; return (-1); } serial_readchar (fd, &s); if (!s) { *len = 0; return (0); } for (i = 0; i < s; i++) { serial_readchar (fd, &b); /* Avoid overflowing the buffer */ if (i < *len) { l++; buf[i] = b; } } *len = l; return (0); }
static int getstart (int fd) { uint8_t b; int i, r; for (i = 0; i < 3; i++) { r = serial_readchar(fd, &b); if (b == MSR_RW_START) break; } if (i == 3) return (-1); return (0); }
static unsigned char get_byte (void) { int c = serial_readchar (io, timeout); if (remote_debug) fprintf_unfiltered (gdb_stdlog, "[%02x]\n", c); if (c == SERIAL_TIMEOUT) { if (timeout == 0) return (unsigned char) c; error ("Timeout reading from remote_system"); } return c; }
int msr_fwrev (int fd) { uint8_t buf[64]; bzero (buf, sizeof(buf)); if (msr_cmd (fd, MSR_CMD_FWREV) != 0) return (-1); serial_readchar (fd, &buf[0]); /* read the result "REV?X.XX" */ serial_read (fd, buf, 8); buf[8] = '\0'; printf ("Firmware Version: %s\n", buf); return (0); }
static void connect_command (char *args, int fromtty) { int c; char cur_esc = 0; serial_ttystate ttystate; struct serial *port_desc; /* TTY port */ dont_repeat (); if (args) fprintf_unfiltered (gdb_stderr, "This command takes no args. They have been ignored.\n"); printf_unfiltered ("[Entering connect mode. Use ~. or ~^D to escape]\n"); tty_desc = serial_fdopen (0); port_desc = last_serial_opened; ttystate = serial_get_tty_state (tty_desc); serial_raw (tty_desc); serial_raw (port_desc); make_cleanup (cleanup_tty, ttystate); while (1) { int mask; mask = serial_wait_2 (tty_desc, port_desc, -1); if (mask & 2) { /* tty input */ char cx; while (1) { c = serial_readchar (tty_desc, 0); if (c == SERIAL_TIMEOUT) break; if (c < 0) perror_with_name ("connect"); cx = c; serial_write (port_desc, &cx, 1); switch (cur_esc) { case 0: if (c == '\r') cur_esc = c; break; case '\r': if (c == '~') cur_esc = c; else cur_esc = 0; break; case '~': if (c == '.' || c == '\004') return; else cur_esc = 0; } } } if (mask & 1) { /* Port input */ char cx; while (1) { c = serial_readchar (port_desc, 0); if (c == SERIAL_TIMEOUT) break; if (c < 0) perror_with_name ("connect"); cx = c; serial_write (tty_desc, &cx, 1); } } } }
/* This is a bit more fancy that need be so that it syncs even in nasty cases. I'be been unable to make it reliably sync up with the change baudrate open command. It likes to sit and say it's been reset, with no more action. So I took all that code out. I'd rather sync reliably at 9600 than wait forever for a possible 19200 connection. */ static void rdp_init (int cold, int tty) { int sync = 0; int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM; int baudtry = 9600; time_t now = time (0); time_t stop_time = now + 10; /* Try and sync for 10 seconds, then give up */ while (time (0) < stop_time && !sync) { int restype; QUIT; serial_flush_input (io); serial_flush_output (io); if (tty) printf_unfiltered ("Trying to connect at %d baud.\n", baudtry); /* ** It seems necessary to reset an EmbeddedICE to get it going. ** This has the side benefit of displaying the startup banner. */ if (cold) { put_byte (RDP_RESET); while ((restype = serial_readchar (io, 1)) > 0) { switch (restype) { case SERIAL_TIMEOUT: break; case RDP_RESET: /* Sent at start of reset process: ignore */ break; default: printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); break; } } if (restype == 0) { /* Got end-of-banner mark */ printf_filtered ("\n"); } } put_byte (RDP_OPEN); put_byte (type | RDP_OPEN_TYPE_RETURN_SEX); put_word (0); while (!sync && (restype = serial_readchar (io, 1)) > 0) { if (remote_debug) fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype); switch (restype) { case SERIAL_TIMEOUT: break; case RDP_RESET: while ((restype = serial_readchar (io, 1)) == RDP_RESET) ; do { printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); } while ((restype = serial_readchar (io, 1)) > 0); if (tty) { printf_unfiltered ("\nThe board has sent notification that it was reset.\n"); printf_unfiltered ("Waiting for it to settle down...\n"); } sleep (3); if (tty) printf_unfiltered ("\nTrying again.\n"); cold = 0; break; default: break; case RDP_RES_VALUE: { int resval = serial_readchar (io, 1); if (remote_debug) fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval); switch (resval) { case SERIAL_TIMEOUT: break; case RDP_RES_VALUE_LITTLE_ENDIAN: #if 0 /* FIXME: cagney/2003-11-22: Ever since the ARM was multi-arched (in 2002-02-08), this assignment has had no effect. There needs to be some sort of check/decision based on the current architecture's byte-order vs the remote target's byte order. For the moment disable the assignment to keep things building. */ target_byte_order = BFD_ENDIAN_LITTLE; #endif sync = 1; break; case RDP_RES_VALUE_BIG_ENDIAN: #if 0 /* FIXME: cagney/2003-11-22: Ever since the ARM was multi-arched (in 2002-02-08), this assignment has had no effect. There needs to be some sort of check/decision based on the current architecture's byte-order vs the remote target's byte order. For the moment disable the assignment to keep things building. */ target_byte_order = BFD_ENDIAN_BIG; #endif sync = 1; break; default: break; } } } } } if (!sync) { error ("Couldn't reset the board, try pressing the reset button"); } }
int main() { unsigned char cmd_buf[8]; int cmd_len; int cmd_len_expected; int cmd_state; int status; clock_init(); AD1PCFGL = 0xFFFF; // All pins as digital. // UART pins/mapping TRISBbits.TRISB3 = 1; RPOR1bits.RP2R = 3; // Assign UART1 TX to RP2 (pin 6). RPINR18bits.U1RXR = 3; // Assign UART1 RX to RP3 (pin 7). serial_init(); // PWM pins/mapping TRISBbits.TRISB15 = 0; TRISBbits.TRISB14 = 0; TRISBbits.TRISB13 = 0; TRISBbits.TRISB12 = 0; RPOR7 = 0b0001001000010011; // RP15 - OC1, RP14 - OC2 RPOR6 = 0b0001010000010101; // RP13 - OC3, RP12 - OC4 _pwmChannel1 = 0; _pwmChannel2 = 0; _pwmChannel3 = 0; _pwmChannel4 = 0; _pwmFailsafeEnabled = 0; pwm_init(); update_pwm(); // Set up timer 3 failsafe to determine when commands are no longer // being sent. When triggered, gradually reduce PWM values until // the next command is sent or the PWM value reaches minimum. T3CON = 0; T3CONbits.TCKPS = 0b11; // 1:256 prescale IFS0bits.T3IF = 0; // Clear interrupt flag IEC0bits.T3IE = 1; // Enable timer interrupt TMR3 = 0; PR3 = 0xFFFF; _timer3high = 0; // High word to create 32-bit timer from 16-bit timer T3CONbits.TON = 0b1; // Enable timer 3 cmd_len = 0; cmd_len_expected = 0; cmd_state = CMD_STATE_NONE; while (1) { update_pwm(); status = serial_readchar(&cmd_buf[cmd_len]); if (status == SERIAL_STATUS_NODATA) { continue; } else if (status == SERIAL_STATUS_ERROR) { cmd_state = CMD_STATE_NONE; cmd_len = 0; cmd_len_expected = 0; } else if (status == SERIAL_STATUS_DATA) { cmd_len++; if (cmd_len >= 8) { // Command data overflow. cmd_state = CMD_STATE_NONE; cmd_len = 0; cmd_len_expected = 0; continue; } if (cmd_state == CMD_STATE_NONE) { // New command - check start byte. if (cmd_buf[0] == CMD_SETDUTYCYCLES) { cmd_state = CMD_STATE_READING; cmd_len_expected = CMD_SETDUTYCYCLES_LEN; } else { // Invalid command. cmd_state = CMD_STATE_NONE; cmd_len = 0; cmd_len_expected = 0; } } // Check for data portion of command (if any). if (cmd_state == CMD_STATE_READING) { if (cmd_len - 1 == cmd_len_expected) { process_command(cmd_buf); cmd_state = CMD_STATE_NONE; cmd_len = 0; cmd_len_expected = 0; } } } } return 0; }