вторник, 15 января 2013 г.

New Literate Programming Tool: Nano-LP

Yes, yet another and, I thing, last of my attempts. Done WiKi (on project page). Main goal is to keep input file clean and readable (not so cryptic like many other tools) with very "regualar" and simple, intuitive syntax. Main features:
  • OpenOffice/LibreOffice
  • MarkDown/MultiMarkdown
  • Creole
  • reStructuredText
  • TeX/LaTeX
  • txt2tags
  • Asciidoc
  • HTML/XML
  • ... all based on these
Utility is little Python script and supports:
  • defining command (macros) with placeholders in the body (code chunk)
  • pasting command code chunk
  • defining multiple parts code-chunks
  • joining, 'ending', etc. several code chunks
  • globbing command when paste
  • including one file to another (library)
  • auto-detecting of cycles
  • configurable via simple .INI like file
  • works with Python 2.7.x - Python 3.x
  • works with Unicode (UTF8)
TODO:
  1. Improvements of error reporting: file, line locating, (a special in OO - missed)
  2. More tests, better testing
  3. Improve Asciidoc parser
  4. Realize 1.0 beta
  5. ...

воскресенье, 13 января 2013 г.

Re-raise exceptions in Python in compatible (2to3) way

Good practice is to keep original traceback (stack-trace) when you re-raise modified exception. In Python 2 it's simple:
        try:
            return buggy()
        except Exception as x:
            cls,obj,tb = sys.exc_info()
            # modify obj OR create new the same class (cls), like here
            raise cls, SOME_ARGS, tb
In Python 3 it's simple too, but now there is a special BaseException method for this and new syntax, so:
        try:
            return buggy()
        except Exception as x:
            cls,obj,tb = sys.exc_info()
            # modify obj OR create new the same class (cls), like here
            raise cls(SOME_ARGS).with_traceback(tb)
Now to make common code compatible with Python 2 and 3 we SHOULD save it in DIFFERENT files, to avoid syntax errors when Python compile it to byte-code. For example, let's save it to 'comp2.py' and 'comp3.py'. And lets represent it as function... with signature reraise(exclass, msg, traceb). In 'comp2.py':
def reraise(exc, msg, tb):
    raise exc, msg, tb

and similar in 'comp3.py' but with with_traceback() usage. Now use it:
import sys
_PY23 = 3 if sys.version_info.major > 2 else 2
if _PY23 == 2:
    from comp2 import *
elif _PY23 == 3:
    from comp3 import *
That is it :)

понедельник, 17 декабря 2012 г.

Tags generation for ASF project

If you use Atmel Software Framework you can generate tags (with ctags|GNU Global) for your Vim/Emacs environment in such way (in Makefile):
ctags = c:/Program Files/ctags.exe
gtags = c:/global/bin/gtags.exe
sed = c:/MinGW/msys/1.0/bin/sed.exe
find = c:/MinGW/msys/1.0/bin/find.exe

GTAGS_FILES = GTAGS GPATH GRTAGS
# Global can not parse out of c:/prj/PRJ1/src
TAGS_DIRS = 'c:/Program Files/Atmel/Atmel Studio 6.0/extensions/Atmel/AVRGCC/3.3.2.31/AVRToolchain/avr32/include' \
   c:/prj/PRJ1/src/asf-3.0.1 \
   c:/prj/PRJ1/src/PRJ1

tags.files: force
 $(find) $(TAGS_DIRS) -type f -name *.S -or -name *.h -or -name *.c|$(sed) 's/c:\/prj\/PRJ1\/src/./g' >tags.files

$(GTAGS_FILES): tags.files
 $(gtags) -f tags.files

.PHONY: global_tags
global_tags: $(GTAGS_FILES)

tags: tags.files
 $(ctags) -L tags.files

.PHONY: all_tags
all_tags: tags global_tags

.PHONY: clean_tags
clean_tags:
 rm -f $(GTAGS_FILES) tags
I suppose in this example you use Windows, have MinGW (with find, sed utils). Project is located in c:\prj and has name PRJ1. To generate use targets: tags, global_tags or all_tags. tags file will be about 100 MB, Global tags files will be about 70 MB, but Global can not parse files out of source tree, so avr32/include will be missed - use ctags instead of.

Calculating timer/clock parameters (prescalers) for 'tick' generation with AVR32

Task similar to this (AVR) but for AVR32 with usage of ASF. If we need to generate ticks, we can use one of wave generation mode of AVR32 TCs. For this we need to define value of RC register and to select clock source (internal line). We use PBA line divided by 2, 8, 32, 128 dividers (so sources are TC_CLOCK_SOURCE2..5 in ASF 'terminology' - macroses :).
Here is the source of calculator of RC, divider:
#include <stdint.h>
#include <limits.h>

// max value of RC register with type uint16_t (unsigned short of AVR32 GCC)
#define MAX_RC (1<<(sizeof(uint16_t)*CHAR_BIT))
int
calc_tc_params(long *freq, long *err, uint16_t *presc, uint16_t *rc)
{
        static const long divs[] = {2, 8, 32, 128};
        static const int ndivs = sizeof divs/sizeof divs[0];
        long _err = 0, _merr = *err;
        uint16_t _rc = 0, _mrc = 0, _idiv = 0, _midiv = 0;

        for (_idiv = 0; _idiv < ndivs; _idiv++) {
                _rc = (FPBA / divs[_idiv]) / (*freq);
                _rc = (_rc==0? 1 : _rc>MAX_RC? MAX_RC : _rc);
                _err = abs((*freq) - (FPBA / divs[_idiv]) / (long)_rc);
                if (_err <= _merr) {
                        _merr = _err;
                        _midiv = _idiv;
                        _mrc = _rc;
                }
                if (!_err) break;
        }

        if (_mrc) {
                *rc = _mrc;
                *err = _merr;
                *presc = divs[_midiv];
                *freq = (FPBA / divs[_midiv]) / _mrc;
                return (1);
        } else
                return (0);
}
NOTE: FPBA is the frequency of PBA line. Inputs are:
  • freq - frequency in Hz
  • err - absolute error in Hz
Outputs are:
  • freq - real frequency for calculated params
  • err - real absolute error
  • presc - divider value (2..128)
  • rc - value for RC register to load
Timer source can be found in this way:
#define PRESC2TCSRC(PRESC) ((PRESC)==2? TC_CLOCK_SOURCE_TC2 \
                            :(PRESC)==8? TC_CLOCK_SOURCE_TC3 \
                            :(PRESC)==32? TC_CLOCK_SOURCE_TC4 \
                            :(PRESC)==128? TC_CLOCK_SOURCE_TC5 \
                            :-1)
and it's result should be used as tcclks member of tc_waveform_opt_t struct.
On success, returns 1, 0 otherwise.
For more information how to start 'ticks' generation, see ASF example TC_EXAMPLE3 of TC module.