Zerocat Chipflasher  v0.4.10-182-333b622f
Flash free firmware to BIOS chips, kick the Management Engine.
Macros | Functions | Variables
kick.c File Reference

This file provides procedure main() of kick, the chipflasher firmware. More...

#include "simpletext.h"
#include "simpletools.h"
#include <ctype.h>
#include "libprop/putChar.h"
#include "libcommon/common.h.tmp"
#include "libcommon/serial-codes.h"
#include "libcommon/filespec.h"
#include "libSPI/SPI-command-set.h"
#include "libSPI/SPI-flash-bits.h"
#include "libkick/proppins.h"
#include "libkick/chipspec.h"
#include "libkick/key-enable-bits.h"
#include "libkick/fast-SPI.h"
#include "kick.h"
#include "libprop/putChar.c"
#include "libcommon/hexdigit2bin.c"
#include "libcommon/bin2hexdigit.c"
#include "libcommon/filespec.c"
#include "libkick/chipspec.c"

Macros

#define SCANNING_DATA   0x00
 
#define DATA_START   0x01
 
#define FF_START   0x02
 
#define SCANNING_FF   0x03
 
#define APPLY_CUT   0x01
 
#define HAS_NOT_BEEN_CUT_YET   0x02
 
#define IS_0XFF   0x04
 
#define MODE_0XFF   filespec->mode_0xff
 
#define INLINE_0XFF   (MODE_0XFF & MODE_INLINE)
 
#define PAYLOAD_DEFAULT   (filespec->payload_default)
 

Functions

int main (void)
 This is main() of kick, the firmware. More...
 
void connected (void)
 
void mirror (char *keymsg)
 
void option_readblock (const enum tag_blocksize blocksize)
 
void range_error (void)
 Reports an Out-of-Range user input error and resets member inlevel of xcog1. More...
 
void option_batchblockerase (const enum tag_blocksize blocksize, const unsigned char blockcmd)
 Versatile block erase function, which allows erasing of multiple blocks of different sizes, i.e. 4K (sectors), 32K and 64K. More...
 
void global_sector_protect (unsigned char pswitch)
 Method to globally protect/unprotect all sectors. More...
 
void key_polling (int *key_is_valid, int *quit)
 Essential function. Scans stdin for configured keys and issues the apropriate actions. Typing 'q' quits this routine. More...
 
void check_dryrun (void)
 Checks whether a write fail should be expected. A function with very basic and poor functionality. More...
 
int plug_detect (void)
 Check if an SPI-Plug is detected and put a message on screen. More...
 
void menu (int mode)
 Put the chipflasher menu on screen and invoke key_polling(). More...
 
void hr (char c, int n, char nl)
 Put a horizontal line on screen. More...
 
unsigned char get_addrlen (enum tag_type_of_addrlen type_of_addrlen, unsigned int addr)
 Auxiliary function that returns the length of an address for different situations. More...
 
void key_config (void)
 Enable menu keys according to register flags. More...
 
void menu_line (unsigned int k1, char *k1msg, unsigned int k2, char *k2msg, unsigned int k3, char *k3msg)
 Put a menu line with selected menu options on terminal screen. More...
 
void menu_options (void)
 Put menu options on terminal screen. More...
 
unsigned char verify_0xff (unsigned int firstloc, unsigned int memsize)
 This function scans the specified chip memory for values different than 0xff. If a value different to 0xff is found, an error status is returned. More...
 
void MOT_mkline (struct tag_linedat *linedat, union tag_typeS *typeS, char *linebuf)
 This function wraps a binary payload into a Motorola S-record frame. More...
 
int strpos (char *str, char c)
 Report the position of a character in a string. More...
 
void MOT_header (char *header, char *linebuf)
 This function invokes MOT_mkline(), but initializes parameters first with apropriate header data. More...
 
void MOT_data (struct tag_linedat *linedat, char *linebuf)
 
void MOT_summary (unsigned int lines, char *linebuf)
 
unsigned char yes_no (char *question, unsigned char level_rst)
 This function allows to put a question which expects true or false. More...
 
void chip_ini (unsigned char new_index)
 
signed char chip_read (struct tag_filespec *filespec, unsigned int firstloc, unsigned int memsize, unsigned int *lines, char *linebuf)
 
void chip_txfile (struct tag_filespec *filespec, unsigned char addrlen_in_bits, unsigned int firstloc, unsigned int memsize, unsigned char screenmode)
 
signed char linebuf_out (char *linebuf)
 Put a formatted data line onto tty. More...
 
char outfifo (char c)
 
int outstr (char *s)
 
void HEXDUMP_mkline (struct tag_linedat *linedat, char *linebuf_orig)
 This function transforms a binary payload into a row of ascii chars including line ending characters and stores it in a buffer. More...
 
void hello ()
 Put a small headline on terminal screen that helps to identify the program. More...
 
void cmd_WREN (void)
 Set Write Enable Latch bit. More...
 
void cmd_WRSR (const unsigned char regno, const unsigned char byte)
 Write to status registers. More...
 
void page_write (const unsigned int addr, unsigned char *buffer)
 Write a page buffer to chip. More...
 
void exit_sequence (const char status)
 Tell terminal to exit listening mode. More...
 
int WIP_polling (int poll_limit)
 Determine end of write cycle by polling the WIP bit. More...
 
unsigned int CPM_polling (void)
 Poll CPM bit. More...
 
unsigned char SR_report (int ireg)
 Put status register's content on screen. More...
 
unsigned char inb (void)
 
unsigned int inbits (unsigned int msbit)
 
void outbits (const unsigned int value, unsigned int msbit)
 
void cmd (const unsigned char cmd, const unsigned int value, unsigned char bits)
 
int cmd_RDID_JEDEC (void)
 
void cmd_DP (void)
 
unsigned char cmd_RDSR (unsigned char regno)
 Read a chip register. More...
 
void cmd_WRDI (void)
 
void SPI_ini (void)
 Initialize SPI bus; activate hardware write protection. More...
 
void SPI_off (int mode)
 Switch SPI bus off. More...
 
int hex2bin (unsigned char a, unsigned char b)
 Converts a pair of hexadecimal chars into binary value. More...
 
void PGM_cycle (enum tag_cmdstat *cmdstat, unsigned char odd_tracker)
 
void ledstat (void *ptr)
 This function controls board LEDs. To be used with extra cog, to be stopped externally. More...
 
void burn (void *ptr)
 Wite data to chip. More...
 
void MOT_typeS_fillup (union tag_typeS *typeS)
 Generating and parsing a Motorola S-record line needs to have some specs available about the line in question. This function fills a struct, based on some data that can be provided during runtime, to have all specs available when needed. More...
 
char HEXDUMP_rxline (struct tag_xcog0 *px, unsigned int *lines)
 Parse a Hexdump line. More...
 
char MOT_rxline (struct tag_xcog0 *px, unsigned int *lines, int hexmode)
 Receive and parse a line in Motorola S-Record format. This func finishes successfully after having parsed the line's checksum data, thus not evaluating any line ending characters. More...
 
char queue (struct tag_xcog0 *px, unsigned char vbin, unsigned int *pwr)
 
void report_err (char reported_err)
 
void chip_rxfile (struct tag_xcog0 *px, char screen_output)
 
void chip_erase (void)
 This function calls the global chip erase command. More...
 

Variables

int _cfg_modeterminal = -1
 configured through propeller-load More...
 
int _cfg_rstdisable = -1
 configured through propeller-load More...
 
int _cfg_baudrate = -1
 configured through propeller-load More...
 
unsigned char cmd_CE = CMD__CE_0X60
 Global chip erase command, may be overridden by key_config(). More...
 
struct tag_xcog0 xcog0
 Cog parameters for burn(). More...
 
struct tag_xcog1 xcog1
 Cog parameters for ledstat(). More...
 
enum tag_spimode spimode = mode_3
 SPI mode to be used through the whole program. More...
 
struct tag_chip chip = { 0, chipspec }
 
struct tag_filespecpfspec
 Pointer to specifications that are associated with selected format type. More...
 

Detailed Description

Copyright

Zerocat Chipflasher — Flash free firmware to BIOS chips, kick the Management Engine.

Copyright (C) 2015–2020 Kai Mertens kmx@p.nosp@m.oste.nosp@m.o.net

The Zerocat Chipflasher is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

The Zerocat Chipflasher is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

This file is part of the Zerocat Chipflasher.

“In file” Documentation

Todo:

Implement a better initial handshake with connect.

Update schematic according to AN 'interfacing higher voltages'.

Notes

Broken Chips

Macro Definition Documentation

◆ APPLY_CUT

#define APPLY_CUT   0x01

◆ DATA_START

#define DATA_START   0x01

◆ FF_START

#define FF_START   0x02

◆ HAS_NOT_BEEN_CUT_YET

#define HAS_NOT_BEEN_CUT_YET   0x02

◆ INLINE_0XFF

#define INLINE_0XFF   (MODE_0XFF & MODE_INLINE)

◆ IS_0XFF

#define IS_0XFF   0x04

◆ MODE_0XFF

#define MODE_0XFF   filespec->mode_0xff

◆ PAYLOAD_DEFAULT

#define PAYLOAD_DEFAULT   (filespec->payload_default)

◆ SCANNING_DATA

#define SCANNING_DATA   0x00

◆ SCANNING_FF

#define SCANNING_FF   0x03

Function Documentation

◆ check_dryrun()

void check_dryrun ( void  )
Todo:
Shall we ignore bit 7 of all chips for the test?
807 {
808  //check for dry-run
809  unsigned char sr;
810  SPI_ON;
811  sr = cmd_RDSR(0);
812 
813  if(chip.pspec->id_JEDEC == 0x00ef3013)
814  sr &= 0b01111111; //don't care for SRP
815 
816  if(sr & chip.pspec->sr_wrmask[0]) {
817  outstr(
818  "Be aware: The Status Register 1 is not zero, some memory areas may be write protected.\r\n"
819  );
820  }
822 }

Referenced by key_polling(), and option_batchblockerase().

◆ chip_erase()

void chip_erase ( void  )

Note that this function will be invoked only if the respective menu option is available.

3002 {
3003  char s[SIZE_STR_MESSAGE];
3004  int r;
3005 
3006  WPn_HIGH;
3007  cmd_WREN(); //send WREN instruction
3008  CHIP_ON;
3009  outbits(cmd_CE, 1 << 7);
3010  CHIP_OFF;
3011  WPn_LOW;
3012 
3013  r = WIP_polling(WIP_CHIP);
3014  if (r == -1) {
3016  }
3017  else {
3018  sprinti(s, MSG_WIPCHECKS, r);
3019  outstr(s);
3020  }
3021 }

Referenced by key_polling().

◆ chip_ini()

void chip_ini ( unsigned char  new_index)
Todo:
What happens on division by zero?
1320 {
1321  chip.pspec = chip.pspec - chip.index + new_index;
1322  chip.index = new_index;
1325  if(chip.pspec->cmdset & (1 << X02_PP))
1327 }

Referenced by key_polling(), and main().

◆ chip_read()

