OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk/mpsoc/src_c
    from Rev 19 to Rev 25
    Reverse comparison

Rev 19 → Rev 25

/Makefile
0,0 → 1,18
TOOLCHAIN:=${PRONOC_WORK}/toolchain
SUBDIRS = ihex2bin ihex2mif jtag plot
BIN_FILES = ihex2bin/ihex2bin ihex2mif/ihex2mif jtag/jtag_main
PRONOC_WORK_BIN := $(TOOLCHAIN)/bin
 
 
all: subdirs binfiles
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done
 
binfiles:
mkdir -p $(PRONOC_WORK_BIN)
cp -f $(BIN_FILES) $(PRONOC_WORK_BIN)
 
Makefile Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/.gitignore =================================================================== --- ihex2bin/.gitignore (nonexistent) +++ ihex2bin/.gitignore (revision 25) @@ -0,0 +1,7 @@ +*.o +*.a +bin2ihex +ihex2bin +xcuserdata +*.xcodeproj/*.xcworkspace +build/
ihex2bin/.gitignore Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/LICENSE =================================================================== --- ihex2bin/LICENSE (nonexistent) +++ ihex2bin/LICENSE (revision 25) @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013-2015 Kimmo Kulovesi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ihex2bin/LICENSE Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/Makefile =================================================================== --- ihex2bin/Makefile (nonexistent) +++ ihex2bin/Makefile (revision 25) @@ -0,0 +1,50 @@ +CC=clang +CFLAGS=-Wall -std=c99 -pedantic -Wextra -Weverything -Wno-padded -Os #-emit-llvm +LDFLAGS=-Os +AR=ar +ARFLAGS=rcs + +OBJS = kk_ihex_write.o kk_ihex_read.o bin2ihex.o ihex2bin.o +BINPATH = ./ +LIBPATH = ./ +BINS = $(BINPATH)bin2ihex $(BINPATH)ihex2bin +LIB = $(LIBPATH)libkk_ihex.a +TESTFILE = $(LIB) +TESTER = +#TESTER = valgrind + +.PHONY: all clean distclean test + +all: $(BINS) $(LIB) + +$(OBJS): kk_ihex.h +$(BINS): | $(BINPATH) +$(LIB): | $(LIBPATH) +bin2ihex.o kk_ihex_write.o: kk_ihex_write.h +ihex2bin.o kk_ihex_read.o: kk_ihex_read.h + +$(LIB): kk_ihex_write.o kk_ihex_read.o + $(AR) $(ARFLAGS) $@ $+ + +$(BINPATH)bin2ihex: bin2ihex.o $(LIB) + $(CC) $(LDFLAGS) -o $@ $+ + +$(BINPATH)ihex2bin: ihex2bin.o $(LIB) + $(CC) $(LDFLAGS) -o $@ $+ + +$(sort $(BINPATH) $(LIBPATH)): + @mkdir -p $@ + +test: $(BINPATH)bin2ihex $(BINPATH)ihex2bin $(TESTFILE) + @$(TESTER) $(BINPATH)bin2ihex -v -a 0x80 -i '$(TESTFILE)' | \ + $(TESTER) $(BINPATH)ihex2bin -A -v | \ + diff '$(TESTFILE)' - + @echo Loopback test success! + +clean: + rm -f $(OBJS) + +distclean: | clean + rm -f $(BINS) $(LIB) + @rmdir $(BINPATH) $(LIBPATH) >/dev/null 2>/dev/null || true +
ihex2bin/Makefile Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/Makefile.arm =================================================================== --- ihex2bin/Makefile.arm (nonexistent) +++ ihex2bin/Makefile.arm (revision 25) @@ -0,0 +1,39 @@ +CROSS=arm-none-eabi- +CC=$(CROSS)gcc +CFLAGS=-Wall -std=c99 -pedantic -Wextra -Wno-unknown-pragmas -Os -mlittle-endian -mthumb -fsingle-precision-constant -ffunction-sections -fdata-sections +LDFLAGS=-Wl,--gc-sections +AR=$(CROSS)ar +ARFLAGS=rcs + +ARM_FLAGS=-DIHEX_DISABLE_SEGMENTS -DIHEX_LINE_MAX_LENGTH=32 + +OBJPATH = ./arm/ +OBJS = $(OBJPATH)kk_ihex_write.o $(OBJPATH)kk_ihex_read.o +LIBPATH = ./arm/ +LIB = $(LIBPATH)libkk_ihex.a + +.PHONY: all clean distclean test + +all: $(LIB) + +$(OBJS): kk_ihex.h +$(OBJS): | $(OBJPATH) +$(LIB): | $(LIBPATH) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $+ + +$(OBJPATH)%.o: %.c %.h + $(CC) $(CFLAGS) $(ARM_FLAGS) -c $< -o $@ + +$(sort $(LIBPATH) $(OBJPATH)): + @mkdir -p $@ + +clean: + rm -f $(OBJS) + @rmdir $(OBJPATH) >/dev/null 2>/dev/null || true + +distclean: | clean + rm -f $(LIB) + @rmdir $(LIBPATH) >/dev/null 2>/dev/null || true +
ihex2bin/Makefile.arm Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/Makefile.avr =================================================================== --- ihex2bin/Makefile.avr (nonexistent) +++ ihex2bin/Makefile.avr (revision 25) @@ -0,0 +1,38 @@ +CC=avr-gcc +CFLAGS=-Wall -std=c99 -pedantic -Wextra -Wno-unknown-pragmas -Os +LDFLAGS=-Os +AR=avr-ar +ARFLAGS=rcs + +AVR_FLAGS=-DIHEX_DISABLE_SEGMENTS -DIHEX_LINE_MAX_LENGTH=32 + +OBJPATH = ./avr/ +OBJS = $(OBJPATH)kk_ihex_write.o $(OBJPATH)kk_ihex_read.o +LIBPATH = ./avr/ +LIB = $(LIBPATH)libkk_ihex.a + +.PHONY: all clean distclean test + +all: $(LIB) + +$(OBJS): kk_ihex.h +$(OBJS): | $(OBJPATH) +$(LIB): | $(LIBPATH) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $+ + +$(OBJPATH)%.o: %.c %.h + $(CC) $(CFLAGS) $(AVR_FLAGS) -c $< -o $@ + +$(sort $(LIBPATH) $(OBJPATH)): + @mkdir -p $@ + +clean: + rm -f $(OBJS) + @rmdir $(OBJPATH) >/dev/null 2>/dev/null || true + +distclean: | clean + rm -f $(LIB) + @rmdir $(LIBPATH) >/dev/null 2>/dev/null || true +
ihex2bin/Makefile.avr Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/README.md =================================================================== --- ihex2bin/README.md (nonexistent) +++ ihex2bin/README.md (revision 25) @@ -0,0 +1,115 @@ +kk_ihex +======= + +A small library for reading and writing the +[Intel HEX](http://en.wikipedia.org/wiki/Intel_HEX) (or IHEX) format. The +library is mainly intended for embedded systems and microcontrollers, such +as Arduino, AVR, PIC, ARM, STM32, etc - hence the emphasis is on small size +rather than features, generality, or error handling. + +See the header file `kk_ihex.h` for documentation, or below for simple examples. + +~ [Kimmo Kulovesi](http://arkku.com/), 2013-12-27 + +Writing +======= + +Basic usage for writing binary data as IHEX ASCII: + + #include "kk_ihex_write.h" + + struct ihex_state ihex; + ihex_init(&ihex); + ihex_write_at_address(&ihex, 0); + ihex_write_bytes(&ihex, my_data_bytes, my_data_size); + ihex_end_write(&ihex); + +The function `ihex_write_bytes` may be called multiple times to pass any +amount of data at a time. + +The actual writing is done by a callback called `ihex_flush_buffer`, +which must be implemented, e.g., as follows: + + void ihex_flush_buffer(struct ihex_state *ihex, char *buffer, char *eptr) { + *eptr = '\0'; + (void) fputs(buffer, stdout); + } + +The length of the buffer can be obtained from `eptr - buffer`. The actual +implementation may of course do with the IHEX data as it pleases, e.g., +transmit it over a serial port. + +For a complete example, see the included program `bin2ihex.c`. + + +Reading +======= + +Basic usage for reading ASCII IHEX into binary data: + + #include "kk_ihex_read.h" + + struct ihex_state ihex; + ihex_begin_read(&ihex); + ihex_read_bytes(&ihex, my_ascii_bytes, my_ascii_length); + ihex_end_read(&ihex); + +The function `ihex_read_bytes` may be called multiple times to pass any +amount of data at a time. + +The reading functions call the function `ihex_data_read`, which must be +implemented by the caller to store the binary data, e.g., as follows: + + ihex_bool_t ihex_data_read (struct ihex_state *ihex, + ihex_record_type_t type, + ihex_bool_t checksum_error) { + if (type == IHEX_DATA_RECORD) { + unsigned long address = (unsigned long) IHEX_LINEAR_ADDRESS(ihex); + (void) fseek(outfile, address, SEEK_SET); + (void) fwrite(ihex->data, ihex->length, 1, outfile); + } else if (type == IHEX_END_OF_FILE_RECORD) { + (void) fclose(outfile); + } + return true; + } + +Of course an actual implementation is free to do with the data as it chooses, +e.g., burn it on an EEPROM instead of writing it to a file. + +For an example complete with error handling, see the included program +`ihex2bin.c`. + + +Example Programs +================ + +The included example programs, `ihex2bin` and `bin2ihex`, implement +a very simple conversion between raw binary data and Intel HEX. +Usage by example: + + # Simple conversion from binary to IHEX: + bin2ihex outfile.hex + + # Add an offset to the output addresses (i.e., make the address + # of the first byte of the input other than zero): + bin2ihex -a 0x8000000 -i infile.bin -o outfile.hex + + # Simple conversion from IHEX to binary: + ihex2bin outfile.bin + + # Manually specify the initial address written (i.e., subtract + # an offset from the input addresses): + ihex2bin -a 0x8000000 -i infile.hex -o outfile.bin + + # Start output at the first data byte (i.e., make the address offset + # equal to the address of the first data byte read from input): + ihex2bin -A -i infile.hex -o outfile.bin + +Both programs also accept the option `-v` to increase verbosity. + +When using `ihex2bin` on Intel HEX files produced by compilers and such, +it is a good idea to specify the command-line option `-A` to autodetect +the address offset. Otherwise the program will simply fill any unused +addresses, starting from 0, with zero bytes, which may total mega- or +even gigabytes. +
ihex2bin/README.md Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/bin2ihex =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ihex2bin/bin2ihex =================================================================== --- ihex2bin/bin2ihex (nonexistent) +++ ihex2bin/bin2ihex (revision 25)
ihex2bin/bin2ihex Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: ihex2bin/bin2ihex.1 =================================================================== --- ihex2bin/bin2ihex.1 (nonexistent) +++ ihex2bin/bin2ihex.1 (revision 25) @@ -0,0 +1,75 @@ +.Dd February 1, 2014 +.Dt bin2ihex 1 +.Os kk_ihex +.Sh NAME +.Nm bin2ihex +.Nd Convert binary data to Intel HEX +.Sh SYNOPSIS +.Nm +.Op Fl a Ar address_offset +.Op Fl i Ar input_file.bin +.Op Fl o Ar output_file.hex +.Op Fl v +.Sh DESCRIPTION +.Nm +reads binary data from standard input and writes the Intel HEX encoded +data to standard output. +.Sh OPTIONS +.Bl -tag -width -indent +.It Fl a Ar address_offset +Set the address of the first input byte to +.Ar address_offset +(default 0) +.It Fl i Ar file +Read the binary input from +.Ar file +instead of standard input +.It Fl o Ar file +Write the Intel HEX output to +.Ar file +instead of standard output +.It Fl v +Print extra status messages to standard error +.El +.Sh EXAMPLES +Read binary data from +.Ar input.bin +and write the Intel HEX output to +.Ar output.hex +.Pp +.Bd -ragged -offset indent +.Nm +.Fl i +.Ar input.bin +.Fl o +.Ar output.hex +.Ed +.Pp +Read binary data from +.Ar input.bin +and write the Intel HEX output to +.Ar output.hex +such that the first byte of the input will have the address +.Ar 0x8000000 +in the output (e.g., for creating an image with the correct addresses for flashing +to a ROM): +.Bd -ragged -offset indent +.Nm +.Fl a +.Ar 0x8000000 +.Fl i +.Ar input.bin +.Fl o +.Ar output.hex +.Ed +.Pp +Note that the address offset does not make the resulting output significantly +larger, but conversion back to binary with +.Xr ihex2bin 1 +must be done with the same +.Fl a +argument to obtain a binary file identical to the original. +.Sh SEE ALSO +.Xr ihex2bin 1 +.Sh AUTHOR +.An "Kimmo Kulovesi" Aq http://arkku.com
ihex2bin/bin2ihex.1 Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/bin2ihex.c =================================================================== --- ihex2bin/bin2ihex.c (nonexistent) +++ ihex2bin/bin2ihex.c (revision 25) @@ -0,0 +1,144 @@ +/* + * bin2ihex.c: Read binary data, output in Intel HEX format. + * + * By default reads from stdin and writes to stdout. Input and + * output files can be specified with arguments `-i` and `-o`, + * respectively. Initial address offset can be set with option + * `-a` (also, `-a 0` forces output of the initial offset even + * though it is the default zero). + * + * Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com + * Provided with absolutely no warranty, use at your own risk only. + * Distribute freely, mark modified copies as such. + */ + +#include "kk_ihex_write.h" +#include +#include +#include +#include + +#ifdef IHEX_EXTERNAL_WRITE_BUFFER +char *ihex_write_buffer = NULL; +#endif + +//#define IHEX_WRITE_INITIAL_EXTENDED_ADDRESS_RECORD + +static FILE *outfile; + +int +main (int argc, char *argv[]) { + struct ihex_state ihex; + FILE *infile = stdin; + ihex_address_t initial_address = 0; + bool write_initial_address = 0; + bool debug_enabled = 0; + ihex_count_t count; + uint8_t buf[1024]; + + outfile = stdout; + + // spaghetti parser of args: -o outfile -i infile -a initial_address + while (--argc) { + char *arg = *(++argv); + if (arg[0] == '-' && arg[1] && arg[2] == '\0') { + switch (arg[1]) { + case 'a': + if (--argc == 0) { + goto invalid_argument; + } + ++argv; + errno = 0; + initial_address = (ihex_address_t) strtoul(*argv, &arg, 0); + if (errno || arg == *argv) { + errno = errno ? errno : EINVAL; + goto argument_error; + } + write_initial_address = 1; + break; + case 'i': + if (--argc == 0) { + goto invalid_argument; + } + ++argv; + if (!(infile = fopen(*argv, "rb"))) { + goto argument_error; + } + break; + case 'o': + if (--argc == 0) { + goto invalid_argument; + } + ++argv; + if (!(outfile = fopen(*argv, "w"))) { + goto argument_error; + } + break; + case 'v': + debug_enabled = 1; + break; + case 'h': + case '?': + arg = NULL; + goto usage; + default: + goto invalid_argument; + } + continue; + } +invalid_argument: + (void) fprintf(stderr, "Invalid argument: %s\n", arg); +usage: + (void) fprintf(stderr, "kk_ihex " KK_IHEX_VERSION + " - Copyright (c) 2013-2015 Kimmo Kulovesi\n"); + (void) fprintf(stderr, "Usage: bin2ihex [-a ]" + " [-o ] [-i ] [-v]\n"); + return arg ? EXIT_FAILURE : EXIT_SUCCESS; +argument_error: + perror(*argv); + return EXIT_FAILURE; + } + + { +#ifdef IHEX_EXTERNAL_WRITE_BUFFER + // How to provide an external write buffer with limited duration: + char buffer[IHEX_WRITE_BUFFER_LENGTH]; + ihex_write_buffer = buffer; +#endif + ihex_init(&ihex); + ihex_write_at_address(&ihex, initial_address); + if (write_initial_address) { + if (debug_enabled) { + (void) fprintf(stderr, "Address offset: 0x%lx\n", + (unsigned long) ihex.address); + } + ihex.flags |= IHEX_FLAG_ADDRESS_OVERFLOW; + } + while ((count = (ihex_count_t) fread(buf, 1, sizeof(buf), infile))) { + ihex_write_bytes(&ihex, buf, count); + } + ihex_end_write(&ihex); + } + + if (outfile != stdout) { + (void) fclose(outfile); + } + if (infile != stdout) { + (void) fclose(infile); + } + + if (debug_enabled) { + (void) fprintf(stderr, "%lu bytes read\n", + (unsigned long) ihex.address - initial_address); + } + + return EXIT_SUCCESS; +} + +#pragma clang diagnostic ignored "-Wunused-parameter" + +void +ihex_flush_buffer(struct ihex_state *ihex, char *buffer, char *eptr) { + *eptr = '\0'; + (void) fputs(buffer, outfile); +}
ihex2bin/bin2ihex.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/ihex2bin =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ihex2bin/ihex2bin =================================================================== --- ihex2bin/ihex2bin (nonexistent) +++ ihex2bin/ihex2bin (revision 25)
ihex2bin/ihex2bin Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: ihex2bin/ihex2bin.1 =================================================================== --- ihex2bin/ihex2bin.1 (nonexistent) +++ ihex2bin/ihex2bin.1 (revision 25) @@ -0,0 +1,78 @@ +.Dd February 1, 2014 +.Dt ihex2bin 1 +.Os kk_ihex +.Sh NAME +.Nm ihex2bin +.Nd Convert Intel HEX encoded data to binary +.Sh SYNOPSIS +.Nm +.Op Fl a Ar address_offset | Fl A +.Op Fl i Ar input_file.hex +.Op Fl o Ar output_file.bin +.Op Fl v +.Sh DESCRIPTION +.Nm +reads Intel HEX encoded data from standard input and writes the +decoded binary data to standard output. +.Sh OPTIONS +.Bl -tag -width -indent +.It Fl a Ar address_offset +Set the address of the first byte output to +.Ar address_offset +- by default the beginning of the output is considered to be at address +0, which may cause large amounts of padding to be written if the input +data begins at an offset (e.g., a ROM address for flashing program images) +.It Fl A +Autodetect the address offset (see +.Ar -a +above), i.e., the first output byte written will have the address of the +first byte of input - this option should almost always be used! +.It Fl i Ar file +Read the Intel HEX input from +.Ar file +instead of standard input +.It Fl o Ar file +Write the binary output to +.Ar file +instead of standard output +.It Fl v +Print extra status messages to standard error +.El +.Sh EXAMPLES +Read Intel HEX from +.Ar input.hex +and write the binary output to +.Ar output.bin +such that the first byte of input is written as the first byte +of output (even if the input specifies an address offset): +.Pp +.Bd -ragged -offset indent +.Nm +.Fl A +.Fl i +.Ar input.hex +.Fl o +.Ar output.bin +.Ed +.Pp +Read Intel HEX from +.Ar input.hex +and write the binary output to +.Ar output.bin +such that the first byte of the output has address +.Ar 0x8000000 +(the beginning of the output is padded if the input data begins +at a greater address): +.Bd -ragged -offset indent +.Nm +.Fl a +.Ar 0x8000000 +.Fl i +.Ar input.hex +.Fl o +.Ar output.bin +.Ed +.Sh SEE ALSO +.Xr bin2ihex 1 +.Sh AUTHOR +.An "Kimmo Kulovesi" Aq http://arkku.com
ihex2bin/ihex2bin.1 Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/ihex2bin.c =================================================================== --- ihex2bin/ihex2bin.c (nonexistent) +++ ihex2bin/ihex2bin.c (revision 25) @@ -0,0 +1,194 @@ +/* + * ihex2bin.c: Read Intel HEX format, write binary data. + * + * By default reads from stdin and writes to stdout. The command-line + * options `-i` and `-o` can be used to specify the input and output + * file, respectively. Specifying an output file allows sparse writes. + * + * NOTE: Many Intel HEX files produced by compilers/etc have data + * beginning at an address greater than zero, potentially causing very + * unnecessarily large files to be created. The command-line option + * `-a` can be used to specify the start address of the output file, + * i.e., the value will be subtracted from the IHEX addresses (the + * result must not be negative). + * + * Alternatively, the command-line option `-A` sets the address offset + * to the first address that would be written (i.e., first byte of + * data written will be at address 0). + * + * Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com + * Provided with absolutely no warranty, use at your own risk only. + * Distribute freely, mark modified copies as such. + */ + +#include "kk_ihex_read.h" +#include +#include +#include +#include +#include + +#define AUTODETECT_ADDRESS (~0UL) + +static FILE *outfile; +static unsigned long line_number = 1L; +static unsigned long file_position = 0L; +static unsigned long address_offset = 0UL; +static bool debug_enabled = 0; + +int +main (int argc, char *argv[]) { + struct ihex_state ihex; + FILE *infile = stdin; + ihex_count_t count; + char buf[256]; + + outfile = stdout; + + while (--argc) { + char *arg = *(++argv); + if (arg[0] == '-' && arg[1] && arg[2] == '\0') { + switch (arg[1]) { + case 'a': + if (--argc == 0) { + goto invalid_argument; + } + ++argv; + errno = 0; + address_offset = strtoul(*argv, &arg, 0); + if (errno || arg == *argv) { + errno = errno ? errno : EINVAL; + goto argument_error; + } + break; + case 'A': + address_offset = AUTODETECT_ADDRESS; + break; + case 'i': + if (--argc == 0) { + goto invalid_argument; + } + ++argv; + if (!(infile = fopen(*argv, "r"))) { + goto argument_error; + } + break; + case 'o': + if (--argc == 0) { + goto invalid_argument; + } + ++argv; + if (!(outfile = fopen(*argv, "wb"))) { + goto argument_error; + } + break; + case 'v': + debug_enabled = 1; + break; + case 'h': + case '?': + arg = NULL; + goto usage; + default: + goto invalid_argument; + } + continue; + } +invalid_argument: + (void) fprintf(stderr, "Invalid argument: %s\n", arg); +usage: + (void) fprintf(stderr, "kk_ihex " KK_IHEX_VERSION + " - Copyright (c) 2013-2015 Kimmo Kulovesi\n"); + (void) fprintf(stderr, "Usage: ihex2bin ([-a ]|[-A])" + " [-o ] [-i ] [-v]\n"); + return arg ? EXIT_FAILURE : EXIT_SUCCESS; +argument_error: + perror(*argv); + return EXIT_FAILURE; + } + + ihex_read_at_address(&ihex, (address_offset != AUTODETECT_ADDRESS) ? + (ihex_address_t) address_offset : + 0); + while (fgets(buf, sizeof(buf), infile)) { + count = (ihex_count_t) strlen(buf); + ihex_read_bytes(&ihex, buf, count); + line_number += (count && buf[count - 1] == '\n'); + } + ihex_end_read(&ihex); + + if (infile != stdin) { + (void) fclose(infile); + } + + return EXIT_SUCCESS; +} + +ihex_bool_t +ihex_data_read (struct ihex_state *ihex, + ihex_record_type_t type, + ihex_bool_t error) { + if (error) { + (void) fprintf(stderr, "Checksum error on line %lu\n", line_number); + exit(EXIT_FAILURE); + } + if ((error = (ihex->length < ihex->line_length))) { + (void) fprintf(stderr, "Line length error on line %lu\n", line_number); + exit(EXIT_FAILURE); + } + if (!outfile) { + (void) fprintf(stderr, "Excess data after end of file record\n"); + exit(EXIT_FAILURE); + } + if (type == IHEX_DATA_RECORD) { + unsigned long address = (unsigned long) IHEX_LINEAR_ADDRESS(ihex); + if (address < address_offset) { + if (address_offset == AUTODETECT_ADDRESS) { + // autodetect initial address + address_offset = address; + if (debug_enabled) { + (void) fprintf(stderr, "Address offset: 0x%lx\n", + address_offset); + } + } else { + (void) fprintf(stderr, "Address underflow on line %lu\n", + line_number); + exit(EXIT_FAILURE); + } + } + address -= address_offset; + if (address != file_position) { + if (debug_enabled) { + (void) fprintf(stderr, + "Seeking from 0x%lx to 0x%lx on line %lu\n", + file_position, address, line_number); + } + if (outfile == stdout || fseek(outfile, (long) address, SEEK_SET)) { + if (file_position < address) { + // "seek" forward in stdout by writing NUL bytes + do { + (void) fputc('\0', outfile); + } while (++file_position < address); + } else { + perror("fseek"); + exit(EXIT_FAILURE); + } + } + file_position = address; + } + if (!fwrite(ihex->data, ihex->length, 1, outfile)) { + perror("fwrite"); + exit(EXIT_FAILURE); + } + file_position += ihex->length; + } else if (type == IHEX_END_OF_FILE_RECORD) { + if (debug_enabled) { + (void) fprintf(stderr, "%lu bytes written\n", file_position); + } + if (outfile != stdout) { + (void) fclose(outfile); + } + outfile = NULL; + } + return true; +}
ihex2bin/ihex2bin.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex.h =================================================================== --- ihex2bin/kk_ihex.h (nonexistent) +++ ihex2bin/kk_ihex.h (revision 25) @@ -0,0 +1,191 @@ +/* + * kk_ihex.h: A simple library for reading and writing the Intel HEX + * or IHEX format. Intended mainly for embedded systems, and thus + * somewhat optimised for size at the expense of error handling and + * generality. + * + * USAGE + * ----- + * + * The library has been split into read and write parts, which use a + * common data structure (`struct ihex_state`), but each can be used + * independently. Include the header `kk_ihex_read.h` for reading, and/or + * the header `kk_ihex_write.h` for writing (and link with their respective + * object files). Both can be used simultaneously - this header defines + * the shared data structures and definitions. + * + * + * READING INTEL HEX DATA + * ---------------------- + * + * To read data in the Intel HEX format, you must perform the actual reading + * of bytes using other means (e.g., stdio). The bytes read must then be + * passed to `ihex_read_byte` and/or `ihex_read_bytes`. The reading functions + * will then call `ihex_data_read`, at which stage the `struct ihex_state` + * structure will contain the data along with its address. See the header + * `kk_ihex_read.h` for details and example implementation of `ihex_data_read`. + * + * The sequence to read data in IHEX format is: + * struct ihex_state ihex; + * ihex_begin_read(&ihex); + * ihex_read_bytes(&ihex, my_input_bytes, length_of_my_input_bytes); + * ihex_end_read(&ihex); + * + * + * WRITING BINARY DATA AS INTEL HEX + * -------------------------------- + * + * In order to write out data, the `ihex_write_at_address` or + * `ihex_write_at_segment` functions are used to set the data location, + * and then the binary bytes are written with `ihex_write_byte` and/or + * `ihex_write_bytes`. The writing functions will then call the function + * `ihex_flush_buffer` whenever the internal write buffer needs to be + * cleared - it is up to the caller to provide an implementation of + * `ihex_flush_buffer` to do the actual writing. See the header + * `kk_ihex_write.h` for details and an example implementation. + * + * See the declaration further down for an example implementation. + * + * The sequence to write data in IHEX format is: + * struct ihex_state ihex; + * ihex_init(&ihex); + * ihex_write_at_address(&ihex, 0); + * ihex_write_bytes(&ihex, my_data, length_of_my_data); + * ihex_end_write(&ihex); + * + * For outputs larger than 64KiB, 32-bit linear addresses are output. Normally + * the initial linear extended address record of zero is NOT written - it can + * be forced by setting `ihex->flags |= IHEX_FLAG_ADDRESS_OVERFLOW` before + * writing the first byte. + * + * Gaps in the data may be created by calling `ihex_write_at_address` with the + * new starting address without calling `ihex_end_write` in between. + * + * + * The same `struct ihex_state` may be used either for reading or writing, + * but NOT both at the same time. Furthermore, a global output buffer is + * used for writing, i.e., multiple threads must not write simultaneously + * (but multiple writes may be interleaved). + * + * + * CONSERVING MEMORY + * ----------------- + * + * For memory-critical use, you can save additional memory by defining + * `IHEX_LINE_MAX_LENGTH` as something less than 255. Note, however, that + * this limit affects both reading and writing, so the resulting library + * will be unable to read lines with more than this number of data bytes. + * That said, I haven't encountered any IHEX files with more than 32 + * data bytes per line. For write only there is no reason to define the + * maximum as greater than the line length you'll actually be writing, + * e.g., 32 or 16. + * + * If the write functionality is only occasionally used, you can provide + * your own buffer for the duration by defining `IHEX_EXTERNAL_WRITE_BUFFER` + * and providing a `char *ihex_write_buffer` which points to valid storage + * for at least `IHEX_WRITE_BUFFER_LENGTH` characters from before the first + * call to any IHEX write function to until after the last. + * + * If you are doing both reading and writing, you can define the maximum + * output length separately as `IHEX_MAX_OUTPUT_LINE_LENGTH` - this will + * decrease the write buffer size, but `struct ihex_state` will still + * use the larger `IHEX_LINE_MAX_LENGTH` for its data storage. + * + * You can also save a few additional bytes by disabling support for + * segmented addresses, by defining `IHEX_DISABLE_SEGMENTS`. Both the + * read and write modules need to be build with the same option, as the + * resulting data structures will not be compatible otherwise. To be honest, + * this is a fairly pointless optimisation. + * + * + * Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com/ + * Provided with absolutely no warranty, use at your own risk only. + * Use and distribute freely, mark modified copies as such. + */ + +#ifndef KK_IHEX_H +#define KK_IHEX_H + +#define KK_IHEX_VERSION "2016-07-11" + +#include + +#ifdef IHEX_USE_STDBOOL +#include +typedef bool ihex_bool_t; +#else +typedef uint_fast8_t ihex_bool_t; +#endif + +typedef uint_least32_t ihex_address_t; +typedef uint_least16_t ihex_segment_t; +typedef int ihex_count_t; + +// Maximum number of data bytes per line (applies to both reading and +// writing!); specify 255 to support reading all possible lengths. Less +// can be used to limit memory footprint on embedded systems, e.g., +// most programs with IHEX output use 32. +#ifndef IHEX_LINE_MAX_LENGTH +#define IHEX_LINE_MAX_LENGTH 255 +#endif + +enum ihex_flags { + IHEX_FLAG_ADDRESS_OVERFLOW = 0x80 // 16-bit address overflow +}; +typedef uint8_t ihex_flags_t; + +typedef struct ihex_state { + ihex_address_t address; +#ifndef IHEX_DISABLE_SEGMENTS + ihex_segment_t segment; +#endif + ihex_flags_t flags; + uint8_t line_length; + uint8_t length; + uint8_t data[IHEX_LINE_MAX_LENGTH + 1]; +} kk_ihex_t; + +enum ihex_record_type { + IHEX_DATA_RECORD, + IHEX_END_OF_FILE_RECORD, + IHEX_EXTENDED_SEGMENT_ADDRESS_RECORD, + IHEX_START_SEGMENT_ADDRESS_RECORD, + IHEX_EXTENDED_LINEAR_ADDRESS_RECORD, + IHEX_START_LINEAR_ADDRESS_RECORD +}; +typedef uint8_t ihex_record_type_t; + +#ifndef IHEX_DISABLE_SEGMENTS + +// Resolve segmented address (if any). It is the author's recommendation that +// segmented addressing not be used (and indeed the write function of this +// library uses linear 32-bit addressing unless manually overridden). +// +#define IHEX_LINEAR_ADDRESS(ihex) ((ihex)->address + (((ihex_address_t)((ihex)->segment)) << 4)) +// +// Note that segmented addressing with the above macro is not strictly adherent +// to the IHEX specification, which mandates that the lowest 16 bits of the +// address and the index of the data byte must be added modulo 64K (i.e., +// at 16 bits precision with wraparound) and the segment address only added +// afterwards. +// +// To implement fully correct segmented addressing, compute the address +// of _each byte_ with its index in `data` as follows: +// +#define IHEX_BYTE_ADDRESS(ihex, byte_index) ((((ihex)->address + (byte_index)) & 0xFFFFU) + (((ihex_address_t)((ihex)->segment)) << 4)) + +#else // IHEX_DISABLE_SEGMENTS: + +#define IHEX_LINEAR_ADDRESS(ihex) ((ihex)->address) +#define IHEX_BYTE_ADDRESS(ihex, byte_index) ((ihex)->address + (byte_index)) + +#endif + +// The newline string (appended to every output line, e.g., "\r\n") +#ifndef IHEX_NEWLINE_STRING +#define IHEX_NEWLINE_STRING "\n" +#endif + +// See kk_ihex_read.h and kk_ihex_write.h for function declarations! + +#endif // !KK_IHEX_H
ihex2bin/kk_ihex.h Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex.xcodeproj/project.pbxproj =================================================================== --- ihex2bin/kk_ihex.xcodeproj/project.pbxproj (nonexistent) +++ ihex2bin/kk_ihex.xcodeproj/project.pbxproj (revision 25) @@ -0,0 +1,464 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 4E06FF8718A15EED00C6B357 /* libkk_ihex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E2D127418A15D9D00E65B41 /* libkk_ihex.a */; }; + 4E06FF8818A15EF100C6B357 /* libkk_ihex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E2D127418A15D9D00E65B41 /* libkk_ihex.a */; }; + 4E2D127818A15DA700E65B41 /* kk_ihex_read.c in Sources */ = {isa = PBXBuildFile; fileRef = 4EA4812A18A1327F00BA2CE1 /* kk_ihex_read.c */; }; + 4E2D127918A15DAC00E65B41 /* kk_ihex_write.c in Sources */ = {isa = PBXBuildFile; fileRef = 4EA4812C18A1327F00BA2CE1 /* kk_ihex_write.c */; }; + 4E2D127A18A15DF100E65B41 /* kk_ihex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EA4812E18A1327F00BA2CE1 /* kk_ihex.h */; }; + 4E2D127B18A15DF100E65B41 /* kk_ihex_read.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EA4812B18A1327F00BA2CE1 /* kk_ihex_read.h */; }; + 4E2D127C18A15DF100E65B41 /* kk_ihex_write.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EA4812D18A1327F00BA2CE1 /* kk_ihex_write.h */; }; + 4EA4813C18A132A800BA2CE1 /* bin2ihex.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4EA4813B18A132A800BA2CE1 /* bin2ihex.1 */; }; + 4EA4814018A132B700BA2CE1 /* bin2ihex.c in Sources */ = {isa = PBXBuildFile; fileRef = 4EA4812818A1327F00BA2CE1 /* bin2ihex.c */; }; + 4EA4814B18A132D400BA2CE1 /* ihex2bin.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4EA4814A18A132D400BA2CE1 /* ihex2bin.1 */; }; + 4EA4814F18A132E100BA2CE1 /* ihex2bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 4EA4812918A1327F00BA2CE1 /* ihex2bin.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 4E06FF8518A15EEA00C6B357 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4EA4811418A131FF00BA2CE1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4E2D127318A15D9D00E65B41; + remoteInfo = kk_ihex; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 4EA4813518A132A800BA2CE1 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + 4EA4813C18A132A800BA2CE1 /* bin2ihex.1 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 4EA4814418A132D400BA2CE1 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + 4EA4814B18A132D400BA2CE1 /* ihex2bin.1 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 4E2D127418A15D9D00E65B41 /* libkk_ihex.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libkk_ihex.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 4EA4812818A1327F00BA2CE1 /* bin2ihex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bin2ihex.c; sourceTree = SOURCE_ROOT; }; + 4EA4812918A1327F00BA2CE1 /* ihex2bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ihex2bin.c; sourceTree = SOURCE_ROOT; }; + 4EA4812A18A1327F00BA2CE1 /* kk_ihex_read.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kk_ihex_read.c; sourceTree = SOURCE_ROOT; }; + 4EA4812B18A1327F00BA2CE1 /* kk_ihex_read.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kk_ihex_read.h; sourceTree = SOURCE_ROOT; }; + 4EA4812C18A1327F00BA2CE1 /* kk_ihex_write.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kk_ihex_write.c; sourceTree = SOURCE_ROOT; }; + 4EA4812D18A1327F00BA2CE1 /* kk_ihex_write.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kk_ihex_write.h; sourceTree = SOURCE_ROOT; }; + 4EA4812E18A1327F00BA2CE1 /* kk_ihex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kk_ihex.h; sourceTree = SOURCE_ROOT; }; + 4EA4813718A132A800BA2CE1 /* bin2ihex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = bin2ihex; sourceTree = BUILT_PRODUCTS_DIR; }; + 4EA4813B18A132A800BA2CE1 /* bin2ihex.1 */ = {isa = PBXFileReference; explicitFileType = text.man; path = bin2ihex.1; sourceTree = SOURCE_ROOT; }; + 4EA4814618A132D400BA2CE1 /* ihex2bin */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ihex2bin; sourceTree = BUILT_PRODUCTS_DIR; }; + 4EA4814A18A132D400BA2CE1 /* ihex2bin.1 */ = {isa = PBXFileReference; explicitFileType = text.man; path = ihex2bin.1; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4E2D127118A15D9D00E65B41 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4EA4813418A132A800BA2CE1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4E06FF8718A15EED00C6B357 /* libkk_ihex.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4EA4814318A132D400BA2CE1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4E06FF8818A15EF100C6B357 /* libkk_ihex.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4EA4811318A131FF00BA2CE1 = { + isa = PBXGroup; + children = ( + 4EA4812E18A1327F00BA2CE1 /* kk_ihex.h */, + 4EA4812A18A1327F00BA2CE1 /* kk_ihex_read.c */, + 4EA4812B18A1327F00BA2CE1 /* kk_ihex_read.h */, + 4EA4812918A1327F00BA2CE1 /* ihex2bin.c */, + 4EA4814A18A132D400BA2CE1 /* ihex2bin.1 */, + 4EA4812C18A1327F00BA2CE1 /* kk_ihex_write.c */, + 4EA4812D18A1327F00BA2CE1 /* kk_ihex_write.h */, + 4EA4812818A1327F00BA2CE1 /* bin2ihex.c */, + 4EA4813B18A132A800BA2CE1 /* bin2ihex.1 */, + 4EA4811D18A131FF00BA2CE1 /* Products */, + ); + sourceTree = ""; + }; + 4EA4811D18A131FF00BA2CE1 /* Products */ = { + isa = PBXGroup; + children = ( + 4EA4813718A132A800BA2CE1 /* bin2ihex */, + 4EA4814618A132D400BA2CE1 /* ihex2bin */, + 4E2D127418A15D9D00E65B41 /* libkk_ihex.a */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 4E2D127218A15D9D00E65B41 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4E2D127A18A15DF100E65B41 /* kk_ihex.h in Headers */, + 4E2D127B18A15DF100E65B41 /* kk_ihex_read.h in Headers */, + 4E2D127C18A15DF100E65B41 /* kk_ihex_write.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 4E2D127318A15D9D00E65B41 /* kk_ihex */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4E2D127518A15D9D00E65B41 /* Build configuration list for PBXNativeTarget "kk_ihex" */; + buildPhases = ( + 4E2D127018A15D9D00E65B41 /* Sources */, + 4E2D127118A15D9D00E65B41 /* Frameworks */, + 4E2D127218A15D9D00E65B41 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = kk_ihex; + productName = kk_ihex; + productReference = 4E2D127418A15D9D00E65B41 /* libkk_ihex.a */; + productType = "com.apple.product-type.library.static"; + }; + 4EA4813618A132A800BA2CE1 /* bin2ihex */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4EA4813D18A132A800BA2CE1 /* Build configuration list for PBXNativeTarget "bin2ihex" */; + buildPhases = ( + 4EA4813318A132A800BA2CE1 /* Sources */, + 4EA4813418A132A800BA2CE1 /* Frameworks */, + 4EA4813518A132A800BA2CE1 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 4E06FF8618A15EEA00C6B357 /* PBXTargetDependency */, + ); + name = bin2ihex; + productName = bin2ihex; + productReference = 4EA4813718A132A800BA2CE1 /* bin2ihex */; + productType = "com.apple.product-type.tool"; + }; + 4EA4814518A132D400BA2CE1 /* ihex2bin */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4EA4814C18A132D400BA2CE1 /* Build configuration list for PBXNativeTarget "ihex2bin" */; + buildPhases = ( + 4EA4814218A132D400BA2CE1 /* Sources */, + 4EA4814318A132D400BA2CE1 /* Frameworks */, + 4EA4814418A132D400BA2CE1 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ihex2bin; + productName = ihex2bin; + productReference = 4EA4814618A132D400BA2CE1 /* ihex2bin */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4EA4811418A131FF00BA2CE1 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0700; + ORGANIZATIONNAME = "Kimmo Kulovesi"; + }; + buildConfigurationList = 4EA4811718A131FF00BA2CE1 /* Build configuration list for PBXProject "kk_ihex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 4EA4811318A131FF00BA2CE1; + productRefGroup = 4EA4811D18A131FF00BA2CE1 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4EA4813618A132A800BA2CE1 /* bin2ihex */, + 4EA4814518A132D400BA2CE1 /* ihex2bin */, + 4E2D127318A15D9D00E65B41 /* kk_ihex */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 4E2D127018A15D9D00E65B41 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4E2D127818A15DA700E65B41 /* kk_ihex_read.c in Sources */, + 4E2D127918A15DAC00E65B41 /* kk_ihex_write.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4EA4813318A132A800BA2CE1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4EA4814018A132B700BA2CE1 /* bin2ihex.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4EA4814218A132D400BA2CE1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4EA4814F18A132E100BA2CE1 /* ihex2bin.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 4E06FF8618A15EEA00C6B357 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4E2D127318A15D9D00E65B41 /* kk_ihex */; + targetProxy = 4E06FF8518A15EEA00C6B357 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 4E2D127618A15D9D00E65B41 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = NO; + EXECUTABLE_PREFIX = lib; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + MACOSX_DEPLOYMENT_TARGET = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 4E2D127718A15D9D00E65B41 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = NO; + EXECUTABLE_PREFIX = lib; + GCC_C_LANGUAGE_STANDARD = gnu99; + MACOSX_DEPLOYMENT_TARGET = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 4EA4812318A131FF00BA2CE1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LLVM_LTO = YES; + LLVM_VECTORIZE_LOOPS = YES; + MACOSX_DEPLOYMENT_TARGET = ""; + ONLY_ACTIVE_ARCH = YES; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 4EA4812418A131FF00BA2CE1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LLVM_LTO = YES; + LLVM_VECTORIZE_LOOPS = YES; + MACOSX_DEPLOYMENT_TARGET = ""; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = macosx; + }; + name = Release; + }; + 4EA4813E18A132A800BA2CE1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + MACOSX_DEPLOYMENT_TARGET = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 4EA4813F18A132A800BA2CE1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + MACOSX_DEPLOYMENT_TARGET = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 4EA4814D18A132D400BA2CE1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + MACOSX_DEPLOYMENT_TARGET = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 4EA4814E18A132D400BA2CE1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + MACOSX_DEPLOYMENT_TARGET = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4E2D127518A15D9D00E65B41 /* Build configuration list for PBXNativeTarget "kk_ihex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4E2D127618A15D9D00E65B41 /* Debug */, + 4E2D127718A15D9D00E65B41 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4EA4811718A131FF00BA2CE1 /* Build configuration list for PBXProject "kk_ihex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4EA4812318A131FF00BA2CE1 /* Debug */, + 4EA4812418A131FF00BA2CE1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4EA4813D18A132A800BA2CE1 /* Build configuration list for PBXNativeTarget "bin2ihex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4EA4813E18A132A800BA2CE1 /* Debug */, + 4EA4813F18A132A800BA2CE1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4EA4814C18A132D400BA2CE1 /* Build configuration list for PBXNativeTarget "ihex2bin" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4EA4814D18A132D400BA2CE1 /* Debug */, + 4EA4814E18A132D400BA2CE1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4EA4811418A131FF00BA2CE1 /* Project object */; +}
ihex2bin/kk_ihex.xcodeproj/project.pbxproj Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/bin2ihex.xcscheme =================================================================== --- ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/bin2ihex.xcscheme (nonexistent) +++ ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/bin2ihex.xcscheme (revision 25) @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/bin2ihex.xcscheme Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/ihex2bin.xcscheme =================================================================== --- ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/ihex2bin.xcscheme (nonexistent) +++ ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/ihex2bin.xcscheme (revision 25) @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/ihex2bin.xcscheme Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/kk_ihex.xcscheme =================================================================== --- ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/kk_ihex.xcscheme (nonexistent) +++ ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/kk_ihex.xcscheme (revision 25) @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ihex2bin/kk_ihex.xcodeproj/xcshareddata/xcschemes/kk_ihex.xcscheme Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex_read.c =================================================================== --- ihex2bin/kk_ihex_read.c (nonexistent) +++ ihex2bin/kk_ihex_read.c (revision 25) @@ -0,0 +1,179 @@ +/* + * kk_ihex_read.c: A simple library for reading the Intel HEX (IHEX) format. + * + * See the header `kk_ihex.h` for instructions. + * + * Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com/ + * Provided with absolutely no warranty, use at your own risk only. + * Use and distribute freely, mark modified copies as such. + */ + +#include "kk_ihex_read.h" + +#define IHEX_START ':' + +#define ADDRESS_HIGH_MASK ((ihex_address_t) 0xFFFF0000U) + +enum ihex_read_state { + READ_WAIT_FOR_START = 0, + READ_COUNT_HIGH = 1, + READ_COUNT_LOW, + READ_ADDRESS_MSB_HIGH, + READ_ADDRESS_MSB_LOW, + READ_ADDRESS_LSB_HIGH, + READ_ADDRESS_LSB_LOW, + READ_RECORD_TYPE_HIGH, + READ_RECORD_TYPE_LOW, + READ_DATA_HIGH, + READ_DATA_LOW +}; + +#define IHEX_READ_RECORD_TYPE_MASK 0x07 +#define IHEX_READ_STATE_MASK 0x78 +#define IHEX_READ_STATE_OFFSET 3 + +void +ihex_begin_read (struct ihex_state * const ihex) { + ihex->address = 0; +#ifndef IHEX_DISABLE_SEGMENTS + ihex->segment = 0; +#endif + ihex->flags = 0; + ihex->line_length = 0; + ihex->length = 0; +} + +void +ihex_read_at_address (struct ihex_state * const ihex, ihex_address_t address) { + ihex_begin_read(ihex); + ihex->address = address; +} + +#ifndef IHEX_DISABLE_SEGMENTS +void +ihex_read_at_segment (struct ihex_state * const ihex, ihex_segment_t segment) { + ihex_begin_read(ihex); + ihex->segment = segment; +} +#endif + +void +ihex_end_read (struct ihex_state * const ihex) { + uint_fast8_t type = ihex->flags & IHEX_READ_RECORD_TYPE_MASK; + uint_fast8_t sum; + if ((sum = ihex->length) == 0 && type == IHEX_DATA_RECORD) { + return; + } + { + // compute and validate checksum + const uint8_t * const eptr = ihex->data + sum; + const uint8_t *r = ihex->data; + sum += type + (ihex->address & 0xFFU) + ((ihex->address >> 8) & 0xFFU); + while (r != eptr) { + sum += *r++; + } + sum = (~sum + 1U) ^ *eptr; // *eptr is the received checksum + } + if (ihex_data_read(ihex, type, (uint8_t) sum)) { + if (type == IHEX_EXTENDED_LINEAR_ADDRESS_RECORD) { + ihex->address &= 0xFFFFU; + ihex->address |= (((ihex_address_t) ihex->data[0]) << 24) | + (((ihex_address_t) ihex->data[1]) << 16); +#ifndef IHEX_DISABLE_SEGMENTS + } else if (type == IHEX_EXTENDED_SEGMENT_ADDRESS_RECORD) { + ihex->segment = (ihex_segment_t) ((ihex->data[0] << 8) | ihex->data[1]); +#endif + } + } + ihex->length = 0; + ihex->flags = 0; +} + +void +ihex_read_byte (struct ihex_state * const ihex, const char byte) { + uint_fast8_t b = (uint_fast8_t) byte; + uint_fast8_t len = ihex->length; + uint_fast8_t state = (ihex->flags & IHEX_READ_STATE_MASK); + ihex->flags ^= state; // turn off the old state + state >>= IHEX_READ_STATE_OFFSET; + + if (b >= '0' && b <= '9') { + b -= '0'; + } else if (b >= 'A' && b <= 'F') { + b -= 'A' - 10; + } else if (b >= 'a' && b <= 'f') { + b -= 'a' - 10; + } else if (b == IHEX_START) { + // sync to a new record at any state + state = READ_COUNT_HIGH; + goto end_read; + } else { + // ignore unknown characters (e.g., extra whitespace) + goto save_read_state; + } + + if (!(++state & 1)) { + // high nybble, store temporarily at end of data: + b <<= 4; + ihex->data[len] = b; + } else { + // low nybble, combine with stored high nybble: + b = (ihex->data[len] |= b); + switch (state >> 1) { + default: + // remain in initial state while waiting for : + return; + case (READ_COUNT_LOW >> 1): + // data length + ihex->line_length = b; +#if IHEX_LINE_MAX_LENGTH < 255 + if (b > IHEX_LINE_MAX_LENGTH) { + ihex_end_read(ihex); + return; + } +#endif + break; + case (READ_ADDRESS_MSB_LOW >> 1): + // high byte of 16-bit address + ihex->address &= ADDRESS_HIGH_MASK; // clear the 16-bit address + ihex->address |= ((ihex_address_t) b) << 8U; + break; + case (READ_ADDRESS_LSB_LOW >> 1): + // low byte of 16-bit address + ihex->address |= (ihex_address_t) b; + break; + case (READ_RECORD_TYPE_LOW >> 1): + // record type + if (b & ~IHEX_READ_RECORD_TYPE_MASK) { + // skip unknown record types silently + return; + } + ihex->flags = (ihex->flags & ~IHEX_READ_RECORD_TYPE_MASK) | b; + break; + case (READ_DATA_LOW >> 1): + if (len < ihex->line_length) { + // data byte + ihex->length = len + 1; + state = READ_DATA_HIGH; + goto save_read_state; + } + // end of line (last "data" byte is checksum) + state = READ_WAIT_FOR_START; + end_read: + ihex_end_read(ihex); + } + } +save_read_state: + ihex->flags |= state << IHEX_READ_STATE_OFFSET; +} + +void +ihex_read_bytes (struct ihex_state * restrict ihex, + const char * restrict data, + ihex_count_t count) { + while (count > 0) { + ihex_read_byte(ihex, *data++); + --count; + } +} +
ihex2bin/kk_ihex_read.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex_read.h =================================================================== --- ihex2bin/kk_ihex_read.h (nonexistent) +++ ihex2bin/kk_ihex_read.h (revision 25) @@ -0,0 +1,113 @@ +/* + * kk_ihex_read.h: A simple library for reading Intel HEX data. See + * the accompanying kk_ihex_write.h for IHEX write support. + * + * + * READING INTEL HEX DATA + * ---------------------- + * + * To read data in the Intel HEX format, you must perform the actual reading + * of bytes using other means (e.g., stdio). The bytes read must then be + * passed to `ihex_read_byte` and/or `ihex_read_bytes`. The reading functions + * will then call `ihex_data_read`, at which stage the `struct ihex_state` + * structure will contain the data along with its address. See below for + * details and example implementation of `ihex_data_read`. + * + * The sequence to read data in IHEX format is: + * struct ihex_state ihex; + * ihex_begin_read(&ihex); + * ihex_read_bytes(&ihex, my_input_bytes, length_of_my_input_bytes); + * ihex_end_read(&ihex); + * + * + * CONSERVING MEMORY + * ----------------- + * + * For memory-critical use, you can save additional memory by defining + * `IHEX_LINE_MAX_LENGTH` as something less than 255. Note, however, that + * this limit affects both reading and writing, so the resulting library + * will be unable to read lines with more than this number of data bytes. + * That said, I haven't encountered any IHEX files with more than 32 + * data bytes per line. + * + * + * Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com/ + * Provided with absolutely no warranty, use at your own risk only. + * Use and distribute freely, mark modified copies as such. + */ + +#ifndef KK_IHEX_READ_H +#define KK_IHEX_READ_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "kk_ihex.h" + +// Begin reading at address 0 +void ihex_begin_read(struct ihex_state *ihex); + +// Begin reading at `address` (the lowest 16 bits of which will be ignored); +// this is required only if the high bytes of the 32-bit starting address +// are not specified in the input data and they are non-zero +void ihex_read_at_address(struct ihex_state *ihex, + ihex_address_t address); + +// Read a single character +void ihex_read_byte(struct ihex_state *ihex, char chr); + +// Read `count` bytes from `data` +void ihex_read_bytes(struct ihex_state * restrict ihex, + const char * restrict data, + ihex_count_t count); + +// End reading (may call `ihex_data_read` if there is data waiting) +void ihex_end_read(struct ihex_state *ihex); + +// Called when a complete line has been read, the record type of which is +// passed as `type`. The `ihex` structure will have its fields `data`, +// `line_length`, `address`, and `segment` set appropriately. In case +// of reading an `IHEX_EXTENDED_LINEAR_ADDRESS_RECORD` or an +// `IHEX_EXTENDED_SEGMENT_ADDRESS_RECORD` the record's data is not +// yet parsed - it will be parsed into the `address` or `segment` field +// only if `ihex_data_read` returns `true`. This allows manual handling +// of extended addresses by parsing the `ihex->data` bytes. +// +// Possible error cases include checksum mismatch (which is indicated +// as an argument), and excessive line length (in case this has been +// compiled with `IHEX_LINE_MAX_LENGTH` less than 255) which is indicated +// by `line_length` greater than `length`. Unknown record types and +// other erroneous data is usually silently ignored by this minimalistic +// parser. (It is recommended to compute a hash over the complete data +// once received and verify that against the source.) +// +// Example implementation: +// +// ihex_bool_t ihex_data_read(struct ihex_state *ihex, +// ihex_record_type_t type, +// ihex_bool_t error) { +// error = error || (ihex->length < ihex->line_length); +// if (type == IHEX_DATA_RECORD && !error) { +// (void) fseek(outfile, IHEX_LINEAR_ADDRESS(ihex), SEEK_SET); +// (void) fwrite(ihex->data, 1, ihex->length, outfile); +// } else if (type == IHEX_END_OF_FILE_RECORD) { +// (void) fclose(outfile); +// } +// return !error; +// } +// +extern ihex_bool_t ihex_data_read(struct ihex_state *ihex, + ihex_record_type_t type, + ihex_bool_t checksum_mismatch); + +// Begin reading at `segment`; this is required only if the initial segment +// is not specified in the input data and it is non-zero. +// +#ifndef IHEX_DISABLE_SEGMENTS +void ihex_read_at_segment(struct ihex_state *ihex, ihex_segment_t segment); +#endif + +#ifdef __cplusplus +} +#endif +#endif // !KK_IHEX_READ_H
ihex2bin/kk_ihex_read.h Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex_write.c =================================================================== --- ihex2bin/kk_ihex_write.c (nonexistent) +++ ihex2bin/kk_ihex_write.c (revision 25) @@ -0,0 +1,240 @@ +/* + * kk_ihex_write.c: A simple library for writing the Intel HEX (IHEX) format. + * + * See the header `kk_ihex.h` for instructions. + * + * Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com/ + * Provided with absolutely no warranty, use at your own risk only. + * Use and distribute freely, mark modified copies as such. + */ + +#include "kk_ihex_write.h" + +#define IHEX_START ':' + +#define ADDRESS_HIGH_MASK ((ihex_address_t) 0xFFFF0000U) +#define ADDRESS_HIGH_BYTES(addr) ((addr) >> 16) + +#define HEX_DIGIT(n) ((char)((n) + (((n) < 10) ? '0' : ('A' - 10)))) + +#ifndef IHEX_EXTERNAL_WRITE_BUFFER +static char ihex_write_buffer[IHEX_WRITE_BUFFER_LENGTH]; +#endif + +#if IHEX_MAX_OUTPUT_LINE_LENGTH > IHEX_LINE_MAX_LENGTH +#error "IHEX_MAX_OUTPUT_LINE_LENGTH > IHEX_LINE_MAX_LENGTH" +#endif + +void +ihex_init (struct ihex_state * const ihex) { + ihex->address = 0; +#ifndef IHEX_DISABLE_SEGMENTS + ihex->segment = 0; +#endif + ihex->flags = 0; + ihex->line_length = IHEX_DEFAULT_OUTPUT_LINE_LENGTH; + ihex->length = 0; +} + +static char * +ihex_buffer_byte (char * restrict w, const uint8_t byte) { + uint8_t n = (byte & 0xF0U) >> 4; // high nybble + *w++ = HEX_DIGIT(n); + n = byte & 0x0FU; // low nybble + *w++ = HEX_DIGIT(n); + return w; +} + +static char * +ihex_buffer_word (char * restrict w, const uint_fast16_t word, + uint8_t * const restrict checksum) { + uint8_t byte = (word >> 8) & 0xFFU; // high byte + w = ihex_buffer_byte(w, (uint8_t)byte); + *checksum += byte; + byte = word & 0xFFU; // low byte + *checksum += byte; + return ihex_buffer_byte(w, (uint8_t)byte); +} + +static char * +ihex_buffer_newline (char * restrict w) { + const char * restrict r = IHEX_NEWLINE_STRING; + do { + *w++ = *r++; + } while (*r); + return w; +} + +static void +ihex_write_end_of_file (struct ihex_state * const ihex) { + char * restrict w = ihex_write_buffer; + *w++ = IHEX_START; // : +#if 1 + *w++ = '0'; *w++ = '0'; // length + *w++ = '0'; *w++ = '0'; *w++ = '0'; *w++ = '0'; // address + *w++ = '0'; *w++ = '1'; // record type + *w++ = 'F'; *w++ = 'F'; // checksum +#else + w = ihex_buffer_byte(w, 0); // length + w = ihex_buffer_byte(w, 0); // address msb + w = ihex_buffer_byte(w, 0); // address lsb + w = ihex_buffer_byte(w, IHEX_END_OF_FILE_RECORD); // record type + w = ihex_buffer_byte(w, (uint8_t)~IHEX_END_OF_FILE_RECORD + 1U); // checksum +#endif + w = ihex_buffer_newline(w); + ihex_flush_buffer(ihex, ihex_write_buffer, w); +} + +static void +ihex_write_extended_address (struct ihex_state * const ihex, + const ihex_segment_t address, + const uint8_t type) { + char * restrict w = ihex_write_buffer; + uint8_t sum = type + 2U; + + *w++ = IHEX_START; // : + w = ihex_buffer_byte(w, 2U); // length + w = ihex_buffer_byte(w, 0); // 16-bit address msb + w = ihex_buffer_byte(w, 0); // 16-bit address lsb + w = ihex_buffer_byte(w, type); // record type + w = ihex_buffer_word(w, address, &sum); // high bytes of address + w = ihex_buffer_byte(w, (uint8_t)~sum + 1U); // checksum + w = ihex_buffer_newline(w); + ihex_flush_buffer(ihex, ihex_write_buffer, w); +} + +// Write out `ihex->data` +// +static void +ihex_write_data (struct ihex_state * const ihex) { + uint_fast8_t len = ihex->length; + uint8_t sum = len; + char * restrict w = ihex_write_buffer; + + if (!len) { + return; + } + + if (ihex->flags & IHEX_FLAG_ADDRESS_OVERFLOW) { + ihex_write_extended_address(ihex, ADDRESS_HIGH_BYTES(ihex->address), + IHEX_EXTENDED_LINEAR_ADDRESS_RECORD); + ihex->flags &= ~IHEX_FLAG_ADDRESS_OVERFLOW; + } + + // : + *w++ = IHEX_START; + + // length + w = ihex_buffer_byte(w, len); + ihex->length = 0; + + // 16-bit address + { + uint_fast16_t addr = ihex->address & 0xFFFFU; + ihex->address += len; + if ((0xFFFFU - addr) < len) { + // signal address overflow (need to write extended address) + ihex->flags |= IHEX_FLAG_ADDRESS_OVERFLOW; + } + w = ihex_buffer_word(w, addr, &sum); + } + + // record type + w = ihex_buffer_byte(w, IHEX_DATA_RECORD); + //sum += IHEX_DATA_RECORD; // IHEX_DATA_RECORD is zero, so NOP + + // data + { + uint8_t * restrict r = ihex->data; + do { + uint8_t byte = *r++; + sum += byte; + w = ihex_buffer_byte(w, byte); + } while (--len); + } + + // checksum + w = ihex_buffer_byte(w, ~sum + 1U); + + w = ihex_buffer_newline(w); + ihex_flush_buffer(ihex, ihex_write_buffer, w); +} + +void +ihex_write_at_address (struct ihex_state * const ihex, ihex_address_t address) { + if (ihex->length) { + // flush any existing data + ihex_write_data(ihex); + } + if ((ihex->address & ADDRESS_HIGH_MASK) != (address & ADDRESS_HIGH_MASK)) { + ihex->flags |= IHEX_FLAG_ADDRESS_OVERFLOW; + } else { + ihex->flags &= ~IHEX_FLAG_ADDRESS_OVERFLOW; + } + ihex->address = address; + ihex_set_output_line_length(ihex, ihex->line_length); +} + +void +ihex_set_output_line_length (struct ihex_state * const ihex, + uint8_t line_length) { +#if IHEX_MAX_OUTPUT_LINE_LENGTH < 255 + if (line_length > IHEX_MAX_OUTPUT_LINE_LENGTH) { + line_length = IHEX_MAX_OUTPUT_LINE_LENGTH; + } else +#endif + if (!line_length) { + line_length = IHEX_DEFAULT_OUTPUT_LINE_LENGTH; + } + ihex->line_length = line_length; +} + +#ifndef IHEX_DISABLE_SEGMENTS +void +ihex_write_at_segment (struct ihex_state * const ihex, + ihex_segment_t segment, + ihex_address_t address) { + ihex_write_at_address(ihex, address); + if (ihex->segment != segment) { + // clear segment + ihex_write_extended_address(ihex, (ihex->segment = segment), + IHEX_EXTENDED_SEGMENT_ADDRESS_RECORD); + } +} +#endif + +void +ihex_write_byte (struct ihex_state * const ihex, const int byte) { + if (ihex->line_length <= ihex->length) { + ihex_write_data(ihex); + } + ihex->data[(ihex->length)++] = (uint8_t) byte; +} + +void +ihex_write_bytes (struct ihex_state * restrict const ihex, + const void * restrict buf, + ihex_count_t count) { + const uint8_t *r = buf; + while (count > 0) { + if (ihex->line_length > ihex->length) { + uint_fast8_t i = ihex->line_length - ihex->length; + uint8_t *w = ihex->data + ihex->length; + i = ((ihex_count_t) i > count) ? (uint_fast8_t) count : i; + count -= i; + ihex->length += i; + do { + *w++ = *r++; + } while (--i); + } else { + ihex_write_data(ihex); + } + } +} + +void +ihex_end_write (struct ihex_state * const ihex) { + ihex_write_data(ihex); // flush any remaining data + ihex_write_end_of_file(ihex); +} +
ihex2bin/kk_ihex_write.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2bin/kk_ihex_write.h =================================================================== --- ihex2bin/kk_ihex_write.h (nonexistent) +++ ihex2bin/kk_ihex_write.h (revision 25) @@ -0,0 +1,166 @@ +/* + * kk_ihex_write.h: A simple library for writing Intel HEX data. + * See the accompanying kk_ihex_read.h for read support, and the + * main header kk_ihex.h for the shared parts. + * + * + * WRITING BINARY DATA AS INTEL HEX + * -------------------------------- + * + * In order to write out data, the `ihex_write_at_address` or + * `ihex_write_at_segment` functions are used to set the data location, + * and then the binary bytes are written with `ihex_write_byte` and/or + * `ihex_write_bytes`. The writing functions will then call the function + * `ihex_flush_buffer` whenever the internal write buffer needs to be + * cleared - it is up to the caller to provide an implementation of + * `ihex_flush_buffer` to do the actual writing. See below for details + * and an example implementation. + * + * See the declaration further down for an example implementation. + * + * The sequence to write data in IHEX format is: + * struct ihex_state ihex; + * ihex_init(&ihex); + * ihex_write_at_address(&ihex, 0); + * ihex_write_bytes(&ihex, my_data, length_of_my_data); + * ihex_end_write(&ihex); + * + * For outputs larger than 64KiB, 32-bit linear addresses are output. Normally + * the initial linear extended address record of zero is NOT written - it can + * be forced by setting `ihex->flags |= IHEX_FLAG_ADDRESS_OVERFLOW` before + * writing the first byte. + * + * Gaps in the data may be created by calling `ihex_write_at_address` with the + * new starting address without calling `ihex_end_write` in between. + * + * + * The same `struct ihex_state` may be used either for reading or writing, + * but NOT both at the same time. Furthermore, a global output buffer is + * used for writing, i.e., multiple threads must not write simultaneously + * (but multiple writes may be interleaved). + * + * + * CONSERVING MEMORY + * ----------------- + * + * If you are using only the write support, you should define + * `IHEX_LINE_MAX_LENGTH` as the length of your output line. This makes + * both the `struct ihex_state' and the internal write buffer smaller. + * For example, 32 or even 16 can be used instead of the default 255. + * + * If the write functionality is not used all the time and can thus + * share its write buffer memory with something else that is inactive + * during writing IHEX, you can define `IHEX_EXTERNAL_WRITE_BUFFER` and + * provide the buffer as `char *ihex_write_buffer`. The size of the + * buffer must be at least `IHEX_WRITE_BUFFER_LENGTH` bytes and it must + * be valid for the entire duration from the first call to a write function + * until after the last call to `ihex_end_write`. Note that there is + * no advantage to this unless something else, mutually exclusive with + * IHEX writing, can share the memory. + * + * If you are reading IHEX as well, then you'll end up limiting the + * maximum length of line that can be read. In that case you may wish to + * define `IHEX_MAX_OUTPUT_LINE_LENGTH` as smaller to decrease the + * write buffer size, but keep `IHEX_LINE_MAX_LENGTH` at 255 to support + * reading any IHEX file. + * + * + * Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com/ + * Provided with absolutely no warranty, use at your own risk only. + * Use and distribute freely, mark modified copies as such. + */ + +#ifndef KK_IHEX_WRITE_H +#define KK_IHEX_WRITE_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "kk_ihex.h" + +// Default number of data bytes written per line +#if IHEX_LINE_MAX_LENGTH >= 32 +#define IHEX_DEFAULT_OUTPUT_LINE_LENGTH 32 +#else +#define IHEX_DEFAULT_OUTPUT_LINE_LENGTH IHEX_LINE_MAX_LENGTH +#endif + +#ifndef IHEX_MAX_OUTPUT_LINE_LENGTH +#define IHEX_MAX_OUTPUT_LINE_LENGTH IHEX_LINE_MAX_LENGTH +#endif + +// Length of the write buffer required +#define IHEX_WRITE_BUFFER_LENGTH (1+2+4+2+(IHEX_MAX_OUTPUT_LINE_LENGTH*2)+2+sizeof(IHEX_NEWLINE_STRING)) + +#ifdef IHEX_EXTERNAL_WRITE_BUFFER +// Define `IHEX_EXTERNAL_WRITE_BUFFER` to provide an external write buffer, +// as `char *ihex_write_buffer`, which must point to a valid storage for +// at least `IHEX_WRITE_BUFFER_LENGTH` characters whenever any of the +// write functionality is used (see above under "CONSERVING MEMORY"). +extern char *ihex_write_buffer; +#endif + +// Initialise the structure `ihex` for writing +void ihex_init(struct ihex_state *ihex); + +// Begin writing at the given 32-bit `address` after writing any +// pending data at the current address. +// +// This can also be used to skip to a new address without calling +// `ihex_end_write`; this allows writing sparse output. +// +void ihex_write_at_address(struct ihex_state *ihex, ihex_address_t address); + +// Write a single byte +void ihex_write_byte(struct ihex_state *ihex, int b); + +// Write `count` bytes from `data` +void ihex_write_bytes(struct ihex_state * restrict ihex, + const void * restrict data, + ihex_count_t count); + +// End writing (flush buffers, write end of file record) +void ihex_end_write(struct ihex_state *ihex); + +// Called whenever the global, internal write buffer needs to be flushed by +// the write functions. The implementation is NOT provided by this library; +// this must be implemented to perform the actual output, i.e., write out +// `(eptr - buffer)` bytes from `buffer` (which is not NUL-terminated, but +// may be modified to make it thus). +// +// Example implementation: +// +// void ihex_flush_buffer(struct ihex_state *ihex, +// char *buffer, char *eptr) { +// *eptr = '\0'; +// (void) fputs(buffer, stdout); +// } +// +// Note that the contents of `buffer` can become invalid immediately after +// this function returns - the data must be copied if it needs to be preserved! +// +extern void ihex_flush_buffer(struct ihex_state *ihex, + char *buffer, char *eptr); + +// As `ihex_write_at_address`, but specify a segment selector. Note that +// segments are not automatically incremented when the 16-bit address +// overflows (the default is to use 32-bit linear addressing). For segmented +// 20-bit addressing you must manually ensure that a write does not overflow +// the segment boundary, and call `ihex_write_at_segment` every time the +// segment needs to be changed. +// +#ifndef IHEX_DISABLE_SEGMENTS +void ihex_write_at_segment(struct ihex_state *ihex, + ihex_segment_t segment, + ihex_address_t address); +#endif + +// Set the output line length to `length` - may be safely called only right +// after `ihex_write_at_address` or `ihex_write_at_segment`. The maximum +// is IHEX_LINE_MAX_LENGTH (which may be changed at compile time). +void ihex_set_output_line_length(struct ihex_state *ihex, uint8_t line_length); + +#ifdef __cplusplus +} +#endif +#endif // !KK_IHEX_WRITE_H
ihex2bin/kk_ihex_write.h Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ihex2mif/Makefile =================================================================== --- ihex2mif/Makefile (revision 19) +++ ihex2mif/Makefile (revision 25) @@ -1,3 +1,3 @@ #!/bin/sh all: - gcc main.c -o ihex2mif + gcc -Wall main.c -o ihex2mif Index: ihex2mif/ihex.c =================================================================== --- ihex2mif/ihex.c (revision 19) +++ ihex2mif/ihex.c (revision 25) @@ -11,7 +11,12 @@ #include #include #include +#include +#ifndef MAX_MEMORY_SIZE + #define MAX_MEMORY_SIZE 65535 +#endif + /* some ansi prototypes.. maybe ought to make a .h file */ /* this loads an intel hex file into the memory[] array */ @@ -30,7 +35,7 @@ void hexout(FILE *fhex, int byte, int memory_location, int end); -extern int memory[65536]; /* the memory is global */ +extern int memory[MAX_MEMORY_SIZE+1]; /* the memory is global */ /* parses a line of intel hex code, stores the data in bytes[] */ /* and the beginning address in addr, and returns a 1 if the */ @@ -145,8 +150,8 @@ printf(" the addresses must be hexidecimal format\n"); return; } - begin &= 65535; - end &= 65535; + begin &= MAX_MEMORY_SIZE; + end &= MAX_MEMORY_SIZE; if (begin > end) { printf(" Begin address must be less than end address.\n"); return;
/ihex2mif/ihex2mif Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
ihex2mif/ihex2mif Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: ihex2mif/main.c =================================================================== --- ihex2mif/main.c (revision 19) +++ ihex2mif/main.c (revision 25) @@ -1,3 +1,5 @@ +#define MAX_MEMORY_SIZE 0xFFFFF //max memory size in bytes mustbe power of 2 + #include "ihex.c" #include #include @@ -5,7 +7,7 @@ #define DEFAULT_OUT_FILE_NAME "out.mif" #define DEAFULT_END_SIZE "1FFF" -int memory[65536]; /* the memory is global */ +int memory[MAX_MEMORY_SIZE+1]; /* the memory is global */ unsigned int end_addr_int; FILE * in, * out; char *file_name, *end_addr, *out_file_name ;
/ihex2mif/out.mif
0,0 → 1,257
-- Copyright (C) 1991-2013 Altera Corporation
-- Your use of Altera Corporation's design tools, logic functions
-- and other software and tools, and its AMPP partner logic
-- functions, and any output files from any of the foregoing
-- (including device programming or simulation files), and any
-- associated documentation or information are expressly subject
-- to the terms and conditions of the Altera Program License
-- Subscription Agreement, Altera MegaCore Function License
-- Agreement, or other applicable license agreement, including,
-- without limitation, that your use is for the sole purpose of
-- programming logic devices manufactured by Altera and sold by
-- Altera or its authorized distributors. Please refer to the
-- applicable agreement for further details.
 
