From e6518cf1ddfc087ca25fa1494f993ce03e43e138 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 20 Nov 2016 00:04:27 -0800 Subject: [PATCH] altos/stm-vga: Implement VGA out from the STM processor Generates vsync/hsync using timers and pixel data using the SPI port. 320x240 video using 640x480 mode and a 24MHz "pixel" clock. Includes the beginings of rendering code for the frame buffer, including bitblt, solid fill and text with a 5x7 font. Signed-off-by: Keith Packard --- src/draw/5x7.bdf | 3190 +++++++++++++++++++++++++++++++++++++++++ src/draw/Makefile | 4 + src/draw/ao_blt.c | 293 ++++ src/draw/ao_draw.h | 129 ++ src/draw/ao_font.h | 138 ++ src/draw/ao_text.c | 44 + src/draw/font-convert | 138 ++ src/drivers/ao_vga.c | 363 +++++ src/drivers/ao_vga.h | 33 + src/stm-vga/Makefile | 76 + src/stm-vga/ao_demo.c | 59 + src/stm-vga/ao_pins.h | 205 +++ src/stm/Makefile.defs | 4 +- src/stm/ao_dma_stm.c | 27 +- src/stm/ao_i2c_stm.c | 3 + src/stm/ao_timer.c | 28 +- src/stm/stm32l.h | 15 +- 17 files changed, 4731 insertions(+), 18 deletions(-) create mode 100644 src/draw/5x7.bdf create mode 100644 src/draw/Makefile create mode 100644 src/draw/ao_blt.c create mode 100644 src/draw/ao_draw.h create mode 100644 src/draw/ao_font.h create mode 100644 src/draw/ao_text.c create mode 100755 src/draw/font-convert create mode 100644 src/drivers/ao_vga.c create mode 100644 src/drivers/ao_vga.h create mode 100644 src/stm-vga/Makefile create mode 100644 src/stm-vga/ao_demo.c create mode 100644 src/stm-vga/ao_pins.h diff --git a/src/draw/5x7.bdf b/src/draw/5x7.bdf new file mode 100644 index 00000000..b511f289 --- /dev/null +++ b/src/draw/5x7.bdf @@ -0,0 +1,3190 @@ +STARTFONT 2.1 +COMMENT Copyright 1991 Massachusetts Institute of Technology +COMMENT +COMMENT Permission to use, copy, modify, and distribute this software +COMMENT and its documentation for any purpose and without fee is +COMMENT hereby granted, provided that the above copyright notice +COMMENT appear in all copies and that both that copyright notice and +COMMENT this permission notice appear in supporting documentation, +COMMENT and that the name of M.I.T. not be used in advertising or +COMMENT publicity pertaining to distribution of the software without +COMMENT specific, written prior permission. M.I.T. makes no +COMMENT representations about the suitability of this software for +COMMENT any purpose. It is provided "as is" without express or +COMMENT implied warranty. +COMMENT +COMMENT M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +COMMENT INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +COMMENT FITNESS, IN NO EVENT SHALL M.I.T. BE LIABLE FOR ANY SPECIAL, +COMMENT INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +COMMENT RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +COMMENT ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +COMMENT ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +COMMENT OF THIS SOFTWARE. +COMMENT +COMMENT Author: Stephen Gildea, MIT X Consortium, June 1991 +COMMENT +FONT -Misc-Fixed-Medium-R-Normal--7-70-75-75-C-50-ISO8859-1 +SIZE 7 75 75 +FONTBOUNDINGBOX 5 7 0 -1 +STARTPROPERTIES 21 +FONTNAME_REGISTRY "" +FOUNDRY "Misc" +FAMILY_NAME "Fixed" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 7 +POINT_SIZE 70 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "C" +AVERAGE_WIDTH 50 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "1" +FONT_ASCENT 6 +FONT_DESCENT 1 +UNDERLINE_POSITION 0 +DESTINATION 1 +DEFAULT_CHAR 0 +COPYRIGHT "Copyright 1991 Massachusetts Institute of Technology" +ENDPROPERTIES +CHARS 224 +STARTCHAR C000 +ENCODING 0 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +f0 +f0 +f0 +f0 +f0 +00 +ENDCHAR +STARTCHAR C001 +ENCODING 1 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +70 +f8 +70 +20 +00 +ENDCHAR +STARTCHAR C002 +ENCODING 2 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +50 +a0 +50 +a0 +00 +ENDCHAR +STARTCHAR C003 +ENCODING 3 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +e0 +a0 +a0 +70 +20 +20 +ENDCHAR +STARTCHAR C004 +ENCODING 4 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +80 +c0 +b0 +20 +30 +20 +ENDCHAR +STARTCHAR C005 +ENCODING 5 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +80 +c0 +60 +50 +60 +50 +ENDCHAR +STARTCHAR C006 +ENCODING 6 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +c0 +30 +20 +30 +20 +ENDCHAR +STARTCHAR C007 +ENCODING 7 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C010 +ENCODING 8 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +70 +20 +00 +70 +00 +00 +ENDCHAR +STARTCHAR C011 +ENCODING 9 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +d0 +b0 +90 +20 +20 +30 +ENDCHAR +STARTCHAR C012 +ENCODING 10 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +a0 +a0 +40 +70 +20 +20 +ENDCHAR +STARTCHAR C013 +ENCODING 11 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +e0 +00 +00 +00 +ENDCHAR +STARTCHAR C014 +ENCODING 12 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +e0 +20 +20 +20 +ENDCHAR +STARTCHAR C015 +ENCODING 13 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +38 +20 +20 +20 +ENDCHAR +STARTCHAR C016 +ENCODING 14 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +38 +00 +00 +00 +ENDCHAR +STARTCHAR C017 +ENCODING 15 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +f8 +20 +20 +20 +ENDCHAR +STARTCHAR C020 +ENCODING 16 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +f8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C021 +ENCODING 17 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 6 7 0 -1 +BITMAP +00 +00 +f8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C022 +ENCODING 18 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +f8 +00 +00 +00 +ENDCHAR +STARTCHAR C023 +ENCODING 19 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +f8 +00 +00 +ENDCHAR +STARTCHAR C024 +ENCODING 20 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +f8 +00 +ENDCHAR +STARTCHAR C025 +ENCODING 21 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +38 +20 +20 +20 +ENDCHAR +STARTCHAR C026 +ENCODING 22 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +e0 +20 +20 +20 +ENDCHAR +STARTCHAR C027 +ENCODING 23 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 6 7 0 -1 +BITMAP +20 +20 +20 +f8 +00 +00 +00 +ENDCHAR +STARTCHAR C030 +ENCODING 24 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +f8 +20 +20 +20 +ENDCHAR +STARTCHAR C031 +ENCODING 25 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR C032 +ENCODING 26 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +10 +20 +40 +20 +10 +70 +00 +ENDCHAR +STARTCHAR C033 +ENCODING 27 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +10 +20 +40 +70 +00 +ENDCHAR +STARTCHAR C034 +ENCODING 28 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +50 +50 +50 +00 +ENDCHAR +STARTCHAR C035 +ENCODING 29 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +10 +70 +20 +70 +40 +00 +ENDCHAR +STARTCHAR C036 +ENCODING 30 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +30 +40 +e0 +40 +b0 +00 +ENDCHAR +STARTCHAR C037 +ENCODING 31 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR C040 +ENCODING 32 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ! +ENCODING 33 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +20 +00 +20 +00 +ENDCHAR +STARTCHAR " +ENCODING 34 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +50 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR # +ENCODING 35 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +50 +f8 +50 +f8 +50 +00 +ENDCHAR +STARTCHAR $ +ENCODING 36 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +70 +a0 +70 +28 +70 +00 +ENDCHAR +STARTCHAR % +ENCODING 37 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +90 +20 +40 +90 +10 +00 +ENDCHAR +STARTCHAR & +ENCODING 38 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +40 +a0 +40 +a0 +50 +00 +ENDCHAR +STARTCHAR ' +ENCODING 39 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +40 +80 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ( +ENCODING 40 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +40 +40 +40 +20 +00 +ENDCHAR +STARTCHAR ) +ENCODING 41 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +20 +20 +20 +40 +00 +ENDCHAR +STARTCHAR * +ENCODING 42 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +a0 +40 +e0 +40 +a0 +00 +ENDCHAR +STARTCHAR + +ENCODING 43 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +20 +f8 +20 +20 +00 +ENDCHAR +STARTCHAR , +ENCODING 44 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +60 +40 +80 +ENDCHAR +STARTCHAR - +ENCODING 45 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +f0 +00 +00 +00 +ENDCHAR +STARTCHAR . +ENCODING 46 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +60 +60 +00 +ENDCHAR +STARTCHAR / +ENCODING 47 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +10 +20 +40 +80 +00 +00 +ENDCHAR +STARTCHAR 0 +ENCODING 48 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +a0 +a0 +a0 +40 +00 +ENDCHAR +STARTCHAR 1 +ENCODING 49 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +c0 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR 2 +ENCODING 50 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +10 +20 +40 +f0 +00 +ENDCHAR +STARTCHAR 3 +ENCODING 51 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +10 +60 +10 +90 +60 +00 +ENDCHAR +STARTCHAR 4 +ENCODING 52 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +60 +a0 +f0 +20 +20 +00 +ENDCHAR +STARTCHAR 5 +ENCODING 53 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +10 +90 +60 +00 +ENDCHAR +STARTCHAR 6 +ENCODING 54 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +80 +e0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR 7 +ENCODING 55 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +10 +20 +20 +40 +40 +00 +ENDCHAR +STARTCHAR 8 +ENCODING 56 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR 9 +ENCODING 57 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +70 +10 +60 +00 +ENDCHAR +STARTCHAR : +ENCODING 58 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +60 +60 +00 +60 +60 +00 +ENDCHAR +STARTCHAR ; +ENCODING 59 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +60 +60 +00 +60 +40 +80 +ENDCHAR +STARTCHAR < +ENCODING 60 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +40 +80 +40 +20 +00 +ENDCHAR +STARTCHAR = +ENCODING 61 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +f0 +00 +f0 +00 +00 +ENDCHAR +STARTCHAR > +ENCODING 62 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +80 +40 +20 +40 +80 +00 +ENDCHAR +STARTCHAR ? +ENCODING 63 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +20 +40 +00 +40 +00 +ENDCHAR +STARTCHAR @ +ENCODING 64 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +b0 +b0 +80 +60 +00 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +90 +e0 +90 +90 +e0 +00 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +80 +80 +90 +60 +00 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +90 +90 +90 +90 +e0 +00 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +80 +00 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +80 +b0 +90 +70 +00 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +f0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +10 +10 +10 +10 +90 +60 +00 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +a0 +c0 +c0 +a0 +90 +00 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +80 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +f0 +f0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +d0 +d0 +b0 +b0 +90 +00 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +90 +90 +e0 +80 +80 +00 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +d0 +60 +10 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +90 +90 +e0 +a0 +90 +00 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +40 +20 +90 +60 +00 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +40 +00 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +60 +60 +00 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +f0 +f0 +90 +00 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +60 +60 +90 +90 +00 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +a0 +a0 +40 +40 +40 +00 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +10 +20 +40 +80 +f0 +00 +ENDCHAR +STARTCHAR [ +ENCODING 91 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +80 +80 +80 +80 +e0 +00 +ENDCHAR +STARTCHAR \ +ENCODING 92 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +80 +40 +20 +10 +00 +00 +ENDCHAR +STARTCHAR ] +ENCODING 93 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +20 +20 +20 +20 +e0 +00 +ENDCHAR +STARTCHAR ^ +ENCODING 94 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR _ +ENCODING 95 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +f0 +00 +ENDCHAR +STARTCHAR ` +ENCODING 96 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +40 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +e0 +90 +90 +e0 +00 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +60 +80 +80 +60 +00 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +10 +10 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +40 +e0 +40 +40 +00 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +90 +60 +80 +70 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +e0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +00 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +00 +20 +20 +20 +a0 +40 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +a0 +c0 +a0 +90 +00 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +a0 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +e0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +e0 +90 +90 +e0 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +90 +90 +70 +10 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +e0 +90 +80 +80 +00 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 6 7 0 -1 +BITMAP +00 +00 +70 +c0 +30 +e0 +00 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +40 +e0 +40 +40 +30 +00 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +a0 +a0 +a0 +40 +00 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +90 +f0 +f0 +00 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +60 +60 +90 +00 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +90 +50 +20 +40 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +f0 +20 +40 +f0 +00 +ENDCHAR +STARTCHAR { +ENCODING 123 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +c0 +40 +40 +20 +00 +ENDCHAR +STARTCHAR | +ENCODING 124 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +40 +40 +40 +40 +40 +00 +ENDCHAR +STARTCHAR } +ENCODING 125 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 6 7 0 -1 +BITMAP +80 +40 +60 +40 +40 +80 +00 +ENDCHAR +STARTCHAR ~ +ENCODING 126 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Blank +ENCODING 127 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C160 +ENCODING 160 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C161 +ENCODING 161 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +00 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR C162 +ENCODING 162 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +70 +a0 +a0 +70 +20 +ENDCHAR +STARTCHAR C163 +ENCODING 163 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +30 +40 +e0 +40 +b0 +00 +ENDCHAR +STARTCHAR C164 +ENCODING 164 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +88 +70 +50 +70 +88 +00 +ENDCHAR +STARTCHAR C165 +ENCODING 165 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +a0 +40 +e0 +40 +40 +00 +ENDCHAR +STARTCHAR C166 +ENCODING 166 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +20 +00 +20 +20 +00 +ENDCHAR +STARTCHAR C167 +ENCODING 167 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +30 +40 +60 +50 +30 +10 +60 +ENDCHAR +STARTCHAR C168 +ENCODING 168 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C169 +ENCODING 169 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +88 +a8 +c8 +a8 +88 +70 +ENDCHAR +STARTCHAR C170 +ENCODING 170 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +a0 +60 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C171 +ENCODING 171 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +48 +90 +48 +00 +00 +ENDCHAR +STARTCHAR C172 +ENCODING 172 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +f0 +10 +00 +00 +00 +ENDCHAR +STARTCHAR C173 +ENCODING 173 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +f0 +00 +00 +00 +ENDCHAR +STARTCHAR C174 +ENCODING 174 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +88 +e8 +c8 +c8 +88 +70 +ENDCHAR +STARTCHAR C175 +ENCODING 175 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C176 +ENCODING 176 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C177 +ENCODING 177 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +f8 +20 +20 +f8 +00 +ENDCHAR +STARTCHAR C178 +ENCODING 178 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +20 +40 +60 +00 +00 +00 +ENDCHAR +STARTCHAR C179 +ENCODING 179 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +60 +20 +60 +00 +00 +00 +ENDCHAR +STARTCHAR C180 +ENCODING 180 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C181 +ENCODING 181 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +90 +90 +e0 +80 +ENDCHAR +STARTCHAR C182 +ENCODING 182 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +d0 +d0 +50 +50 +50 +00 +ENDCHAR +STARTCHAR C183 +ENCODING 183 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +60 +60 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C184 +ENCODING 184 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +20 +40 +ENDCHAR +STARTCHAR C185 +ENCODING 185 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +60 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR C186 +ENCODING 186 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C187 +ENCODING 187 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +48 +90 +00 +00 +ENDCHAR +STARTCHAR C188 +ENCODING 188 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +80 +90 +30 +70 +10 +ENDCHAR +STARTCHAR C189 +ENCODING 189 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +80 +b0 +10 +20 +30 +ENDCHAR +STARTCHAR C190 +ENCODING 190 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +c0 +40 +d0 +30 +70 +10 +ENDCHAR +STARTCHAR C191 +ENCODING 191 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +00 +40 +80 +a0 +40 +00 +ENDCHAR +STARTCHAR Agrave +ENCODING 192 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C193 +ENCODING 193 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C194 +ENCODING 194 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C195 +ENCODING 195 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C196 +ENCODING 196 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C197 +ENCODING 197 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C198 +ENCODING 198 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +a0 +b0 +e0 +a0 +b0 +00 +ENDCHAR +STARTCHAR C199 +ENCODING 199 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +80 +80 +90 +60 +40 +ENDCHAR +STARTCHAR Egrave +ENCODING 200 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR C201 +ENCODING 201 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR C202 +ENCODING 202 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR C203 +ENCODING 203 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR C204 +ENCODING 204 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C205 +ENCODING 205 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C206 +ENCODING 206 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C207 +ENCODING 207 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C208 +ENCODING 208 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +50 +d0 +50 +50 +e0 +00 +ENDCHAR +STARTCHAR C209 +ENCODING 209 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +b0 +90 +d0 +b0 +b0 +90 +00 +ENDCHAR +STARTCHAR Ograve +ENCODING 210 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C211 +ENCODING 211 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C212 +ENCODING 212 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C213 +ENCODING 213 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C214 +ENCODING 214 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C215 +ENCODING 215 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +60 +60 +90 +00 +ENDCHAR +STARTCHAR C216 +ENCODING 216 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +b0 +b0 +d0 +d0 +e0 +00 +ENDCHAR +STARTCHAR Ugrave +ENCODING 217 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C218 +ENCODING 218 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C219 +ENCODING 219 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C220 +ENCODING 220 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C221 +ENCODING 221 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +a0 +a0 +40 +40 +40 +00 +ENDCHAR +STARTCHAR C222 +ENCODING 222 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +e0 +90 +e0 +80 +80 +00 +ENDCHAR +STARTCHAR C223 +ENCODING 223 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +e0 +90 +d0 +a0 +80 +ENDCHAR +STARTCHAR a-grave +ENCODING 224 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C225 +ENCODING 225 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C226 +ENCODING 226 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C227 +ENCODING 227 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C228 +ENCODING 228 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +00 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C229 +ENCODING 229 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +60 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C230 +ENCODING 230 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +b0 +a0 +70 +00 +ENDCHAR +STARTCHAR C231 +ENCODING 231 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +60 +80 +80 +60 +40 +ENDCHAR +STARTCHAR e-grave +ENCODING 232 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR C233 +ENCODING 233 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR C234 +ENCODING 234 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR C235 +ENCODING 235 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +00 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR C236 +ENCODING 236 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +40 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C237 +ENCODING 237 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +80 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C238 +ENCODING 238 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C239 +ENCODING 239 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +00 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C240 +ENCODING 240 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +30 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C241 +ENCODING 241 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +e0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR C242 +ENCODING 242 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C243 +ENCODING 243 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C244 +ENCODING 244 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C245 +ENCODING 245 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C246 +ENCODING 246 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C247 +ENCODING 247 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +60 +00 +f0 +00 +60 +00 +ENDCHAR +STARTCHAR C248 +ENCODING 248 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +b0 +d0 +e0 +00 +ENDCHAR +STARTCHAR C249 +ENCODING 249 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR C250 +ENCODING 250 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR C251 +ENCODING 251 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR C252 +ENCODING 252 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR C253 +ENCODING 253 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +90 +90 +50 +20 +40 +ENDCHAR +STARTCHAR C254 +ENCODING 254 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +80 +e0 +90 +90 +e0 +80 +ENDCHAR +STARTCHAR C255 +ENCODING 255 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +00 +90 +90 +50 +20 +40 +ENDCHAR +ENDFONT diff --git a/src/draw/Makefile b/src/draw/Makefile new file mode 100644 index 00000000..0a542a1f --- /dev/null +++ b/src/draw/Makefile @@ -0,0 +1,4 @@ +BDF=5x7.bdf + +ao_font.h: font-convert $(BDF) + nickle font-convert $(BDF) > $@ diff --git a/src/draw/ao_blt.c b/src/draw/ao_blt.c new file mode 100644 index 00000000..2060f007 --- /dev/null +++ b/src/draw/ao_blt.c @@ -0,0 +1,293 @@ +/* + * Copyright © 2016 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_draw.h" + +#define O 0 +#define I AO_ALLONES + +struct ao_merge_rop { + uint32_t ca1, cx1, ca2, cx2; +}; + +const struct ao_merge_rop ao_merge_rop[16] = { + {O, O, O, O}, /* clear 0x0 0 */ + {I, O, O, O}, /* and 0x1 src AND dst */ + {I, O, I, O}, /* andReverse 0x2 src AND NOT dst */ + {O, O, I, O}, /* copy 0x3 src */ + {I, I, O, O}, /* andInverted 0x4 NOT src AND dst */ + {O, I, O, O}, /* noop 0x5 dst */ + {O, I, I, O}, /* xor 0x6 src XOR dst */ + {I, I, I, O}, /* or 0x7 src OR dst */ + {I, I, I, I}, /* nor 0x8 NOT src AND NOT dst */ + {O, I, I, I}, /* equiv 0x9 NOT src XOR dst */ + {O, I, O, I}, /* invert 0xa NOT dst */ + {I, I, O, I}, /* orReverse 0xb src OR NOT dst */ + {O, O, I, I}, /* copyInverted 0xc NOT src */ + {I, O, I, I}, /* orInverted 0xd NOT src OR dst */ + {I, O, O, I}, /* nand 0xe NOT src OR NOT dst */ + {O, O, O, I}, /* set 0xf 1 */ +}; + +#define ao_do_merge_rop(src, dst) \ + (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2)) + +#define ao_do_dst_invarient_merge_rop(src) (((src) & _ca2) ^ _cx2) + +#define ao_do_mask_merge_rop(src, dst, mask) \ + (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask))) + +#define ao_dst_invarient_merge_rop() (_ca1 == 0 && _cx1 == 0) + +void +ao_blt(uint32_t *src_line, + int16_t src_stride, + int16_t src_x, + uint32_t *dst_line, + int16_t dst_stride, + int16_t dst_x, + int16_t width, + int16_t height, + uint8_t rop, + uint8_t reverse, + uint8_t upsidedown) +{ + uint32_t *src, *dst; + uint32_t _ca1, _cx1, _ca2, _cx2; + uint8_t dst_invarient; + uint32_t startmask, endmask; + int16_t nmiddle, n; + uint32_t bits1, bits; + int16_t left_shift, right_shift; + + _ca1 = ao_merge_rop[rop].ca1; + _cx1 = ao_merge_rop[rop].cx1; + _ca2 = ao_merge_rop[rop].ca2; + _cx2 = ao_merge_rop[rop].cx2; + dst_invarient = ao_dst_invarient_merge_rop(); + + if (upsidedown) { + src_line += (height - 1) * src_stride; + dst_line += (height - 1) * dst_stride; + src_stride = -src_stride; + dst_stride = -dst_stride; + } + + ao_mask_bits(dst_x, width, startmask, nmiddle, endmask); + if (reverse) { + src_line += ((src_x + width - 1) >> AO_SHIFT) + 1; + dst_line += ((dst_x + width - 1) >> AO_SHIFT) + 1; + src_x = (src_x + width - 1) & AO_MASK; + dst_x = (dst_x + width - 1) & AO_MASK; + } else { + src_line += src_x >> AO_SHIFT; + dst_line += dst_x >> AO_SHIFT; + src_x &= AO_MASK; + dst_x &= AO_MASK; + } + if (src_x == dst_x) { + while (height--) { + src = src_line; + src_line += src_stride; + dst = dst_line; + dst_line += dst_stride; + if (reverse) { + if (endmask) { + bits = *--src; + --dst; + *dst = ao_do_mask_merge_rop(bits, *dst, endmask); + } + n = nmiddle; + if (dst_invarient) { + while (n--) + *--dst = ao_do_dst_invarient_merge_rop(*--src); + } + else { + while (n--) { + bits = *--src; + --dst; + *dst = ao_do_merge_rop(bits, *dst); + } + } + if (startmask) { + bits = *--src; + --dst; + *dst = ao_do_mask_merge_rop(bits, *dst, startmask); + } + } + else { + if (startmask) { + bits = *src++; + *dst = ao_do_mask_merge_rop(bits, *dst, startmask); + dst++; + } + n = nmiddle; + if (dst_invarient) { + while (n--) + *dst++ = ao_do_dst_invarient_merge_rop(*src++); + } + else { + while (n--) { + bits = *src++; + *dst = ao_do_merge_rop(bits, *dst); + dst++; + } + } + if (endmask) { + bits = *src; + *dst = ao_do_mask_merge_rop(bits, *dst, endmask); + } + } + } + } else { + if (src_x > dst_x) { + left_shift = src_x - dst_x; + right_shift = AO_UNIT - left_shift; + } else { + right_shift = dst_x - src_x; + left_shift = AO_UNIT - right_shift; + } + while (height--) { + src = src_line; + src_line += src_stride; + dst = dst_line; + dst_line += dst_stride; + + bits1 = 0; + if (reverse) { + if (src_x < dst_x) + bits1 = *--src; + if (endmask) { + bits = ao_right(bits1, right_shift); + if (ao_right(endmask, left_shift)) { + bits1 = *--src; + bits |= ao_left(bits1, left_shift); + } + --dst; + *dst = ao_do_mask_merge_rop(bits, *dst, endmask); + } + n = nmiddle; + if (dst_invarient) { + while (n--) { + bits = ao_right(bits1, right_shift); + bits1 = *--src; + bits |= ao_left(bits1, left_shift); + --dst; + *dst = ao_do_dst_invarient_merge_rop(bits); + } + } else { + while (n--) { + bits = ao_right(bits1, right_shift); + bits1 = *--src; + bits |= ao_left(bits1, left_shift); + --dst; + *dst = ao_do_merge_rop(bits, *dst); + } + } + if (startmask) { + bits = ao_right(bits1, right_shift); + if (ao_right(startmask, left_shift)) { + bits1 = *--src; + bits |= ao_left(bits1, left_shift); + } + --dst; + *dst = ao_do_mask_merge_rop(bits, *dst, startmask); + } + } + else { + if (src_x > dst_x) + bits1 = *src++; + if (startmask) { + bits = ao_left(bits1, left_shift); + if (ao_left(startmask, right_shift)) { + bits1 = *src++; + bits |= ao_right(bits1, right_shift); + } + *dst = ao_do_mask_merge_rop(bits, *dst, startmask); + dst++; + } + n = nmiddle; + if (dst_invarient) { + while (n--) { + bits = ao_left(bits1, left_shift); + bits1 = *src++; + bits |= ao_right(bits1, right_shift); + *dst = ao_do_dst_invarient_merge_rop(bits); + dst++; + } + } + else { + while (n--) { + bits = ao_left(bits1, left_shift); + bits1 = *src++; + bits |= ao_right(bits1, right_shift); + *dst = ao_do_merge_rop(bits, *dst); + dst++; + } + } + if (endmask) { + bits = ao_left(bits1, left_shift); + if (ao_left(endmask, right_shift)) { + bits1 = *src; + bits |= ao_right(bits1, right_shift); + } + *dst = ao_do_mask_merge_rop(bits, *dst, endmask); + } + } + } + } +} + +void +ao_solid(uint32_t and, + uint32_t xor, + uint32_t *dst, + int16_t dst_stride, + int16_t dst_x, + int16_t width, + int16_t height) +{ + uint32_t startmask, endmask; + int16_t nmiddle; + int16_t n; + + dst += dst_x >> AO_SHIFT; + dst_x &= AO_MASK; + + ao_mask_bits(dst_x, width, startmask, nmiddle, endmask); + + if (startmask) + dst_stride--; + + dst_stride -= nmiddle; + while (height--) { + if (startmask) { + *dst = ao_do_mask_rrop(*dst, and, xor, startmask); + dst++; + } + n = nmiddle; + if (!and) + while (n--) + *dst++ = xor; + else + while (n--) { + *dst = ao_do_rrop(*dst, and, xor); + dst++; + } + if (endmask) + *dst = ao_do_mask_rrop(*dst, and, xor, endmask); + dst += dst_stride; + } +} diff --git a/src/draw/ao_draw.h b/src/draw/ao_draw.h new file mode 100644 index 00000000..1ff3e748 --- /dev/null +++ b/src/draw/ao_draw.h @@ -0,0 +1,129 @@ +/* + * Copyright © 2016 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef _AO_DRAW_H_ +#define _AO_DRAW_H_ + +void +ao_blt(uint32_t *src_line, + int16_t src_stride, + int16_t src_x, + uint32_t *dst_line, + int16_t dst_stride, + int16_t dst_x, + int16_t width, + int16_t height, + uint8_t rop, + uint8_t reverse, + uint8_t upsidedown); + +void +ao_solid(uint32_t and, + uint32_t xor, + uint32_t *dst, + int16_t dst_stride, + int16_t dst_x, + int16_t width, + int16_t height); + +void +ao_text(char *string, + uint32_t *dst_line, + int16_t dst_stride, + int16_t dst_x); + +#define AO_ROP_CLEAR 0x0 +#define AO_ROP_COPY 0x3 +#define AO_ROP_SET 0xf + +#define AO_SHIFT 5 +#define AO_UNIT (1 << AO_SHIFT) +#define AO_MASK (AO_UNIT - 1) +#define AO_ALLONES ((uint32_t) -1) + +static inline uint32_t +ao_left(uint32_t bits, int16_t shift) { + return bits >> shift; +} + +static inline uint32_t +ao_right(uint32_t bits, int16_t shift) { + return bits << shift; +} + +static inline uint32_t +ao_right_mask(int16_t x) { + if ((AO_UNIT - x) & AO_MASK) + return ao_left(AO_ALLONES,(AO_UNIT - x) & AO_MASK); + else + return 0; +} + +static inline uint32_t +ao_left_mask(int16_t x) { + if (x & AO_MASK) + return ao_right(AO_ALLONES, x & AO_MASK); + else + return 0; +} + +static inline uint32_t +ao_bits_mask(int16_t x, int16_t w) { + return ao_right(AO_ALLONES, x & AO_MASK) & + ao_left(AO_ALLONES,(AO_UNIT - (x + w)) & AO_MASK); +} + +#define ao_mask_bits(x,w,l,n,r) { \ + n = (w); \ + r = ao_right_mask((x)+n); \ + l = ao_left_mask(x); \ + if (l) { \ + n -= AO_UNIT - ((x) & AO_MASK); \ + if (n < 0) { \ + n = 0; \ + l &= r; \ + r = 0; \ + } \ + } \ + n >>= AO_SHIFT; \ +} + +static inline uint32_t +ao_do_mask_rrop(uint32_t dst, uint32_t and, uint32_t xor, uint32_t mask) { + return (dst & (and | ~mask)) ^ (xor & mask); +} + +static inline uint32_t +ao_do_rrop(uint32_t dst, uint32_t and, uint32_t xor) { + return (dst & and) ^ xor; +} + +#define AO_CLEAR 0x0 /* 0 */ +#define AO_AND 0x1 /* src AND dst */ +#define AO_AND_REVERSE 0x2 /* src AND NOT dst */ +#define AO_COPY 0x3 /* src */ +#define AO_AND_INVERTED 0x4 /* NOT src AND dst */ +#define AO_NOOP 0x5 /* dst */ +#define AO_XOR 0x6 /* src XOR dst */ +#define AO_OR 0x7 /* src OR dst */ +#define AO_NOR 0x8 /* NOT src AND NOT dst */ +#define AO_EQUIV 0x9 /* NOT src XOR dst */ +#define AO_INVERT 0xa /* NOT dst */ +#define AO_OR_REVERSE 0xb /* src OR NOT dst */ +#define AO_COPY_INVERTED 0xc /* NOT src */ +#define AO_OR_INVERTED 0xd /* NOT src OR dst */ +#define AO_NAND 0xe /* NOT src OR NOT dst */ +#define AO_SET 0xf /* 1 */ + +#endif /* _AO_DRAW_H_ */ diff --git a/src/draw/ao_font.h b/src/draw/ao_font.h new file mode 100644 index 00000000..ac424ef9 --- /dev/null +++ b/src/draw/ao_font.h @@ -0,0 +1,138 @@ +static uint8_t glyph_bytes[] = { + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x04, 0x0e, 0x1f, 0x0e, 0x04, 0x00, 0x0a, 0x05, + 0x0a, 0x05, 0x0a, 0x05, 0x00, 0x05, 0x07, 0x05, 0x05, 0x0e, 0x04, 0x04, 0x03, 0x01, 0x03, 0x0d, + 0x04, 0x0c, 0x04, 0x03, 0x01, 0x03, 0x06, 0x0a, 0x06, 0x0a, 0x01, 0x01, 0x03, 0x0c, 0x04, 0x0c, + 0x04, 0x04, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0e, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x09, + 0x0b, 0x0d, 0x09, 0x04, 0x04, 0x0c, 0x05, 0x05, 0x05, 0x02, 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x04, + 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0x00, 0x04, 0x04, 0x04, 0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x02, 0x04, 0x08, 0x0e, 0x00, 0x02, 0x04, 0x08, + 0x04, 0x02, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x08, 0x0e, 0x04, 0x0e, + 0x02, 0x00, 0x00, 0x0c, 0x02, 0x07, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, 0x0a, 0x0a, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x00, 0x00, 0x0e, 0x05, 0x0e, + 0x14, 0x0e, 0x00, 0x01, 0x09, 0x04, 0x02, 0x09, 0x08, 0x00, 0x00, 0x02, 0x05, 0x02, 0x05, 0x0a, + 0x00, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x04, 0x00, 0x02, + 0x04, 0x04, 0x04, 0x04, 0x02, 0x00, 0x00, 0x05, 0x02, 0x07, 0x02, 0x05, 0x00, 0x00, 0x04, 0x04, + 0x1f, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, + 0x02, 0x05, 0x05, 0x05, 0x05, 0x02, 0x00, 0x02, 0x03, 0x02, 0x02, 0x02, 0x07, 0x00, 0x06, 0x09, + 0x08, 0x04, 0x02, 0x0f, 0x00, 0x0f, 0x08, 0x06, 0x08, 0x09, 0x06, 0x00, 0x04, 0x06, 0x05, 0x0f, + 0x04, 0x04, 0x00, 0x0f, 0x01, 0x07, 0x08, 0x09, 0x06, 0x00, 0x06, 0x01, 0x07, 0x09, 0x09, 0x06, + 0x00, 0x0f, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x06, 0x09, 0x06, 0x09, 0x09, 0x06, 0x00, 0x06, + 0x09, 0x09, 0x0e, 0x08, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, + 0x00, 0x06, 0x02, 0x01, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x02, 0x01, 0x00, 0x02, 0x05, 0x04, 0x02, 0x00, 0x02, 0x00, + 0x06, 0x09, 0x0d, 0x0d, 0x01, 0x06, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x07, 0x09, + 0x07, 0x09, 0x09, 0x07, 0x00, 0x06, 0x09, 0x01, 0x01, 0x09, 0x06, 0x00, 0x07, 0x09, 0x09, 0x09, + 0x09, 0x07, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x01, + 0x00, 0x06, 0x09, 0x01, 0x0d, 0x09, 0x0e, 0x00, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x09, 0x00, 0x07, + 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06, 0x00, 0x09, 0x05, 0x03, + 0x03, 0x05, 0x09, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x00, 0x09, 0x0f, 0x0f, 0x09, 0x09, + 0x09, 0x00, 0x09, 0x0b, 0x0b, 0x0d, 0x0d, 0x09, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, + 0x07, 0x09, 0x09, 0x07, 0x01, 0x01, 0x00, 0x06, 0x09, 0x09, 0x09, 0x0b, 0x06, 0x08, 0x07, 0x09, + 0x09, 0x07, 0x05, 0x09, 0x00, 0x06, 0x09, 0x02, 0x04, 0x09, 0x06, 0x00, 0x07, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x06, 0x06, + 0x00, 0x09, 0x09, 0x09, 0x0f, 0x0f, 0x09, 0x00, 0x09, 0x09, 0x06, 0x06, 0x09, 0x09, 0x00, 0x05, + 0x05, 0x05, 0x02, 0x02, 0x02, 0x00, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x0f, 0x00, 0x07, 0x01, 0x01, + 0x01, 0x01, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, + 0x07, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x03, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x01, 0x01, + 0x07, 0x09, 0x09, 0x07, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x08, 0x08, 0x0e, 0x09, + 0x09, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x04, 0x0a, 0x02, 0x07, 0x02, 0x02, + 0x00, 0x00, 0x00, 0x0e, 0x09, 0x06, 0x01, 0x0e, 0x01, 0x01, 0x07, 0x09, 0x09, 0x09, 0x00, 0x02, + 0x00, 0x03, 0x02, 0x02, 0x07, 0x00, 0x04, 0x00, 0x04, 0x04, 0x04, 0x05, 0x02, 0x01, 0x01, 0x05, + 0x03, 0x05, 0x09, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x00, 0x00, 0x05, 0x0f, 0x09, + 0x09, 0x00, 0x00, 0x00, 0x07, 0x09, 0x09, 0x09, 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x06, 0x00, + 0x00, 0x00, 0x07, 0x09, 0x09, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x09, 0x09, 0x0e, 0x08, 0x00, 0x00, + 0x07, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x03, 0x0c, 0x07, 0x00, 0x02, 0x02, 0x07, 0x02, + 0x02, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x05, 0x05, 0x02, + 0x00, 0x00, 0x00, 0x09, 0x09, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x06, 0x06, 0x09, 0x00, 0x00, + 0x00, 0x09, 0x09, 0x0a, 0x04, 0x02, 0x00, 0x00, 0x0f, 0x04, 0x02, 0x0f, 0x00, 0x04, 0x02, 0x03, + 0x02, 0x02, 0x04, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x06, 0x02, 0x02, + 0x01, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x04, + 0x0e, 0x05, 0x05, 0x0e, 0x04, 0x00, 0x0c, 0x02, 0x07, 0x02, 0x0d, 0x00, 0x00, 0x11, 0x0e, 0x0a, + 0x0e, 0x11, 0x00, 0x05, 0x05, 0x02, 0x07, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, + 0x00, 0x0c, 0x02, 0x06, 0x0a, 0x0c, 0x08, 0x06, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x11, 0x15, 0x13, 0x15, 0x11, 0x0e, 0x06, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x09, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x0e, 0x11, 0x17, 0x13, 0x13, 0x11, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x1f, 0x00, 0x06, 0x04, + 0x02, 0x06, 0x00, 0x00, 0x00, 0x06, 0x06, 0x04, 0x06, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x07, 0x01, 0x0e, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x04, + 0x06, 0x04, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x12, 0x09, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x0c, 0x0e, 0x08, 0x01, 0x01, 0x01, 0x0d, 0x08, + 0x04, 0x0c, 0x03, 0x03, 0x02, 0x0b, 0x0c, 0x0e, 0x08, 0x02, 0x00, 0x02, 0x01, 0x05, 0x02, 0x00, + 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, + 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, + 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x0e, 0x05, 0x0d, 0x07, 0x05, 0x0d, + 0x00, 0x06, 0x09, 0x01, 0x01, 0x09, 0x06, 0x02, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, + 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07, + 0x01, 0x01, 0x0f, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, + 0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, + 0x07, 0x0a, 0x0b, 0x0a, 0x0a, 0x07, 0x00, 0x0d, 0x09, 0x0b, 0x0d, 0x0d, 0x09, 0x00, 0x06, 0x09, + 0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, + 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, + 0x00, 0x00, 0x00, 0x09, 0x06, 0x06, 0x09, 0x00, 0x0e, 0x0d, 0x0d, 0x0b, 0x0b, 0x07, 0x00, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x05, 0x05, 0x05, 0x02, 0x02, + 0x02, 0x00, 0x01, 0x07, 0x09, 0x07, 0x01, 0x01, 0x00, 0x06, 0x09, 0x07, 0x09, 0x0b, 0x05, 0x01, + 0x02, 0x04, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x04, 0x02, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x04, 0x0a, + 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x0a, 0x05, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x0a, 0x00, 0x0e, 0x09, + 0x0d, 0x0a, 0x00, 0x06, 0x06, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0x0d, 0x05, 0x0e, + 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x02, 0x02, 0x04, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x04, + 0x02, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x02, 0x05, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x05, 0x00, 0x06, + 0x0d, 0x03, 0x06, 0x00, 0x01, 0x02, 0x03, 0x02, 0x02, 0x07, 0x00, 0x02, 0x01, 0x03, 0x02, 0x02, + 0x07, 0x00, 0x02, 0x05, 0x03, 0x02, 0x02, 0x07, 0x00, 0x05, 0x00, 0x03, 0x02, 0x02, 0x07, 0x00, + 0x02, 0x0c, 0x06, 0x09, 0x09, 0x06, 0x00, 0x0a, 0x05, 0x07, 0x09, 0x09, 0x09, 0x00, 0x02, 0x04, + 0x06, 0x09, 0x09, 0x06, 0x00, 0x04, 0x02, 0x06, 0x09, 0x09, 0x06, 0x00, 0x06, 0x00, 0x06, 0x09, + 0x09, 0x06, 0x00, 0x0a, 0x05, 0x06, 0x09, 0x09, 0x06, 0x00, 0x05, 0x00, 0x06, 0x09, 0x09, 0x06, + 0x00, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x0d, 0x0b, 0x07, 0x00, 0x02, + 0x04, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x04, 0x02, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x06, 0x00, 0x09, + 0x09, 0x09, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x04, 0x02, 0x09, 0x09, 0x0a, + 0x04, 0x02, 0x00, 0x01, 0x07, 0x09, 0x09, 0x07, 0x01, 0x0a, 0x00, 0x09, 0x09, 0x0a, 0x04, 0x02, +}; + +static uint16_t glyph_pos[] = { + 0, 7, 14, 21, 28, 35, 42, 49, + 56, 63, 70, 77, 84, 91, 98, 105, + 112, 119, 126, 133, 140, 147, 154, 161, + 168, 175, 182, 189, 196, 203, 210, 217, + 224, 231, 238, 245, 252, 259, 266, 273, + 280, 287, 294, 301, 308, 315, 322, 329, + 336, 343, 350, 357, 364, 371, 378, 385, + 392, 399, 406, 413, 420, 427, 434, 441, + 448, 455, 462, 469, 476, 483, 490, 497, + 504, 511, 518, 525, 532, 539, 546, 553, + 560, 567, 574, 581, 588, 595, 602, 609, + 616, 623, 630, 637, 644, 651, 658, 665, + 672, 679, 686, 693, 700, 707, 714, 721, + 728, 735, 742, 749, 756, 763, 770, 777, + 784, 791, 798, 805, 812, 819, 826, 833, + 840, 847, 854, 861, 868, 875, 882, 889, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 896, 903, 910, 917, 924, 931, 938, 945, + 952, 959, 966, 973, 980, 987, 994, 1001, + 1008, 1015, 1022, 1029, 1036, 1043, 1050, 1057, + 1064, 1071, 1078, 1085, 1092, 1099, 1106, 1113, + 1120, 1127, 1134, 1141, 1148, 1155, 1162, 1169, + 1176, 1183, 1190, 1197, 1204, 1211, 1218, 1225, + 1232, 1239, 1246, 1253, 1260, 1267, 1274, 1281, + 1288, 1295, 1302, 1309, 1316, 1323, 1330, 1337, + 1344, 1351, 1358, 1365, 1372, 1379, 1386, 1393, + 1400, 1407, 1414, 1421, 1428, 1435, 1442, 1449, + 1456, 1463, 1470, 1477, 1484, 1491, 1498, 1505, + 1512, 1519, 1526, 1533, 1540, 1547, 1554, 1561, +}; + +#define GLYPH_WIDTH 5 +#define GLYPH_HEIGHT 7 diff --git a/src/draw/ao_text.c b/src/draw/ao_text.c new file mode 100644 index 00000000..68d6c2cf --- /dev/null +++ b/src/draw/ao_text.c @@ -0,0 +1,44 @@ +/* + * Copyright © 2016 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_font.h" + +void +ao_text(char *string, + uint32_t *dst_line, + int16_t dst_stride, + int16_t dst_x) +{ + char c; + uint32_t src[GLYPH_HEIGHT]; + + while ((c = *string++)) { + uint8_t *bytes = &glyph_bytes[glyph_pos[(uint8_t) c]]; + int h; + + for (h = 0; h < GLYPH_HEIGHT; h++) + src[h] = bytes[h]; + + ao_blt(src, 1, 0, + dst_line, dst_stride, + dst_x, + GLYPH_WIDTH, + GLYPH_HEIGHT, + AO_AND_INVERTED, + 0, 0); + dst_x += GLYPH_WIDTH; + } +} diff --git a/src/draw/font-convert b/src/draw/font-convert new file mode 100755 index 00000000..2446592b --- /dev/null +++ b/src/draw/font-convert @@ -0,0 +1,138 @@ +#!/usr/bin/nickle + +typedef struct { + int[] bytes; + int width; + int height; + int encoding; + int location; +} glyph_t; + +typedef struct { + glyph_t[...] glyphs; + int default_char; +} font_t; + +glyph_t +read_glyph(file f) +{ + glyph_t glyph = { .encoding = -1, .bytes = (int[...]){}, .width = 0 }; + + while (!File::end(f)) { + string l = fgets(f); + + string[*] tokens = String::split(l, " "); + if (dim(tokens) == 0) + continue; + + switch (tokens[0]) { + case "ENCODING": + glyph.encoding = atoi(tokens[1]); + break; + case "BBX": + glyph.width = atoi(tokens[1]); + glyph.height = atoi(tokens[2]); + break; + case "ENDCHAR": + return glyph; + case "BITMAP": + while (!File::end(f)) { + string l = fgets(f); + if (l == "ENDCHAR") + return glyph; + glyph.bytes[dim(glyph.bytes)] = atoi(l, 16); + } + break; + } + } + return glyph; +} + +font_t read_font(file f) { + font_t font = { .glyphs = {}, .default_char = -1 }; + + while (!File::end(f)) { + string l = File::fgets(f); + + string[*] tokens = String::split(l, " "); + if (tokens[0] == "DEFAULT_CHAR") + font.default_char = atoi(tokens[1]); + if (tokens[0] == "CHARS") + break; + } + while (!File::end(f)) { + glyph_t glyph = read_glyph(f); + if (glyph.encoding == -1) + break; + font.glyphs[dim(font.glyphs)] = glyph; + } + return font; +} + +int +flip_byte(int x) +{ + int dest = 0; + + for (int i = 0; i < 8; i++) + dest |= ((x >> (7 - i)) & 1) << i; + return dest; +} + +void print_font(font_t font) { + int width = font.glyphs[0].width; + int height = font.glyphs[0].height; + int[256] pos = { -1 ... }; + int[...] bytes; + + if (false) { + for (int i = 1; i < dim(font.glyphs); i++) { + if (font.glyphs[i].width != width || + font.glyphs[i].height != height) + { + File::fprintf(stderr, "font not constant size, glyph %d is %dx%d\n", + font.glyphs[i].encoding, font.glyphs[i].width, font.glyphs[i].height); + exit(1); + } + } + } + + if (font.default_char == -1) + font.default_char = font.glyphs[0].encoding; + + /* build byte array */ + for (int i = 0; i < dim(font.glyphs); i++) { + pos[font.glyphs[i].encoding] = dim(bytes); + for (int b = 0; b < dim(font.glyphs[i].bytes); b++) + bytes[dim(bytes)] = font.glyphs[i].bytes[b]; + } + + /* Fill in default glyph */ + for (int i = 0; i < dim(pos); i++) + if (pos[i] == -1) + pos[i] = pos[font.default_char]; + + printf("static uint8_t glyph_bytes[] = {"); + for (int b = 0; b < dim(bytes); b++) { + if ((b & 15) == 0) + printf("\n\t"); + printf("0x%02x, ", flip_byte(bytes[b])); + } + printf("\n};\n\n"); + + printf("static uint16_t glyph_pos[] = {"); + for (int i = 0; i < dim(pos); i++) { + if ((i & 7) == 0) + printf("\n\t"); + printf("%4d, ", pos[i]); + } + printf("\n};\n\n"); + + printf("#define GLYPH_WIDTH %d\n", width); + printf("#define GLYPH_HEIGHT %d\n", height); +} + +twixt (file f = File::open(argv[1], "r"); File::close(f)) { + font_t font = read_font(f); + print_font(font); +} diff --git a/src/drivers/ao_vga.c b/src/drivers/ao_vga.c new file mode 100644 index 00000000..24a645c7 --- /dev/null +++ b/src/drivers/ao_vga.c @@ -0,0 +1,363 @@ +/* + * Copyright © 2016 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_vga.h" + +/* VGA output from the SPI port */ + +struct ao_modeline { + long dot_clock; /* in Hz */ + + /* All timings are in pixels, with the first pixel out at 0,0 */ + int hactive; /* active pixels */ + int hsync_start; /* start of hsync pulse */ + int hsync_end; /* end of hsync pulse */ + int htotal; /* total h pixels */ + + int vactive; /* active scalines */ + int vsync_start; /* start of vsync pulse */ + int vsync_end; /* end of vsync pulse */ + int vtotal; /* total scanlines */ +}; + +const struct ao_modeline vga_640x480x60 = { + .dot_clock = 23856000, /* 23.86MHz dot, 29.82kHz line, 60.00Hz frame */ + + .hactive = 640, + .hsync_start = 656, + .hsync_end = 720, + .htotal = 800, + + .vactive = 480, + .vsync_start = 481, + .vsync_end = 484, + .vtotal = 497 +}; + +const struct ao_modeline vga_640x480x30 = { + .dot_clock = 120000000, /* 12.00MHz dot, 29.82kHz line, 30.00Hz frame */ + + .hactive = 640, + .hsync_start = 656, + .hsync_end = 720, + .htotal = 800, + + .vactive = 480, + .vsync_start = 481, + .vsync_end = 484, + .vtotal = 497 +}; + +#define mode vga_640x480x60 + +#define WIDTH_BYTES (AO_VGA_WIDTH >> 3) +#define SCANOUT ((WIDTH_BYTES + 2) >> 1) + +uint32_t ao_vga_fb[AO_VGA_STRIDE * AO_VGA_HEIGHT]; + +static uint32_t *scanline; + +#define DMA_INDEX STM_DMA_INDEX(STM_DMA_CHANNEL_SPI2_TX) + +static int line; +static int vblank; + +#define DMA_CCR(en) ((0 << STM_DMA_CCR_MEM2MEM) | \ + (STM_DMA_CCR_PL_VERY_HIGH << STM_DMA_CCR_PL) | \ + (STM_DMA_CCR_MSIZE_16 << STM_DMA_CCR_MSIZE) | \ + (STM_DMA_CCR_PSIZE_16 << STM_DMA_CCR_PSIZE) | \ + (1 << STM_DMA_CCR_MINC) | \ + (0 << STM_DMA_CCR_PINC) | \ + (0 << STM_DMA_CCR_CIRC) | \ + (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR) | \ + (0 << STM_DMA_CCR_TCIE) | \ + (en << STM_DMA_CCR_EN)) + +int vblank_off = 13; + +void stm_tim2_isr(void) +{ + ao_arch_block_interrupts(); + if (!vblank) { + /* Disable */ + stm_dma.channel[DMA_INDEX].ccr = DMA_CCR(0); + /* Reset DMA engine for the next scanline */ + stm_dma.channel[DMA_INDEX].cndtr = SCANOUT; + /* Enable */ + stm_dma.channel[DMA_INDEX].ccr = DMA_CCR(1); + } + stm_tim2.sr = ~(1 << STM_TIM234_SR_CC2IF); + line = stm_tim3.cnt; + if (vblank_off <= line && line < (AO_VGA_HEIGHT << 1) + vblank_off + 12) { + vblank = 0; + if ((line - vblank_off) & 1) + scanline += AO_VGA_STRIDE; + } else { + scanline = ao_vga_fb; + vblank = 1; + } + stm_dma.channel[DMA_INDEX].cmar = scanline; + ao_arch_release_interrupts(); +} + +static void +ao_vga_fb_init(void) +{ + ao_solid(0x0, AO_ALLONES, + ao_vga_fb, + AO_VGA_STRIDE, + 0, + AO_VGA_WIDTH, + AO_VGA_HEIGHT); + + ao_solid(0x0, 0x0, + ao_vga_fb + 10 * AO_VGA_STRIDE, + AO_VGA_STRIDE, + 10, + 10, + 10); + + + ao_solid(0x0, 0x0, + ao_vga_fb + 220 * AO_VGA_STRIDE, + AO_VGA_STRIDE, + 10, + 10, + 10); + + ao_solid(0x0, 0x0, + ao_vga_fb + 10 * AO_VGA_STRIDE, + AO_VGA_STRIDE, + 220, + 10, + 10); + + ao_solid(0x0, 0x0, + ao_vga_fb + 220 * AO_VGA_STRIDE, + AO_VGA_STRIDE, + 220, + 10, + 10); + + ao_text("Hello, Bdale!", + ao_vga_fb + 100 * AO_VGA_STRIDE, + AO_VGA_STRIDE, + 20); + + ao_text("UL", + ao_vga_fb, + AO_VGA_STRIDE, + 0); + + ao_text("BL", + ao_vga_fb + (240 - 7) * AO_VGA_STRIDE, + AO_VGA_STRIDE, + 0); +} + +void +ao_vga_init(void) +{ + /* Initialize spi2 using PB15 for output */ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); + + stm_ospeedr_set(&stm_gpiob, 15, STM_OSPEEDR_40MHz); + stm_afr_set(&stm_gpiob, 15, STM_AFR_AF5); + + /* turn on SPI */ + stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN); + + stm_spi2.cr1 = ((1 << STM_SPI_CR1_BIDIMODE) | /* Two wire mode */ + (1 << STM_SPI_CR1_BIDIOE) | + (0 << STM_SPI_CR1_CRCEN) | /* CRC disabled */ + (0 << STM_SPI_CR1_CRCNEXT) | + (1 << STM_SPI_CR1_DFF) | + (0 << STM_SPI_CR1_RXONLY) | + (1 << STM_SPI_CR1_SSM) | /* Software SS handling */ + (1 << STM_SPI_CR1_SSI) | /* ... */ + (1 << STM_SPI_CR1_LSBFIRST) | /* Little endian */ + (1 << STM_SPI_CR1_SPE) | /* Enable SPI unit */ + (0 << STM_SPI_CR1_BR) | /* baud rate to pclk/2 */ + (1 << STM_SPI_CR1_MSTR) | + (0 << STM_SPI_CR1_CPOL) | /* Format 0 */ + (0 << STM_SPI_CR1_CPHA)); + stm_spi2.cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (1 << STM_SPI_CR2_TXDMAEN) | + (0 << STM_SPI_CR2_RXDMAEN)); + + (void) stm_spi2.dr; + (void) stm_spi2.sr; + + /* Grab the DMA channel for SPI2 MOSI */ + stm_dma.channel[DMA_INDEX].cpar = &stm_spi2.dr; + stm_dma.channel[DMA_INDEX].cmar = ao_vga_fb; + + /* hclock on timer 2 */ + + /* Turn on timer 2 */ + stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM2EN); + + /* Turn on GPIOA */ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); + + stm_tim2.psc = 0; + + /* Disable channels while modifying */ + stm_tim2.ccer = 0; + + /* Channel 1 hsync PWM values */ + stm_tim2.ccr1 = mode.hsync_end - mode.hsync_start; + + /* Channel 2 trigger scanout */ + /* wait for the time to start scanout */ + stm_tim2.ccr2 = 90; + + stm_tim2.ccmr1 = ((0 << STM_TIM234_CCMR1_OC2CE) | + (STM_TIM234_CCMR1_OC2M_SET_HIGH_ON_MATCH << STM_TIM234_CCMR1_OC2M) | + (1 << STM_TIM234_CCMR1_OC2PE) | + (0 << STM_TIM234_CCMR1_OC2FE) | + + (0 << STM_TIM234_CCMR1_OC1CE) | + (STM_TIM234_CCMR1_OC1M_PWM_MODE_1 << STM_TIM234_CCMR1_OC1M) | + (1 << STM_TIM234_CCMR1_OC1PE) | + (0 << STM_TIM234_CCMR1_OC1FE) | + (STM_TIM234_CCMR1_CC1S_OUTPUT << STM_TIM234_CCMR1_CC1S)); + + stm_tim2.arr = mode.htotal; + stm_tim2.cnt = 0; + + /* Update the register contents */ + stm_tim2.egr |= (1 << STM_TIM234_EGR_UG); + + /* Enable the timer */ + + /* Enable the output */ + stm_tim2.ccer = ((0 << STM_TIM234_CCER_CC1NP) | + (STM_TIM234_CCER_CC1P_ACTIVE_LOW << STM_TIM234_CCER_CC1P) | + (1 << STM_TIM234_CCER_CC1E)); + + stm_tim2.cr2 = ((0 << STM_TIM234_CR2_TI1S) | + (STM_TIM234_CR2_MMS_UPDATE << STM_TIM234_CR2_MMS) | + (0 << STM_TIM234_CR2_CCDS)); + + stm_tim2.smcr = 0; + + stm_tim2.dier = ((1 << STM_TIM234_DIER_CC2IE)); + + stm_tim2.cr1 = ((STM_TIM234_CR1_CKD_1 << STM_TIM234_CR1_CKD) | + (1 << STM_TIM234_CR1_ARPE) | + (STM_TIM234_CR1_CMS_EDGE << STM_TIM234_CR1_CMS) | + (STM_TIM234_CR1_DIR_UP << STM_TIM234_CR1_DIR) | + (0 << STM_TIM234_CR1_OPM) | + (1 << STM_TIM234_CR1_URS) | + (0 << STM_TIM234_CR1_UDIS) | + (0 << STM_TIM234_CR1_CEN)); + + /* Configure pins */ + + /* PA5 is Timer 2 CH1 output */ + stm_ospeedr_set(&stm_gpioa, 5, STM_OSPEEDR_40MHz); + stm_afr_set(&stm_gpioa, 5, STM_AFR_AF1); + + /* Turn on timer 3, slaved to timer 1 using ITR1 (table 61) */ + + /* Use CH1 on PB6 (AF2) */ + + stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM3EN); + + /* Turn on GPIOB */ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); + + /* No prescale */ + stm_tim3.psc = 0; + + /* Channel 1 vsync PWM values */ + stm_tim3.ccr1 = mode.vsync_end - mode.vsync_start; + stm_tim3.ccmr1 = ((0 << STM_TIM234_CCMR1_OC2CE) | + (0 << STM_TIM234_CCMR1_OC2PE) | + (0 << STM_TIM234_CCMR1_OC2FE) | + + (0 << STM_TIM234_CCMR1_OC1CE) | + (STM_TIM234_CCMR1_OC1M_PWM_MODE_1 << STM_TIM234_CCMR1_OC1M) | + (1 << STM_TIM234_CCMR1_OC1PE) | + (0 << STM_TIM234_CCMR1_OC1FE) | + (STM_TIM234_CCMR1_CC1S_OUTPUT << STM_TIM234_CCMR1_CC1S)); + + stm_tim3.arr = mode.vtotal; + stm_tim3.cnt = 0; + + /* Update the register contents */ + stm_tim3.egr |= (1 << STM_TIM234_EGR_UG); + + /* Enable the timer */ + + /* Enable the output */ + stm_tim3.ccer = ((0 << STM_TIM234_CCER_CC1NP) | + (STM_TIM234_CCER_CC1P_ACTIVE_LOW << STM_TIM234_CCER_CC1P) | + (1 << STM_TIM234_CCER_CC1E)); + + stm_tim3.cr2 = ((0 << STM_TIM234_CR2_TI1S) | + (STM_TIM234_CR2_MMS_UPDATE << STM_TIM234_CR2_MMS) | + (0 << STM_TIM234_CR2_CCDS)); + + stm_tim3.smcr = 0; + stm_tim3.smcr = ((0 << STM_TIM234_SMCR_ETP) | + (0 << STM_TIM234_SMCR_ECE) | + (STM_TIM234_SMCR_ETPS_OFF << STM_TIM234_SMCR_ETPS) | + (STM_TIM234_SMCR_ETF_NONE << STM_TIM234_SMCR_ETF) | + (0 << STM_TIM234_SMCR_MSM) | + (STM_TIM234_SMCR_TS_ITR1 << STM_TIM234_SMCR_TS) | + (0 << STM_TIM234_SMCR_OCCS) | + (STM_TIM234_SMCR_SMS_EXTERNAL_CLOCK << STM_TIM234_SMCR_SMS)); + + stm_tim3.dier = 0; + + stm_tim3.cr1 = ((STM_TIM234_CR1_CKD_1 << STM_TIM234_CR1_CKD) | + (1 << STM_TIM234_CR1_ARPE) | + (STM_TIM234_CR1_CMS_EDGE << STM_TIM234_CR1_CMS) | + (STM_TIM234_CR1_DIR_UP << STM_TIM234_CR1_DIR) | + (0 << STM_TIM234_CR1_OPM) | + (1 << STM_TIM234_CR1_URS) | + (0 << STM_TIM234_CR1_UDIS) | + (1 << STM_TIM234_CR1_CEN)); + + /* Configure pins */ + + /* PB4 is Timer 3 CH1 output */ + stm_ospeedr_set(&stm_gpiob, 4, STM_OSPEEDR_40MHz); + stm_afr_set(&stm_gpiob, 4, STM_AFR_AF2); + + + /* Enable the scanline interrupt */ + stm_nvic_set_priority(STM_ISR_TIM2_POS, 0); + stm_nvic_set_enable(STM_ISR_TIM2_POS); +} + +void +ao_vga_enable(int enable) +{ + if (enable) { + vblank_off = enable; + ao_vga_fb_init(); + stm_tim2.cr1 |= (1 << STM_TIM234_CR1_CEN); + stm_systick.csr &= ~(1 << STM_SYSTICK_CSR_ENABLE); + } else { + stm_tim2.cr1 &= ~(1 << STM_TIM234_CR1_CEN); + stm_systick.csr |= (1 << STM_SYSTICK_CSR_ENABLE); + } +} diff --git a/src/drivers/ao_vga.h b/src/drivers/ao_vga.h new file mode 100644 index 00000000..caec8f48 --- /dev/null +++ b/src/drivers/ao_vga.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2016 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef _AO_VGA_H_ +#define _AO_VGA_H_ + +#include "ao_draw.h" + +void +ao_vga_init(void); + +void +ao_vga_enable(int active); + +#define AO_VGA_WIDTH 320 +#define AO_VGA_HEIGHT 240 +#define AO_VGA_PAD 64 +#define AO_VGA_STRIDE ((AO_VGA_WIDTH + AO_VGA_PAD) >> AO_SHIFT) + +extern uint32_t ao_vga_fb[AO_VGA_STRIDE * AO_VGA_HEIGHT]; + +#endif /* _AO_VGA_H_ */ diff --git a/src/stm-vga/Makefile b/src/stm-vga/Makefile new file mode 100644 index 00000000..5db8c641 --- /dev/null +++ b/src/stm-vga/Makefile @@ -0,0 +1,76 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_boot.h \ + ao_pins.h \ + ao_product.h \ + ao_vga.h \ + ao_draw.h \ + ao_font.h + +# +# Common AltOS sources +# +ALTOS_SRC = \ + ao_interrupt.c \ + ao_boot_chain.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_task.c \ + ao_led.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer.c \ + ao_lcd_stm.c \ + ao_lcd_font.c \ + ao_blt.c \ + ao_text.c \ + ao_mutex.c \ + ao_dma_stm.c \ + ao_adc_stm.c \ + ao_data.c \ + ao_i2c_stm.c \ + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_vga.c + +PRODUCT=StmVga-v0.0 +IDPRODUCT=0x000a + +CFLAGS = $(STM_CFLAGS) -g -Os + +PROG=stm-vga-$(VERSION) +ELF=$(PROG).elf +IHX=$(PROG).ihx + +SRC=$(ALTOS_SRC) ao_demo.c +OBJ=$(SRC:.c=.o) + +all: $(ELF) $(IHX) + +$(ELF): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJ) $(LIBS) + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +$(OBJ): $(INC) + +distclean: clean + +clean: + rm -f *.o *.elf *.ihx + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/stm-vga/ao_demo.c b/src/stm-vga/ao_demo.c new file mode 100644 index 00000000..582e4156 --- /dev/null +++ b/src/stm-vga/ao_demo.c @@ -0,0 +1,59 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" +#include +#include +#include +#include +#include +#include + +static void +ao_video_toggle(void) +{ + ao_cmd_decimal(); + ao_vga_enable(ao_cmd_lex_i); +} + +__code struct ao_cmds ao_demo_cmds[] = { + { ao_video_toggle, "V\0Toggle video" }, + { 0, NULL } +}; + +int +main(void) +{ + ao_clock_init(); + + ao_task_init(); + + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_GREEN); + ao_led_off(AO_LED_BLUE); + ao_timer_init(); + ao_dma_init(); + ao_cmd_init(); + ao_vga_init(); + ao_usb_init(); + + ao_cmd_register(&ao_demo_cmds[0]); + + ao_start_scheduler(); + return 0; +} diff --git a/src/stm-vga/ao_pins.h b/src/stm-vga/ao_pins.h new file mode 100644 index 00000000..3526cb6c --- /dev/null +++ b/src/stm-vga/ao_pins.h @@ -0,0 +1,205 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +/* Bridge SB17 on the board and use the MCO from the other chip */ +#define AO_HSE 8000000 +#define AO_HSE_BYPASS 1 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL 12 +#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 24MHz */ +#define AO_PLLDIV 4 +#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_4) + +/* HCLK = 24MHZ (CPU clock) */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at HCLK/1 */ +#define AO_APB1_PRESCALER 1 +#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_1 + +/* Run APB2 at HCLK/1 */ +#define AO_APB2_PRESCALER 1 +#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_1 + +#define HAS_SERIAL_1 0 +#define USE_SERIAL_1_STDIN 0 +#define SERIAL_1_PB6_PB7 1 +#define SERIAL_1_PA9_PA10 0 + +#define HAS_SERIAL_2 0 +#define USE_SERIAL_2_STDIN 0 +#define SERIAL_2_PA2_PA3 0 +#define SERIAL_2_PD5_PD6 1 + +#define HAS_SERIAL_3 0 +#define USE_SERIAL_3_STDIN 1 +#define SERIAL_3_PB10_PB11 0 +#define SERIAL_3_PC10_PC11 0 +#define SERIAL_3_PD8_PD9 1 + +#define HAS_SPI_1 0 +#define SPI_1_PB3_PB4_PB5 1 +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_SPI_2 0 + +#define HAS_USB 1 +#define HAS_BEEP 0 +#define PACKET_HAS_SLAVE 0 + +#define STM_DMA1_5_STOLEN 1 + +#define AO_BOOT_CHAIN 1 + +#define LOW_LEVEL_DEBUG 0 + +#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOBEN +#define LED_PORT (&stm_gpiob) +#define LED_PIN_GREEN 7 +#define LED_PIN_BLUE 6 +#define AO_LED_GREEN (1 << LED_PIN_GREEN) +#define AO_LED_BLUE (1 << LED_PIN_BLUE) +#define AO_LED_PANIC AO_LED_BLUE + +#define LEDS_AVAILABLE (AO_LED_BLUE | AO_LED_GREEN) + +#define AO_LCD_STM_SEG_ENABLED_0 ( \ + (1 << 0) | /* PA1 */ \ + (1 << 1) | /* PA2 */ \ + (1 << 2) | /* PA3 */ \ + (0 << 3) | /* PA6 */ \ + (0 << 4) | /* PA7 */ \ + (0 << 5) | /* PB0 */ \ + (0 << 6) | /* PB1 */ \ + (1 << 7) | /* PB3 */ \ + (1 << 8) | /* PB4 */ \ + (1 << 9) | /* PB5 */ \ + (1 << 10) | /* PB10 */ \ + (1 << 11) | /* PB11 */ \ + (1 << 12) | /* PB12 */ \ + (1 << 13) | /* PB13 */ \ + (1 << 14) | /* PB14 */ \ + (1 << 15) | /* PB15 */ \ + (1 << 16) | /* PB8 */ \ + (1 << 17) | /* PA15 */ \ + (1 << 18) | /* PC0 */ \ + (1 << 19) | /* PC1 */ \ + (1 << 20) | /* PC2 */ \ + (1 << 21) | /* PC3 */ \ + (0 << 22) | /* PC4 */ \ + (0 << 23) | /* PC5 */ \ + (1 << 24) | /* PC6 */ \ + (1 << 25) | /* PC7 */ \ + (1 << 26) | /* PC8 */ \ + (1 << 27) | /* PC9 */ \ + (1 << 28) | /* PC10 or PD8 */ \ + (1 << 29) | /* PC11 or PD9 */ \ + (0 << 30) | /* PC12 or PD10 */ \ + (0 << 31)) /* PD2 or PD11 */ + +#define AO_LCD_STM_SEG_ENABLED_1 ( \ + (0 << 0) | /* PD12 */ \ + (0 << 1) | /* PD13 */ \ + (0 << 2) | /* PD14 */ \ + (0 << 3) | /* PD15 */ \ + (0 << 4) | /* PE0 */ \ + (0 << 5) | /* PE1 */ \ + (0 << 6) | /* PE2 */ \ + (0 << 7)) /* PE3 */ + +#define AO_LCD_STM_COM_ENABLED ( \ + (1 << 0) | /* PA8 */ \ + (1 << 1) | /* PA9 */ \ + (1 << 2) | /* PA10 */ \ + (1 << 3) | /* PB9 */ \ + (0 << 4) | /* PC10 */ \ + (0 << 5) | /* PC11 */ \ + (0 << 6)) /* PC12 */ + +#define AO_LCD_28_ON_C 1 + +#define AO_LCD_DUTY STM_LCD_CR_DUTY_STATIC + +#define HAS_ADC 1 + +#define AO_ADC_RING 32 + +struct ao_adc { + uint16_t tick; + int16_t idd; + int16_t temp; + int16_t vref; +}; + +#define AO_ADC_IDD 4 +#define AO_ADC_PIN0_PORT (&stm_gpioa) +#define AO_ADC_PIN0_PIN 4 + +#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN)) +#define AO_ADC_TEMP 16 +#define AO_ADC_VREF 17 + +#define HAS_ADC_TEMP 1 + +#define AO_DATA_RING 32 +#define AO_NUM_ADC 3 + +#define AO_ADC_SQ1 AO_ADC_IDD +#define AO_ADC_SQ2 AO_ADC_TEMP +#define AO_ADC_SQ3 AO_ADC_VREF + +#define HAS_I2C_1 1 +#define I2C_1_PB6_PB7 0 +#define I2C_1_PB8_PB9 1 + +#define HAS_I2C_2 0 +#define I2C_2_PB10_PB11 0 + +#define AO_EVENT 1 + +#define AO_QUADRATURE_COUNT 2 +#define AO_QUADRATURE_MODE AO_EXTI_MODE_PULL_UP + +#define AO_QUADRATURE_0_PORT &stm_gpioc +#define AO_QUADRATURE_0_A 1 +#define AO_QUADRATURE_0_B 0 + +#define AO_QUADRATURE_1_PORT &stm_gpioc +#define AO_QUADRATURE_1_A 3 +#define AO_QUADRATURE_1_B 2 + +#define AO_BUTTON_COUNT 2 +#define AO_BUTTON_MODE AO_EXTI_MODE_PULL_UP + +#define AO_BUTTON_0_PORT &stm_gpioc +#define AO_BUTTON_0 6 + +#define AO_BUTTON_1_PORT &stm_gpioc +#define AO_BUTTON_1 7 + +#define AO_TICK_TYPE uint32_t +#define AO_TICK_SIGNED int32_t + +#endif /* _AO_PINS_H_ */ diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs index c3d2707f..25504629 100644 --- a/src/stm/Makefile.defs +++ b/src/stm/Makefile.defs @@ -1,4 +1,4 @@ -vpath % ../stm:../product:../drivers:../kernel:../util:../kalman:../aes:../math:.. +vpath % ../stm:../product:../drivers:../kernel:../util:../kalman:../aes:../math:../draw:.. vpath make-altitude ../util vpath make-kalman ../util vpath kalman.5c ../kalman @@ -26,7 +26,7 @@ LIBS=$(PDCLIB_LIBS_M3) -lgcc WARN_FLAGS=-Wall -Wextra -Werror -AO_CFLAGS=-I. -I../stm -I../kernel -I../drivers -I../math -I.. $(PDCLIB_INCLUDES) +AO_CFLAGS=-I. -I../stm -I../kernel -I../drivers -I../math -I../draw -I.. $(PDCLIB_INCLUDES) STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb \ -ffreestanding -nostdlib $(AO_CFLAGS) $(WARN_FLAGS) diff --git a/src/stm/ao_dma_stm.c b/src/stm/ao_dma_stm.c index 6d779660..0c86b49a 100644 --- a/src/stm/ao_dma_stm.c +++ b/src/stm/ao_dma_stm.c @@ -29,7 +29,6 @@ uint8_t ao_dma_done[NUM_DMA]; static struct ao_dma_config ao_dma_config[NUM_DMA]; static uint8_t ao_dma_allocated[NUM_DMA]; static uint8_t ao_dma_mutex[NUM_DMA]; -static uint8_t ao_dma_active; static void ao_dma_isr(uint8_t index) { @@ -51,10 +50,18 @@ void stm_dma1_channel1_isr(void) { ao_dma_isr(STM_DMA_INDEX(1)); } void stm_dma1_channel2_isr(void) { ao_dma_isr(STM_DMA_INDEX(2)); } void stm_dma1_channel3_isr(void) { ao_dma_isr(STM_DMA_INDEX(3)); } void stm_dma1_channel4_isr(void) { ao_dma_isr(STM_DMA_INDEX(4)); } +#ifdef STM_DMA1_5_STOLEN +#define LEAVE_DMA_ON +#else void stm_dma1_channel5_isr(void) { ao_dma_isr(STM_DMA_INDEX(5)); } +#endif void stm_dma1_channel6_isr(void) { ao_dma_isr(STM_DMA_INDEX(6)); } void stm_dma1_channel7_isr(void) { ao_dma_isr(STM_DMA_INDEX(7)); } +#ifndef LEAVE_DMA_ON +static uint8_t ao_dma_active; +#endif + void ao_dma_set_transfer(uint8_t index, volatile void *peripheral, @@ -68,10 +75,12 @@ ao_dma_set_transfer(uint8_t index, ao_dma_mutex[index] = 0xff; } else ao_mutex_get(&ao_dma_mutex[index]); +#ifndef LEAVE_DMA_ON ao_arch_critical( if (ao_dma_active++ == 0) stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMA1EN); ); +#endif stm_dma.channel[index].ccr = ccr | (1 << STM_DMA_CCR_TCIE); stm_dma.channel[index].cndtr = count; stm_dma.channel[index].cpar = peripheral; @@ -96,10 +105,12 @@ void ao_dma_done_transfer(uint8_t index) { stm_dma.channel[index].ccr &= ~(1 << STM_DMA_CCR_EN); +#ifndef LEAVE_DMA_ON ao_arch_critical( if (--ao_dma_active == 0) stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_DMA1EN); ); +#endif if (ao_dma_allocated[index]) ao_dma_mutex[index] = 0; else @@ -120,10 +131,12 @@ ao_dma_dump_cmd(void) { int i; +#ifndef LEAVE_DMA_ON ao_arch_critical( if (ao_dma_active++ == 0) stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMA1EN); ); +#endif printf ("isr %08x ifcr%08x\n", stm_dma.isr, stm_dma.ifcr); for (i = 0; i < NUM_DMA; i++) printf("%d: done %d allocated %d mutex %2d ccr %04x cndtr %04x cpar %08x cmar %08x isr %08x\n", @@ -136,10 +149,12 @@ ao_dma_dump_cmd(void) stm_dma.channel[i].cpar, stm_dma.channel[i].cmar, ao_dma_config[i].isr); +#ifndef LEAVE_DMA_ON ao_arch_critical( if (--ao_dma_active == 0) stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_DMA1EN); ); +#endif } static const struct ao_cmds ao_dma_cmds[] = { @@ -153,7 +168,17 @@ ao_dma_init(void) { int index; +#ifdef LEAVE_DMA_ON + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMA1EN); +#endif for (index = 0; index < STM_NUM_DMA; index++) { +#if STM_DMA1_5_STOLEN + if (index == STM_DMA_INDEX(5)) { + ao_dma_allocated[index] = 1; + ao_dma_mutex[index] = 0xff; + continue; + } +#endif stm_nvic_set_enable(STM_ISR_DMA1_CHANNEL1_POS + index); stm_nvic_set_priority(STM_ISR_DMA1_CHANNEL1_POS + index, 4); ao_dma_allocated[index] = 0; diff --git a/src/stm/ao_i2c_stm.c b/src/stm/ao_i2c_stm.c index 29a8f173..59cad495 100644 --- a/src/stm/ao_i2c_stm.c +++ b/src/stm/ao_i2c_stm.c @@ -75,6 +75,9 @@ uint8_t ao_i2c_mutex[STM_NUM_I2C]; #if AO_PCLK1 == 16000000 # define AO_STM_I2C_CR2_FREQ STM_I2C_CR2_FREQ_16_MHZ #endif +#if AO_PCLK1 == 24000000 +# define AO_STM_I2C_CR2_FREQ STM_I2C_CR2_FREQ_24_MHZ +#endif #if AO_PCLK1 == 32000000 # define AO_STM_I2C_CR2_FREQ STM_I2C_CR2_FREQ_32_MHZ #endif diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index f86a5116..b25dbd1a 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -42,31 +42,30 @@ volatile __data uint8_t ao_data_count; void stm_systick_isr(void) { + ao_arch_release_interrupts(); ao_validate_cur_stack(); - if (stm_systick.csr & (1 << STM_SYSTICK_CSR_COUNTFLAG)) { - ++ao_tick_count; + ++ao_tick_count; #if HAS_TASK_QUEUE - if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0) - ao_task_check_alarm((uint16_t) ao_tick_count); + if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0) + ao_task_check_alarm((uint16_t) ao_tick_count); #endif #if AO_DATA_ALL - if (++ao_data_count == ao_data_interval) { - ao_data_count = 0; + if (++ao_data_count == ao_data_interval) { + ao_data_count = 0; #if HAS_FAKE_FLIGHT - if (ao_fake_flight_active) - ao_fake_flight_poll(); - else + if (ao_fake_flight_active) + ao_fake_flight_poll(); + else #endif - ao_adc_poll(); + ao_adc_poll(); #if (AO_DATA_ALL & ~(AO_DATA_ADC)) - ao_wakeup((void *) &ao_data_count); + ao_wakeup((void *) &ao_data_count); #endif - } + } #endif #ifdef AO_TIMER_HOOK - AO_TIMER_HOOK; + AO_TIMER_HOOK; #endif - } } #if HAS_ADC @@ -90,6 +89,7 @@ ao_timer_init(void) stm_systick.csr = ((1 << STM_SYSTICK_CSR_ENABLE) | (1 << STM_SYSTICK_CSR_TICKINT) | (STM_SYSTICK_CSR_CLKSOURCE_HCLK_8 << STM_SYSTICK_CSR_CLKSOURCE)); + stm_nvic.shpr15_12 |= 0xff << 24; } #endif diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 463125e2..f42ed97c 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -897,7 +897,11 @@ struct stm_nvic { vuint32_t sc; /* 0xc10 0xe000ed10 System Control Register */ vuint32_t cc; /* 0xc14 0xe000ed14 Configuration Control Register */ - uint8_t _unusedc18[0xe00 - 0xc18]; + vuint32_t shpr7_4; /* 0xc18 0xe000ed18 System Hander Priority Registers */ + vuint32_t shpr11_8; /* 0xc1c */ + vuint32_t shpr15_12; /* 0xc20 */ + + uint8_t _unusedc18[0xe00 - 0xc24]; vuint32_t stir; /* 0xe00 */ }; @@ -1594,6 +1598,7 @@ extern struct stm_i2c stm_i2c1, stm_i2c2; #define STM_I2C_CR2_FREQ_4_MHZ 4 #define STM_I2C_CR2_FREQ_8_MHZ 8 #define STM_I2C_CR2_FREQ_16_MHZ 16 +#define STM_I2C_CR2_FREQ_24_MHZ 24 #define STM_I2C_CR2_FREQ_32_MHZ 32 #define STM_I2C_CR2_FREQ_MASK 0x3f @@ -1740,6 +1745,12 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4; #define STM_TIM234_SMCR_SMS_EXTERNAL_CLOCK 7 #define STM_TIM234_SMCR_SMS_MASK 7 +#define STM_TIM234_DIER_CC4IE 4 +#define STM_TIM234_DIER_CC3IE 3 +#define STM_TIM234_DIER_CC2IE 2 +#define STM_TIM234_DIER_CC1IE 1 +#define STM_TIM234_DIER_UIE 0 + #define STM_TIM234_SR_CC4OF 12 #define STM_TIM234_SR_CC3OF 11 #define STM_TIM234_SR_CC2OF 10 @@ -1849,6 +1860,8 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4; #define STM_TIM234_CCER_CC2E 4 #define STM_TIM234_CCER_CC1NP 3 #define STM_TIM234_CCER_CC1P 1 +#define STM_TIM234_CCER_CC1P_ACTIVE_HIGH 0 +#define STM_TIM234_CCER_CC1P_ACTIVE_LOW 1 #define STM_TIM234_CCER_CC1E 0 struct stm_usb { -- 2.30.2