signed char chip_read ( struct tag_filespec filespec,
unsigned int  firstloc,
unsigned int  memsize,
unsigned int *  lines,
char *  linebuf 
)
1338 {
1339  //switches:
1340  #define SCANNING_DATA 0x00 //test != 0xff, test_old != 0xff
1341  #define DATA_START 0x01 //test != 0xff, test_old == 0xff
1342  #define FF_START 0x02 //test == 0xff, test_old != 0xff
1343  #define SCANNING_FF 0x03 //test == 0xff, test_old == 0xff
1344  //flags:
1345  #define APPLY_CUT 0x01
1346  #define HAS_NOT_BEEN_CUT_YET 0x02
1347  #define IS_0XFF 0x04
1348  //aux:
1349  #define MODE_0XFF filespec->mode_0xff
1350  #define INLINE_0XFF (MODE_0XFF & MODE_INLINE)
1351  #define PAYLOAD_DEFAULT (filespec->payload_default)
1352 
1353  struct tag_linedat linedat = {
1354  malloc(PAYLOAD_DEFAULT << 1), //shift left: provide extra space for inline prefetch
1355  (PAYLOAD_DEFAULT << 1) - 1,
1356  0,
1357  0,
1358  firstloc,
1359  0
1360  };
1361  unsigned char chars_tested = 0;
1362  unsigned char cut = 0;
1363  unsigned char test_old;
1364 
1365  /*
1366  * Create special startup condition:
1367  * We are jumping directly into DATA_START or SCANNING_FF.
1368  */
1369  unsigned char test = 0xff; //makes it easy to check for 0xff
1370  unsigned char runlen = INLINE_0XFF + 1; //SCANNING_FF decrements runlen
1371  unsigned char flags = ((IS_0XFF | HAS_NOT_BEEN_CUT_YET) & ~APPLY_CUT);
1372 
1373  //scan specified memory
1374  while(memsize) {
1375  //save & prefetch
1376  test_old = test; //save
1377  test = inb(); //prefetch in respect to chars_tested
1378 
1379  //check memsize first to catch address roll-over
1380  if(chars_tested == memsize) {
1381  cut = chars_tested;
1382  flags |= APPLY_CUT;
1383  }
1384  else if(MODE_0XFF & MODE_SPLIT) {
1385  switch((((test == 0xff) << 1) | (test_old == 0xff))) {
1386  case FF_START:
1387  cut = chars_tested; //save cut position in case we need later
1388  flags |= HAS_NOT_BEEN_CUT_YET;
1389  runlen = INLINE_0XFF;
1390  if(!runlen) {
1391  if(cut)
1392  flags |= APPLY_CUT;
1393  }
1394  break;
1395 
1396  case SCANNING_FF:
1397  if(runlen) {
1398  runlen--;
1399  }
1400  else {
1401  if(flags & HAS_NOT_BEEN_CUT_YET) {
1402  flags &= ~HAS_NOT_BEEN_CUT_YET;
1403  if(cut)
1404  flags |= APPLY_CUT;
1405  }
1406  }
1407  break;
1408 
1409  case DATA_START:
1410  if(!runlen) {
1411  cut = chars_tested; //save cut position in case we need later
1412  if(cut)
1413  flags |= APPLY_CUT;
1414  }
1415  else {
1416  cut = 0; //we didn’t use the saved cut position, let’s reset to zero
1417  }
1418  break;
1419 
1420  case SCANNING_DATA:
1421  break;
1422  }
1423  }
1424 
1425  //maximal payload?
1426  if(!(flags & APPLY_CUT)) {
1427  if(chars_tested == PAYLOAD_DEFAULT) {
1428  if(!cut)
1429  cut = chars_tested;
1430  flags |= APPLY_CUT;
1431  }
1432  }
1433 
1434  //store prefetch in buffer
1435  linedat.buf[linedat.wr++ & linedat.mask] = test;
1436 
1437  //check for 0xff line
1438  if(test_old != 0xff)
1439  flags &= ~IS_0XFF;
1440 
1441  //evaluate flags
1442  if(flags & APPLY_CUT) {
1443  //update
1444  chars_tested -= cut;
1445  memsize -= cut;
1446 
1447  //skip output of 0xff?
1448  if((MODE_0XFF & MODE_STRIP) && (flags & IS_0XFF)) {
1449  linedat.rd += cut;
1450  linedat.startaddr += cut;
1451  if(linebuf_out(NULL) == -1)
1452  goto ERROR;
1453  }
1454  else {
1455  //update linedat
1456  linedat.payload = cut;
1457 
1458  //make data line
1459  switch(filespec->format) {
1460  case HEXDUMP:
1461  HEXDUMP_mkline(&linedat, linebuf);
1462  break;
1463 
1464  case MOTBIN:
1465  MOT_data(&linedat, linebuf);
1466  break;
1467  }
1468 
1469  //put out
1470  if(linebuf_out(linebuf) == -1)
1471  goto ERROR;
1472  *lines += 1; //sum up
1473  }
1474 
1475  //reset values
1476  cut = 0;
1477  flags = (IS_0XFF & ~APPLY_CUT & ~HAS_NOT_BEEN_CUT_YET);
1478  }
1479 
1480  //increment counter
1481  chars_tested++;
1482  }
1483  free(linedat.buf);
1484  return 0;
1485 
1486  ERROR:
1487  free(linedat.buf);
1488  return -1;
1489 }

Referenced by chip_txfile().

◆ chip_rxfile()

void chip_rxfile ( struct tag_xcog0 px,
char  screen_output 
)
2863 {
2864  enum tag_rxstep {
2865  rx_stx_or_eot,
2866  rx_error,
2867  send_nak,
2868  rx_done
2869  } rx = rx_stx_or_eot;
2870  char errcode = ERRC__SUCCESS;
2871  unsigned int lines = 0;
2872  char a = 0;
2873 
2874  //cog setup
2876  px->pbuf = malloc(px->bufsize);
2877  if(chip.pspec->cmdset & (1 << X02_PP)) {
2878  px->cmd = CMD__PP;
2879  px->psize = SIZE_256;
2880  }
2881  else if(chip.pspec->cmdset & (1 << XAD_CP)) {
2882  px->cmd = CMD__CP;
2883  px->psize = 2;
2884  }
2885  else if(chip.pspec->cmdset & (1 << X02_BP)) {
2886  px->cmd = CMD__BP;
2887  px->psize = 1;
2888  }
2889  px->offrd = 0;
2890  px->offwr = 0;
2891  px->lineaddr = 0;
2892  px->rq_spioff = 0;
2893  px->queue_empty = 1;
2894  px->abits = chip.addrlen_in_bits;
2895  px->pcog = cog_run(&burn, STACK_BURNBUF);
2896 
2897  //send header
2898  outfifo(SOH);
2899  if(screen_output)
2901  else
2903  outfifo(pfspec->format);
2904 
2905  while(1) {
2906  switch(rx) {
2907  case rx_stx_or_eot:
2908  do
2909  a = getChar();
2910  while(a != EOT && a != STX);
2911  if(a == EOT) {
2912  rx = rx_done;
2913  break;
2914  }
2915  outfifo(a); //feedback
2916  switch(pfspec->format) {
2917  case MOTBIN:
2918  errcode = MOT_rxline(px, &lines, BINMODE);
2919  break;
2920 
2921  case HEXDUMP:
2922  errcode = HEXDUMP_rxline(px, &lines);
2923  break;
2924  }
2925  if(errcode) {
2926  rx = rx_error;
2927  break;
2928  }
2929 
2930  //rx_etx_or_can:
2931  a = getChar(); //fetch ETX
2932  if(a == CAN) {
2933  errcode = ERRC__JOB_CANCELLATION;
2934  rx = send_nak;
2935  break;
2936  }
2937  /*
2938  * NOTE connect is NOT sending any line ending characters except:
2939  * - ETX for MOT format
2940  * - CLIM_HEXDUMP + ETX for HEXDUMP format, but the
2941  * received CLIM_HEXDUMP has already been processed by HEXDUMP_rxline().
2942  *
2943  */
2944 
2945  //send_LE:
2946  /*
2947  * NOTE: HEXDUMP_rxline uses CLIM_HEXDUMP for detection of line ending,
2948  * and this character, i.e. a Carriage Return, has already been sent
2949  * as feedback.
2950  *
2951  */
2952  PUTCHAR_CR;
2953  PUTCHAR_NL;
2954 
2955  //wait_burn:
2956  while(!px->queue_empty);
2957 
2958  //send_ack:
2959  outfifo(ACK);
2960  rx = rx_stx_or_eot;
2961  break;
2962 
2963  case rx_error:
2964  if(errcode != ERRC__JOB_CANCELLATION)
2965  do
2966  a = outfifo(getChar()); //feedback
2967  while(a != ETX && a != CAN); //CAN?! Yes, user may hit 'q' after error occured...
2968  // ...and transmission will then end with CAN
2969 
2970  case send_nak:
2971  outfifo(NAK);
2972  outfifo(errcode); //send error code
2973  rx = rx_stx_or_eot;
2974  break;
2975 
2976  case rx_done:
2977  px->rq_spioff = 1;
2978  while(px->rq_spioff);
2979  cog_end(px->pcog);
2980  free(px->pbuf);
2982  report_err(errcode);
2983  return;
2984  }
2985  }
2986 }

Referenced by key_polling().

◆ chip_txfile()

void chip_txfile ( struct tag_filespec filespec,
unsigned char  addrlen_in_bits,
unsigned int  firstloc,
unsigned int  memsize,
unsigned char  screenmode 
)
1500 {
1501  char linebuf[SIZE_LINEBUF];
1502  unsigned int lines = 0;
1503 
1504  //activate host
1505  outfifo(SOH);
1506  if(screenmode & MODE_SCREEN_OUTPUT)
1508  else
1511 
1512  //put chip on
1513  CHIP_ON;
1514  cmd(CMD__READ, firstloc, addrlen_in_bits);
1515 
1516  //create header
1517  char header[SIZE_HEADER];
1518  sprinti(header, HEADER, chip.pspec->name);
1519 
1520  //select format
1521  switch(filespec->format) {
1522  case MOTBIN:
1523  //make & put header
1524  MOT_header(header, linebuf);
1525  if(linebuf_out(linebuf) == -1)
1526  goto ERROR;
1527 
1528  //read chip
1529  if(chip_read(filespec, firstloc, memsize, &lines, linebuf) == -1)
1530  goto ERROR;
1531 
1532  //make & put summary line
1533  MOT_summary(lines, linebuf);
1534  if(linebuf_out(linebuf) == -1)
1535  goto ERROR;
1536  break;
1537 
1538  case HEXDUMP:
1539  //make & put header
1540  *linebuf = sprinti(linebuf, "-#header: %s\r\n", header) - 1;
1541  if(linebuf_out(linebuf) == -1)
1542  goto ERROR;
1543 
1544  //read chip
1545  if(chip_read(filespec, firstloc, memsize, &lines, linebuf) == -1)
1546  goto ERROR;
1547 
1548  //make & put summary line
1549  *linebuf = sprinti(linebuf, "-#lines: %d\r\n", lines) - 1;
1550  if(linebuf_out(linebuf) == -1)
1551  goto ERROR;
1552  break;
1553  }
1554  goto SUCCESS;
1555 
1556  ERROR:
1557 
1558  SUCCESS:
1559  CHIP_OFF;
1560  //terminate connection
1561  outfifo(EOT);
1562  return;
1563 }

Referenced by key_polling(), and option_readblock().

◆ cmd()

void cmd ( const unsigned char  cmd,
const unsigned int  value,
unsigned char  bits 
)
2011 {
2012  outbits(cmd, 1 << 7);
2013  outbits(value, 1 << --bits);
2014 }

Referenced by burn(), chip_txfile(), cmd(), option_batchblockerase(), page_write(), and verify_0xff().

◆ cmd_DP()

