// Read status reg. static uint8_t read_status_reg() { start_command(COMMAND_READ_STATUS); uint8_t value = spi_tx(0); end_command(); return value; }
// Reads the JEDEC ID. static uint32_t read_device_id() { start_command(COMMAND_JEDEC_ID); uint32_t id = 0; char* id_bytes = reinterpret_cast<char*>(&id); id_bytes[2] = spi_tx(0); id_bytes[1] = spi_tx(0); id_bytes[0] = spi_tx(0); end_command(); return id; }
// Read data. static void read_data(uint32_t offset, char* buf, uint32_t size) { start_command(COMMAND_READ_DATA); write_address(offset); // The file data bit order is reversed. spi_set_bit_order(SPI_LSB_FIRST); for (; size > 0; --size, ++buf) { *buf = spi_tx(0); } spi_set_bit_order(SPI_MSB_FIRST); end_command(); }
/** * Read an arbitrary amount of data. * @param location Location to read from. * @param length Amount of bytes to read. * @return Data read. */ std::vector<byte> SerialInterface::read_data(address location, size_t length) { if (!request(location) || !send_command(0xA1)) return std::vector<byte>(); // TODO: error? std::vector<byte> readdata(length); readdata[0] = read_byte(); for (size_t i = 1; i < length; i++) { request_next(); readdata[i] = read_byte(); } end_command(); return readdata; }
// Programs a page of data. static void page_program(uint32_t offset, const char* buf, uint16_t size) { start_command(COMMAND_PAGE_PROGRAM); write_address(offset); if (size > PAGE_SIZE) { size = PAGE_SIZE; } // The file data bit order is reversed. spi_set_bit_order(SPI_LSB_FIRST); for (; size > 0; --size, ++buf) { spi_tx(*buf); } spi_set_bit_order(SPI_MSB_FIRST); end_command(); }
/** * Write an arbitrary amount of data. * @param location Location to write to. * @param data Data to write. */ bool SerialInterface::write_data(address location, const std::vector<byte> &data) { start_sequence(); if (!request(location)) return false; for (size_t i = 0; i < data.size(); i++) if (!write_byte(data[i])) return false; end_command(); start_sequence(); for (size_t i = 0; i < 3; i++) send_command(0xA0, false); set_DTR(false); nanodelay(); bool result = get_CTS(); set_DTR(true); nanodelay(); return result; }
static void tintin(void) { int i, result, maxfd; struct timeval tv; fd_set readfdmask; #ifdef XTERM_TITLE struct session *lastsession=0; #endif char kbdbuf[BUFFER_SIZE]; WC ch; int inbuf=0; mbstate_t instate; memset(&instate, 0, sizeof(instate)); for (;;) { #ifdef XTERM_TITLE if (ui_own_output && activesession!=lastsession) { lastsession=activesession; if (activesession==nullsession) user_title(XTERM_TITLE, "(no session)"); else user_title(XTERM_TITLE, activesession->name); } #endif tv.tv_sec = check_events(); tv.tv_usec = 0; maxfd=0; FD_ZERO(&readfdmask); if (!eofinput) FD_SET(0, &readfdmask); else if (activesession==nullsession) end_command(0, activesession); for (struct session *ses = sessionlist; ses; ses = ses->next) { if (ses==nullsession) continue; if (ses->nagle) flush_socket(ses); FD_SET(ses->socket, &readfdmask); if (ses->socket>maxfd) maxfd=ses->socket; } result = select(maxfd+1, &readfdmask, 0, 0, &tv); if (need_resize) { char buf[BUFFER_SIZE]; user_resize(); sprintf(buf, "#NEW SCREEN SIZE: %dx%d.", COLS, LINES); tintin_puts1(buf, activesession); } if (result == 0) continue; else if (result < 0 && errno == EINTR) continue; /* Interrupted system call */ else if (result < 0) syserr("select"); if (FD_ISSET(0, &readfdmask)) { PROFSTART; PROFPUSH("user interface"); result=read(0, kbdbuf+inbuf, BUFFER_SIZE-inbuf); if (result==-1) myquitsig(0); if (result==0 && !isatty(0)) eofinput=true; inbuf+=result; i=0; while (i<inbuf) { result=mbrtowc(&ch, kbdbuf+i, inbuf-i, &instate); if (result==-2) /* incomplete but valid sequence */ { memmove(kbdbuf, kbdbuf+i, inbuf-i); inbuf-=i; goto partial; } else if (result==-1) /* invalid sequence */ { ch=0xFFFD; i++; errno=0; /* Shift by 1 byte. We can use a more intelligent shift, * but staying charset-agnostic makes the code simpler. */ } else if (result==0) /* literal 0 */ i++; /* oops... bad ISO/ANSI, bad */ else i+=result; if (user_process_kbd(activesession, ch)) { hist_num=-1; if (term_echoing || (got_more_kludge && done_input[0])) /* got_more_kludge: echo any non-empty line */ { if (activesession && *done_input) if (strcmp(done_input, prev_command)) do_history(done_input, activesession); if (activesession->echo) echo_input(done_input); if (activesession->logfile) write_logf(activesession, done_input, activesession->loginputprefix, activesession->loginputsuffix); } if (*done_input) strcpy(prev_command, done_input); aborting=false; activesession = parse_input(done_input, false, activesession); recursion=0; } } inbuf=0; partial: PROFEND(kbd_lag, kbd_cnt); PROFPOP; } for (struct session *ses = sessionlist; ses; ses = ses->next) { if (ses->socket && FD_ISSET(ses->socket, &readfdmask)) { aborting=false; any_closed=false; do { read_mud(ses); if (any_closed) { any_closed=false; goto after_read; /* The remaining sessions will be done after select() */ } #ifdef HAVE_ZLIB } while (ses->mccp_more); #else } while (0); #endif } } after_read: if (activesession->server_echo && (2-activesession->server_echo != gotpassword)) { gotpassword= 2-activesession->server_echo; if (!gotpassword) got_more_kludge=false; user_passwd(gotpassword && !got_more_kludge); term_echoing=!gotpassword; } }
// Initiates chip erase. static void chip_erase() { start_command(COMMAND_CHIP_ERASE); end_command(); }
// Initiates block erase. static void block_erase(uint32_t offset) { start_command(COMMAND_BLOCK_ERASE); write_address(offset); end_command(); }
// Write enable. static void write_enable() { start_command(COMMAND_WRITE_ENABLE); end_command(); }