diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2015-09-07 17:06:05 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2015-09-07 17:06:05 +0900 |
commit | 014dbf25f628a3befb930d23ee0c24d4e9b8f929 (patch) | |
tree | 31b25440aa30c411e98571efcaa3a7d15cd9d181 /example-primer2 | |
parent | 41610443d4d53d229d83509464f73f2bd52d98e2 (diff) |
Add example-primer2
Diffstat (limited to 'example-primer2')
-rw-r--r-- | example-primer2/Makefile | 40 | ||||
-rw-r--r-- | example-primer2/README | 18 | ||||
-rw-r--r-- | example-primer2/aes-constant-ft.c | 145 | ||||
-rw-r--r-- | example-primer2/lcd.c | 388 | ||||
-rw-r--r-- | example-primer2/lcd.ld | 148 | ||||
-rw-r--r-- | example-primer2/main.c | 266 | ||||
-rw-r--r-- | example-primer2/primer2-switches.c | 73 | ||||
-rw-r--r-- | example-primer2/primer2-switches.h | 9 | ||||
-rw-r--r-- | example-primer2/primer2-ts.c | 223 | ||||
-rw-r--r-- | example-primer2/primer2-ts.h | 8 | ||||
-rw-r--r-- | example-primer2/st7732.h | 83 | ||||
-rw-r--r-- | example-primer2/sys.c | 467 | ||||
-rw-r--r-- | example-primer2/sys.h | 115 |
13 files changed, 1983 insertions, 0 deletions
diff --git a/example-primer2/Makefile b/example-primer2/Makefile new file mode 100644 index 0000000..7dd70c5 --- /dev/null +++ b/example-primer2/Makefile @@ -0,0 +1,40 @@ +# Makefile for example application of Chopstx + +PROJECT = lcd + +CHOPSTX = .. +NEUGSRC = ./neug/src +LDSCRIPT= lcd.ld +CSRC = sys.c aes-constant-ft.c primer2-switches.c primer2-ts.c lcd.c main.c \ + adc_stm32f103.c neug.c sha256.c + +################################### +CROSS = arm-none-eabi- +CC = $(CROSS)gcc +LD = $(CROSS)gcc +OBJCOPY = $(CROSS)objcopy +MCU = cortex-m3 +CWARN = -Wall -Wextra -Wstrict-prototypes +DEFS = -DHAVE_SYS_H -DFREE_STANDING -DMHZ=48 +# DEFS = -DFREE_STANDING -DHAVE_SYS_H -DBUSY_LOOP -DCHX_FLAGS_MAIN=CHOPSTX_SCHED_RR +OPT = -O3 -Os -g +INCDIR = $(NEUGSRC) +LIBS = + +#################### +include ../rules.mk + +board.h: ../board/board-stm32-primer2.h neug + ln -s ../board/board-stm32-primer2.h ./board.h + +sys.c: board.h + +neug: + @echo Please make a symbolic link \'neug\' to the neug directory; + @exit 1 + +adc_stm32f103.c neug.c sha256.c: + ln -s $(NEUGSRC)/$@ $@ + +distclean: clean + rm -f board.h neug adc_stm32f103.c neug.c sha256.c diff --git a/example-primer2/README b/example-primer2/README new file mode 100644 index 0000000..b27a52a --- /dev/null +++ b/example-primer2/README @@ -0,0 +1,18 @@ +Example for STM32 Primer2 by Kazmoto Kojima + +It is taken from: + + http://www.rr.iij4u.or.jp/~kkojima/letschopstx.html + +From the original tar archive, chopstx-logo.data is removed because +it's too big. + +You can generate it by ImageMagick. + + $ convert ../chopstx.svg -depth 8 -flip \( +clone -channel B -fx R \) +swap -channel R -fx v.B -resize 128x160 -background white -compress none -flatten chopstx.ppm + + $ tail -n +4 chopstx.ppm | sed -e 's/ /, /g' > chopstx-logo.data + + +Since it was written for Chopstx 0.06, you would need to change a bit, +perhaps. diff --git a/example-primer2/aes-constant-ft.c b/example-primer2/aes-constant-ft.c new file mode 100644 index 0000000..21d1ba7 --- /dev/null +++ b/example-primer2/aes-constant-ft.c @@ -0,0 +1,145 @@ +/* + * aes-constant-ft.c - AES forward tables. + * + * We need something useful for the initial flash ROM page (4 Ki + * bytes), which cannot be modified after installation. Even after + * upgrade of the firmware, it stays intact. + * + * We decide to put 3/4 of AES forward tables to fill 3 Ki bytes, as + * its useful and it won't change. + * + * The code was taken from aes.c of PolarSSL version 0.14, and then, + * modified to add section names. + * + * Since this is just a data, it wouldn't be copyright-able, but the + * original auther would claim so. Thus, we put original copyright + * notice here. It is highly likely that there will be no such a + * thing for copyright. Nevertheless, we think that PolarSSL is good + * software to address here, and encourage people using it. + * + */ + +#include <stdint.h> + +/* + * Original copyright notice is below: + */ + +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +const uint32_t FT0[256] __attribute__((section(".sys.0"))) = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +const uint32_t FT1[256] __attribute__((section(".sys.1"))) = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +const uint32_t FT2[256] __attribute__((section(".sys.2"))) = { FT }; +#undef V + +#ifdef ORIGINAL_IMPLEMENTATION +#define V(a,b,c,d) 0x##d##a##b##c +const uint32_t FT3[256] = { FT }; +#undef V +#endif diff --git a/example-primer2/lcd.c b/example-primer2/lcd.c new file mode 100644 index 0000000..effbe24 --- /dev/null +++ b/example-primer2/lcd.c @@ -0,0 +1,388 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> +#include "sys.h" /* for set_led */ +#include "st7732.h" +#include "board.h" + +#define PERIPH_BASE 0x40000000 +#define APBPERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) + +struct GPIO { + volatile uint32_t CRL; + volatile uint32_t CRH; + volatile uint32_t IDR; + volatile uint32_t ODR; + volatile uint32_t BSRR; + volatile uint32_t BRR; + volatile uint32_t LCKR; +}; + +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOA ((struct GPIO *) GPIOA_BASE) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOB ((struct GPIO *) GPIOB_BASE) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOC ((struct GPIO *) GPIOC_BASE) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#define GPIOD ((struct GPIO *) GPIOD_BASE) +#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) +#define GPIOE ((struct GPIO *) GPIOE_BASE) + +static struct GPIO *const GPIO_LCD = ((struct GPIO *const) GPIO_LED_BASE); +static struct GPIO *const GPIO_LCD_CTRL = ((struct GPIO *const) GPIO_USB_BASE); + +#define GPIO_LCD_RD 4 +#define GPIO_LCD_WR 5 +#define GPIO_LCD_RST 6 +#define GPIO_LCD_CS 7 +#define GPIO_LCD_RS 11 +/* PE7:LCD_D0 - PE14:LCD_D7 */ +#define GPIO_DATA_SHIFT 7 +#define GPIO_DATA_MASK (0xff << GPIO_DATA_SHIFT) + +static void +lcd_command_common (st7732_cmd_t cmd) +{ + /* Set command. */ + GPIO_LCD->BRR = GPIO_DATA_MASK & ~(cmd << GPIO_DATA_SHIFT); + GPIO_LCD->BSRR = GPIO_DATA_MASK & (cmd << GPIO_DATA_SHIFT); + /* Set CMD mode. */ + GPIO_LCD_CTRL->BRR = (1 << GPIO_LCD_RS); + /* Asert /CS. */ + GPIO_LCD_CTRL->BRR = (1<< GPIO_LCD_CS); + /* Asert /WR. */ + GPIO_LCD_CTRL->BRR = (1<< GPIO_LCD_WR); + // chopstx_usec_wait (1); + /* Negate /WR. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_WR); + + /* Return DATA mode. */ + GPIO_LCD_CTRL->BSRR = (1 << GPIO_LCD_RS); +} + +/* Issue command with no data read/write. */ +void +lcd_command_no (st7732_cmd_t cmd) +{ + lcd_command_common (cmd); + + /* Negate /CS. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_CS); +} + +#if 0 +void +lcd_command_readn (st7732_cmd_t cmd, uint8_t *data, size_t n) +{ + volatile int dummy __attribute__ ((unused)); + + lcd_command_common (cmd); + + /* Set GPIO_LCD to input mode. */ + GPIO_LCD->CRH = 0x88888888; + GPIO_LCD->CRL = 0x88888833; + + /* Assert /RD. */ + GPIO_LCD_CTRL->BRR = (1<< GPIO_LCD_RD); + // chopstx_usec_wait (1); + /* Dummy read. */ + dummy = GPIO_LCD->IDR; + /* Negate /RD. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_RD); + + /* Read loop. */ + while (n-- > 0) + { + /* Assert /RD. */ + GPIO_LCD_CTRL->BRR = (1<< GPIO_LCD_RD); + // chopstx_usec_wait (1); + /* Negate /RD. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_RD); + *data++ = GPIO_LCD->IDR >> GPIO_DATA_SHIFT; + } + + /* Negate /CS. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_CS); + + /* Set GPIO_LCD to output mode. */ + GPIO_LCD->CRH = 0x83333333; + GPIO_LCD->CRL = 0x38888833; +} +#endif + +/* Issue command with N data write. */ +void +lcd_command_writen (st7732_cmd_t cmd, uint8_t *data, size_t n) +{ + lcd_command_common (cmd); + + /* Write loop. */ + while (n-- > 0) + { + uint8_t b = *data++; + + GPIO_LCD->BRR = GPIO_DATA_MASK & ~(b << GPIO_DATA_SHIFT); + GPIO_LCD->BSRR = GPIO_DATA_MASK & (b << GPIO_DATA_SHIFT); + /* Assert /WR. */ + GPIO_LCD_CTRL->BRR = (1<< GPIO_LCD_WR); + // chopstx_usec_wait (1); + /* Negate /WR. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_WR); + } + + /* Negate /CS. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_CS); +} + +/* Issue command with N same data write. */ +void +lcd_command_filln (st7732_cmd_t cmd, uint8_t b, size_t n) +{ + lcd_command_common (cmd); + + /* Write loop. */ + while (n-- > 0) + { + GPIO_LCD->BRR = GPIO_DATA_MASK & ~(b << GPIO_DATA_SHIFT); + GPIO_LCD->BSRR = GPIO_DATA_MASK & (b << GPIO_DATA_SHIFT); + /* Assert /WR. */ + GPIO_LCD_CTRL->BRR = (1<< GPIO_LCD_WR); + // chopstx_usec_wait (1); + /* Negate /WR. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_WR); + } + + /* Negate /CS. */ + GPIO_LCD_CTRL->BSRR = (1<< GPIO_LCD_CS); +} + +static chopstx_mutex_t lcd_mtx; +static chopstx_cond_t lcd_cnd0; +static chopstx_cond_t lcd_cnd1; + +/* Process for initializing ST7732. */ +static void * +lcd_initializer (void *arg __attribute__((unused))) +{ + uint8_t args[16]; + + chopstx_mutex_lock (&lcd_mtx); + chopstx_cond_wait (&lcd_cnd0, &lcd_mtx); + chopstx_mutex_unlock (&lcd_mtx); + + /* Set GPIO_LCD to write mode. */ + GPIO_LCD->CRH = 0x83333333; + GPIO_LCD->CRL = 0x38888833; + + /* Set GPIO_LCD_CTRL IO mode. */ + GPIO_LCD_CTRL->CRH = 0x88883888; + GPIO_LCD_CTRL->CRL = 0x33333888; + + /* Restart ST7732. */ + /* Hard reset. */ + chopstx_usec_wait (100000); + GPIO_LCD_CTRL->BRR = (1 << GPIO_LCD_RST); + chopstx_usec_wait (100000); + GPIO_LCD_CTRL->BSRR = (1 << GPIO_LCD_RST); + chopstx_usec_wait (100000); + + /* Software reset. */ + lcd_command_no (SWRESET); + chopstx_usec_wait (150000); + + /* Sleep in. */ + lcd_command_no (SLPIN); + chopstx_usec_wait (100000); + + /* Sleep out. */ + lcd_command_no (SLPOUT); + chopstx_usec_wait (100000); + + /* Configure ST7732. Set display mode, pixel mode, etc. */ + /* FRMCTR1, 6, 3, 2 */ + args[0] = 0x06; args[1] = 0x03; args[2] = 0x02; + lcd_command_writen (FRMCTR1, args, 3); + /* INVCTR, 3 */ + args[0] = 0x03; + lcd_command_writen (INVCTR, args, 1); + /* DISSET5, 2, eh */ + args[0] = 0x02; args[1] = 0x0e; + lcd_command_writen (DISSET5, args, 2); + /* DISPCTRL, 1ah */ + args[0] = 0x1a; + lcd_command_writen (DISPCTRL, args, 1); + /* PWCTR1, 2, 0 */ + args[0] = 0x02; args[1] = 0x00; + lcd_command_writen (PWCTR1, args, 2); + /* PWCTR2, 5 */ + args[0] = 0x05; + lcd_command_writen (PWCTR2, args, 1); + /* PWCTR3, 2, 2 */ + args[0] = 0x02; args[1] = 0x02; + lcd_command_writen (PWCTR3, args, 2); + /* PWCTR4, 1, 2 */ + args[0] = 0x01; args[1] = 0x00; + lcd_command_writen (PWCTR4, args, 2); + /* PWCTR5, 1, 2 */ + args[0] = 0x01; args[1] = 0x00; + lcd_command_writen (PWCTR5, args, 2); + /* VMCTR1, 47h, 2ah */ + args[0] = 0x47; args[1] = 0x2a; + lcd_command_writen (VMCTR1, args, 2); + /* OSCADJ, 4ch */ + args[0] = 0x4c; + lcd_command_writen (OSCADJ, args, 1); + /* DEFADJ, 6 */ + args[0] = 0x06; + lcd_command_writen (DEFADJ, args, 1); + + /* gamma adjust */ + + /* MADCTL, c0h MY=1, MX=1 */ + args[0] = 0xc0; + lcd_command_writen (MADCTL, args, 1); + + /* Set RA and CA. */ + /* RASET, 0, 0, 0, 159 */ + args[0] = 0x00; args[1] = 0x00; args[2] = 0x00; args[3] = LCD_ROW-1; + lcd_command_writen (RASET, args, 4); + /* CASET, 0, 0, 0, 127 */ + args[0] = 0x00; args[1] = 0x00; args[2] = 0x00; args[3] = LCD_COLUMN-1; + lcd_command_writen (CASET, args, 4); + + /* 0x06: RGB 6-6-6-bit. */ + args[0] = 0x06; + lcd_command_writen (COLMOD, args, 1); + + args[0] = 0; + lcd_command_writen (TEON, args, 1); + + lcd_command_no (DISPON); + + /* Wait 20ms. */ + chopstx_usec_wait (20000); + + chopstx_mutex_lock (&lcd_mtx); + chopstx_cond_signal (&lcd_cnd1); + chopstx_mutex_unlock (&lcd_mtx); + + return NULL; +} + +/* Plot a point with rgb color. 2 LSBs of rgb values will be ignored. */ +void +lcd_draw_point (int x, int y, int r, int g, int b) +{ + uint8_t args[4]; + + /* Set RA and CA. */ + /* RASET, 0, y, 0, y */ + args[0] = 0x00; args[1] = y; args[2] = 0x00; args[3] = y; + lcd_command_writen (RASET, args, 4); + /* CASET, 0, x, 0, x */ + args[0] = 0x00; args[1] = x; args[2] = 0x00; args[3] = x; + lcd_command_writen (CASET, args, 4); + + args[0] = r; args[1] = g; args[2] = b; + lcd_command_writen (RAMWR, args, 3); +} + +static uint8_t hexfont5x8[16*5] = { + 0x7e, 0x89, 0x91, 0xa1, 0x7e, /* 0 */ + 0x00, 0x41, 0xff, 0x01, 0x00, /* 1 */ + 0x43, 0x85, 0x89, 0x91, 0x61, /* 2 */ + 0x42, 0x81, 0x91, 0x91, 0x6e, /* 3 */ + 0x18, 0x28, 0x48, 0xff, 0x08, /* 4 */ + 0xf2, 0x91, 0x91, 0x91, 0x8e, /* 5 */ + 0x1e, 0x29, 0x49, 0x89, 0x86, /* 6 */ + 0x80, 0x8f, 0x90, 0xa0, 0xc0, /* 7 */ + 0x6e, 0x91, 0x91, 0x91, 0x6e, /* 8 */ + 0x70, 0x89, 0x89, 0x8a, 0x7c, /* 9 */ + 0x7f, 0x88, 0x88, 0x88, 0x7f, /* A */ + 0xff, 0x91, 0x91, 0x91, 0x6e, /* B */ + 0x7e, 0x81, 0x81, 0x81, 0x42, /* C */ + 0xff, 0x81, 0x81, 0x42, 0x3c, /* D */ + 0xff, 0x91, 0x91, 0x91, 0x81, /* E */ + 0xff, 0x90, 0x90, 0x90, 0x80, /* F */ +}; + +/* Draw hex number with rgb color. */ +void +lcd_draw_hexfont5x8 (uint32_t hex, int x, int y, int r, int g, int b, int bg) +{ + int i, j; + uint8_t *p; + uint8_t args[5*8*3]; + + p = &hexfont5x8[(hex & 0xf)*5]; + + /* Set RA and CA. */ + /* RASET, 0, y, 0, y+8-1 */ + args[0] = 0x00; args[1] = y; args[2] = 0x00; args[3] = y+7; + lcd_command_writen (RASET, args, 4); + /* CASET, 0, x, 0, x+5-1 */ + args[0] = 0x00; args[1] = x; args[2] = 0x00; args[3] = x+4; + lcd_command_writen (CASET, args, 4); + + for (i = 0; i < 5; i++) + { + uint8_t rb = *p++; + for (j = 0; j < 8; j++) + { + int k = (5*j+i)*3; + if (rb & (0x80 >> j)) + { + args[k] = r; args[k+1] = g; args[k+2] = b; + } + else + { + args[k] = bg; args[k+1] = bg; args[k+2] = bg; + } + } + } + + lcd_command_writen (RAMWR, args, 5*8*3); +} + +void +lcd_printhex (uint32_t hex, int x, int y, int r, int g, int b, int bg) +{ + int i; + + if (y < 0 || y >= LCD_ROW - 8) + return; + for (i = 7; i >= 0; i--) + { + lcd_draw_hexfont5x8 ((hex >> 4*i)&0xf, x, y, r, g, b, bg); + x += 5; + if (x >= LCD_COLUMN - 5) + break; + } +} + +#define PRIO_LCD 3 + +extern uint8_t __process1_stack_base__, __process1_stack_size__; +const uint32_t __stackaddr_lcd = (uint32_t)&__process1_stack_base__; +const size_t __stacksize_lcd = (size_t)&__process1_stack_size__; + +/* Initialize LCD. */ +void +lcd_init (void) +{ + chopstx_mutex_init (&lcd_mtx); + chopstx_cond_init (&lcd_cnd0); + chopstx_cond_init (&lcd_cnd1); + + chopstx_create (PRIO_LCD, __stackaddr_lcd, __stacksize_lcd, + lcd_initializer, NULL); + + chopstx_usec_wait (200*1000); + + chopstx_mutex_lock (&lcd_mtx); + chopstx_cond_signal (&lcd_cnd0); + chopstx_cond_wait (&lcd_cnd1, &lcd_mtx); + chopstx_mutex_unlock (&lcd_mtx); +} diff --git a/example-primer2/lcd.ld b/example-primer2/lcd.ld new file mode 100644 index 0000000..dbda939 --- /dev/null +++ b/example-primer2/lcd.ld @@ -0,0 +1,148 @@ +/* + * ST32F103 memory setup. + */ +__main_stack_size__ = 0x0100; /* Exception handlers */ +__process0_stack_size__ = 0x0200; /* main */ +__process1_stack_size__ = 0x0100; /* lcd init */ +__process2_stack_size__ = 0x0180; /* rng */ +__process3_stack_size__ = 0x0100; /* None yet */ + +MEMORY +{ + flash0 : org = 0x08000000, len = 4k + flash : org = 0x08000000+0x1000, len = 512k - 4k + ram : org = 0x20000000, len = 64k +} + +/* __flash_start__: flash ROM start address regardless of DFU_SUPPORT */ +__flash_start__ = 0x08001000; +__flash_end__ = ORIGIN(flash) + LENGTH(flash); + +__ram_start__ = ORIGIN(ram); +__ram_size__ = LENGTH(ram); +__ram_end__ = __ram_start__ + __ram_size__; + +SECTIONS +{ + . = 0; + + .sys : ALIGN(4) SUBALIGN(4) + { + _sys = .; + KEEP(*(.vectors)) + . = ALIGN(16); + *(.sys.version) + build/sys.o(.text) + build/sys.o(.text.*) + build/sys.o(.rodata) + build/sys.o(.rodata.*) + . = ALIGN(1024); + *(.sys.0) + *(.sys.1) + *(.sys.2) + } > flash0 + + _text = .; + + .startup : ALIGN(128) SUBALIGN(128) + { + KEEP(*(.startup.vectors)) + . = ALIGN (16); + } > flash =0xffffffff + + .text : ALIGN(16) SUBALIGN(16) + { + *(.text.startup.*) + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + *(.glue_7t) + *(.glue_7) + *(.gcc*) + . = ALIGN(8); + } > flash + + .ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash + + .ARM.exidx : { + PROVIDE(__exidx_start = .); + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + PROVIDE(__exidx_end = .); + } > flash + + .eh_frame_hdr : {*(.eh_frame_hdr)} > flash + + .eh_frame : ONLY_IF_RO {*(.eh_frame)} > flash + + .textalign : ONLY_IF_RO { . = ALIGN(8); } > flash + + _etext = .; + _textdata = _etext; + + .stacks : + { + . = ALIGN(8); + __main_stack_base__ = .; + . += __main_stack_size__; + . = ALIGN(8); + __main_stack_end__ = .; + __process0_stack_base__ = .; + . += __process0_stack_size__; + . = ALIGN(8); + __process0_stack_end__ = .; + __process1_stack_base__ = .; + . += __process1_stack_size__; + . = ALIGN(8); + __process1_stack_end__ = .; + __process2_stack_base__ = .; + . += __process2_stack_size__; + . = ALIGN(8); + __process2_stack_end__ = .; + __process3_stack_base__ = .; + . += __process3_stack_size__; + . = ALIGN(8); + __process3_stack_end__ = .; + } > ram + + .data : + { + . = ALIGN(4); + PROVIDE(_data = .); + *(.data) + . = ALIGN(4); + *(.data.*) + . = ALIGN(4); + *(.ramtext) + . = ALIGN(4); + PROVIDE(_edata = .); + } > ram AT > flash + + .bss : + { + . = ALIGN(4); + PROVIDE(_bss_start = .); + *(.bss) + . = ALIGN(4); + *(.bss.*) + . = ALIGN(4); + *(COMMON) + . = ALIGN(4); + PROVIDE(_bss_end = .); + } > ram + + PROVIDE(end = .); + _end = .; + . = ALIGN(512); + /* reGNUal is now relocatable, it's OK not using fixed address. */ + _regnual_start = .; + + .fill_ffff : + { + . = ALIGN (2048); + *(.passwd) + } > flash =0xffffffff +} + +__heap_base__ = _end; +__heap_end__ = __ram_end__; diff --git a/example-primer2/main.c b/example-primer2/main.c new file mode 100644 index 0000000..c83a810 --- /dev/null +++ b/example-primer2/main.c @@ -0,0 +1,266 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> +#include "neug.h" +#include "sys.h" /* for set_led */ +#include "stm32f103.h" +#include "adc.h" +#include "st7732.h" +#include "primer2-switches.h" +#include "primer2-ts.h" +#include "board.h" + +#ifdef TEST_DISPLAY_LOGO +static uint8_t buf[LCD_COLUMN*LCD_ROW*BYTES_PER_PIXEL] = { +#include "chopstx-logo.data" +}; + +void +lcd_logo (void) +{ + uint8_t args[4]; + + /* Set RA and CA. */ + /* RASET, 0, 0, 0, 159 */ + args[0] = 0x00; args[1] = 0; args[2] = 0x00; args[3] = LCD_ROW-1; + lcd_command_writen (RASET, args, 4); + /* CASET, 0, 0, 0, 127 */ + args[0] = 0x00; args[1] = 0; args[2] = 0x00; args[3] = LCD_COLUMN-1; + lcd_command_writen (CASET, args, 4); + + /* Write logo. */ + lcd_command_writen (RAMWR, buf, LCD_COLUMN*LCD_ROW*BYTES_PER_PIXEL); +} +#endif + +/* Table of 32*(cos, sin) for range 0 to pi/2 with step pi/256. */ +static uint8_t ctable[128*2] = { +32, 0, 31, 0, 31, 0, 31, 1, 31, 1, 31, 1, 31, 2, 31, 2, +31, 3, 31, 3, 31, 3, 31, 4, 31, 4, 31, 5, 31, 5, 31, 5, +31, 6, 31, 6, 31, 7, 31, 7, 31, 7, 30, 8, 30, 8, 30, 8, +30, 9, 30, 9, 30, 10, 30, 10, 30, 10, 29, 11, 29, 11, 29, 11, +29, 12, 29, 12, 29, 12, 29, 13, 28, 13, 28, 14, 28, 14, 28, 14, +28, 15, 28, 15, 27, 15, 27, 16, 27, 16, 27, 16, 27, 17, 26, 17, +26, 17, 26, 18, 26, 18, 25, 18, 25, 19, 25, 19, 25, 19, 24, 19, +24, 20, 24, 20, 24, 20, 23, 21, 23, 21, 23, 21, 23, 22, 22, 22, +22, 22, 22, 22, 22, 23, 21, 23, 21, 23, 21, 23, 20, 24, 20, 24, +20, 24, 19, 24, 19, 25, 19, 25, 19, 25, 18, 25, 18, 26, 18, 26, +17, 26, 17, 26, 17, 27, 16, 27, 16, 27, 16, 27, 15, 27, 15, 28, +15, 28, 14, 28, 14, 28, 14, 28, 13, 28, 13, 29, 12, 29, 12, 29, +12, 29, 11, 29, 11, 29, 11, 29, 10, 30, 10, 30, 10, 30, 9, 30, +9, 30, 8, 30, 8, 30, 8, 30, 7, 31, 7, 31, 7, 31, 6, 31, +6, 31, 5, 31, 5, 31, 5, 31, 4, 31, 4, 31, 3, 31, 3, 31, +3, 31, 2, 31, 2, 31, 1, 31, 1, 31, 1, 31, 0, 31, 0, 31, +}; + +#ifdef TEST_LCD_CIRCLE +void +lcd_circle (void) +{ + int i, j; + uint8_t *p; + int x, y; + + /* Clear display. */ + /* Set RA and CA. */ + /* RASET, 0, 0, 0, 159 */ + args[0] = 0x00; args[1] = 0; args[2] = 0x00; args[3] = LCD_ROW-1; + lcd_command_writen (RASET, args, 4); + /* CASET, 0, 0, 0, 127 */ + args[0] = 0x00; args[1] = 0; args[2] = 0x00; args[3] = LCD_COLUMN-1; + lcd_command_writen (CASET, args, 4); + + lcd_command_writen (RAMWR, 0, LCD_COLUMN*LCD_ROW*BYTES_PER_PIXEL); + + /* Draw a circle. */ + for (i = 0; i < 128; i++) + { + x = 64 + ctable[2*i]; + y = 80 + ctable[2*i+1]; + lcd_draw_point (x, y, 0xfc, 0xfc, 0xfc); + } + for (i = 0; i < 128; i++) + { + x = 64 - ctable[2*i+1]; + y = 80 + ctable[2*i]; + lcd_draw_point (x, y, 0xfc, 0, 0xfc); + } + for (i = 0; i < 128; i++) + { + x = 64 - ctable[2*i]; + y = 80 - ctable[2*i+1]; + lcd_draw_point (x, y, 0, 0xfc, 0xfc); + } + for (i = 0; i < 128; i++) + { + x = 64 + ctable[2*i+1]; + y = 80 - ctable[2*i]; + lcd_draw_point (x, y, 0xfc, 0xfc, 0); + } +} +#endif + +#define RANDOM_BYTES_LENGTH 64 +static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)]; + +int +main (int argc, const char *argv[]) +{ + int count; + int vx, vy; + int r, g, b; + uint8_t args[4]; + + (void)argc; + (void)argv; + + set_led (1); + set_backlight (1); + + adc_init (); + neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t)); + + lcd_init (); + +#ifdef TEST_LCD_LOGO + lcd_logo (); + + while (! joystick ()) + chopstx_usec_wait (500*1000); +#endif + + /* Set RA and CA. */ + /* RASET, 0, 0, 0, 159 */ + args[0] = 0x00; args[1] = 0; args[2] = 0x00; args[3] = LCD_ROW-1; + lcd_command_writen (RASET, args, 4); + /* CASET, 0, 0, 0, 127 */ + args[0] = 0x00; args[1] = 0; args[2] = 0x00; args[3] = LCD_COLUMN-1; + lcd_command_writen (CASET, args, 4); + + /* Fill display. */ + lcd_command_filln (RAMWR, 0xfc, LCD_COLUMN*LCD_ROW*BYTES_PER_PIXEL); + + vx = (LCD_COLUMN/2) << 5; + vy = (LCD_ROW/2) << 5; + r = g = b = 0; +#if 1 + adc3_init (); + adc3_start (); + + count = 0; + while (1) + { + uint32_t resv[4]; + + adc3_conversion (resv); + if (ts_pushed (resv[2])) + { + int reg[3], point[2]; + + ts_conversion (resv, reg); +#if 0 + lcd_printhex (reg[0], 5, 8, 0x00, 0x00, 0xfc, 0xfc); + lcd_printhex (reg[1], 5, 18, 0x00, 0x00, 0xfc, 0xfc); + lcd_printhex (reg[2], 5, 28, 0x00, 0x00, 0xfc, 0xfc); +#endif + if (!ts_adjust (reg, point)) + { + chopstx_usec_wait (50*1000); + continue; + } + + lcd_draw_point (point[0], point[1], r, g, b); + } + else + ts_adjust (NULL, NULL); + + chopstx_usec_wait (50*1000); + count++; + if ((count/10) & 1) + set_led (0); + else + set_led (1); + if (pbutton()) + break; + } + + adc3_stop (); +#endif + + count = 0; + while (1) + { + int jo; + uint32_t th = neug_get (NEUG_KICK_FILLING) & 0x1ff; + + /* Get random point on a circle with the radius of 32 and walk + towards it. */ + if (th < 128) + { + vx += ctable[2*th]; + vy += ctable[2*th+1]; + } + else if (th < 256) + { + vx -= ctable[2*(th & 0x7f)+1]; + vy += ctable[2*(th & 0x7f)]; + } + else if (th < 384) + { + vx -= ctable[2*(th & 0x7f)]; + vy -= ctable[2*(th & 0x7f)+1]; + } + else + { + vx += ctable[2*(th & 0x7f)+1]; + vy -= ctable[2*(th & 0x7f)]; + } + + if (vx < 0) + vx += (LCD_COLUMN << 5); + if (vy < 0) + vy += (LCD_ROW << 5); + + /* Change draw color with joystick. */ + jo = joystick (); + if (JOYSTICK_L (jo)) + r = 0xfc; + if (JOYSTICK_R (jo)) + g = 0xfc; + if (JOYSTICK_U (jo)) + b = 0xfc; + if (JOYSTICK_D (jo)) + r = g = b = 0; + + /* 2-dim random walk on torus. */ + lcd_draw_point ((vx>>5)%LCD_COLUMN, (vy>>5)%LCD_ROW, r, g, b); + chopstx_usec_wait (10*1000); + + if (pbutton ()) + count++; + /* Shutdown when p-button is held down for 5 sec. */ + if (count > 500) + { + set_led (0); + shutdown (); + } + else + { + /* Disable backlight when p-button is held down for 3 sec. */ + if (count > 300) + set_backlight (0); + + /* Blink led when p-button is held. */ + if ((count/50) & 1) + set_led (0); + else + set_led (1); + } +#if 1 + lcd_printhex (count, 5, 8, 0x00, 0x00, 0xfc, 0xfc); +#endif + + } + + return 0; +} diff --git a/example-primer2/primer2-switches.c b/example-primer2/primer2-switches.c new file mode 100644 index 0000000..5ab73ac --- /dev/null +++ b/example-primer2/primer2-switches.c @@ -0,0 +1,73 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> +#include "board.h" + +#define PERIPH_BASE 0x40000000 +#define APBPERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) + +struct GPIO { + volatile uint32_t CRL; + volatile uint32_t CRH; + volatile uint32_t IDR; + volatile uint32_t ODR; + volatile uint32_t BSRR; + volatile uint32_t BRR; + volatile uint32_t LCKR; +}; + +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOA ((struct GPIO *) GPIOA_BASE) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOB ((struct GPIO *) GPIOB_BASE) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOC ((struct GPIO *) GPIOC_BASE) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#define GPIOD ((struct GPIO *) GPIOD_BASE) +#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) +#define GPIOE ((struct GPIO *) GPIOE_BASE) + +static struct GPIO *const GPIO_STICK = ((struct GPIO *const) GPIO_LED_BASE); +static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE); +static struct GPIO *const GPIO_OTHER1 = ((struct GPIO *const) GPIOC_BASE); +static struct GPIO *const GPIO_OTHER2 = ((struct GPIO *const) GPIOB_BASE); + +#define GPIO_STICK_L 3 +#define GPIO_STICK_R 4 +#define GPIO_STICK_U 5 +#define GPIO_STICK_D 6 +#define GPIO_SHUTDOWN 13 +#define GPIO_PBUTTON 8 +#define GPIO_BACKLIGHT 8 + +void +shutdown (void) +{ + GPIO_OTHER1->BRR = (1 << GPIO_SHUTDOWN); + GPIO_OTHER1->BSRR = (1 << GPIO_SHUTDOWN); + + while (1) + chopstx_usec_wait (500*1000); +} + +void +set_backlight (int on) +{ + if (on) + GPIO_OTHER2->BSRR = (1 << GPIO_BACKLIGHT); + else + GPIO_OTHER2->BRR = (1 << GPIO_BACKLIGHT); +} + +int +joystick (void) +{ + return (GPIO_STICK->IDR >> GPIO_STICK_L) & 0xf; +} + +int +pbutton (void) +{ + return (GPIO_OTHER->IDR >> GPIO_PBUTTON) & 1; +} diff --git a/example-primer2/primer2-switches.h b/example-primer2/primer2-switches.h new file mode 100644 index 0000000..e1d0c85 --- /dev/null +++ b/example-primer2/primer2-switches.h @@ -0,0 +1,9 @@ +extern void shutdown (void); +extern void set_backlight (int on); +extern int pbutton (void); +extern int joystick (void); + +#define JOYSTICK_L(x) ((x) & 1) +#define JOYSTICK_R(x) ((x) & 2) +#define JOYSTICK_U(x) ((x) & 4) +#define JOYSTICK_D(x) ((x) & 8) diff --git a/example-primer2/primer2-ts.c b/example-primer2/primer2-ts.c new file mode 100644 index 0000000..eb1c4ec --- /dev/null +++ b/example-primer2/primer2-ts.c @@ -0,0 +1,223 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> +#include "stm32f103.h" +#include "st7732.h" +#include "primer2-ts.h" + +/* ADC3 routines. */ + +#define ADC3_BASE (APB2PERIPH_BASE + 0x3c00) +static struct ADC *const ADC3 = (struct ADC *const)ADC3_BASE; + +#define RCC_APB2ENR_ADC3EN 0x8000 +#define RCC_APB2RSTR_ADC3RST 0x8000 + +#define ADC_SR_JEOC 0x0004 + +#define ADC_CR1_JEOCIE (1 << 7) + +#define ADC_CR2_JSWSTART (1 << 21) +#define ADC_CR2_JEXTTRIG (1 << 15) +#define ADC_CR2_JEXTSEL(n) ((n) << 12) + +#define ADC_JSQR_NUM_CH(n) (((n) - 1) << 20) +#define ADC_JSQR_JSQ1_N(n) ((n) << 0) +#define ADC_JSQR_JSQ2_N(n) ((n) << 5) +#define ADC_JSQR_JSQ3_N(n) ((n) << 10) +#define ADC_JSQR_JSQ4_N(n) ((n) << 15) + +#define ADC_CHANNEL_IN10 10 +#define ADC_CHANNEL_IN11 11 +#define ADC_CHANNEL_IN12 12 +#define ADC_CHANNEL_IN13 13 + +#define USE_ADC3_INTR 1 +#define INTR_REQ_ADC3 47 + +/* + * Do calibration for ADC3. + */ +void adc3_init (void) +{ + RCC->APB2ENR |= RCC_APB2ENR_ADC3EN; + RCC->APB2RSTR = RCC_APB2RSTR_ADC3RST; + RCC->APB2RSTR = 0; + + ADC3->CR1 = 0; + ADC3->CR2 = ADC_CR2_ADON; + ADC3->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL; + while ((ADC3->CR2 & ADC_CR2_RSTCAL) != 0) + ; + ADC3->CR2 = ADC_CR2_ADON | ADC_CR2_CAL; + while ((ADC3->CR2 & ADC_CR2_CAL) != 0) + ; + ADC3->CR2 = 0; + RCC->APB2ENR &= ~RCC_APB2ENR_ADC3EN; +} + +static chopstx_intr_t adc3_intr; + +void +adc3_start (void) +{ + RCC->APB2ENR |= RCC_APB2ENR_ADC3EN; + +#if USE_ADC3_INTR + ADC3->CR1 = ADC_CR1_SCAN | ADC_CR1_JEOCIE; +#else + ADC3->CR1 = ADC_CR1_SCAN; +#endif + ADC3->CR2 = ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL(7) | ADC_CR2_ADON; + ADC3->SMPR1 = 0xfff; + ADC3->SMPR2 = 0; + ADC3->JSQR = (ADC_JSQR_NUM_CH(4) | ADC_JSQR_JSQ4_N(ADC_CHANNEL_IN13) + | ADC_JSQR_JSQ3_N(ADC_CHANNEL_IN12) + | ADC_JSQR_JSQ2_N(ADC_CHANNEL_IN11) + | ADC_JSQR_JSQ1_N(ADC_CHANNEL_IN10)); + +#if USE_ADC3_INTR + chopstx_claim_irq (&adc3_intr, INTR_REQ_ADC3); +#endif +} + +void adc3_conversion (uint32_t *result) +{ + + /* Start conversion. */ + ADC3->CR2 |= ADC_CR2_JSWSTART; + +#if USE_ADC3_INTR + chopstx_intr_wait (&adc3_intr); +#else + while (1) + { + chopstx_usec_wait (1000); + if (ADC3->SR & ADC_SR_JEOC) + break; + } +#endif + ADC3->SR &= ~ADC_SR_JEOC; + + result[0] = ADC3->JDR1; + result[1] = ADC3->JDR2; + result[2] = ADC3->JDR3; + result[3] = ADC3->JDR4; + + /* Stop conversion. */ + ADC3->CR2 &= ~ADC_CR2_JSWSTART; + + return; +} + +void adc3_stop (void) +{ + +#if USE_ADC3_INTR + chopstx_release_irq (&adc3_intr); +#endif + + /* Power off. */ + ADC3->CR1 = 0; + ADC3->CR2 = 0; + + RCC->APB2ENR &= ~RCC_APB2ENR_ADC3EN; +} + +/* Touch screen routines. */ + +int +ts_pushed (uint32_t u) +{ + return (u < 0xc00); +} + +#define FILTER_SIZE 8 + +static void +ts_filter (int buf[FILTER_SIZE][2], int result[2]) +{ + int s0, s1; + int i; + + s0 = 0; + s1 = 0; + for (i = 0; i < FILTER_SIZE; i++) + { + s0 += buf[i][0]; + s1 += buf[i][1]; + } + + result[0] = s0/FILTER_SIZE; + result[1] = s1/FILTER_SIZE; +} + +/* Simple model of primer2 touch screen: + Vdd-[R1]-[Ry]-[Rp]-[Rx]-Vss + U D l R + where R1=1k external register, Rx(resp. Ry)=resisitive component on + X(resp. Y) film and Rp=resisitive component of contact point. + Convert [L, R, U, D] to [Rx, Ry, Rp]. */ +void +ts_conversion (uint32_t a[], int r[]) +{ + int l, u, d, ir1; + int x, y, rp; + + l = a[0] & 0xfff; + u = a[2] & 0xfff; + d = a[3] & 0xfff; + ir1 = 4096 - u; + /* r1 = 1000 */ + x = (1000 * l)/ir1; + y = (1000 * (u - d))/ir1; + rp = (1000 * (d - l))/ir1; + r[0] = x; + r[1] = y; + r[2] = rp; +} + +int +ts_adjust (int *r, int *cord) +{ + int x, y; + static int buf[FILTER_SIZE][2]; + static int i = 0; + static int fill = 0; + + if (!r) + { + i = 0; + fill = 0; + return 0; + } + + /* TODO: We might need calibration. */ + x = (LCD_COLUMN * (r[0] - 0x20))/0x100; + y = (LCD_ROW * (0x1e0 - r[1]))/0x1c0; + + if (x < 0) + x = 0; + if (x >= LCD_COLUMN) + x = LCD_COLUMN - 1; + if (y < 0) + y = 0; + if (y >= LCD_ROW) + y = LCD_ROW - 1; + + buf[i][0] = x; + buf[i][1] = y; + + i++; + if (i >= FILTER_SIZE) + { + i = 0; + fill = 1; + } + + if (!fill) + return 0; + + ts_filter (buf, cord); + return 1; +} diff --git a/example-primer2/primer2-ts.h b/example-primer2/primer2-ts.h new file mode 100644 index 0000000..552d6db --- /dev/null +++ b/example-primer2/primer2-ts.h @@ -0,0 +1,8 @@ +extern void adc3_init (void); +extern void adc3_start (void); +extern void adc3_conversion (uint32_t *result); +extern void adc3_stop (void); + +extern int ts_pushed (uint32_t u); +extern void ts_conversion (uint32_t a[], int r[]); +extern int ts_adjust (int r[], int cord[]); diff --git a/example-primer2/st7732.h b/example-primer2/st7732.h new file mode 100644 index 0000000..bc684d7 --- /dev/null +++ b/example-primer2/st7732.h @@ -0,0 +1,83 @@ +/* ST7732 LCD driver chip command byte. + command_name = value read_n_bytes:write_n_bytes: simple description */ +enum st7732_cmd { + NOP = 0x00, /* 0:0: No Operatin */ + SWRESET = 0x01, /* 0:0: Software reset */ + RDDID = 0x04, /* 0:3: Read Display ID */ + RDRST = 0x09, /* 0:4: Read Display Status */ + RDDPM = 0x0a, /* 0:1: Read Display Power Mode */ + RDD_MADCTL = 0x0b, /* 0:1: Read Display MADCTL */ + RDD_COLMOD = 0x0c, /* 0:1: Read Display Pixel Format */ + RDDIM = 0x0d, /* 0:1: Read Display Image Mode */ + RDDSM = 0x0e, /* 0:1: Read Display Signal Mode */ + RDDSDR = 0x0f, /* 0:1: Read Display Self-diagnostic result */ + SLPIN = 0x10, /* 0:0: Sleep in & booster off */ + SLPOUT = 0x11, /* 0:0: Sleep out & booster on */ + PTLON = 0x12, /* 0:0: Pertial mode on */ + NORON = 0x13, /* 0:0: Normal mode on (Pertial off) */ + INVOFF = 0x20, /* 0:0: Display inversion off */ + INVON = 0x21, /* 0:0: Display inversion on */ + GAMSET = 0x26, /* 1:0: Gamma curve select */ + DISPOFF = 0x28, /* 0:0: Display off */ + DISPON = 0x29, /* 0:0: Display on */ + CASET = 0x2a, /* 4:0: Column address set */ + RASET = 0x2b, /* 4:0: Raw address set */ + RAMWR = 0x2c, /* 1:0: Memory write */ + RAMRD = 0x2e, /* 0:1: Memory read */ + PTLAR = 0x30, /* 4:0: Partial start/end address set */ + SCRLAR = 0x33, /* 6:0: Scroll area set */ + TEOFF = 0x34, /* 0:0: Tearing effect line off */ + TEON = 0x35, /* 1:0: Tearing effect mode set & on */ + MADCTL = 0x36, /* 1:0: Memory data access control */ + VSCSAD = 0x37, /* 2:0: Scroll start address of RAM */ + IDMOFF = 0x38, /* 0:0: Idle mode off */ + IDMON = 0x39, /* 0:0: Idle mode on */ + COLMOD = 0x3a, /* 1:0: Interface pixel format */ + RDID1 = 0xda, /* 0:1: Read ID1 */ + RDID2 = 0xdb, /* 0:1: Read ID2 */ + RDID3 = 0xdc, /* 0:1: Read ID3 */ + RGBCTR = 0xb0, /* 1:0: Set RGB signal control */ + FRMCTR1 = 0xb1, /* 3:0: In normal mode */ + FRMCTR2 = 0xb2, /* 3:0: In Idel mode (8-colors) */ + FRMCTR3 = 0xb3, /* 6:0: In partial mode + Full colors */ + INVCTR = 0xb4, /* 1:0: Display inversion control */ + RGB_BPCTR = 0xb5, /* 4:0: RGB I/F Blanking porch setting */ + DISSET5 = 0xb6, /* 2:0: Display function setting */ + PWCTR1 = 0xc0, /* 2:0: Power control setting */ + PWCTR2 = 0xc1, /* 1:0: Power control setting */ + PWCTR3 = 0xc2, /* 2:0: Power control setting (Full colors) */ + PWCTR4 = 0xc3, /* 2:0: Power control setting (8-colors) */ + PWCTR5 = 0xc4, /* 2:0: Power control setting (In partial mode) */ + VMCTR1 = 0xc5, /* 2:0: VCOM control */ + VMOFCTR = 0xc6, /* 1:0: VCOM offset control */ + WRID2 = 0xd1, /* 1:0: Write ID2 value to NV */ + WRID3 = 0xd2, /* 1:0: Write ID3 value to NV */ + RDID4 = 0xd3, /* 0:4: IC Vender code */ + NVCTR1 = 0xd9, /* 0:1:no-fummy NVM control status */ + NVCTR2 = 0xde, /* 3:0: NVM read command (aa, 0f, a5) */ + NVCTR3 = 0xdf, /* 3:0: NVM write command (55, f0, 5a) */ + GAMCTRP1 = 0xe0, /* 13:0: Set Gamma correction + */ + GAMCTRN1 = 0xe1, /* 13:0: Set Gamma correction - */ + AUTO_CTRL = 0xf1, /* 1:0: NVM write function ON/OFF */ + OSCADJ = 0xf2, /* 1:0: Osillator frequency setting */ + DISPCTRL = 0xf5, /* 1:0: Display function control */ + DEFADJ = 0xf6, /* 1:0: Default mode setting */ +}; + +typedef enum st7732_cmd st7732_cmd_t; + +extern void lcd_command_no (st7732_cmd_t cmd); +extern void lcd_command_readn (st7732_cmd_t cmd, uint8_t *p, size_t n); +extern void lcd_command_writen (st7732_cmd_t cmd, uint8_t *p, size_t n); +extern void lcd_command_filln (st7732_cmd_t cmd, uint8_t b, size_t n); +extern void lcd_init (void); + +extern void lcd_draw_point (int x, int y, int r, int g, int b); +extern void lcd_draw_hexfont5x8 (uint32_t hex, int x, int y, int r, int g, + int b, int bg); +extern void lcd_printhex (uint32_t hex, int x, int y, int r, int g, int b, + int bg); + +#define LCD_COLUMN 128 +#define LCD_ROW 160 +#define BYTES_PER_PIXEL 3 diff --git a/example-primer2/sys.c b/example-primer2/sys.c new file mode 100644 index 0000000..6481703 --- /dev/null +++ b/example-primer2/sys.c @@ -0,0 +1,467 @@ +/* + * sys.c - system routines for the initial page for STM32F103. + * + * Copyright (C) 2013, 2014, 2015 Flying Stone Technology + * Author: NIIBE Yutaka <gniibe@fsij.org> + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + * + * When the flash ROM is protected, we cannot modify the initial page. + * We put some system routines (which is useful for any program) here. + */ + +#include <stdint.h> +#include <stdlib.h> +#include "board.h" + +/* Adds port C for shutdown function. */ +#undef RCC_ENR_IOP_EN +#undef RCC_RSTR_IOP_RST +#define RCC_ENR_IOP_EN \ + (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_IOPEEN \ + | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPBEN) +#define RCC_RSTR_IOP_RST \ + (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPDRST | RCC_APB2RSTR_IOPERST \ + | RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPBRST) + +#include "clk_gpio_init.c" + +static struct GPIO *const GPIO_OTHER1 = ((struct GPIO *const) GPIOC_BASE); +static struct GPIO *const GPIO_OTHER2 = ((struct GPIO *const) GPIOB_BASE); + +static void __attribute__((used)) +gpio_init_primer2 (void) +{ + gpio_init (); + + /* + * Port C setup. + * Everything input with pull-up except: + * PC0 - Analog input (Touch panel L X+) + * PC1 - Analog input (Touch panel R X-) + * PC2 - Analog input (Touch panel U Y+) + * PC3 - Analog input (Touch panel D Y-) + * PC6 - Normal input because there is an external resistor. + * PC7 - Normal input because there is an external resistor. + * PC13 - Push Pull output (SHUTDOWN) + */ + GPIO_OTHER1->ODR = 0xffffdfff; + GPIO_OTHER1->CRL = 0x44880000; + GPIO_OTHER1->CRH = 0x88388888; + + /* + * Port B setup. + * Everything input with pull-up except: + * PB8 - Backlight enable output. + * PB13 - Alternate output (AUDIO SPI2 SCK). + * PB14 - Normal input (AUDIO SPI2 MISO). + * PB15 - Alternate output (AUDIO SPI2 MOSI). + */ + GPIO_OTHER2->ODR = 0xffffffff; + GPIO_OTHER2->CRL = 0x88888888; + GPIO_OTHER2->CRH = 0xb4b88883; +} + +#define CORTEX_PRIORITY_BITS 4 +#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS)) +#define USB_LP_CAN1_RX0_IRQn 20 +#define STM32_USB_IRQ_PRIORITY 11 + +struct NVIC { + uint32_t ISER[8]; + uint32_t unused1[24]; + uint32_t ICER[8]; + uint32_t unused2[24]; + uint32_t ISPR[8]; + uint32_t unused3[24]; + uint32_t ICPR[8]; + uint32_t unused4[24]; + uint32_t IABR[8]; + uint32_t unused5[56]; + uint32_t IPR[60]; +}; + +static struct NVIC *const NVICBase = ((struct NVIC *const)0xE000E100); +#define NVIC_ISER(n) (NVICBase->ISER[n >> 5]) +#define NVIC_ICPR(n) (NVICBase->ICPR[n >> 5]) +#define NVIC_IPR(n) (NVICBase->IPR[n >> 2]) + +static void +nvic_enable_vector (uint32_t n, uint32_t prio) +{ + unsigned int sh = (n & 3) << 3; + + NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh)) | (prio << sh); + NVIC_ICPR (n) = 1 << (n & 0x1F); + NVIC_ISER (n) = 1 << (n & 0x1F); +} + +static void +usb_cable_config (int enable) +{ +#if defined(GPIO_USB_SET_TO_ENABLE) + if (enable) + GPIO_USB->BSRR = (1 << GPIO_USB_SET_TO_ENABLE); + else + GPIO_USB->BRR = (1 << GPIO_USB_SET_TO_ENABLE); +#elif defined(GPIO_USB_CLEAR_TO_ENABLE) + if (enable) + GPIO_USB->BRR = (1 << GPIO_USB_CLEAR_TO_ENABLE); + else + GPIO_USB->BSRR = (1 << GPIO_USB_CLEAR_TO_ENABLE); +#else + (void)enable; +#endif +} + +void +set_led (int on) +{ +#if defined(GPIO_LED_CLEAR_TO_EMIT) + if (on) + GPIO_LED->BRR = (1 << GPIO_LED_CLEAR_TO_EMIT); + else + GPIO_LED->BSRR = (1 << GPIO_LED_CLEAR_TO_EMIT); +#else + if (on) + GPIO_LED->BSRR = (1 << GPIO_LED_SET_TO_EMIT); + else + GPIO_LED->BRR = (1 << GPIO_LED_SET_TO_EMIT); +#endif +} + +static void wait (int count) +{ + int i; + + for (i = 0; i < count; i++) + asm volatile ("" : : "r" (i) : "memory"); +} + + +static void +usb_lld_sys_shutdown (void) +{ + RCC->APB1ENR &= ~RCC_APB1ENR_USBEN; + RCC->APB1RSTR = RCC_APB1RSTR_USBRST; + usb_cable_config (0); +} + +static void +usb_lld_sys_init (void) +{ + if ((RCC->APB1ENR & RCC_APB1ENR_USBEN) + && (RCC->APB1RSTR & RCC_APB1RSTR_USBRST) == 0) + /* Make sure the device is disconnected, even after core reset. */ + { + usb_lld_sys_shutdown (); + /* Disconnect requires SE0 (>= 2.5uS). */ + wait (300); + } + + usb_cable_config (1); + RCC->APB1ENR |= RCC_APB1ENR_USBEN; + nvic_enable_vector (USB_LP_CAN1_RX0_IRQn, + CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY)); + /* + * Note that we also have other IRQ(s): + * USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous) + * USBWakeUp_IRQn (suspend/resume) + */ + RCC->APB1RSTR = RCC_APB1RSTR_USBRST; + RCC->APB1RSTR = 0; +} + +#define FLASH_KEY1 0x45670123UL +#define FLASH_KEY2 0xCDEF89ABUL + +enum flash_status +{ + FLASH_BUSY = 1, + FLASH_ERROR_PG, + FLASH_ERROR_WRP, + FLASH_COMPLETE, + FLASH_TIMEOUT +}; + +static void __attribute__ ((used)) +flash_unlock (void) +{ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; +} + + +#define intr_disable() asm volatile ("cpsid i" : : : "memory") +#define intr_enable() asm volatile ("cpsie i" : : : "memory") + +#define FLASH_SR_BSY 0x01 +#define FLASH_SR_PGERR 0x04 +#define FLASH_SR_WRPRTERR 0x10 +#define FLASH_SR_EOP 0x20 + +#define FLASH_CR_PG 0x0001 +#define FLASH_CR_PER 0x0002 +#define FLASH_CR_MER 0x0004 +#define FLASH_CR_OPTPG 0x0010 +#define FLASH_CR_OPTER 0x0020 +#define FLASH_CR_STRT 0x0040 +#define FLASH_CR_LOCK 0x0080 +#define FLASH_CR_OPTWRE 0x0200 +#define FLASH_CR_ERRIE 0x0400 +#define FLASH_CR_EOPIE 0x1000 + +static int +flash_wait_for_last_operation (uint32_t timeout) +{ + int status; + + do + { + status = FLASH->SR; + if (--timeout == 0) + break; + } + while ((status & FLASH_SR_BSY) != 0); + + return status & (FLASH_SR_BSY|FLASH_SR_PGERR|FLASH_SR_WRPRTERR); +} + +#define FLASH_PROGRAM_TIMEOUT 0x00010000 +#define FLASH_ERASE_TIMEOUT 0x01000000 + +static int +flash_program_halfword (uint32_t addr, uint16_t data) +{ + int status; + + status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->CR |= FLASH_CR_PG; + + *(volatile uint16_t *)addr = data; + + status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); + FLASH->CR &= ~FLASH_CR_PG; + } + intr_enable (); + + return status; +} + +static int +flash_erase_page (uint32_t addr) +{ + int status; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->CR |= FLASH_CR_PER; + FLASH->AR = addr; + FLASH->CR |= FLASH_CR_STRT; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + FLASH->CR &= ~FLASH_CR_PER; + } + intr_enable (); + + return status; +} + +static int +flash_check_blank (const uint8_t *p_start, size_t size) +{ + const uint8_t *p; + + for (p = p_start; p < p_start + size; p++) + if (*p != 0xff) + return 0; + + return 1; +} + +extern uint8_t __flash_start__, __flash_end__; + +static int +flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) +{ + int status; + uint32_t flash_start = (uint32_t)&__flash_start__; + uint32_t flash_end = (uint32_t)&__flash_end__; + + if (dst_addr < flash_start || dst_addr + len > flash_end) + return 0; + + while (len) + { + uint16_t hw = *src++; + + hw |= (*src++ << 8); + status = flash_program_halfword (dst_addr, hw); + if (status != 0) + return 0; /* error return */ + + dst_addr += 2; + len -= 2; + } + + return 1; +} + +#define OPTION_BYTES_ADDR 0x1ffff800 + +static int +flash_protect (void) +{ + int status; + uint32_t option_bytes_value; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + + FLASH->CR |= FLASH_CR_OPTER; + FLASH->CR |= FLASH_CR_STRT; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + FLASH->CR &= ~FLASH_CR_OPTER; + } + intr_enable (); + + if (status != 0) + return 0; + + option_bytes_value = *(uint32_t *)OPTION_BYTES_ADDR; + return (option_bytes_value & 0xff) == 0xff ? 1 : 0; +} + +static void __attribute__((naked)) +flash_erase_all_and_exec (void (*entry)(void)) +{ + uint32_t addr = (uint32_t)&__flash_start__; + uint32_t end = (uint32_t)&__flash_end__; + int r; + + while (addr < end) + { + r = flash_erase_page (addr); + if (r != 0) + break; + + addr += FLASH_PAGE_SIZE; + } + + if (addr >= end) + (*entry) (); + + for (;;); +} + +struct SCB +{ + volatile uint32_t CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint8_t SHP[12]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; + volatile uint32_t PFR[2]; + volatile uint32_t DFR; + volatile uint32_t ADR; + volatile uint32_t MMFR[4]; + volatile uint32_t ISAR[5]; +}; + +#define SCS_BASE (0xE000E000) +#define SCB_BASE (SCS_BASE + 0x0D00) +static struct SCB *const SCB = ((struct SCB *const) SCB_BASE); + +#define SYSRESETREQ 0x04 +static void +nvic_system_reset (void) +{ + SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ); + asm volatile ("dsb"); + for (;;); +} + +static void __attribute__ ((naked)) +reset (void) +{ + extern const unsigned long *FT0, *FT1, *FT2; + + /* + * This code may not be at the start of flash ROM, because of DFU. + * So, we take the address from PC. + */ + asm volatile ("cpsid i\n\t" /* Mask all interrupts. */ + "ldr r0, 1f\n\t" /* r0 = SCR */ + "mov r1, pc\n\t" /* r1 = (PC + 0x1000) & ~0x0fff */ + "mov r2, #0x1000\n\t" + "add r1, r1, r2\n\t" + "sub r2, r2, #1\n\t" + "bic r1, r1, r2\n\t" + "str r1, [r0, #8]\n\t" /* Set SCR->VCR */ + "ldr r0, [r1], #4\n\t" + "msr MSP, r0\n\t" /* Main (exception handler) stack. */ + "ldr r0, [r1]\n\t" /* Reset handler. */ + "bx r0\n\t" + ".align 2\n" + "1: .word 0xe000ed00" + : /* no output */ : /* no input */ : "memory"); + + /* Never reach here. */ + /* Artificial entry to refer FT0, FT1, and FT2. */ + asm volatile ("" + : : "r" (FT0), "r" (FT1), "r" (FT2)); +} + +typedef void (*handler)(void); +extern uint8_t __ram_end__; + +handler vector[] __attribute__ ((section(".vectors"))) = { + (handler)&__ram_end__, + reset, + (handler)set_led, + flash_unlock, + (handler)flash_program_halfword, + (handler)flash_erase_page, + (handler)flash_check_blank, + (handler)flash_write, + (handler)flash_protect, + (handler)flash_erase_all_and_exec, + usb_lld_sys_init, + usb_lld_sys_shutdown, + nvic_system_reset, + clock_init, + gpio_init_primer2, + NULL, +}; + +const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = { + 3*2+2, /* bLength */ + 0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE*/ + /* sys version: "2.0" */ + '2', 0, '.', 0, '0', 0, +}; diff --git a/example-primer2/sys.h b/example-primer2/sys.h new file mode 100644 index 0000000..25d33f1 --- /dev/null +++ b/example-primer2/sys.h @@ -0,0 +1,115 @@ +extern const uint8_t sys_version[8]; + +typedef void (*handler)(void); +extern handler vector[16]; + +static inline const uint8_t * +unique_device_id (void) +{ + /* STM32F103 has 96-bit unique device identifier */ + const uint8_t *addr = (const uint8_t *)0x1ffff7e8; + + return addr; +} + +static inline void +set_led (int on) +{ + void (*func) (int) = (void (*)(int))vector[2]; + + return (*func) (on); +} + +static inline void +flash_unlock (void) +{ + (*vector[3]) (); +} + +static inline int +flash_program_halfword (uint32_t addr, uint16_t data) +{ + int (*func) (uint32_t, uint16_t) = (int (*)(uint32_t, uint16_t))vector[4]; + + return (*func) (addr, data); +} + +static inline int +flash_erase_page (uint32_t addr) +{ + int (*func) (uint32_t) = (int (*)(uint32_t))vector[5]; + + return (*func) (addr); +} + +static inline int +flash_check_blank (const uint8_t *p_start, size_t size) +{ + int (*func) (const uint8_t *, int) = (int (*)(const uint8_t *, int))vector[6]; + + return (*func) (p_start, size); +} + +static inline int +flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) +{ + int (*func) (uint32_t, const uint8_t *, size_t) + = (int (*)(uint32_t, const uint8_t *, size_t))vector[7]; + + return (*func) (dst_addr, src, len); +} + +static inline int +flash_protect (void) +{ + int (*func) (void) = (int (*)(void))vector[8]; + + return (*func) (); +} + +static inline void __attribute__((noreturn)) +flash_erase_all_and_exec (void (*entry)(void)) +{ + void (*func) (void (*)(void)) = (void (*)(void (*)(void)))vector[9]; + + (*func) (entry); + for (;;); +} + +static inline void +usb_lld_sys_init (void) +{ + (*vector[10]) (); +} + +static inline void +usb_lld_sys_shutdown (void) +{ + (*vector[11]) (); +} + +static inline void +nvic_system_reset (void) +{ + (*vector[12]) (); +} + +/* + * Users can override INLINE by 'attribute((used))' to have an + * implementation defined. + */ +#if !defined(INLINE) +#define INLINE __inline__ +#endif + +static INLINE void +clock_init (void) +{ + (*vector[13]) (); +} + +static INLINE void +gpio_init (void) +{ + (*vector[14]) (); +} |