void cmd_DP ( void  )
2037 {
2038  int dt = (CLKFREQ / 1000000) * 10;
2039 
2040  CHIP_ON;
2041  outbits(CMD__DP, 1 << 7);
2042  CHIP_OFF;
2043  //Macronix Datasheet:
2044  //now wait about 10µs for tDP(2)
2045  waitcnt(CNT + dt);
2046 }

Referenced by SPI_off().

◆ cmd_RDID_JEDEC()

int cmd_RDID_JEDEC ( void  )
2021 {
2022  int id_JEDEC;
2023  CHIP_ON;
2024  outbits(CMD__RDID, 1 << 7);
2025  id_JEDEC = inbits(1 << 23);
2026  if(chip.pspec->cmdset & (1 << X00_NOP)) //for SST25VF016B only?
2027  outbits(CMD__NOP, 1 << 7);
2028  CHIP_OFF;
2029  return id_JEDEC;
2030 }

Referenced by key_polling().

◆ cmd_RDSR()

unsigned char cmd_RDSR ( unsigned char  regno)
Parameters
regnoNumber of the register to be read.
Value 0 attempts to read the standard Status Register.
Value 3 attempts to read the Security Register.
Returns
Returns the content of the register.
2063 {
2064  unsigned char buf;
2065 
2066  CHIP_ON;
2067  switch(regno) {
2068  case 3:
2069  outbits(CMD__RDSCUR, 1 << 7);
2070  break;
2071 
2072  case 2:
2073  outbits(CMD__RDSR3, 1 << 7);
2074  break;
2075 
2076  case 1:
2077  outbits(CMD__RDSR2, 1 << 7);
2078  break;
2079 
2080  case 0:
2081  default:
2082  outbits(CMD__RDSR, 1 << 7);
2083  break;
2084  }
2085  buf = inb();
2086  CHIP_OFF;
2087 
2088  return buf;
2089 }

Referenced by check_dryrun(), cmd_WRSR(), and SR_report().

◆ cmd_WRDI()

void cmd_WRDI ( void  )
2096 {
2097  CHIP_ON;
2098  outbits(CMD__WRDI, 1 << 7);
2099  CHIP_OFF;
2100 }

Referenced by PGM_cycle().

◆ cmd_WREN()

void cmd_WREN ( void  )
1716 {
1717  CHIP_ON;
1718  outbits(CMD__WREN, 1 << 7);
1719  CHIP_OFF;
1720 }

Referenced by burn(), chip_erase(), global_sector_protect(), option_batchblockerase(), and page_write().

◆ cmd_WRSR()

void cmd_WRSR ( const unsigned char  regno,
const unsigned char  byte 
)
1733 {
1734  unsigned char msbit = 7;
1735  unsigned int value = 0x00000000 | byte;
1736 
1737  //get SR0 backup for some chips using X01_WRSR to access SR1.
1738  value |= (cmd_RDSR(0) & chip.pspec->sr_wrmask[0]) << 8;
1739 
1740  CHIP_ON;
1741  if(chip.pspec->cmdset & (1 << X50_EWSR))
1742  outbits(CMD__EWSR, 1 << 7);
1743  else
1744  outbits(CMD__WREN, 1 << 7);
1745  CHIP_OFF;
1746  CHIP_ON;
1747  switch(regno) {
1748  case 2:
1749  outbits(CMD__WRSR3, 1 << 7);
1750  break;
1751 
1752  case 1:
1753  if(!(chip.pspec->cmdset & (1 << X31_WRSR2))) {
1754  /*
1755  * FIXME
1756  * Take care NOT to read volatile '1'-bits of SR0 and writing it
1757  * into non-volatile bits!
1758  *
1759  */
1760  msbit = 15;
1761  outbits(CMD__WRSR, 1 << 7);
1762  }
1763  else {
1764  outbits(CMD__WRSR2, 1 << 7);
1765  }
1766  break;
1767 
1768  case 0:
1769  default:
1770  outbits(CMD__WRSR, 1 << 7);
1771  break;
1772  }
1773  outbits(value, 1 << msbit);
1774  CHIP_OFF;
1775 }

Referenced by key_polling().

◆ connected()

void connected ( void  )
190 {
191  char s[SIZE_STR_MESSAGE];
192  sprinti(s, "%s%d%s", "Connected with ", _cfg_baudrate, " baud.\r\n");
193  outstr(s);
194 }

Referenced by main().

◆ exit_sequence()

void exit_sequence ( const char  status)
Parameters
statusA status byte could be passed as well.
1840 {
1843  outfifo(status); //status
1844 }

Referenced by main().

◆ get_addrlen()

unsigned char get_addrlen ( enum tag_type_of_addrlen  type_of_addrlen,
unsigned int  addr 
)
929 {
930  unsigned char addrlen_in_bytes;
931 
932  if(addr < SIZE_256) {
933  if(type_of_addrlen == ADDRLEN_MOT)
934  addrlen_in_bytes = 2;
935  else
936  addrlen_in_bytes = 1;
937  }
938  else if(addr < SIZE_64K)
939  addrlen_in_bytes = 2;
940  else if(addr < SIZE_128MBIT)
941  addrlen_in_bytes = 3;
942  else
943  addrlen_in_bytes = 4;
944 
945  if(type_of_addrlen == ADDRLEN_IN_BITS)
946  return(addrlen_in_bytes << 3);
947  return(addrlen_in_bytes);
948 }

Referenced by chip_ini(), MOT_data(), and MOT_summary().

◆ global_sector_protect()

void global_sector_protect ( unsigned char  pswitch)
367 {
368  xcog1.inlevel = 0;
369  if(yes_no(MSG_SURETOPROCEED, 0)) {
370  SPI_ON;
371  WPn_HIGH;
372 
373  //any address within sector will do
374  for(unsigned int addr = chip.pspec->chipsize; addr; addr -= SIZE_4K) {
375  cmd_WREN();
376  CHIP_ON;
377  pswitch == OFF ? \
378  cmd(CMD__US, addr - 1, 24) : \
379  cmd(CMD__PS, addr - 1, 24);
380  CHIP_OFF;
382  }
383  WPn_LOW;
384  SR_report(0);
386  }
387 }

Referenced by key_polling().

◆ hello()

void hello ( )
1699 {
1700  outfifo('\r');
1701  hr('=', 5, NULL);
1703  hr('=', MENUWIDTH - (sizeof(HEADER_KICK) - 1) - 5, '\n');
1704 }

Referenced by main(), and menu().

◆ hex2bin()

int hex2bin ( unsigned char  a,
unsigned char  b 
)
Parameters
aFirst char (i.e. msnibble) of the character pair.
bSecond char (i.e. lsnibble) of the character pair.
Returns
Returns binary value 0x00 to 0xff or -1 if no validation possible.
2204 {
2205  signed char hnib;
2206  signed char lnib;
2207 
2208  hnib = hexdigit2bin(a);
2209  lnib = hexdigit2bin(b);
2210 
2211  if(hnib == -1 || lnib == -1)
2212  return -1; //no true hex
2213  return (hnib << 4) | lnib;
2214 }

Referenced by HEXDUMP_rxline(), and MOT_rxline().

◆ hr()

void hr ( char  c,
int  n,
char  nl 
)
910 {
911  while(n--)
912  outfifo(c);
913  if(nl != NULL)
914  outstr("\r\n");
915 }

Referenced by hello(), and menu_options().

◆ inb()

unsigned char inb ( void  )
inline
1963 {
1964  return inbits(1 << 7);
1965 }

Referenced by chip_read(), cmd_RDSR(), CPM_polling(), verify_0xff(), and WIP_polling().

◆ inbits()

unsigned int inbits ( unsigned int  msbit)
1972 {
1973  unsigned int in = 0;
1974  while(msbit) {
1975  CLOCK_LOW; tCLQV;
1976  if(INA & BIT_MISO)
1977  in |= msbit;
1978  CLOCK_HIGH;
1979  msbit >>= 1;
1980  }
1981  return in;
1982 }

Referenced by cmd_RDID_JEDEC(), and inb().

◆ key_config()

void key_config ( void  )
960 {
961  if(chip.pspec->cmdset & (1 << X03_READ)) {
962  unsigned int reg = keyreg;
963 
964  //enable 'fetch file and write chip'
965  if((chip.pspec->cmdset & (1 << X02_PP)) ||
966  (chip.pspec->cmdset & (1 << X02_BP)) ||
967  (chip.pspec->cmdset & (1 << XAD_CP)))
968  reg |= KEYBIT_I;
969 
970  //enable 'read page'
971  if(chip.pspec->cmdset & (1 << X02_PP))
972  reg |= KEYBIT_p;
973 
974  //enable 'sector erase'
975  if(chip.pspec->cmdset & (1 << X20_SE))
976  reg |= KEYBIT_s | KEYBIT_S;
977 
978  //read block 32k
979  //erase block 32k
980  if(chip.pspec->cmdset & (1 << X52_BE32K))
981  reg |= KEYBIT_k | KEYBIT_K;
982 
983  //read block 64k
984  //erase block 64k
985  if(chip.pspec->cmdset & (1 << XD8_BE64K))
986  reg |= KEYBIT_b | KEYBIT_B;
987 
988  reg |= KEYBIT_c | KEYBIT_m;
989 
990  //enable 'erase chip'
991  if(chip.pspec->cmdset & (1 << X60_CE)) {
992  reg |= KEYBIT_C;
993  }
994  else if(chip.pspec->cmdset & (1 << XC7_CE)) {
995  reg |= KEYBIT_C;
996  cmd_CE = CMD__CE_0XC7; //override global CE command
997  }
998 
999  //enable 'report status register'
1000  if(chip.pspec->cmdset & (1 << X05_RDSR))
1001  reg |= KEYBIT_r;
1002 
1003  //enable 'write block protection bits'
1004  if(chip.pspec->cmdset & (1 << X01_WRSR))
1005  reg |= KEYBIT_W;
1006 
1007  //enable 'global protect'
1008  if(chip.pspec->cmdset & (1 << X36_PS))
1009  reg |= KEYBIT_G;
1010 
1011  //enable 'global unprotect'
1012  if(chip.pspec->cmdset & (1 << X39_US))
1013  reg |= KEYBIT_X;
1014 
1015  keyreg = reg;
1016  }
1017 }

Referenced by menu().

◆ key_polling()

