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