-- Quartus II generated Memory Initialization File (.mif)
 
WIDTH=32;
DEPTH=8191;
 
ADDRESS_RADIX=HEX;
DATA_RADIX=HEX;
 
CONTENT BEGIN
0000 : B8080050;
0001 : 00000000;
0002 : B808017C;
0003 : 00000000;
0004 : B808018C;
[0005..0007] : 00000000;
0008 : B8080184;
[0009..0013] : 00000000;
0014 : 31A004C0;
0015 : 304003B8;
0016 : 30200D30;
0017 : B9F40014;
0018 : 80000000;
0019 : B9F40140;
001A : 30A30000;
001B : B8000000;
001C : 2021FFEC;
001D : F9E10000;
001E : 20C004C0;
001F : 20E004C0;
0020 : 06463800;
0021 : BC720014;
0022 : F8060000;
0023 : 20C60004;
0024 : 06463800;
0025 : BC92FFF4;
0026 : 20C004C0;
0027 : 20E0053C;
0028 : 06463800;
0029 : BC720014;
002A : F8060000;
002B : 20C60004;
002C : 06463800;
002D : BC92FFF4;
002E : B9F400E4;
002F : 80000000;
0030 : 20C00000;
0031 : 20E00000;
0032 : B9F40024;
0033 : 20A00000;
0034 : 32630000;
0035 : B9F400C0;
0036 : 80000000;
0037 : C9E10000;
0038 : 30730000;
0039 : B60F0008;
003A : 20210014;
003B : E8A003B8;
003C : E8E003C0;
003D : E94003C4;
003E : B00000F8;
003F : 312004C0;
0040 : B0001A00;
0041 : 31000000;
0042 : 30600001;
0043 : F8650000;
0044 : 10C00000;
0045 : E8650000;
0046 : 30800002;
0047 : 30630001;
0048 : F8650000;
0049 : 10642000;
004A : F88304C0;
004B : 30840002;
004C : AA44001E;
004D : BE32FFF4;
004E : 10642000;
004F : F90004C0;
0050 : F9270000;
0051 : BC26FFD0;
0052 : E86A0000;
0053 : A4C30001;
0054 : BC26FFC4;
0055 : E86A0000;
0056 : A4C30001;
0057 : BC26FFB8;
0058 : B800FFE8;
0059 : B8000008;
005A : 80000000;
005B : BE25FFFC;
005C : 30A5FFFF;
005D : B60F0008;
005E : 80000000;
005F : B6110000;
0060 : 80000000;
0061 : B6910000;
0062 : 80000000;
0063 : B62E0000;
0064 : 80000000;
0065 : B60F0008;
0066 : 80000000;
0067 : B60F0008;
0068 : 80000000;
0069 : 3021FFE0;
006A : 10C00000;
006B : FA61001C;
006C : F9E10000;
006D : B9F40024;
006E : 12650000;
006F : E8A003AC;
0070 : E8650028;
0071 : BC03000C;
0072 : 99FC1800;
0073 : 80000000;
0074 : B9F4FE9C;
0075 : 10B30000;
0076 : E86003AC;
0077 : 3021FFC8;
0078 : FB410030;
0079 : FB610034;
007A : F9E10000;
007B : FA61001C;
007C : FAC10020;
007D : FAE10024;
007E : FB010028;
007F : FB21002C;
0080 : EB030048;
0081 : 13650000;
0082 : BE180050;
0083 : 13460000;
0084 : E8780004;
0085 : EB380088;
0086 : 3263FFFF;
0087 : BC53003C;
0088 : 64930402;
0089 : 30640008;
008A : 12D81800;
008B : BE060074;
008C : 12F92000;
008D : BC1900C0;
008E : E8770080;
008F : 1643D000;
0090 : BC1200EC;
0091 : 3273FFFF;
0092 : 32F7FFFC;
0093 : AA53FFFF;
0094 : BE32FFE8;
0095 : 32D6FFFC;
0096 : E9E10000;
0097 : EA61001C;
0098 : EAC10020;
0099 : EAE10024;
009A : EB010028;
009B : EB21002C;
009C : EB410030;
009D : EB610034;
009E : B60F0008;
009F : 30210038;
00A0 : E8B70000;
00A1 : 99FC3800;
00A2 : 80000000;
00A3 : 3273FFFF;
00A4 : 32F7FFFC;
00A5 : AA53FFFF;
00A6 : BE12FFC0;
00A7 : 32D6FFFC;
00A8 : E8780004;
00A9 : E8F60000;
00AA : 3063FFFF;
00AB : 16439800;
00AC : BC120074;
00AD : F8160000;
00AE : BC07FFD4;
00AF : BE190058;
00B0 : 30800001;
00B1 : E8790100;
00B2 : 44849C00;
00B3 : 84641800;
00B4 : BC030044;
00B5 : E8790104;
00B6 : 84641800;
00B7 : BC23FFA4;
00B8 : E8D70000;
00B9 : 99FC3800;
00BA : 10BB0000;
00BB : B810FFA4;
[00BC..00BD] : 3273FFFF;
00BE : AA53FFFF;
00BF : BE12FF5C;
00C0 : 3273FFFF;
00C1 : AA53FFFF;
00C2 : BE32FFF0;
00C3 : 3273FFFF;
00C4 : B800FF48;
00C5 : 99FC3800;
00C6 : 3273FFFF;
00C7 : B810FF78;
00C8 : 32F7FFFC;
00C9 : FA780004;
00CA : B800FF90;
00CB : E8780004;
00CC : E8F60000;
00CD : 3063FFFF;
00CE : 16439800;
00CF : BC120054;
00D0 : F8160000;
00D1 : BC07FF00;
00D2 : BC190038;
00D3 : 30800001;
00D4 : E8790100;
00D5 : 44849C00;
00D6 : 84641800;
00D7 : BC030024;
00D8 : E8790104;
00D9 : 84641800;
00DA : BC230030;
00DB : E8D70000;
00DC : 99FC3800;
00DD : 10BB0000;
00DE : B810FED0;
00DF : 3273FFFF;
00E0 : 99FC3800;
00E1 : 3273FFFF;
00E2 : B810FEC4;
00E3 : 32F7FFFC;
00E4 : FA780004;
00E5 : B800FFB0;
00E6 : E8B70000;
00E7 : 99FC3800;
00E8 : 3273FFFF;
00E9 : B810FEA8;
00EA : 32F7FFFC;
00EB : 000003CC;
00EC : 43000000;
00ED : 00000000;
00EE : 41000000;
00EF : 40000000;
00F0 : 40000004;
00F1 : 40000008;
00F2 : 000003CC;
[00F3..00FA] : 00000000;
00FB : 000003B0;
[00FC..1FFE] : 00000000;
END;
ihex2mif/out.mif Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/Makefile =================================================================== --- jtag/Makefile (nonexistent) +++ jtag/Makefile (revision 25) @@ -0,0 +1,23 @@ + +CFLAGS := -g -Wall +LIBS := -lusb-1.0 + +all: jinfo jtag_main + +jinfo.c: jtag.h +jtag_main.c: jtag.h +jtag.c: jtag.h +jtag-virtual.c: jtag.h + + + +JINFO_OBJS := jinfo.o jtag-virtual.o jtag.o +jinfo: $(JINFO_OBJS) + $(CC) -o jinfo $(JINFO_OBJS) $(LIBS) + +JTAG_MAIN_OBJS := jtag_main.o jtag-virtual.o jtag.o +jtag_main: $(JTAG_MAIN_OBJS) + $(CC) -o jtag_main $(JTAG_MAIN_OBJS) $(LIBS) + +clean:: + rm -f jinfo jtag_main *.o
jtag/Makefile Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/README =================================================================== --- jtag/README (nonexistent) +++ jtag/README (revision 25) @@ -0,0 +1,20 @@ + +Quick hack commandline tools to interact with Altera FPGA Virtual JTAG interfaces, +using the USB Blaster device (as integrated on Terasic dev boards, etc). + +Not terribly fancy or optimized but only depends on libusb-1.0 + +Currently does not support multiple devices on the chain. + +jtag.c - provides simple jtag interface +jtag-virtual.c - provides simple virtual jtag interface + +jload.c - example of using the virtual jtag interface for a downloader interface + with a CTRL/ADDR/DATA register set. CTRL[0] asserts reset, writes to + DATA store to [ADDR] and auto-increment ADRR. + +jinfo.c - dumps idcode and virtual jtag hub and device info table + + +Why? Scripting the Altera quartus_stp tool in TCL was driving me nuts. +
jtag/README Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/jconsole.c =================================================================== --- jtag/jconsole.c (nonexistent) +++ jtag/jconsole.c (revision 25) @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include + + +#include +#include "jtag.h" + +#define VIR_CTRL 0x0 +#define VIR_ADDR 0x1 +#define VIR_DATA 0x2 +#define VIR_UART 0x7 + + +#define UPDATE_WB_ADDR 0x7 +#define UPDATE_WB_WR_DATA 0x6 +#define UPDATE_WB_RD_DATA 0x5 +#define RD_WR_STATUS 0x4 + +int main(int argc, char **argv) { + //unsigned bits; + //unsigned int val; + + //unsigned bits; + uint32_t val; + FILE *fp; + + if (argc != 2) { + fprintf(stderr,"usage: download bin file\n"); + return -1; + } + fp = fopen(argv[1],"rb"); + if (!fp) return -1; + + if (jtag_open_virtual_device(126)) + return -1; + + + int i=0; + unsigned int out; +//disable the cpu + jtag_vir(RD_WR_STATUS); + jtag_vdr(32, 0xFFFFFFFF, &out); + printf ("status=%x\n",out); + getchar(); +// + jtag_vir(UPDATE_WB_WR_DATA); + unsigned char ch; + char cnt=0; + val=0; + ch=fgetc(fp); + while(!feof(fp)){ + val<<=8; + val|=ch; + cnt++; + printf("ch=%x\t",ch); + if(cnt==4){ + printf("%d:%x\n",i,val); + jtag_vdr(32, val, 0); + val=0; + cnt=0; + i++; + } + ch=fgetc(fp); + } + if( cnt>0){ + val<<=(8 *(4-cnt)); + printf("%d:%x\n",i,val); + jtag_vdr(32, val, 0); + + } + + + getchar(); +/* + printf ("start=\n"); + jtag_vir(UPDATE_WB_ADDR); + jtag_vdr(32, 0, 0); + jtag_vir(UPDATE_WB_WR_DATA); + + for(i=0;i<1000; i++){ + //printf ("addr=\n"); + //scanf("%x", &val); + + jtag_vdr(32, 2*i, 0); + //jtag_vdr(32, 0, &out); + //printf ("out=%x\n",out); + + printf ("data=\n"); + scanf("%x", &val); + jtag_vir(UPDATE_WB_WR_DATA); + jtag_vdr(32, val, 0); + + printf ("data=\n"); + scanf("%x", &val); + jtag_vdr(32, val, 0); + + printf ("data=\n"); + scanf("%x", &val); + jtag_vdr(32, val, 0); + + + } +*/ + printf ("done programing\n"); + jtag_vir(UPDATE_WB_RD_DATA); + jtag_vdr(32, 0, &out); + for(i=1;i<1001; i++){ + jtag_vdr(32, i, &out); + printf ("out[%d]=%x\n",i-1,out); + + + } + + jtag_vir(RD_WR_STATUS); + jtag_vdr(32, 0, &out); + printf ("status=%x\n",out); + for (;;) { + /* + jtag_vdr(9, 0, &bits); + if (bits & 0x100) { + bits &= 0xFF; + if ((bits < ' ') || (bits > 127)) + fputc('.', stderr); + else + fputc(bits, stderr); + } + */ + } + + return 0; +} +
jtag/jconsole.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/jinfo =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: jtag/jinfo =================================================================== --- jtag/jinfo (nonexistent) +++ jtag/jinfo (revision 25)
jtag/jinfo Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: jtag/jinfo.c =================================================================== --- jtag/jinfo.c (nonexistent) +++ jtag/jinfo.c (revision 25) @@ -0,0 +1,36 @@ +/* Copyright 2012 Brian Swetland + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "jtag.h" + +int main(int argc, char **argv) { + unsigned bits; + + if (jtag_open() < 0) + return -1; + + if (jtag_reset() < 0) + return -1; + if (jtag_dr(32, 0, &bits) < 0) + return -1; + fprintf(stderr,"IDCODE: %08x\n", bits); + + if (jtag_open_virtual_device(0xffffffff)) + return -1; + + jtag_close(); + return 0; +}
jtag/jinfo.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/jtag-virtual.c =================================================================== --- jtag/jtag-virtual.c (nonexistent) +++ jtag/jtag-virtual.c (revision 25) @@ -0,0 +1,139 @@ +/* Copyright 2012 Brian Swetland + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "jtag.h" + +int jtag_dr_8x4(unsigned *out) { + unsigned bits = 0; + unsigned tmp; + int n, r; + + for (n = 0; n < 8; n++) { + if ((r = jtag_dr(4, 0, &tmp)) < 0) return r; + bits |= (tmp <<= (n * 4)); + } + *out = bits; + return 0; +} + +/* number of bits needed given a max value 1-255 */ +unsigned needbits(unsigned max) { + if (max > 127) return 8; + if (max > 63) return 7; + if (max > 31) return 6; + if (max > 15) return 5; + if (max > 7) return 4; + if (max > 3) return 3; + if (max > 1) return 2; + return 1; +} + +static unsigned ir_width = 10; + +static unsigned hub_version = 0; +static unsigned hub_nodecount = 0; +static unsigned hub_mfg = 0; + +static unsigned vir_width = 0; +static unsigned vir_width_addr = 0; +static unsigned vir_width_ir = 0; +static unsigned vir_addr = 0; + + +int jtag_vir(unsigned vir) { + int r; + if ((r = jtag_ir(ir_width, 14)) < 0) return r; + if ((r = jtag_dr(vir_width, vir_addr | vir, 0)) < 0) return r; + return 0; +} + +int jtag_vdr(unsigned sz, unsigned bits, unsigned *out) { + int r; + if ((r = jtag_ir(ir_width, 12)) < 0) return r; + if ((r = jtag_dr(sz, bits, out)) < 0) return r; + return 0; +} + +int jtag_vdr_long(unsigned sz, unsigned * bits, unsigned *out, int words) { + int r; + if ((r = jtag_ir(ir_width, 12)) < 0) return r; + if ((r = jtag_dr_long(sz, bits, out, words)) < 0) return r; + return 0; +} + +int jtag_open_virtual_device(unsigned iid) { + unsigned n, bits; + int r; + + if ((r = jtag_open()) < 0) return r; + + if ((r = jtag_reset()) < 0) return r; + + /* select empty node_addr + node_vir -- all zeros */ + if ((r = jtag_ir(ir_width, 14)) < 0) return r; + if ((r = jtag_dr(32, 0, 0)) < 0) return r; + + /* select vdr - this will be the hub info (addr=0,vir=0) */ + if ((r = jtag_ir(ir_width, 12)) < 0) return r; + + /* read hub info */ + if ((r = jtag_dr_8x4(&bits)) < 0) return r; + hub_version = (bits >> 27) & 0x1F; + hub_nodecount = (bits >> 19) & 0xFF; + hub_mfg = (bits >> 8) & 0x7FF; + + if (hub_mfg != 0x06e) { + fprintf(stderr,"HUB: Cannot Find Virtual JTAG HUB\n"); + return -1; + } + + /* altera docs claim this field is the sum of M bits (VIR field) and + * N bits (ADDR field), but empirical evidence suggests it is actually + * just the width of the ADDR field and the docs are wrong... + */ + vir_width_ir = bits & 0xFF; + vir_width_addr = needbits(hub_nodecount); + vir_width = vir_width_ir + vir_width_addr; + + fprintf(stderr,"HUB: Mfg=0x%03x, Ver=0x%02x, Nodes=%d, VIR=%d+%d bits\n", + hub_mfg, hub_version, hub_nodecount, vir_width_addr, vir_width_ir); + + for (n = 0; n < hub_nodecount; n++) { + unsigned node_ver, node_id, node_mfg, node_iid; + if ((r = jtag_dr_8x4(&bits)) < 0) return r; + node_ver = (bits >> 27) & 0x1F; + node_id = (bits >> 19) & 0xFF; + node_mfg = (bits >> 8) & 0x7FF; + node_iid = bits & 0xFF; + + fprintf(stderr,"NODE: Mfg=0x%03x, Ver=0x%02x, ID=0x%02x, IID=0x%02x\n", + node_mfg, node_ver, node_id, node_iid); + + if ((node_id == 0x08) && (node_iid) == iid) { + vir_addr = (n + 1) << vir_width_ir; + } + } + + if ((vir_addr == 0) && (iid < 256)) { + fprintf(stderr,"ERROR: IID 0x%02x not found\n", iid); + return -1; + } + return 0; +} + +
jtag/jtag-virtual.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/jtag.c =================================================================== --- jtag/jtag.c (nonexistent) +++ jtag/jtag.c (revision 25) @@ -0,0 +1,321 @@ +/* Copyright 2012 Brian Swetland + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include + +#define TRACE_USB 0 +#define TRACE_JTAG 0 + +static struct libusb_device_handle *udev; +static int usb_open(unsigned vid, unsigned pid) { + if (libusb_init(NULL) < 0) + return -1; + + if (!(udev = libusb_open_device_with_vid_pid(NULL, vid, pid))) { + fprintf(stderr,"cannot find device\n"); + return -1; + } + + if (libusb_claim_interface(udev, 0) < 0) { + fprintf(stderr,"cannot claim interface\n"); + return -1; + } + return 0; +} +static void usb_close(void) { + libusb_exit(NULL); +} +#if TRACE_USB +static void dump(char *prefix, void *data, int len) { + unsigned char *x = data; + fprintf(stderr,"%s: (%d)", prefix, len); + while (len > 0) { + fprintf(stderr," %02x", *x++); + len--; + } + fprintf(stderr,"\n"); +} +#endif +static int usb_bulk(unsigned char ep, void *data, int len, unsigned timeout) { + int r, xfer; +#if TRACE_USB + if (!(ep & 0x80)) + dump("xmit", data, len); +#endif + r = libusb_bulk_transfer(udev, ep, data, len, &xfer, timeout); + if (r < 0) { + fprintf(stderr,"bulk: error: %d\n", r); + return r; + } +#if TRACE_USB + if (ep & 0x80) + dump("recv", data, xfer); +#endif + return xfer; +} + +#define EP1_IN 0x81 +#define EP2_OUT 0x02 + +#define UB_BYTEMODE 0x80 +#define UB_BITMODE 0x00 +#define UB_READBACK 0x40 + +/* bits in bit mode */ +#define UB_OE 0x20 +#define UB_TDI 0x10 +#define UB_nCS 0x08 +#define UB_nCE 0x04 +#define UB_TMS 0x02 +#define UB_TCK 0x01 +#define BUFF_SZ 512 +/* bytecount for data bytes that follow in byte mode */ +#define UB_COUNT(n) ((n) & 0x3F) + +int jtag_move(int count, unsigned bits){ + unsigned char buf[BUFF_SZ]; + int n = 0; +#if TRACE_JTAG + fprintf(stderr,"move: %08x (%d)\n", bits, count); +#endif + while (count-- > 0) { + if (bits & 1) { + buf[n++] = UB_TMS; + buf[n++] = UB_TMS | UB_TCK; + } else { + buf[n++] = 0; + buf[n++] = UB_TCK; + } + bits >>= 1; + } + return usb_bulk(EP2_OUT, buf, n, 1000); +} + +int jtag_shift(int count, unsigned bits, unsigned *out) { + unsigned char buf[BUFF_SZ]; + unsigned RB = out ? UB_READBACK : 0; + int n = 0; + int readcount = count; + int r,bit; +#if TRACE_JTAG + fprintf(stderr,"xfer: %08x (%d)\n", bits, count); +#endif + while (count-- > 0) { + if (bits & 1) { + buf[n++] = UB_TDI; + buf[n++] = UB_TDI | UB_TCK | RB; + } else { + buf[n++] = 0; + buf[n++] = UB_TCK | RB; + } + bits >>= 1; + } + buf[n-1] |= UB_TMS; + buf[n-2] |= UB_TMS; + r = usb_bulk(EP2_OUT, buf, n, 1000); + if (r < 0) + return r; + if (!out) + return 0; + bits = 0; + bit = 1; + while (readcount > 0) { + r = usb_bulk(EP1_IN, buf, BUFF_SZ, 1000); + if (r < 0) + return r; + if (r < 3) + continue; + for (n = 2; n < r; n++) { + if (buf[n] & 1) + bits |= bit; + bit <<= 1; + readcount--; + if (readcount == 0) { +#if TRACE_JTAG + fprintf(stderr," : %08x\n", bits); +#endif + *out = bits; + return 0; + } + } + } + return -1; +} + + +int jtag_shift_long(int count, unsigned * bits, unsigned *out) { + unsigned char buf[BUFF_SZ]; + unsigned RB = out ? UB_READBACK : 0; + int n = 0; + int readcount = count; + int r,bit; + unsigned int p=0; + +#if TRACE_JTAG + fprintf(stderr,"xfer: %08x (%d)\n", bits[count>>5], count); +#endif + while (count-- > 0) { + p=((readcount-count)-1)>>5; + if (bits[p] & 1) { + buf[n++] = UB_TDI; + buf[n++] = UB_TDI | UB_TCK | RB; + } else { + buf[n++] = 0; + buf[n++] = UB_TCK | RB; + } + bits[p] = bits[p] >> 1; + } + buf[n-1] |= UB_TMS; + buf[n-2] |= UB_TMS; + r = usb_bulk(EP2_OUT, buf, n, 1000); + if (r < 0) + return r; + if (!out) + return 0; + + unsigned B = 0; + bit = 1; + + count=readcount; + int shift=0; + while (readcount > 0) { + + r = usb_bulk(EP1_IN, buf, BUFF_SZ, 1000); + //int j; + //for(j=0;j>5; + //printf("%u",buf[n]&1); + if (buf[n] & 1) + B |= bit; + bit <<= 1; + shift++; + if(shift%32==0){ + bit=1; + out[p]= B; + //printf("out[%u]=%x\n",p, out[p]); + B=0; + + + } + readcount--; + if (readcount == 0) { +#if TRACE_JTAG + fprintf(stderr," : %08x\n", bits[p]); +#endif + out[p]= B; + //printf("out[%u]=%x\n",p, out[p]); + return 0; + } + } + } + return -1; +} + + + +/* JTAG notes + * + * TMS is sampled on +TCK + * Capture-XR state loads shift register on +TCK as state is exited + * Shift-XR state TDO goes active (containing shiftr[0]) on the first -TCK + * after entry, shifts occur on each +TCK, *including* the +TCK + * that will exist Shift-XR when TMS=1 again + * Update-XR update occurs on the -TCK after entry to state + * + * Any -> Reset: 11111 + * Any -> Reset -> RTI: 111110 + * RTI -> ShiftDR: 100 + * ShiftDR shifting: 0 x N + * ShiftDR -> UpdateDR -> RTI: 110 + * ShiftDR -> UpdateDR -> ShiftDR: 11100 + * RTI -> ShiftIR: 1100 + * ShiftIR shifting: 0 x N + * ShiftIR -> UpdateIR -> RTI: 110 + */ + +#define RESET 8,0b01111111 +#define SHIFTDR 3,0b001 +#define SHIFTIR 4,0b0011 +#define DONE 2,0b01 +#define AGAIN 4,0b0011 + +int jtag_ir(unsigned sz, unsigned bits) { + int r; + if ((r = jtag_move(SHIFTIR)) < 0) return r; + if ((r = jtag_shift(sz, bits, 0)) < 0) return r; + if ((r = jtag_move(DONE)) < 0) return r; + return 0; +} + +int jtag_dr(unsigned sz, unsigned bits, unsigned *out) { + int r; + if ((r = jtag_move(SHIFTDR)) < 0) return r; + if ((r = jtag_shift(sz, bits, out)) < 0) return r; + if ((r = jtag_move(DONE)) < 0) return r; + return 0; +} + +int jtag_dr_long(unsigned sz, unsigned * bits, unsigned *out, int words) { + int r; + //unsigned s=32; + if ((r = jtag_move(SHIFTDR)) < 0) return r; + //for(i=0;i
jtag/jtag.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/jtag.h =================================================================== --- jtag/jtag.h (nonexistent) +++ jtag/jtag.h (revision 25) @@ -0,0 +1,50 @@ +/* Copyright 2012 Brian Swetland + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _JTAG_H_ +#define _JTAG_H_ + +int jtag_open(void); +int jtag_close(void); + +/* move into RESET state */ +int jtag_reset(void); + +/* clock count times, TDI=0, TMS=bits[0], bits >>= 1 */ +int jtag_move(int count, unsigned bits); + +/* clock count-1 times, TMS=0, TDI=bits[0], bits >>= 1 + * clock 1 time, TMS=1, TDI=bits[0] + * if out, capture TDO into out + */ +int jtag_shift(int count, unsigned bits, unsigned *out); + + +/* load sz bits into IR */ +int jtag_ir(unsigned sz, unsigned bits); + +/* load sz bits into DR, capture sz bits into out if non-null */ +int jtag_dr(unsigned sz, unsigned bits, unsigned *out); +int jtag_dr_long(unsigned sz, unsigned * bits, unsigned *out, int words); + + + +/* altera virtual jtag support */ +int jtag_open_virtual_device(unsigned iid); +int jtag_vir(unsigned vir); +int jtag_vdr(unsigned sz, unsigned bits, unsigned *out); +int jtag_vdr_long(unsigned , unsigned * , unsigned *, int ); + +#endif
jtag/jtag.h Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/jtag_main =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: jtag/jtag_main =================================================================== --- jtag/jtag_main (nonexistent) +++ jtag/jtag_main (revision 25)
jtag/jtag_main Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: jtag/jtag_main.c =================================================================== --- jtag/jtag_main.c (nonexistent) +++ jtag/jtag_main.c (revision 25) @@ -0,0 +1,363 @@ +#include +#include +#include +#include +#include // getopt +#include +#include +#include "jtag.h" + + + + +#define UPDATE_WB_ADDR 0x7 +#define UPDATE_WB_WR_DATA 0x6 +#define UPDATE_WB_RD_DATA 0x5 +#define RD_WR_STATUS 0x4 + +#define BIT_NUM (word_width<<3) +#define BYTE_NUM word_width +/* Global vars */ +unsigned int index_num=126; +unsigned int word_width=4; // +unsigned int write_verify=0; +unsigned int memory_offset=0; +unsigned int memory_boundary=0xFFFFFFFF; + + + +char * binary_file_name=0; +char enable_binary_send=0; +char * write_data=0; + + + + +/* functions */ +int send_binary_file(); +void usage(); +void processArgs (int , char** ); +int send_data (); +int hexcut( char * , unsigned * , int ); +int vdr_large (unsigned , char * , char *); +void hexgen( char * , unsigned *, int ); + +int main(int argc, char **argv) { + //unsigned bits; + //unsigned int val; + + //unsigned bits; + //unsigned val; + + processArgs (argc, argv ); + printf("index num=%u\n",index_num); + if (jtag_open_virtual_device(index_num)){ + fprintf (stderr, "Error openning jtag IP with %d index num\n",index_num); + return -1; + } + if (enable_binary_send) { + if( send_binary_file() == -1) return -1; + } + + if (write_data!=0){ + printf("send %s to jtag\n",write_data); + send_data(); + + + } + + return 0; +} + + + +void usage(){ + + printf ("usage:./jtag_main [-n index number] [-i file_name][-c][-s rd/wr offset address][-d string]\n"); + + printf ("\t-n index number: the target jtag IP core index number. The default number is 126\n"); + printf ("\t-i file_name: input binary file name (.bin file)\n"); + printf ("\t-w bin file word width in byte. default is 4 bytes (32 bits)\n"); + printf ("\t-c verify after write\n"); + printf ("\t-s memory wr/rd offset address in hex. The default value is 0x0000000\n"); + printf ("\t-e memory boundary address in hex. The default value is 0xFFFFFFFF\n"); + printf ("\t-d string: use for setting instruction or data value to jtag tap. string format : \"instr1,instr2,...,instrn\"\n \tinstri = I:instruct_num: send instruct_num to instruction register \n \tD:data_size_in_bit:data : send data in hex to data register\n \tR:data_size_in_bit:data : Read data register and show it on screan then write given data in hex to data register\n"); + +} + +void processArgs (int argc, char **argv ) +{ + char c; +int p; + + /* don't want getopt to moan - I can do that just fine thanks! */ + opterr = 0; + if (argc < 2) usage(); + while ((c = getopt (argc, argv, "s:e:d:n:i:w:c")) != -1) + { + switch (c) + { + case 'n': /* index number */ + index_num = atoi(optarg); + break; + case 'i': /* input binary file name */ + binary_file_name = optarg; + enable_binary_send=1; + break; + case 'w': /* word width in byte */ + word_width= atoi(optarg); + break; + case 'c': /* word width in byte */ + write_verify= 1; + break; + case 'd': /* word width in byte */ + write_data= optarg; + break; + case 's': /* word width in byte */ + + p=sscanf(optarg,"%x",&memory_offset); + if( p==0){ + fprintf (stderr, "invalid memory offset adress format `%s'.\n", optarg); + usage(); + exit(1); + } + //printf("p=%d,memory_offset=%x\n",p,memory_offset); + break; + case 'e': /* word width in byte */ + p=sscanf(optarg,"%x",&memory_boundary); + if( p==0){ + fprintf (stderr, "invalid memory boundary adress format `%s'.\n", optarg); + usage(); + exit(1); + } + break; + + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + default: + usage(); + exit(1); + } + } +} + +unsigned * read_file (FILE * fp, unsigned int * n ){ + + unsigned * buffer; + unsigned val; + unsigned char ch; + unsigned int i=0; + char cnt=0; + unsigned int num=0; + fseek(fp, 0, SEEK_END); // seek to end of file + num = ftell(fp); // get current file pointer + *n=num;// number of bytes from the beginning of the file + num=(num/BYTE_NUM)+2; + fseek(fp, 0, SEEK_SET); + //printf ("num=%u\n",num); + buffer = (unsigned *) malloc(num * sizeof(unsigned)); //memory allocated using malloc + if(buffer == NULL) + { + printf("Error! memory not allocated."); + exit(0); + } + ch=fgetc(fp); + while(!feof(fp)){ + val<<=8; + val|=ch; + cnt++; + //printf("ch=%x\t",ch); + if(cnt==BYTE_NUM){ + //printf("%d:%x\n",i,val); + buffer[i] = val; + val=0; + cnt=0; + i++; + } + ch=fgetc(fp); + } + if( cnt>0){ + val<<=(8 *(BYTE_NUM-cnt)); + printf("%d:%x\n",i,val); + buffer[i] = val; + + } + +return buffer; + +} + + + +int send_data () +{ + char * pch; + char string[100]; + int bit=0, inst=0, d=0; + char out[100]; + pch = strtok (write_data,","); + printf("%s\n",pch); + while (pch != NULL) + { + while(1){ + d=1; + if(sscanf( pch, "D:%d:%s", &bit, string )) break; + if(sscanf( pch, "d:%d:%s", &bit, string )) break; + //if(sscanf( pch, "D:%d:" PRIx64 , &bit, &data )) break; + //if(sscanf( pch, "d:%d:%016x", &bit, &data )) break; + d=2; + if(sscanf( pch, "R:%d:%s",&bit, string)) break; + if(sscanf( pch, "r:%d:%s",&bit, string)) break; + d=0; + if(sscanf( pch, "I:%d", &inst)) break; + if(sscanf( pch, "i:%d", &inst)) break; + printf("invalid format : %s\n",pch); + return -1; + + } + if(d==1){ + //printf ("(bit=%d, data=%s)",bit, string); + //jtag_vdr(bit, data, 0); + vdr_large(bit,string,0); + }if(d==2){ + + vdr_large(bit,string,out); + printf("###read data#%s###read data#\n",out); + }else{ + + jtag_vir(inst); + //printf("%d\n",inst); + } + + pch = strtok (NULL, ","); + + } + return 0; +} + + + +int send_binary_file(){ + FILE *fp; + int i=0; + unsigned out; + unsigned int num=0; + unsigned int mem_size; + unsigned int memory_offset_in_word; + printf("send %s to the wishbone bus\n",binary_file_name); + fp = fopen(binary_file_name,"rb"); + if (!fp) { + fprintf (stderr,"Error: can not open %s file in read mode\n",binary_file_name); + return -1; + } + unsigned * buffer; + buffer=read_file (fp, &num); + mem_size=memory_boundary-memory_offset; + if(num>mem_size){ + printf("\n\n Warning: %s file size (%x) is larger than the given memory size (%x). I will stop writing on end of memory address\n\n",binary_file_name,num,mem_size); + num=mem_size; + } + fclose(fp); + //disable the cpu + jtag_vir(RD_WR_STATUS); + jtag_vdr(BIT_NUM, 0x1, &out); + //getchar(); + jtag_vir(UPDATE_WB_ADDR); + // change memory sizes from byte to word + memory_offset_in_word=memory_offset /BYTE_NUM; + num=num /BYTE_NUM; + + jtag_vdr(BIT_NUM, memory_offset_in_word, 0); + jtag_vir(UPDATE_WB_WR_DATA); + + printf ("start programing\n"); + //printf ("num=%d\n",num); + for(i=0;isize)? 0 : size-count*8; + + sscanf(hexstring+start, "%08x", &val[count-1]); + *(hexstring+start)=0; + } + + // printf("size=%d, hexnum=%u\n",size,hexnum); + + + return hexnum; +} + + +void hexgen( char * hexstring, unsigned * val, int words ){ + size_t count = 0; + sprintf(hexstring,"0x"); + for(count = 0; count < words; count++) { + if(count == 0) sprintf((hexstring+2),"%x",val[words-count-1]); + else sprintf(hexstring,"%08x",val[words-count-1]); + hexstring+=strlen(hexstring); + } + + // return hexnum; +} + +
jtag/jtag_main.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: jtag/rom.bin =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: jtag/rom.bin =================================================================== --- jtag/rom.bin (nonexistent) +++ jtag/rom.bin (revision 25)
jtag/rom.bin Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: jtag/usb-blaster-protocol.txt =================================================================== --- jtag/usb-blaster-protocol.txt (nonexistent) +++ jtag/usb-blaster-protocol.txt (revision 25) @@ -0,0 +1,60 @@ +http://sf.net/apps/mediawiki/urjtag/index.php?title=Cable_Altera_USB-Blaster +---------------------------------------------------------------------------- + +Altera USB-Blaster +------------------ + +General +------- + _________ + | | + | AT93C46 | + |_________| + __|__________ _________ + | | | | + USB__| FTDI 245BM |__| EPM7064 |__JTAG (B_TDO,B_TDI,B_TMS,B_TCK) + |_____________| |_________| + __|__________ _|___________ + | | | | + | 6 MHz XTAL | | 24 MHz Osc. | + |_____________| |_____________| + + +Quoting from ixo.de (http://www.ixo.de/info/usb_jtag/) +usb_jtag/device/c51/usbjtag.c comments: + +usb_jtag firmware now happens to behave just like the combination of +FT245BM and Altera-programmed EPM7064 CPLD in Altera's USB-Blaster. +The CPLD knows two major modes: Bit banging mode and Byte shift mode. +It starts in Bit banging mode. While bytes are received from the host +on EP2OUT, each byte B of them is processed as follows: + +Bit banging mode +---------------- +1. Remember bit 6 (0x40) in B as the "Read bit". +2. If bit 7 (0x80) is set, switch to Byte shift mode for the coming X + bytes ( X := B & 0x3F ), and don't do anything else now. +3. Otherwise, set the JTAG signals as follows: + - TCK/DCLK high if bit 0 was set (0x01), otherwise low + - TMS/nCONFIG high if bit 1 was set (0x02), otherwise low + - nCE high if bit 2 was set (0x04), otherwise low + - nCS high if bit 3 was set (0x08), otherwise low + - TDI/ASDI/DATAO high if bit 4 was set (0x10), otherwise low + - Output Enable/LED active if bit 5 was set (0x20), otherwise low +4. If "Read bit" (0x40) was set, record the state of TDO(CONF_DONE) and + DATAOUT/(nSTATUS) pins and put is as a byte( (DATAOUT<<1)|TDO) in the + output FIFO _to_ the host. + +Byte shift mode +--------------- +1. Load shift register with byte from host +2. Do 8 times (i.e. for each bit of the byte; implemented in shift.a51) + - if nCS=1, set carry bit from TDO, else set carry bit from DATAOUT + (Active Serial mode) + - Rotate shift register through carry bit + - TDI := Carry bit + - Raise TCK, then lower TCK. +3. If "Read bit" was set when switching into byte shift mode, record the + shift register content and put it into the FIFO to the host. + +
jtag/usb-blaster-protocol.txt Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.