void key_polling ( int *  key_is_valid,
int *  quit 
)
401 {
402  char keyinput;
403  int keyid = 0;
404 
405  keyinput = getChar();
406  while((keymsg[keyid][1] != keyinput) &&
407  (keymsg[keyid][3] != keyinput || keyinput == ' ') &&
408  (keyid != ID_NONE))
409  keyid++;
410 
411  if(!(keyreg & (1 << keyid))) {
412  *key_is_valid = 0;
413  }
414  else {
415  mirror(keymsg[keyid]);
416 
417  switch(keyinput) {
418  //key active by default
419  case 'q': //quit
420  {
421  //action
422  if(DIRA & BIT_PNP_DEVICE) {
424  outstr("The SPI bus has been powered off.\r\n");
425  //TODO: Why do we have to reset the chip index?
428  }
429  else {
430  xcog1.inlevel = 0;
431  *quit = 1;
432  xcog1.green = ON; //restore LED
433  }
434  }
435  break;
436 
437  //key active by default
438  case 't': //toggle output format
439  {
440  //action
441  xcog1.inlevel = 0;
442  if(pfspec == &(filespec[MOTBIN]))
443  pfspec = &(filespec[HEXDUMP]);
444  else
445  pfspec--;
446  }
447  break;
448 
449  case 'W': { //set config
450  int m = 8;
451  int bit;
452  int bitmask;
453  int byte = 0;
454  int ireg = 0;
455  int ireg_max = 0;
456  char s[SIZE_STR_MESSAGE];
457  char* p;
458 
459  if(chip.pspec->cmdset & (1 << X35_RDSR2))
460  ireg_max = 1;
461  if(chip.pspec->cmdset & (1 << X15_RDSR3))
462  ireg_max = 2;
463 
464  if(ireg_max > 0) {
465  xcog1.inlevel++;
466  sprinti(s, "Which register to change (%d..%d)? ", 1, ireg_max + 1);
467  outstr(s);
468  ireg = getDec() - 1;
469  if(ireg < 0 || ireg > ireg_max) {
470  range_error();
471  break;
472  }
473  }
474  bitmask = chip.pspec->sr_wrmask[ireg];
475  p = chip.pspec->sr_bitnames[ireg];
476 
477  SPI_ON;
478  byte = SR_report(ireg);
480  xcog1.inlevel++;
481  outstr("Name\tBit\tStatus\tValue?\r\n" \
482  "----\t---\t------\t------\r\n" \
483  );
484  while(*p != '\0') {
485  outfifo(*p);
486  if(*p == '\t') {
487  char cstat;
488  outfifo('0' + --m);
489  outstr(":\t"); //trigger permanent flush with ':'.
490  bit = 1 << m;
491  cstat = byte & bit ? '1' : '0';
492  outfifo(cstat);
493  outfifo('\t');
494  if(bitmask & bit) {
495  unsigned char in;
496  in = getChar();
497  if(in == '0') {
498  outfifo('0');
499  byte &= ~bit;
500  }
501  else if(in == '1') {
502  outfifo('1');
503  byte |= bit;
504  }
505  else {
506  outfifo(cstat);
507  }
508  }
509  else {
510  outfifo('x');
511  }
512  outstr("\r\n");
513  }
514  p++;
515  }
516  sprinti(s, "New register value would be: $%02x\r\n", byte);
517  outstr(s);
518  //action
519  if(yes_no(MSG_SURETOPROCEED, 0)) {
520  SPI_ON;
521  WPn_HIGH;
522  cmd_WRSR(ireg, byte);
523  sprinti(s, MSG_WIPCHECKS, WIP_polling(WIP_PAGE));
524  outstr(s);
525  WPn_LOW;
526  SR_report(ireg);
528  }
529  }
530  break;
531 
532  case 'r': //show config
533  {
534  //action
535  xcog1.inlevel = 0;
536  SPI_ON;
537  SR_report(0);
538  if(chip.pspec->cmdset & (1 << X35_RDSR2))
539  SR_report(1);
540  if(chip.pspec->cmdset & (1 << X15_RDSR3))
541  SR_report(2);
542  if(chip.pspec->cmdset & (1 << X2B_RDSCUR))
543  SR_report(3);
545  }
546  break;
547 
548  case 'G': //global sector protect
550  break;
551 
552  case 'X': //global sector unprotect
554  break;
555 
556  //key active by default
557  case 'f': //force chip model
558  {
559  //action
560  xcog1.inlevel = 0;
561  if(!chip.index)
563  else
564  chip_ini(chip.index - 1);
566  }
567  break;
568 
569  //key active by default
570  case 'd': //detect chip
571  {
572  char s[SIZE_STR_MESSAGE];
573 
574  //JEDEC__RDID (should be the first command to use)
575  xcog1.inlevel = 0;
576  unsigned char powerup_extra = POWERUP_EXTRA;
577  int id_JEDEC;
578 
579  //power up
580  do {
581  SPI_ON;
582  if(!(id_JEDEC = cmd_RDID_JEDEC())) {
584  usleep(POWERUP_OFFTIME);
585  }
586  else
587  break;
588  } while(powerup_extra--);
589 
590  //set chip
591  if(powerup_extra == 0xff) {
592  outstr("Power failure? Clip attached?\r\n");
593  }
594  else {
595  struct tag_chipspec * check = chip.pspec - chip.index;
596  unsigned char i = 0;
597  while(i < ARRAY_CHIPSPEC) {
598  if((check->cmdset & (1 << X9F_RDID)) && id_JEDEC == check->id_JEDEC)
599  break;
600  i++;
601  check++;
602  }
603  if(i == ARRAY_CHIPSPEC) { //no match occured
604  outstr("No match in database.\r\n");
605  sprinti(s, "Chip's JEDEC ID: $%06x\r\n", id_JEDEC);
606  outstr(s);
608  }
609  else {
610  chip_ini(i);
612  sprinti(s, "Chip successfully detected: %s\r\n", chip.pspec->name);
613  outstr(s);
614  if(!chip.pspec->sr_is_static)
615  outstr(
616  "NOTE: The Status Register is not static, the SPI bus is kept powered until you quit.\r\n"
617  );
618  if(chip.pspec->id_JEDEC == 0x00ef3013)
619  outstr(
620  "NOTE: You may set bit SRP in the status register to enable #WP control.\r\n"
621  );
623  }
624  }
625  }
626  break;
627 
628  case 'p': //read page
629  {
630  //get more input
631  char s[SIZE_STR_MESSAGE];
632  unsigned int page_to_read;
633  xcog1.inlevel++;
634  sprinti(s, "Page to read" MSG_HEXRANGE, 0, chip.pages - 1);
635  outstr(s);
636  page_to_read = getHex();
637 
638  //catch range error
639  if(page_to_read >= chip.pages) {
640  range_error();
641  break;
642  }
643 
644  //more input
645  unsigned char mode_screen_output;
646  mode_screen_output = yes_no(MSG_OUTPUTONSCREEN, 0) << 7;
647 
648  //action
649  unsigned int firstloc;
650  SPI_ON;
651  firstloc = page_to_read * SIZE_256;
652  chip_txfile(
653  pfspec,
655  firstloc,
656  SIZE_256,
657  mode_screen_output
658  );
660  }
661  break;
662 
663  case 'm': //read random area
664  {
665  //more input
666  char s[SIZE_STR_MESSAGE];
667  unsigned int startaddr;
668  xcog1.inlevel++;
669  sprinti(s, "Start address" MSG_HEXRANGE, 0, chip.pspec->chipsize - 1);
670  outstr(s);
671  startaddr = getHex();
672 
673  //catch error
674  if(startaddr >= chip.pspec->chipsize) {
675  range_error();
676  break;
677  }
678 
679  //more input
680  unsigned int lastaddr;
681  xcog1.inlevel++;
682  sprinti(s, "Last address" MSG_HEXRANGE, startaddr, chip.pspec->chipsize - 1);
683  outstr(s);
684  lastaddr = getHex();
685 
686  //catch error
687  if(lastaddr >= chip.pspec->chipsize) {
688  range_error();
689  break;
690  }
691 
692  //more input
693  unsigned char mode_screen_output;
694  mode_screen_output = yes_no(MSG_OUTPUTONSCREEN, 0) << 7;
695 
696  //action
697  SPI_ON;
698  chip_txfile(
699  pfspec,
701  startaddr,
702  lastaddr - startaddr + 1,
703  mode_screen_output
704  );
706  }
707  break;
708 
709  case 's': //read block 4k
711  break;
712 
713  case 'k': //read block 32k
715  break;
716 
717  case 'b': //read block 64k
719  break;
720 
721  case 'c': //read chip
722  {
723  //more input
724  unsigned char mode_screen_output;
725  mode_screen_output = yes_no(MSG_OUTPUTONSCREEN, 0) << 7;
726 
727  //action
728  SPI_ON;
729  chip_txfile(
730  pfspec,
732  0x00,
734  mode_screen_output
735  );
737  }
738  break;
739 
740  case 'S': //4k block erase
742  break;
743 
744  case 'K': //erase block 32k
746  break;
747 
748  case 'B': //erase block 64k
750  break;
751 
752  case 'C': //erase chip
753  {
754  //action
755  if(yes_no(MSG_SURETOPROCEED, 0)) {
756  SPI_ON;
757  chip_erase();
759  if(verify_0xff(0x00, chip.pspec->chipsize) != 0)
760  outstr(MSG_FAIL);
761  else
762  outstr(MSG_OK);
764  }
765  }
766  break;
767 
768  case 'I': //write file to chip
769  {
770  //more input
771  unsigned char screen_output;
772  screen_output = yes_no(MSG_OUTPUTONSCREEN, 1);
773 
774  //check for dry-run
775  check_dryrun();
776 
777  //action
778  if(yes_no(MSG_SURETOPROCEED, 0))
779  chip_rxfile(&xcog0, screen_output);
780  else
782  }
783  break;
784 
785  default:
786  *key_is_valid = 0;
787  }
788  if(key_is_valid)
789  outstr(MSG_DONE);
790  }
791 }

Referenced by menu().

◆ linebuf_out()

signed char linebuf_out ( char *  linebuf)
Parameters
*linebufPointer to the prepared line, NULL is used to skip the line while keeping the STX/ETX/CAN protocol.
Returns
Returns -1 if the line has not been acknowledged by connect.
1581 {
1582  unsigned char c;
1583  char * p;
1584 
1585  do {
1586  p = linebuf;
1587  outfifo(STX);
1588  for(int n = *p++; n; n--)
1589  outfifo(*p++);
1590  outfifo(ETX);
1591  c = getChar();
1592  } while(c == ENQ);
1593 
1594  if(c != ACK)
1595  return -1;
1596  return 0;
1597 }

Referenced by chip_read(), and chip_txfile().

◆ main()

int main ( void  )
Returns
Never returns.

Notes on Boot Conditions:

  1. SPI power is disabled during boot, because the pnp MOSFET does not switch on with its gate pulled up and PIN_PNP being in tristate.
  2. Function ledstat() is started on another cog, and won’t be disabled other by switching the board off.
  3. Variable _cfg_rstdisable allows to disable the RST line for a while, so that the system may be started from RAM.
  4. Variable _cfg_baudrate will always be patched by propeller-load, even if not specified in the board config file. Its default value is 115200.
  5. Variable _cfg_modeterminal allows to start a basic “propeller-terminal” communication instead of talking to connect, meant as a simple proof-of-concept. Btw, the Propeller exit sequence is understood by both: connect and (of course) “propeller-terminal” (set up with propeller-load).
121 {
122  //setup ledstat():
123  xcog1.yellow = ON;
124  xcog1.inlevel = 0;
125  cog_run(&ledstat, STACK_LEDSTAT);
126 
127  //SPI-Bus ini: SPI-Bus is off
128  xcog1.green = ON; //indicate status: SPI-Bus is off
129 
130  //disable RST
131  if(_cfg_rstdisable > 0) {
132  high(RST_DISABLE); //disable RST
133  xcog1.orange = ON;
134  }
135 
136  //reconfigure simpleterm
138  simpleterm_reopen(PIN_RX, PIN_TX, 0, _cfg_baudrate);
139 
140  //data initialisation
142  pfspec = &(filespec[MOTBIN]);
143 
144  //Do we talk to connect or to a “propeller-terminal”?
145  if(_cfg_modeterminal > 0) { //terminal mode?
146  hello();
147  connected();
148  if(plug_detect()) {
149  outstr("Terminal Mode. Using reduced set of keys.\r\n\n");
150  menu(MODE_TERMINAL); //call menu
151  }
152  }
153  else { //normal connect mode
154  char k; //used for initial handshake
155  outfifo(ENQ); //request trigger (if not already on the way)
156  k = getChar(); //receive (any) trigger
157 
158  //enable RST
159  _cfg_rstdisable = 0;
160  low(RST_DISABLE);
161  xcog1.orange = OFF;
162 
163  if(k == ACK) { //connect has replied
164  hello();
165  connected();
166  if(plug_detect()) {
167  outstr("\r\n");
168  menu(MODE_CONNECT); //call menu
169  }
170  }
171  }
172 
173  //end of program
175  OUTA |= BIT_PNP_DEVICE; //disable pnp device, make sure SPI-Bus is off
176  outstr("Detach clip and switch off the board.\r\n");
177  for(int n = 3; n; n--) {
178  exit_sequence(0x00); //this is understood by both, connect _and_ “propeller-terminal”
179  usleep(200000);
180  }
181  while(1); //hang-up
182  return(0); //normal quit
183 }

◆ menu()

void menu ( int  mode)
855 {
856  char s[SIZE_STR_MESSAGE];
857  int quit = 0;
858  int key_is_valid = 1;
859 
860  while(!quit) {
861  if(key_is_valid) {
862  //set key
864  if(mode & MODE_CONNECT)
865  key_config();
866 
867  //greeting
868  hello();
869 
870  //status line 1
871  sprinti(s, "Chip: %s", chip.pspec->name);
872  outstr(s);
873  sprinti(s, TAB1"Format: %s", pfspec->format_name);
874  outstr(s);
875  {
876  unsigned char mode_0xff = pfspec->mode_0xff;
877  outstr(TAB2"$FF: ");
878  outstr(mode_0xff & MODE_SPLIT ? "split, " : "");
879  outstr(mode_0xff & MODE_STRIP ? "strip, " : "");
880  sprinti(s, "inline_%d\r\n", mode_0xff & 0b00011111);
881  outstr(s);
882  }
883 
884  //menu
885  menu_options();
886  outstr("Your Choice? ");
887  }
888  else
889  key_is_valid = 1;
890 
891  //key polling
892  xcog1.inlevel = 1;
893  key_polling(&key_is_valid, &quit);
894  xcog1.inlevel = 0;
895  }
896 }

Referenced by main().

◆ menu_line()

void menu_line ( unsigned int  k1,
char *  k1msg,
unsigned int  k2,
char *  k2msg,
unsigned int  k3,
char *  k3msg 
)
1034 {
1035  if(keyreg & (k1 | k2 | k3)) {
1036  if(keyreg & k1)
1037  outstr(k1msg);
1038  if(keyreg & k2) {
1039  outstr(TAB1);
1040  outstr(k2msg);
1041  }
1042  if(keyreg & k3) {
1043  outstr(TAB2);
1044  outstr(k3msg);
1045  }
1046  outstr("\r\n");
1047  }
1048 }

Referenced by menu_options().

◆ menu_options()

void menu_options ( void  )
1060 {
1061  hr('-', MENUWIDTH, '\n');
1062  menu_line(
1066  );
1067  menu_line(
1071  );
1072  menu_line(
1076  );
1077  menu_line(
1081  );
1082  menu_line(
1086  );
1087  menu_line(
1091  );
1092  menu_line(
1094  0, NULL,
1095  0, NULL
1096  );
1097 }

Referenced by menu().

◆ mirror()

void mirror ( char *  keymsg)
201 {
202  outstr("\r\n");
203  outstr(keymsg);
204  outstr(MSG_DOTS);
205 }

Referenced by key_polling().

◆ option_batchblockerase()

void option_batchblockerase ( const enum tag_blocksize  blocksize,
const unsigned char  blockcmd 
)
275 {
276  char s[SIZE_STR_MESSAGE];
277  unsigned int first_block;
278  unsigned int last_block;
279  unsigned int blocks;
280 
281  //setup
282  blocks = chip.pspec->chipsize / blocksize;
283 
284  //more input
285  xcog1.inlevel++;
286  sprinti(s, "First " MSG_BLOCKTOERASE MSG_HEXRANGE, 0, blocks - 1);
287  outstr(s);
288  first_block = getHex();
289 
290  //catch out of range error
291  if(first_block >= blocks) {
292  range_error();
293  return;
294  }
295 
296  //more input
297  xcog1.inlevel++;
298  sprinti(s, "Last " MSG_BLOCKTOERASE MSG_HEXRANGE, first_block, blocks - 1);
299  outstr(s);
300  last_block = getHex();
301 
302  //catch out of range error
303  if( (last_block >= blocks) ||
304  (last_block < first_block) ) {
305  range_error();
306  return;
307  }
308 
309  //check for dry-run
310  check_dryrun();
311 
312  //action
313  if(yes_no(MSG_SURETOPROCEED, 0)) {
314  SPI_ON;
315  while(first_block <= last_block) {
316  unsigned int firstloc;
317  int r;
318 
319  sprinti(s, "Block $%x" MSG_DOTS, first_block);
320  outstr(s);
321 
322  firstloc = first_block * blocksize;
323  WPn_HIGH;
324  cmd_WREN();
325  CHIP_ON;
326  cmd(blockcmd, firstloc, chip.addrlen_in_bits);
327  CHIP_OFF;
328  WPn_LOW;
329 
330  r = WIP_polling(WIP_BLOCK);
331  if(r == -1) {
333  }
334  else {
335  {
336  char s[SIZE_STR_MESSAGE];
337  sprinti(s, MSG_WIPCHECKS, r);
338  outstr(s);
339  }
340  }
341 
343  if(verify_0xff(firstloc, blocksize)) {
344  outstr(MSG_FAIL);
345  break;
346  }
347  else {
348  outstr(MSG_OK);
349  }
350 
351  first_block++;
352  }
353  }
354  SPI_OFF(MODE_SPI_OFF); //check_dryrun() has left SPI Bus in standby mode
355 }

Referenced by key_polling().

◆ option_readblock()

void option_readblock ( const enum tag_blocksize  blocksize)
212 {
213  char s[SIZE_STR_MESSAGE];
214  unsigned int blocks;
215 
216  //setup
217  blocks = chip.pspec->chipsize / blocksize;
218 
219  //more input
220  unsigned int block_to_read;
221  xcog1.inlevel++;
222  sprinti(s, "Block to read" MSG_HEXRANGE, 0, blocks - 1);
223  outstr(s);
224  block_to_read = getHex();
225 
226  //catch range errors
227  if(block_to_read >= blocks) {
228  range_error();
229  return;
230  }
231 
232  //more input
233  unsigned char mode_screen_output;
234  mode_screen_output = yes_no(MSG_OUTPUTONSCREEN, 0) << 7;
235 
236  //action
237  SPI_ON;
238  chip_txfile(
239  pfspec,
241  block_to_read * blocksize,
242  blocksize,
243  mode_screen_output
244  );
246 }

Referenced by key_polling().

◆ outbits()

void outbits ( const unsigned int  value,
unsigned int  msbit 
)
1990 {
1991  while(msbit) {
1992  CLOCK_LOW;
1993  if(value & msbit) {
1994  SO_HIGH;
1995  }
1996  else {
1997  SO_LOW;
1998  }
1999  CLOCK_HIGH;
2000  msbit >>= 1;
2001  }
2002 }

Referenced by burn(), chip_erase(), cmd(), cmd_DP(), cmd_RDID_JEDEC(), cmd_RDSR(), cmd_WRDI(), cmd_WREN(), cmd_WRSR(), CPM_polling(), page_write(), PGM_cycle(), and WIP_polling().

◆ outfifo()

char outfifo ( char  c)
1604 {
1605  if(c == CARR_RET)
1606  c = CLIM_CR;
1607  else if(c == NEW_LINE)
1608  c = CLIM_NL;
1609  putChar(c);
1610  return (c);
1611 }

Referenced by chip_rxfile(), chip_txfile(), exit_sequence(), hello(), hr(), key_polling(), linebuf_out(), main(), outstr(), and report_err().

◆ outstr()

int outstr ( char *  s)
1618 {
1619  int n = 0;
1620 
1621  //don't allow this loop to run infinitively
1622  while(*s != '\0' && n < 256) {
1623  outfifo(*s++);
1624  n++;
1625  }
1626  return(n);
1627 }

Referenced by check_dryrun(), chip_erase(), connected(), hello(), hr(), key_polling(), main(), menu(), menu_line(), mirror(), option_batchblockerase(), option_readblock(), plug_detect(), range_error(), report_err(), SR_report(), and yes_no().

◆ page_write()

void page_write ( const unsigned int  addr,
unsigned char *  buffer 
)
Note
This func is to be used with paged memories only.
Parameters
addrPage start address.
*bufferPointer to page buffer.
1789 {
1790  unsigned int pageaddr;
1791  int n_bytes;
1792 
1793  //mask page address
1794  pageaddr = addr & ~(SIZE_256 - 1);
1795 
1796  //disable hardware write protection
1797  WPn_HIGH;
1798 
1799  //set Write Enable Latch Bit
1800  cmd_WREN();
1801 
1802  //start
1803  CHIP_ON;
1804 
1805  //send PAGE PROGRAM command
1806  cmd(CMD__PP, pageaddr, chip.addrlen_in_bits);
1807 
1808  //how many bytes?
1809  n_bytes = SIZE_256;
1810 
1811  while(n_bytes--) {
1812  //send databyte
1813  outbits(*buffer, 1 << 7);
1814 
1815  //increment pointers
1816  buffer++;
1817 
1818  //TODO: still in range?
1819  }
1820 
1821  //initiate pgm-cycle
1822  CHIP_OFF;
1823 
1824  //detect end of write cycle
1825  WIP_polling(WIP_PAGE); //wait until write cycle is finished
1826 
1827  //enable hardware write protection
1828  WPn_LOW;
1829 }

◆ plug_detect()

int plug_detect ( void  )
834 {
835  if(input(PIN_PLUGTESTn)) {
836  outstr("No SPI-plug detected!\r\n");
837  return(0);
838  }
839  else {
840  outstr("SPI-plug seems to be attached.\r\n");
841  return(1);
842  }
843 }

Referenced by main().

◆ queue()

char queue ( struct tag_xcog0 px,
unsigned char  vbin,
unsigned int *  pwr 
)
2834 {
2835  if((*pwr - px->offrd) >= px->bufsize)
2836  return ERRC__BUFFER_OVERRUN;
2837  else {
2838  *(px->pbuf + (*pwr & (px->bufsize - 1))) = vbin; //access volatile globals
2839  (*pwr)++;
2840  return ERRC__SUCCESS;
2841  }
2842 }

Referenced by burn(), HEXDUMP_rxline(), and MOT_rxline().

◆ range_error()

void range_error ( void  )
258 {
259  xcog1.inlevel = 0;
260  outstr("Out of range error!\r\n");
261 }

Referenced by key_polling(), option_batchblockerase(), and option_readblock().

◆ report_err()

void report_err ( char  reported_err)
2849 {
2850  if(reported_err != 0) {
2851  outstr("Error Code: ");
2852  outfifo(reported_err + 48);
2853  outstr("\r\n");
2854  }
2855 }

Referenced by chip_rxfile().

◆ SR_report()

unsigned char SR_report ( int  ireg)
1912 {
1913  int bitmask = chip.pspec->sr_wrmask[ireg];
1914  int is_static = chip.pspec->sr_is_static[ireg];
1915  int status;
1916  char r[15];
1917  char s[SIZE_STR_MESSAGE];
1918  char* p = chip.pspec->sr_bitnames[ireg];
1919 
1920  //register name, bits and current status
1921  if (ireg < 3) {
1922  sprinti(r, "Register %d", ireg);
1923  }
1924  else {
1925  sprinti(r, "S-Register %d", ireg - 3);
1926  }
1927 
1928  status = cmd_RDSR(ireg);
1929  sprinti(s, "\r\n" \
1930  "%s:\r\n" \
1931  "Info\t\tw=writable\tv=volatile\r\n" \
1932  "Bit\t\t7\t6\t5\t4\t3\t2\t1\t0\r\n" \
1933  "Name\t\t%s\r\n" \
1934  "Status\t\t", \
1935  r, \
1936  p \
1937  );
1938  outstr(s);
1939  for(int n = 0b10000000; n; n >>= 1)
1940  outstr((status & n) != 0 ? "1\t" : "0\t");
1941 
1942  //flags (writable? volatile?)
1943  outstr( "\r\n" \
1944  "Flags\t\t" \
1945  );
1946  for(int n = 0b10000000; n; n >>= 1) {
1947  outstr((bitmask & n) != 0 ? "w" : "");
1948  outstr((is_static & n) != 0 ? "" : "v");
1949  outstr("\t");
1950  }
1951 
1952  //new lines
1953  outstr("\r\n\n");
1954 
1955  return status;
1956 }

Referenced by global_sector_protect(), and key_polling().

◆ strpos()

int strpos ( char *  str,
char  c 
)
1204 {
1205  int n = 0;
1206  char * p = str;
1207 
1208  while((*(p++) != c) && (n < SIZE_STRBUF))
1209  n++;
1210  return n;
1211 }

Referenced by MOT_header().

◆ verify_0xff()

unsigned char verify_0xff ( unsigned int  firstloc,
unsigned int  memsize 
)
1112 {
1113  unsigned char err = 0;
1114 
1115  CHIP_ON;
1116  cmd(CMD__READ, firstloc, chip.addrlen_in_bits);
1117  while(memsize--) {
1118  if(inb() != 0xff) {
1119  err = 1;
1120  break;
1121  }
1122  }
1123  CHIP_OFF;
1124  return err;
1125 }

Referenced by key_polling(), and option_batchblockerase().

◆ yes_no()

unsigned char yes_no ( char *  question,
unsigned char  level_rst 
)

If it is used as a last security check before some delicate action takes place, level_rst should be zero in order to flag that no more inquiry will follow.

1293 {
1294  unsigned char k;
1295 
1296  xcog1.inlevel++; //increase input level
1297  outstr(question);
1298  outstr(" (Y|n)? ");
1299  k = getChar();
1300  if(!level_rst)
1301  xcog1.inlevel = 0; //no more input, action follows
1302  if(k == 'Y') {
1303  outstr("yes\r\n");
1304  return 1;
1305  }
1306  outstr("no\r\n");
1307  return 0;
1308 }

Referenced by global_sector_protect(), key_polling(), option_batchblockerase(), and option_readblock().

Variable Documentation

◆ _cfg_baudrate

int _cfg_baudrate = -1

Referenced by connected(), and main().

◆ _cfg_modeterminal

int _cfg_modeterminal = -1

Referenced by main().

◆ _cfg_rstdisable

int _cfg_rstdisable = -1

Referenced by main().

◆ chip

struct tag_chip chip = { 0, chipspec }

◆ cmd_CE

unsigned char cmd_CE = CMD__CE_0X60

Referenced by chip_erase(), and key_config().

◆ pfspec

struct tag_filespec* pfspec

◆ spimode

enum tag_spimode spimode = mode_3

Referenced by SPI_ini().

CAN
#define CAN
Ascii 'cancel'.
Definition: serial-codes.h:85
SR_report
unsigned char SR_report(int ireg)
Put status register's content on screen.
Definition: kick.c:1909
CMD__WRSR3
#define CMD__WRSR3
Write Status Register 3.
Definition: SPI-command-set.h:53
connected
void connected(void)
Definition: kick.c:187
X01_WRSR
#define X01_WRSR
SPI Write Status Register Command (0x01) flag number.
Definition: chipspec.h:258
MSG_DONE
#define MSG_DONE
Definition: kick.h:149
CMD__RDSR3
#define CMD__RDSR3
Read Status Register 3.
Definition: SPI-command-set.h:69
filespec
struct tag_filespec filespec[2]
Definition: filespec.c:34
SIZE_256
#define SIZE_256
Usual page size.
Definition: chipspec.h:67
PIN_PLUGTESTn
#define PIN_PLUGTESTn
This pin is used detect an adapter plug.
Definition: proppins.h:77
BIT_PNP_DEVICE
#define BIT_PNP_DEVICE
Alternative Macro Name for BIT_PNP.
Definition: proppins.h:162
tag_filespec::payload_default
unsigned char payload_default
Pure data bytes per line.
Definition: filespec.h:111
xcog0
struct tag_xcog0 xcog0
Cog parameters for burn().
Definition: kick.c:79
STACK_BURNBUF
#define STACK_BURNBUF
Stack size for burn().
Definition: kick.h:66
MOT_rxline
char MOT_rxline(struct tag_xcog0 *px, unsigned int *lines, int hexmode)
Receive and parse a line in Motorola S-Record format. This func finishes successfully after having pa...
Definition: kick.c:2676
EOT
#define EOT
Ascii 'end of transmission'.
Definition: serial-codes.h:53
KEYID_S
#define KEYID_S
Definition: key-enable-bits.h:45
PIN_RX
#define PIN_RX
RS232 RX (Receive) Pin.
Definition: proppins.h:105
SIZE_STRBUF
#define SIZE_STRBUF
Definition: kick.h:52
MODE_SCREEN_OUTPUT
#define MODE_SCREEN_OUTPUT
This mode bit is not strictly related to “0xff data handling”.
Definition: filespec.h:88
mirror
void mirror(char *keymsg)
Definition: kick.c:198
SIZE_LINEBUF
#define SIZE_LINEBUF
Definition: kick.h:53
X05_RDSR
#define X05_RDSR
SPI Read Status Register Command (0x05) flag number.
Definition: chipspec.h:254
MODE_0XFF
#define MODE_0XFF
KEYID_B
#define KEYID_B
Definition: key-enable-bits.h:50
cmd_WREN
void cmd_WREN(void)
Set Write Enable Latch bit.
Definition: kick.c:1713
tag_linedat::startaddr
unsigned int startaddr
Line’s startaddress.
Definition: kick.h:211
putChar
void putChar(char c)
Definition: putChar.c:49
FILE_TO_CHIP
#define FILE_TO_CHIP
Send data to Propeller and write to chip.
Definition: serial-codes.h:157
KEYBIT_X
#define KEYBIT_X
Definition: key-enable-bits.h:89
KEYBIT_q
#define KEYBIT_q
Definition: key-enable-bits.h:66
POWERUP_EXTRA
#define POWERUP_EXTRA
If chip detection fails, how often shall we retry?
Definition: kick.h:103
KEYID_C
#define KEYID_C
Definition: key-enable-bits.h:52
X9F_RDID
#define X9F_RDID
SPI Read JEDEC Manufacturer and Device ID (3 Databytes) Command (0x9f) flag number.
Definition: chipspec.h:273
yes_no
unsigned char yes_no(char *question, unsigned char level_rst)
This function allows to put a question which expects true or false.
Definition: kick.c:1289
X31_WRSR2
#define X31_WRSR2
SPI Write Status Register 2 Command (0x31) flag number.
Definition: chipspec.h:323
X03_READ
#define X03_READ
SPI Read Command (0x03) flag number.
Definition: chipspec.h:196
global_sector_protect
void global_sector_protect(unsigned char pswitch)
Method to globally protect/unprotect all sectors.
Definition: kick.c:364
tag_xcog0::queue_empty
volatile unsigned char queue_empty
Flag to indicate that the data queue is empty.
Definition: kick.h:250
HAS_NOT_BEEN_CUT_YET
#define HAS_NOT_BEEN_CUT_YET
tag_chipspec::sr_is_static
const unsigned char sr_is_static[4]
True, if chip register bits are not initialized during Power-Up.
Definition: chipspec.h:373
IS_0XFF
#define IS_0XFF
KEYBIT_c
#define KEYBIT_c
Definition: key-enable-bits.h:78
X39_US
#define X39_US
SPI Unprotect 4K Sector Command (0x39) flag number.
Definition: chipspec.h:303
cmd
void cmd(const unsigned char cmd, const unsigned int value, unsigned char bits)
Definition: kick.c:2006
ARRAY_CHIPSPEC
#define ARRAY_CHIPSPEC
Number of members of the chipspec database.
Definition: chipspec.h:35
NEW_LINE
#define NEW_LINE
Ascii LF "\n" 'line feed'.
Definition: serial-codes.h:65
tag_chipspec::sr_bitnames
char * sr_bitnames[4]
Bit names of chip registers.
Definition: chipspec.h:375
KEYBIT_S
#define KEYBIT_S
Definition: key-enable-bits.h:72
cmd_RDID_JEDEC
int cmd_RDID_JEDEC(void)
Definition: kick.c:2018
SIZE_64K
#define SIZE_64K
Size of 64K-block.
Definition: chipspec.h:89
tag_xcog0::abits
unsigned char abits
Short for: addrbits.
Definition: kick.h:243
tag_xcog1::yellow
volatile unsigned char yellow
Switch for yellow LED usage.
Definition: kick.h:221
CMD__PP
#define CMD__PP
Page Program.
Definition: SPI-command-set.h:124
DATA_START
#define DATA_START
KEYID_K
#define KEYID_K
Definition: key-enable-bits.h:47
MODE_STRIP
#define MODE_STRIP
This flag forces lines of just 0xff bytes to be deleted.
Definition: filespec.h:84
_cfg_modeterminal
int _cfg_modeterminal
configured through propeller-load
Definition: kick.c:71
menu_options
void menu_options(void)
Put menu options on terminal screen.
Definition: kick.c:1057
KEYBIT_p
#define KEYBIT_p
Definition: key-enable-bits.h:69
outstr
int outstr(char *s)
Definition: kick.c:1615
xcog1
struct tag_xcog1 xcog1
Cog parameters for ledstat().
Definition: kick.c:82
keymsg
char * keymsg[]
Definition: key-enable-bits.h:102
XD8_BE64K
#define XD8_BE64K
SPI 64K block Erase Command (0xd8) flag number.
Definition: chipspec.h:214
hr
void hr(char c, int n, char nl)
Put a horizontal line on screen.
Definition: kick.c:905
tag_linedat::rd
unsigned int rd
Read pointer.
Definition: kick.h:209
tag_xcog0::psize
int psize
Page size.
Definition: kick.h:245
tag_xcog1::green
volatile unsigned char green
Switch for green LED usage.
Definition: kick.h:220
ID_NONE
#define ID_NONE
Definition: key-enable-bits.h:63
tag_chipspec::name
char name[15]
Chip’s name, i.e. “MX25L1605D”
Definition: chipspec.h:365
KEYBIT_r
#define KEYBIT_r
Definition: key-enable-bits.h:84
KEYBIT_K
#define KEYBIT_K
Definition: key-enable-bits.h:74
CMD__WRSR2
#define CMD__WRSR2
Write Status Register 2.
Definition: SPI-command-set.h:49
WPn_HIGH
#define WPn_HIGH
Definition: fast-SPI.h:110
CLOCK_LOW
#define CLOCK_LOW
Definition: fast-SPI.h:131
KEYBIT_C
#define KEYBIT_C
Definition: key-enable-bits.h:79
inb
unsigned char inb(void)
Definition: kick.c:1960
APPLY_CUT
#define APPLY_CUT
get_addrlen
unsigned char get_addrlen(enum tag_type_of_addrlen type_of_addrlen, unsigned int addr)
Auxiliary function that returns the length of an address for different situations.
Definition: kick.c:925
X00_NOP
#define X00_NOP
If this flag number is set, a CMD__NOP is send to the device after CMD__RDID. Our NOP Flag....
Definition: chipspec.h:267
tag_linedat
Struct that characterizes a data line.
Definition: kick.h:206
KEYREG_DEFAULT
#define KEYREG_DEFAULT
Definition: key-enable-bits.h:92
KEYBIT_k
#define KEYBIT_k
Definition: key-enable-bits.h:73
HEADER_KICK
#define HEADER_KICK
Definition: kick.h:50
XAD_CP
#define XAD_CP
SPI Continuous Program Command (0xad) flag number.
Definition: chipspec.h:230
INLINE_0XFF
#define INLINE_0XFF
CMD__CE_0XC7
#define CMD__CE_0XC7
Full Chip Erase (0xc7)
Definition: SPI-command-set.h:116
BLOCK_32K
@ BLOCK_32K
Hexadecimal Size (SIZE_32K) of a 32K Block.
Definition: kick.h:180
tag_xcog0::cmd
unsigned char cmd
Command to be used for writing.
Definition: kick.h:242
outfifo
char outfifo(char c)
Definition: kick.c:1601
X15_RDSR3
#define X15_RDSR3
SPI Read Status Register 3 Command (0x15) flag number.
Definition: chipspec.h:319
ACK
#define ACK
Ascii 'acknowledge'.
Definition: serial-codes.h:61
KEYBIT_B
#define KEYBIT_B
Definition: key-enable-bits.h:77
check_dryrun
void check_dryrun(void)
Checks whether a write fail should be expected. A function with very basic and poor functionality.
Definition: kick.c:804
CHIP_OFF
#define CHIP_OFF
Definition: fast-SPI.h:103
X60_CE
#define X60_CE
SPI Chip Erase Command (0x60) flag number.
Definition: chipspec.h:218
MENUWIDTH
#define MENUWIDTH
Width of menu headlines (in chars).
Definition: common.h:46
CMD__PS
#define CMD__PS
Protect Sector.
Definition: SPI-command-set.h:156
TAB2
#define TAB2
Definition: kick.h:158
ledstat
void ledstat(void *ptr)
This function controls board LEDs. To be used with extra cog, to be stopped externally.
Definition: kick.c:2258
HEXDUMP
@ HEXDUMP
File format indicator: hexadecimal dump (no checksum per line)
Definition: filespec.h:105
keyreg
unsigned int keyreg
Definition: key-enable-bits.h:94
key_polling
void key_polling(int *key_is_valid, int *quit)
Essential function. Scans stdin for configured keys and issues the apropriate actions....
Definition: kick.c:397
tag_chipspec::chipsize
const unsigned int chipsize
Size of the chip.
Definition: chipspec.h:367
hexdigit2bin
signed char hexdigit2bin(unsigned char hexdigit)
Convert a hexadecimal digit into a binary value.
Definition: hexdigit2bin.c:40
CMD__RDSCUR
#define CMD__RDSCUR
Read Security Register, i.e. MX25L12835E.
Definition: SPI-command-set.h:73
CMD__SE
#define CMD__SE
Sector Erase (4K)
Definition: SPI-command-set.h:100
tag_xcog0::rq_spioff
volatile unsigned char rq_spioff
Flag to request SPI off.
Definition: kick.h:251
KEYBIT_I
#define KEYBIT_I
Definition: key-enable-bits.h:81
CMD__WRSR
#define CMD__WRSR
Write Status Register 1.
Definition: SPI-command-set.h:45
MSG_HEXRANGE
#define MSG_HEXRANGE
Definition: kick.h:156
FF_START
#define FF_START
MODE_FORCE_SPI_OFF
#define MODE_FORCE_SPI_OFF
Definition: kick.h:113
CMD__RDSR
#define CMD__RDSR
Read Status Register 1.
Definition: SPI-command-set.h:61
filespec_ini
void filespec_ini(int chipsize)
Definition: filespec.c:76
XC7_CE
#define XC7_CE
SPI Chip Erase Command (0xc7) flag number.
Definition: chipspec.h:222
KEYID_d
#define KEYID_d
Definition: key-enable-bits.h:40
menu_line
void menu_line(unsigned int k1, char *k1msg, unsigned int k2, char *k2msg, unsigned int k3, char *k3msg)
Put a menu line with selected menu options on terminal screen.
Definition: kick.c:1026
cmd_CE
unsigned char cmd_CE
Global chip erase command, may be overridden by key_config().
Definition: kick.c:76
KEYID_X
#define KEYID_X
Definition: key-enable-bits.h:61
PUTCHAR_CR
#define PUTCHAR_CR
Definition: kick.h:134
X20_SE
#define X20_SE
SPI 4K Sector Erase Command (0x20) flag number.
Definition: chipspec.h:206
OFF
#define OFF
Definition: common.h:43
CMD__CP
#define CMD__CP
Continuous Program.
Definition: SPI-command-set.h:128
_cfg_rstdisable
int _cfg_rstdisable
configured through propeller-load
Definition: kick.c:72
RST_DISABLE
#define RST_DISABLE
Disable Propeller’s Reset Pin, active high.
Definition: proppins.h:101
X2B_RDSCUR
#define X2B_RDSCUR
SPI Read Security Register Command (0x2b) flag number.
Definition: chipspec.h:331
tag_xcog0::lineaddr
unsigned int lineaddr
Start address of data line.
Definition: kick.h:244
X52_BE32K
#define X52_BE32K
SPI 32K Block Erase Command (0x52) flag number.
Definition: chipspec.h:210
ERRC__SUCCESS
#define ERRC__SUCCESS
Used by connect and kick.
Definition: serial-codes.h:166
MOT_summary
void MOT_summary(unsigned int lines, char *linebuf)
Definition: kick.c:1266
CLIM_NL
#define CLIM_NL
Used by outfifo() to send the NEW_LINE character – or a different, printable character,...
Definition: serial-codes.h:127
HEADER
#define HEADER
Typical headline (i.e. first line) of a data file created by the chipflasher.
Definition: filespec.h:39
CMD__WREN
#define CMD__WREN
Write Enable.
Definition: SPI-command-set.h:81
WIP_PAGE
#define WIP_PAGE
Set a timeout value for the WIP polling routine (e.g. byte/page/register write).
Definition: kick.h:82
tag_xcog1::orange
volatile unsigned char orange
Switch for orange LED usage.
Definition: kick.h:222
chip_rxfile
void chip_rxfile(struct tag_xcog0 *px, char screen_output)
Definition: kick.c:2859
cmd_WRSR
void cmd_WRSR(const unsigned char regno, const unsigned char byte)
Write to status registers.
Definition: kick.c:1729
cmd_RDSR
unsigned char cmd_RDSR(unsigned char regno)
Read a chip register.
Definition: kick.c:2060
KEYID_r
#define KEYID_r
Definition: key-enable-bits.h:57
MSG_OUTPUTONSCREEN
#define MSG_OUTPUTONSCREEN
Definition: kick.h:146
WIP_BLOCK
#define WIP_BLOCK
Set a timeout value for the WIP polling routine (e.g. block/sector erase).
Definition: kick.h:78
KEYBIT_t
#define KEYBIT_t
Definition: key-enable-bits.h:68
KEYBIT_s
#define KEYBIT_s
Definition: key-enable-bits.h:71
SO_HIGH
#define SO_HIGH
Definition: fast-SPI.h:138
MOT_header
void MOT_header(char *header, char *linebuf)
This function invokes MOT_mkline(), but initializes parameters first with apropriate header data.
Definition: kick.c:1223
SPI_ON
#define SPI_ON
Definition: kick.h:119
STX
#define STX
Ascii 'start of text'.
Definition: serial-codes.h:45
ADDRLEN_MOT
@ ADDRLEN_MOT
Minimal lenght is 2, but not 1 or 0.
Definition: kick.h:174
tag_xcog0::offrd
volatile unsigned int offrd
Buffer read pointer offset.
Definition: kick.h:248
X50_EWSR
#define X50_EWSR
SPI Enable Write Status Register Command (0x50) flag number.
Definition: chipspec.h:248
BLOCK_64K
@ BLOCK_64K
Hexadecimal Size (SIZE_64K) of a 64K Block.
Definition: kick.h:181
CMD__WRDI
#define CMD__WRDI
Write Disable.
Definition: SPI-command-set.h:57
tag_xcog0::pbuf
unsigned char * pbuf
Pointer to ringbuffer.
Definition: kick.h:246
tag_filespec::format
enum tag_format format
Indicate the format of the file, i.e. HEXDUMP or MOTBIN.
Definition: filespec.h:112
MODE_TERMINAL
#define MODE_TERMINAL
Usage mode for main(): Simple terminal mode, reduced communication capabilities. The terminal should ...
Definition: kick.h:87
tag_linedat::wr
unsigned int wr
Write pointer.
Definition: kick.h:210
SIZE_128MBIT
#define SIZE_128MBIT
Chipsize 128Mbit.
Definition: chipspec.h:113
POWERUP_OFFTIME
#define POWERUP_OFFTIME
Separate consecutive chip detections, time in microseconds.
Definition: kick.h:107
chip_ini
void chip_ini(unsigned char new_index)
Definition: kick.c:1317
CMD__EWSR
#define CMD__EWSR
Enable Write Status Register.
Definition: SPI-command-set.h:41
option_readblock
void option_readblock(const enum tag_blocksize blocksize)
Definition: kick.c:209
SCANNING_FF
#define SCANNING_FF
SIZE_STR_MESSAGE
#define SIZE_STR_MESSAGE
Definition: kick.h:51
menu
void menu(int mode)
Put the chipflasher menu on screen and invoke key_polling().
Definition: kick.c:852
SIZE_HEADER
#define SIZE_HEADER
Allowed size (i.e. number of characters) for the header string.
Definition: filespec.h:47
pfspec
struct tag_filespec * pfspec
Pointer to specifications that are associated with selected format type.
Definition: kick.c:86
CLIM_CR
#define CLIM_CR
Used by outfifo() to send the CARR_RET character – or a different, printable character,...
Definition: serial-codes.h:121
CHIP_ON
#define CHIP_ON
Definition: fast-SPI.h:96
KEYID_f
#define KEYID_f
Definition: key-enable-bits.h:55
KEYID_W
#define KEYID_W
Definition: key-enable-bits.h:59
KEYBIT_b
#define KEYBIT_b
Definition: key-enable-bits.h:76
exit_sequence
void exit_sequence(const char status)
Tell terminal to exit listening mode.
Definition: kick.c:1837
outbits
void outbits(const unsigned int value, unsigned int msbit)
Definition: kick.c:1986
X02_PP
#define X02_PP
SPI Page Program Command (0x02) flag number.
Definition: chipspec.h:226
MSG_TIMEOUT
#define MSG_TIMEOUT
Definition: kick.h:152
HEXDUMP_mkline
void HEXDUMP_mkline(struct tag_linedat *linedat, char *linebuf_orig)
This function transforms a binary payload into a row of ascii chars including line ending characters ...
Definition: kick.c:1646
CMD__NOP
#define CMD__NOP
No Operation.
Definition: SPI-command-set.h:37
SOH
#define SOH
Ascii 'start of header'.
Definition: serial-codes.h:41
CHIP_TO_FILE
#define CHIP_TO_FILE
Send data to terminal and save on disk.
Definition: serial-codes.h:149
MSG_WIPCHECKS
#define MSG_WIPCHECKS
Definition: kick.h:155
X35_RDSR2
#define X35_RDSR2
SPI Read Status Register 2 Command (0x35) flag number.
Definition: chipspec.h:315
KEYID_q
#define KEYID_q
Definition: key-enable-bits.h:39
ERRC__JOB_CANCELLATION
#define ERRC__JOB_CANCELLATION
Used by connect and kick.
Definition: serial-codes.h:170
ERRC__BUFFER_OVERRUN
#define ERRC__BUFFER_OVERRUN
Used by kick only.
Definition: serial-codes.h:194
range_error
void range_error(void)
Reports an Out-of-Range user input error and resets member inlevel of xcog1.
Definition: kick.c:255
TAB1
#define TAB1
Definition: kick.h:157
MSG_SURETOPROCEED
#define MSG_SURETOPROCEED
Definition: kick.h:147
KEYBIT_f
#define KEYBIT_f
Definition: key-enable-bits.h:82
CMD__BE32K
#define CMD__BE32K
Block Erase (32K)
Definition: SPI-command-set.h:104
MSG_DOTS
#define MSG_DOTS
Definition: kick.h:150
BAUDRATE_DEFAULT
#define BAUDRATE_DEFAULT
Default baudrate for propeller-load.
Definition: kick.h:56
CMD__READ
#define CMD__READ
Read (at up to 25MHz)
Definition: SPI-command-set.h:92
KEYID_I
#define KEYID_I
Definition: key-enable-bits.h:54
linebuf_out
signed char linebuf_out(char *linebuf)
Put a formatted data line onto tty.
Definition: kick.c:1578
MODE_SPI_POWEROFF
#define MODE_SPI_POWEROFF
Definition: kick.h:116
PIN_TX
#define PIN_TX
RS232 TX (Transmit) Pin.
Definition: proppins.h:109
chip_erase
void chip_erase(void)
This function calls the global chip erase command.
Definition: kick.c:2999
tag_chipspec::cmdset
const int cmdset
Command register, holding SPI command flags in respect to SPI Command Flags.
Definition: chipspec.h:372
chip_txfile
void chip_txfile(struct tag_filespec *filespec, unsigned char addrlen_in_bits, unsigned int firstloc, unsigned int memsize, unsigned char screenmode)
Definition: kick.c:1493
KEYID_s
#define KEYID_s
Definition: key-enable-bits.h:44
tag_chip::pages
int pages
Number of pages (on a paged chip).
Definition: kick.h:263
CMD__RDSR2
#define CMD__RDSR2
Read Status Register 2.
Definition: SPI-command-set.h:65
MOTBIN
@ MOTBIN
File format indicator: Motorola S with hexadecimal or binary payload.
Definition: filespec.h:104
ETX
#define ETX
Ascii 'end of text'.
Definition: serial-codes.h:49
PAYLOAD_DEFAULT
#define PAYLOAD_DEFAULT
report_err
void report_err(char reported_err)
Definition: kick.c:2846
tag_chip::pspec
struct tag_chipspec * pspec
Pointer into chipspec database.
Definition: kick.h:261
CMD__DP
#define CMD__DP
Deep Powerdown.
Definition: SPI-command-set.h:132
BLOCK_4K
@ BLOCK_4K
Hexadecimal Size (SIZE_4K) of a 4K Block respective Sector.
Definition: kick.h:179
SO_LOW
#define SO_LOW
Definition: fast-SPI.h:145
tag_chip::addrlen_in_bits
unsigned char addrlen_in_bits
Number of bits, used to feed an address into the SPI-bus.
Definition: kick.h:262
tag_chipspec::id_JEDEC
const int id_JEDEC
If not applicable or unknown, flag number X9F_RDID should be cleared in cmdset.
Definition: chipspec.h:366
MSG_OK
#define MSG_OK
Definition: kick.h:154
KEYID_c
#define KEYID_c
Definition: key-enable-bits.h:51
CMD__BP
#define CMD__BP
Byte Program.
Definition: SPI-command-set.h:120
MODE_CONNECT
#define MODE_CONNECT
Usage mode for main(): Use connect to communicate with the Propeller microcontroller.
Definition: kick.h:91
option_batchblockerase
void option_batchblockerase(const enum tag_blocksize blocksize, const unsigned char blockcmd)
Versatile block erase function, which allows erasing of multiple blocks of different sizes,...
Definition: kick.c:271
tag_xcog1::inlevel
volatile unsigned char inlevel
Current menu input level.
Definition: kick.h:223
HEXDUMP_rxline
char HEXDUMP_rxline(struct tag_xcog0 *px, unsigned int *lines)
Parse a Hexdump line.
Definition: kick.c:2541
tag_xcog0::offwr
volatile unsigned int offwr
Buffer write pointer offset.
Definition: kick.h:249
WIP_CHIP
#define WIP_CHIP
Set a timeout value for the WIP polling routine (e.g. chip erase).
Definition: kick.h:74
BINMODE
#define BINMODE
Definition: common.h:52
CMD__BE64K
#define CMD__BE64K
Block Erase (64K)
Definition: SPI-command-set.h:108
ON
#define ON
Definition: common.h:42
NAK
#define NAK
Ascii 'neg. acknowledge'.
Definition: serial-codes.h:73
KEYBIT_m
#define KEYBIT_m
Definition: key-enable-bits.h:87
plug_detect
int plug_detect(void)
Check if an SPI-Plug is detected and put a message on screen.
Definition: kick.c:831
CHIPSPEC_DEFAULT
#define CHIPSPEC_DEFAULT
Default member of chipspec to show up.
Definition: chipspec.h:39
SCANNING_DATA
#define SCANNING_DATA
KEYBIT_W
#define KEYBIT_W
Definition: key-enable-bits.h:86
X02_BP
#define X02_BP
SPI Byte Program Command (0x02) flag number.
Definition: chipspec.h:234
ENQ
#define ENQ
Ascii 'enquiry'.
Definition: serial-codes.h:57
WIP_polling
int WIP_polling(int poll_limit)
Determine end of write cycle by polling the WIP bit.
Definition: kick.c:1856
MOT_data
void MOT_data(struct tag_linedat *linedat, char *linebuf)
Definition: kick.c:1249
PUTCHAR_NL
#define PUTCHAR_NL
Definition: kick.h:138
tag_filespec::mode_0xff
unsigned char mode_0xff
How to deal with 0xff data?
Definition: filespec.h:113
burn
void burn(void *ptr)
Wite data to chip.
Definition: kick.c:2345
FILE_TO_CHIP_NOSCREEN
#define FILE_TO_CHIP_NOSCREEN
Send data to Propeller and write to chip, without output on screen.
Definition: serial-codes.h:161
tag_chipspec::sr_wrmask
const unsigned char sr_wrmask[4]
Maskout unwritable bits of chip registers.
Definition: chipspec.h:374
tag_linedat::mask
unsigned int mask
Mask for read and write pointers.
Definition: kick.h:208
MSG_VERIFYING
#define MSG_VERIFYING
Definition: kick.h:151
WPn_LOW
#define WPn_LOW
Definition: fast-SPI.h:117
tag_filespec::format_name
char * format_name
String that holds the name of the file format.
Definition: filespec.h:114
tag_chip::index
unsigned char index
Definition: kick.h:260
verify_0xff
unsigned char verify_0xff(unsigned int firstloc, unsigned int memsize)
This function scans the specified chip memory for values different than 0xff. If a value different to...
Definition: kick.c:1108
NOT_APPLICABLE
#define NOT_APPLICABLE
Some chipspec members may not make sense for some chips.
Definition: kick.h:59
inbits
unsigned int inbits(unsigned int msbit)
Definition: kick.c:1969
tag_xcog0::bufsize
unsigned char bufsize
Size of ringbuffer.
Definition: kick.h:247
X36_PS
#define X36_PS
SPI Protect 4K Sector Command (0x36) flag number.
Definition: chipspec.h:299
MODE_SPLIT
#define MODE_SPLIT
The flag forces data lines to be split into lines of data and lines of just 0xff bytes.
Definition: filespec.h:80
KEYBIT_G
#define KEYBIT_G
Definition: key-enable-bits.h:83
_cfg_baudrate
int _cfg_baudrate
configured through propeller-load
Definition: kick.c:73
KEYID_k
#define KEYID_k
Definition: key-enable-bits.h:46
MODE_SPI_OFF
#define MODE_SPI_OFF
Definition: kick.h:110
KEYID_p
#define KEYID_p
Definition: key-enable-bits.h:42
SIZE_4K
#define SIZE_4K
Size of 4K-sector.
Definition: chipspec.h:78
tag_xcog0::pcog
int * pcog
Cog info pointer, used by cog_end().
Definition: kick.h:241
tag_linedat::buf
char * buf
Pointer to buffer, that holds the data.
Definition: kick.h:207
CLOCK_HIGH
#define CLOCK_HIGH
Definition: fast-SPI.h:124
EXIT_CHAR_A
#define EXIT_CHAR_A
First char of Parallax’ exit sequence.
Definition: serial-codes.h:139
chip
struct tag_chip chip
Definition: kick.c:85
BIT_MISO
#define BIT_MISO
Definition: proppins.h:141
hello
void hello()
Put a small headline on terminal screen that helps to identify the program.
Definition: kick.c:1697
EXIT_CHAR_B
#define EXIT_CHAR_B
Second char of Parallax’ exit sequence.
Definition: serial-codes.h:143
KEYID_G
#define KEYID_G
Definition: key-enable-bits.h:56
SPI_OFF
#define SPI_OFF(mode)
Definition: kick.h:122
tag_chipspec
Chip specifications, provided within the source code.
Definition: chipspec.h:364
CMD__US
#define CMD__US
Unprotect Sector.
Definition: SPI-command-set.h:160
MSG_FAIL
#define MSG_FAIL
Definition: kick.h:153
tag_linedat::payload
unsigned char payload
Number of payload bytes.
Definition: kick.h:212
tCLQV
#define tCLQV
CE# Low to Output valid.
Definition: fast-SPI.h:65
ADDRLEN_IN_BITS
@ ADDRLEN_IN_BITS
Definition: kick.h:175
KEYID_b
#define KEYID_b
Definition: key-enable-bits.h:49
MSG_BLOCKTOERASE
#define MSG_BLOCKTOERASE
Definition: kick.h:148
chip_read
signed char chip_read(struct tag_filespec *filespec, unsigned int firstloc, unsigned int memsize, unsigned int *lines, char *linebuf)
Definition: kick.c:1331
CHIP_TO_FILE_NOSCREEN
#define CHIP_TO_FILE_NOSCREEN
Send data to terminal and save on disk, without feedback on screen.
Definition: serial-codes.h:153
KEYID_t
#define KEYID_t
Definition: key-enable-bits.h:41
key_config
void key_config(void)
Enable menu keys according to register flags.
Definition: kick.c:957
CMD__RDID
#define CMD__RDID
Read JEDEC Device ID Some old chips (Please review ID_JEDEC_AT26DF161 and ID_JEDEC_SST25VF016B) do re...
Definition: SPI-command-set.h:88
CARR_RET
#define CARR_RET
Ascii CR "\r" 'carriage return'.
Definition: serial-codes.h:69
STACK_LEDSTAT
#define STACK_LEDSTAT
Stack size for ledstat().
Definition: kick.h:70
KEYBIT_d
#define KEYBIT_d
Definition: key-enable-bits.h:67
KEYID_m
#define KEYID_m
Definition: key-enable-bits.h:60