Compare commits

62 Commits

Author SHA1 Message Date
NIIBE Yutaka
14ad395523 Version 0.09 2015-09-10 20:22:32 +09:00
NIIBE Yutaka
acd4460a6e Update API doc 2015-09-09 17:06:51 +09:00
NIIBE Yutaka
79b13fb4a9 Cancellation fixes 2015-09-09 17:04:59 +09:00
NIIBE Yutaka
e9521648d5 move exception handling routines 2015-09-09 11:55:17 +09:00
NIIBE Yutaka
2bd7a8e6db move svc, preempt, and sched 2015-09-09 11:35:20 +09:00
NIIBE Yutaka
c57b13bedc factor out chx_prio_init 2015-09-09 11:06:52 +09:00
NIIBE Yutaka
06e4459c21 factoring: systick 2015-09-09 09:47:25 +09:00
NIIBE Yutaka
baef99bf11 fix white spaces 2015-09-08 17:19:14 +09:00
NIIBE Yutaka
1b25cc5dcb fix more spin lock 2015-09-08 17:14:43 +09:00
NIIBE Yutaka
ee3c5d4e6f prepare kkojima's patch for Cortex-A7 2015-09-08 17:06:53 +09:00
NIIBE Yutaka
80408902d7 fix spin-locking of INTR_TOP 2015-09-08 14:46:11 +09:00
NIIBE Yutaka
f6d79e6821 Add Mateusz Zalega 2015-09-07 17:10:42 +09:00
NIIBE Yutaka
014dbf25f6 Add example-primer2 2015-09-07 17:06:05 +09:00
NIIBE Yutaka
41610443d4 Netrokey Start change 2015-09-07 15:52:38 +09:00
NIIBE Yutaka
46468760a3 Nitrokey start support 2015-09-04 17:09:56 +09:00
NIIBE Yutaka
85ef4a5391 Fix for Nitrokey-start 2015-09-04 16:43:45 +09:00
Mateusz Zalega
8650bde8a0 board: add Nitrokey Start
Signed-off-by: Mateusz Zalega <mateusz@nitrokey.com>
2015-09-04 16:38:01 +09:00
NIIBE Yutaka
6e7334dcff Fix the score about A and tone-table change 2015-08-08 13:50:20 +09:00
NIIBE Yutaka
04a948024a Celebrate Happy Hacking Day. 2015-08-06 11:10:48 +09:00
NIIBE Yutaka
1bbbaabe0d Add a speaker 2015-08-06 11:02:34 +09:00
NIIBE Yutaka
218102c5c4 Version 0.08 2015-07-31 17:58:20 +09:00
NIIBE Yutaka
2c9e6b69d2 update example-fsm-55 2015-07-31 17:56:35 +09:00
NIIBE Yutaka
1d38c24233 Add Nucleo 2015-07-30 20:35:21 +09:00
NIIBE Yutaka
a9de53c36b board update, adding ST Dongle 2015-07-29 17:06:17 +09:00
NIIBE Yutaka
83486efd5f update USB driver 2015-07-28 15:09:43 +09:00
NIIBE Yutaka
bdaae5661d Version 0.07 2015-07-15 12:09:07 +09:00
NIIBE Yutaka
2de0e2c405 Update example CDC 2015-07-15 12:04:45 +09:00
NIIBE Yutaka
d19570954e Update example for FSM-55 2015-07-15 12:03:49 +09:00
NIIBE Yutaka
44b4bf640f Update example for LED blink 2015-07-15 12:01:53 +09:00
NIIBE Yutaka
9898639165 Update Cortex-M0 boards 2015-07-15 11:48:36 +09:00
NIIBE Yutaka
cd61ff5653 share sys with example-fsm-55 2015-07-15 09:51:24 +09:00
NIIBE Yutaka
27f42c8522 ADC settings are consolidated into the driver 2015-07-14 21:31:18 +09:00
NIIBE Yutaka
a48ffaef47 fix sys.c 2015-07-14 21:26:10 +09:00
NIIBE Yutaka
27f71ff5c0 New sys.c 2015-07-14 16:10:07 +09:00
NIIBE Yutaka
3ba8234cec sys_board and stm32 primer2 2015-07-13 16:45:32 +09:00
NIIBE Yutaka
2bb0e0de5d Version 0.06 2015-07-08 08:38:18 +09:00
NIIBE Yutaka
4dc10d6b18 Update for FSM-55 2015-07-07 12:31:15 +09:00
NIIBE Yutaka
43bd3bcefd fix STBee Mini 2015-06-30 10:47:07 +09:00
NIIBE Yutaka
6d13bd3770 fix clk_gpio_init 2015-06-30 10:20:11 +09:00
NIIBE Yutaka
6665723154 Add support for CQ STARM. 2015-06-29 15:59:30 +09:00
NIIBE Yutaka
97b4471cee Make it clear LED is mandatory. 2015-06-29 15:58:21 +09:00
NIIBE Yutaka
15ae2d8b32 cleanup entry.c 2015-06-29 13:48:30 +09:00
NIIBE Yutaka
48273b3cb6 Clean up clock/gpio code 2015-06-22 17:34:17 +09:00
NIIBE Yutaka
b298648079 Kaz Kojima add STM32 Primer2 support 2015-06-22 16:18:44 +09:00
NIIBE Yutaka
fc26cf0889 Version 0.05
Merge branch 'cortex-m0-support'
2015-04-20 14:17:40 +09:00
NIIBE Yutaka
18b38533f7 Merge branch 'master' of git.gniibe.org:chopstx/chopstx
Conflicts:
	ChangeLog
2015-04-18 12:28:00 +09:00
NIIBE Yutaka
a0f33c1036 New: chopstx_main_init 2015-04-18 12:23:35 +09:00
NIIBE Yutaka
431e62a077 Add board-maple-mini.h 2015-04-08 09:16:25 +09:00
NIIBE Yutaka
7c022432d1 fix rebase 2014-12-10 18:53:00 +09:00
NIIBE Yutaka
b0992073d7 Add debian-logo.c (from Portland). 2014-12-10 18:50:11 +09:00
NIIBE Yutaka
5f4cca00fc It should be BSS section not to output data to .hex. 2014-12-10 18:50:10 +09:00
NIIBE Yutaka
1fcfc846b8 Button pushed, then another demo. 2014-12-10 18:50:10 +09:00
NIIBE Yutaka
f4fb26a56a add button thread and join on exit. 2014-12-10 18:50:10 +09:00
NIIBE Yutaka
98e25c1cb2 Add GNU as hidden command. 2014-12-10 18:50:10 +09:00
NIIBE Yutaka
aeb8bd5a95 l55 and hh only. 2014-12-10 18:50:10 +09:00
NIIBE Yutaka
447b11fd1c Add Happy Hacking. 2014-12-10 18:50:10 +09:00
NIIBE Yutaka
f4f2afd0ad Use SIZE55. 2014-12-10 18:50:10 +09:00
NIIBE Yutaka
dffcf2d4bf fix col/row. 2014-12-10 18:50:10 +09:00
NIIBE Yutaka
b05e4030d2 Add example-fsm-55. 2014-12-10 18:50:09 +09:00
NIIBE Yutaka
f865e5149c Add FSM-55. 2014-12-10 18:50:09 +09:00
NIIBE Yutaka
5137db8290 Cortex-M0 works. 2014-12-10 18:50:09 +09:00
NIIBE Yutaka
522380097e Support Cortex-M0. 2014-12-10 18:49:02 +09:00
66 changed files with 6941 additions and 1409 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,3 @@
*/board.h
*/build
*/.dep
doc/chopstx.info

37
AUTHORS Normal file
View File

@@ -0,0 +1,37 @@
Aidan Thornton:
Added Maple Mini support.
board/board-maple-mini.h
Kaz Kojima:
Added STM32 Primer2 support.
board/board-stm32-primer2.h
example-primer2
Kenji Rikitake:
Added ST Dongle support.
board/board-st-dongle.h
Added ST Nucleo F103 support.
board/board-st-nucleo-f103.h
Kiwamu Okabe:
Wrote an OpenOCD scirpt:
example-fsm-55/stlink-v2.cfg
Mateusz Zalega:
Added Nitrokey-Start support.
board/board-nitrokey-start.h
NIIBE Yutaka:
Write the library:
chopstx.c, eventflag.c, entry.c, clk_gpio_init.c
chopstx.h, eventflag.h
Draw the logo:
chopstx.svg, chopstx.png
Write examples:
example-led, example-cdc, example-fsm-55
Write board:
board-fst-01.h, board-fst-01-00.h,
board-olimex-stm32-h103.h, board-stm8s-discovery.h
board-cq-starm.h, board-stbee-mini.h, board-stbee.h,
board-stm32f0-discovery.h, board-fsm-55.h

174
ChangeLog
View File

@@ -1,3 +1,177 @@
2015-09-10 Niibe Yutaka <gniibe@fsij.org>
* VERSION: 0.09.
* doc/chopstx.texi (VERSION): 0.09.
* chopstx.c (chx_release_irq_thread): Rename.
2015-09-09 Niibe Yutaka <gniibe@fsij.org>
* example-cdc/usb-cdc.c (usb_cb_ctrl_write_finish): Distinguish
DTR signal.
(usb_cb_device_reset): Fix USB reset handling.
* chopstx.c (chopstx_usec_wait_var, chopstx_cond_wait)
(chopstx_intr_wait): Call chopstx_testcancel.
(chopstx_setcancelstate): New.
* chopstx.c (chx_systick_reset, chx_systick_reload)
(chx_systick_get): Factor out systick functions.
(chx_prio_init): Factor out.
2015-09-08 Niibe Yutaka <gniibe@fsij.org>
* chopstx.c (chx_request_preemption): Add PRIO argument and check
the condition inside.
(chx_timer_expired, chx_handle_intr): Call unconditionally.
(intr_lock): New variable.
(chx_handle_intr, chopstx_claim_irq, chopstx_release_irq)
(chopstx_release_irq_thread): Add spin lock with intr_lock.
* chopstx.h (chx_intr): Remove member LOCK.
2015-09-07 Niibe Yutaka <gniibe@fsij.org>
* example-primer2: New from Kazumoto Kojima.
* board/board-nitrokey-start.h (VAL_GPIO_USB_ODR)
(VAL_GPIO_USB_CRL): Fix the values for NeuG settings.
2015-09-04 Niibe Yutaka <gniibe@fsij.org>
* example-cdc/sys.h (BOARD_ID_NITROKEY_START): New.
* board/board-nitrokey-start.h (BOARD_ID): Fix the value.
* clk_gpio_init.c (AFIO_MAPR_SWJ_CFG_JTAGDISABLE): New.
2015-08-07 Mateusz Zalega <mateusz@nitrokey.com>
* board/board-nitrokey-start.h: New.
2015-08-06 Niibe Yutaka <gniibe@fsij.org>
* example-fsm-55/README: Updated.
2015-07-31 Niibe Yutaka <gniibe@fsij.org>
* VERSION: 0.08.
* doc/chopstx.texi (VERSION): 0.08.
* example-fsm-55/Makefile (DEFS): Remove HAVE_SYS_H.
Add MAKE_ENTRY_PUBLIC.
* example-fsm-55/hacker-emblem.ld: Put vectors on ROM.
* example-fsm-55/sys.c: No system services.
* entry.c (entry): Can be public.
* clk_gpio_init.c [MCU_STM32F0] (clock_init): Don't change CFGR1.
2015-07-30 Niibe Yutaka <gniibe@fsij.org>
* board/board-st-nucleo-f103.h: New. Contributed by Kenji
Rikitake.
2015-07-29 Niibe Yutaka <gniibe@fsij.org>
* board/board-st-dongle.h: New. Contributed by Kenji Rikitake.
* board/board-*.h (FLASH_PAGE_SIZE): Remove.
2015-07-28 Niibe Yutaka <gniibe@fsij.org>
* example-cdc/usb_stm32f103.c: Update from Gnuk.
* example-cdc/usb_lld.h: Ditto.
* example-cdc/usb-cdc.c: Follow the change.
2015-07-15 Niibe Yutaka <gniibe@fsij.org>
* VERSION: 0.07.
* doc/chopstx.texi (VERSION): 0.07.
2015-07-14 Niibe Yutaka <gniibe@fsij.org>
* board/board-*.h (BOARD_ID): New.
* example-cdc/sys.c (sys_board_id): New.
* example-cdc/sample.ld (.sys.board_id): New.
(__flash_start__, __flash_end__): Remove.
* entry.c [HAVE_SYS_H] (vector_table): By undefining STM32F10X_MD,
prepare for high density device even compiled for MD device.
2015-07-13 Kaz Kojima <kkojima@rr.iij4u.or.jp>
* board/board-stm32-primer2.h: Update.
* entry.c (vector_table): Less or more.
2015-07-13 Niibe Yutaka <gniibe@fsij.org>
* board/board-*.h (BOARD_NAME): New.
(STM32F10X_MD): Define for medium-density devices.
* example-led/sys.c, sample.ld: Update.
* example-fsm-55/sys.c, hacker-emblem.ld: Update.
* example-cdc/sys.c (sys_board_name): New.
* example-cdc/sample.ld: Update.
2015-07-08 Niibe Yutaka <gniibe@fsij.org>
* VERSION: 0.06.
* doc/chopstx.texi (VERSION): 0.06.
2015-07-07 Niibe Yutaka <gniibe@fsij.org>
* example-fsm-55/sys.c: Include clk_gpio_init.c.
* board/board-stm32f0-discovery.h, board/board-fsm-55.h: Update.
* clk_gpio_init.c (gpio_init): Use VAL_GPIO_LED_*.
2015-06-29 Niibe Yutaka <gniibe@fsij.org>
* board/board-cq-starm.h: New for CQ STARM.
* clk_gpio_init.c (gpio_init): LED is mandatory, but USB enabler
is optional.
* board/*.h: Update.
2015-06-22 Niibe Yutaka <gniibe@fsij.org>
* clk_gpio_init.c: New, adding ports E/F/G.
* entry.c: Include clk_gpio.init.c if not HAVE_SYS_H.
* example-led/sys.c: Include clk_gpio_init.c.
* example-cdc/sys.c: Ditto.
* board/board-stm32-primer2.h: New from Kaz Kojima.
2015-04-20 Niibe Yutaka <gniibe@fsij.org>
Merge cortex-m0-support branch.
* VERSION: 0.05.
* example-led/sys.c (gpio_init): Support MCU_STM32F0.
(reset): Support __ARM_ARCH_6M__.
* example-led/sample.ld: Change for Cortex-M0.
* example-fsm-55/*: New example for FSM-55.
* entry.c (STM32_PPRE1, STM32_PLLSRC, STM32_FLASHBITS)
(STM32_PLLCLKIN): Support MCU_STM32F0.
(struct RCC, RCC_*): Support MCU_STM32F0.
(struct SYSCFG) [MCU_STM32F0]: New.
(struct GPIO, GPIO*): Support MCU_STM32F0.
(clock_init, gpio_init): Support MCU_STM32F0.
(hard_fault, vectors_in_ram, entry): Support Cortex-M0.
* chopstx.c (chx_cpu_sched_lock, chx_cpu_sched_unlock)
(sched, preempt, svc): Support Cortex-M0.
* board/board-fsm-55.h: New.
* board/board-stm32f0-discovery.h: New.
2015-04-17 Niibe Yutaka <gniibe@fsij.org>
* chopstx.c (CHX_PRIO_MAIN_INIT): New, removing CHX_PRIO_MAIN.
(chopstx_main_init): New.
(chx_init): Use CHX_PRIO_MAIN_INIT.
2015-04-08 Niibe Yutaka <gniibe@fsij.org>
* board/board-maple-mini.h: New from Aidan Thornton.
2015-03-17 Niibe Yutaka <gniibe@fsij.org>
* VERSION: 0.04a.

75
NEWS
View File

@@ -1,5 +1,80 @@
NEWS - Noteworthy changes
* Major changes in Chopstx 0.09
Released 2015-09-10
** New board support: Nitrokey-Start
It is contributed by Mateusz Zalega.
** Thread cancellation
Add new API: chopstx_setcancelstate.
* Major changes in Chopstx 0.08
Released 2015-07-31
** New board support: ST Nucleo F103
It is contributed by Kenji Rikitake.
** New board support: ST Dongle
It is contributed by Kenji Rikitake.
It's the ST-Link/V2-1 part of ST Nucleo F103.
* Major changes in Chopstx 0.07
Released 2015-07-15
** New Board macro definitions
Each board-*.h should have BOARD_ID and BOARD_NAME now.
FLASH_PAGE_SIZE and NEUG_ADC_SETTING2_* are deprecated.
** New sys.c (2.1)
Flash memory size is probed at runtime now. System
service flash pages now include sys_board_id and sys_board_name.
* Major changes in Chopstx 0.06
Released 2015-07-08
** New file: clk_gpio_init.c
To avoid duplication of code, clock and GPIO initialization code
is now in this file.
** New board support: STM32 Primer2
It is contributed by Kaz Kojima.
** New board support: CQ STARM
The old board which was "published" by CQ Publishing in 2008 is added.
* Major changes in Chopstx 0.05
Released 2015-04-20, by NIIBE Yutaka
** New function: chopstx_main_init
chopstx_main_init is the function to change the schedule priority of
main thread. This is useful to enter main loop after initialization
of other threads.
** The use of CHX_PRIO_MAIN
CHX_PRIO_MAIN is deprecated. Instead, please use the function
chopstx_main_init.
** Cortex-M0 support
Cortex-M0 support has been added.
** New board support: Maple mini
It is contributed by Aidan Thornton.
** New board support: FSM-55 and STM32F0 Discovery
Those boards with STM32F0 (Cortex-M0) are now supported.
* Major changes in Chopstx 0.04
Released 2014-12-10, by NIIBE Yutaka

30
README
View File

@@ -1,17 +1,17 @@
Chopstx - Threads and only Threads
Version 0.04
2014-12-10
Version 0.09
2015-09-10
Niibe Yutaka
Flying Stone Technology
What's Chopstx?
===============
Chopstx is an RT thread library for ARM Cortex-M3, specifically,
STM32F103.
Chopstx is an RT thread library for STM32F103 (ARM Cortex-M3)
or STM32F0 (ARM Cortex-M0).
While most RTOSes come with many features, drivers, and stacks,
Chopstx just offers a RT thread library.
Chopstx just offers a simple RT thread library.
With Chopstx, interrupt handling is also done by a thread. This
enables coherent code for ease of maintenance.
@@ -28,20 +28,24 @@ EXCEPTION.
Example code
============
We have two examples in this distribution, LED blinker and
USB CDC-ACM function. You can build it like:
We have some examples in this distribution; Useful ones are LED
blinker and USB CDC-ACM function. For STM32F103, you can build it
USB CDC-ACM demo by:
$ cd example-cdc
$ ln -s ../board/board-olimex-stm32-h103.h board.h
$ ln -sf ../board/board-olimex-stm32-h103.h board.h
$ make
For a specific board named FSM-55, an example of LED matrix dynamic
driver is provided. See the directory: example-fsm-55.
For STM32 Primer2, see the directory: example-primer2.
Future Works
============
We have a development branch for ARM Cortex-M0 and it works fine.
It will be merged into mainline.
Thread local storage and support of interface like poll/select would
be next thing to be done.
Convenience function to determine bottom of thread stack, thread local
storage and support of interface like poll/select would be next thing
to be done.
--

View File

@@ -1 +1 @@
release/0.04a
release/0.09

46
board/board-cq-starm.h Normal file
View File

@@ -0,0 +1,46 @@
#define BOARD_NAME "CQ STARM"
#define BOARD_ID 0xc5480875
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HSECLK 8000000
#define GPIO_LED_BASE GPIOC_BASE
#define GPIO_LED_SET_TO_EMIT 6
#undef GPIO_USB_BASE /* No external DISCONNECT/RENUM circuit. */
#define GPIO_OTHER_BASE GPIOA_BASE
/*
* Port A setup.
* PA0 - input with pull-up. AN0
* PA1 - input with pull-up. AN1
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_OTHER_ODR 0xFFFFE7FF
#define VAL_GPIO_OTHER_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_OTHER_CRH 0x88811888 /* PA15...PA8 */
/*
* Port C setup.
* PC0 - Push Pull output 50MHz.
* PC1 - Push Pull output 50MHz.
* Everything input with pull-up except:
* PC4 - Normal input (ADC_IN14 : VoutY of LIS344ALH).
* PC5 - Normal input (ADC_IN15 : VoutZ of LIS344ALH).
* PC6 - Push Pull output (LED).
* (PC9 - SDCard CD)
* (PC12 - SDCard CS)
* PC14 - Normal input (XTAL).
* PC15 - Normal input (XTAL).
*/
#define VAL_GPIO_LED_CRL 0x83448833 /* PC7...PC0 */
#define VAL_GPIO_LED_CRH 0x44888888 /* PC15...PC8 */
#define VAL_GPIO_LED_ODR 0xFFFFFFFF
#define RCC_ENR_IOP_EN (RCC_APB2ENR_IOPAEN|RCC_APB2ENR_IOPCEN)
#define RCC_RSTR_IOP_RST (RCC_APB2RSTR_IOPARST|RCC_APB2RSTR_IOPCRST)

42
board/board-fsm-55.h Normal file
View File

@@ -0,0 +1,42 @@
#define BOARD_NAME "FSM-55"
#define BOARD_ID 0x83433c76
/*
* Running at 48MHz with HSI as clock source.
*
*/
#define MCU_STM32F0 1
/* __ARM_ARCH_6M__ */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 12
#define STM32_HSICLK 8000000
#define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_SET_TO_EMIT 5
#define GPIO_OTHER_BASE GPIOF_BASE /* USER BUTTON */
/*
* Port A setup.
* PA5 - ON (LED 1:ON 0:OFF)
* PA4 - Pull DOWN
*/
#define VAL_GPIO_LED_MODER 0x00145555 /* Output Pin0-7, Pin9 and Pin10 */
#define VAL_GPIO_LED_OTYPER 0x0000001f /* Open-drain for Pin0-4, Push-Pull*/
#define VAL_GPIO_LED_OSPEEDR 0x003cffff /* High speed */
#define VAL_GPIO_LED_PUPDR 0x00000000 /* No pull-up/pull-down */
#define RCC_ENR_IOP_EN (RCC_AHBENR_IOPAEN | RCC_AHBENR_IOPFEN)
#define RCC_RSTR_IOP_RST (RCC_AHBRSTR_IOPARST | RCC_AHBRSTR_IOPFRST)
/*
* Port F setup.
* PF0 - USER Button
* PF1 - SPEAKER
*/
#define VAL_GPIO_OTHER_MODER 0x00000004 /* Input Pin0, Output Pin1 */
#define VAL_GPIO_OTHER_OTYPER 0x00000000 /* Push-Pull Pin1 */
#define VAL_GPIO_OTHER_OSPEEDR 0x00000000
#define VAL_GPIO_OTHER_PUPDR 0x00000009 /* Pull-up Pin0, Pull-down Pin1 */

View File

@@ -1,11 +1,17 @@
#define FLASH_PAGE_SIZE 1024
#define BOARD_NAME "FST-01-00"
#define BOARD_ID 0x613870a9
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HSECLK 8000000
#define GPIO_USB_SET_TO_ENABLE 10
#define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_SET_TO_EMIT 8
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_USB_SET_TO_ENABLE 10
#undef GPIO_OTHER_BASE
/*
* Port A setup.
@@ -18,14 +24,9 @@
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_ODR 0xFFFFE7FF
#define VAL_GPIO_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_CRH 0x88811383 /* PA15...PA8 */
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_LED_BASE GPIOA_BASE
#define VAL_GPIO_LED_ODR 0xFFFFE7FF
#define VAL_GPIO_LED_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x88811383 /* PA15...PA8 */
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPAEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPARST
/* NeuG settings for ADC2 is default (PA0: Analog IN0, PA1: Analog IN1). */

View File

@@ -1,24 +1,18 @@
#define FLASH_PAGE_SIZE 1024
#define BOARD_NAME "FST-01"
#define BOARD_ID 0x696886af
/* echo -n "FST-01" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 6
#define STM32_HSECLK 12000000
#define GPIO_USB_SET_TO_ENABLE 10
#define GPIO_LED_BASE GPIOB_BASE
#define GPIO_LED_SET_TO_EMIT 0
/* For pin-cir settings of Gnuk */
#define TIMx TIM2
#define INTR_REQ_TIM TIM2_IRQ
#define AFIO_EXTICR_INDEX 0
#define AFIO_EXTICR1_EXTIx_Py AFIO_EXTICR1_EXTI2_PA
#define EXTI_PR EXTI_PR_PR2
#define EXTI_IMR EXTI_IMR_MR2
#define EXTI_FTSR_TR EXTI_FTSR_TR2
#define INTR_REQ_EXTI EXTI2_IRQ
#define ENABLE_RCC_APB1
#define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_USB_SET_TO_ENABLE 10
#undef GPIO_OTHER_BASE
/*
* Port A setup.
@@ -40,9 +34,9 @@
* PA14 - input with pull-up.
* PA15 - input with pull-up.
*/
#define VAL_GPIO_ODR 0xFFFFE7FD
#define VAL_GPIO_CRL 0xBBB38888 /* PA7...PA0 */
#define VAL_GPIO_CRH 0x88811388 /* PA15...PA8 */
#define VAL_GPIO_USB_ODR 0xFFFFE7FD
#define VAL_GPIO_USB_CRL 0xBBB38888 /* PA7...PA0 */
#define VAL_GPIO_USB_CRH 0x88811388 /* PA15...PA8 */
/*
* Port B setup.
@@ -55,16 +49,36 @@
#define VAL_GPIO_LED_CRL 0x88888883 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x88888888 /* PA15...PA8 */
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_LED_BASE GPIOB_BASE
#define RCC_ENR_IOP_EN (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN)
#define RCC_RSTR_IOP_RST (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST)
/* NeuG settings for ADC2. */
#define NEUG_ADC_SETTING2_SMPR1 0
#define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) \
| ADC_SMPR2_SMP_AN9(ADC_SAMPLE_1P5)
#define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) \
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN9)
#define NEUG_ADC_SETTING2_NUM_CHANNELS 2
/*
* Board specific information other than clock and GPIO initial
* setting should not be in board-*.h, but each driver should include
* information by itself.
*
* Please see NeuG's ADC driver how board specific handling is done.
*
* Given the situation of Chopstx's boards support, which is not that
* huge, this works well. If scalability and flexibility will matter,
* we will need something like device tree in which boot process can
* pass information to application program.
*
* Following constants are here, because experimental CIR driver is
* written before this design decision of Chopstx.
*
* Those will be removed soon, once such an driver will be improved
* in new style.
*/
/* For pin-cir settings of Gnuk */
#define TIMx TIM2
#define INTR_REQ_TIM TIM2_IRQ
#define AFIO_EXTICR_INDEX 0
#define AFIO_EXTICR1_EXTIx_Py AFIO_EXTICR1_EXTI2_PA
#define EXTI_PR EXTI_PR_PR2
#define EXTI_IMR EXTI_IMR_MR2
#define EXTI_FTSR_TR EXTI_FTSR_TR2
#define INTR_REQ_EXTI EXTI2_IRQ
#define ENABLE_RCC_APB1
#define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST

41
board/board-maple-mini.h Normal file
View File

@@ -0,0 +1,41 @@
#define BOARD_NAME "Maple Mini"
#define BOARD_ID 0x7a445272
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HSECLK 8000000
#define GPIO_LED_BASE GPIOB_BASE
#define GPIO_LED_SET_TO_EMIT 1
#define GPIO_USB_BASE GPIOB_BASE
#define GPIO_USB_CLEAR_TO_ENABLE 9
#define GPIO_OTHER_BASE GPIOA_BASE
/*
* Port A setup.
* PA0 - input with pull-up. AN0
* PA1 - input with pull-up. AN1
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_OTHER_ODR 0xFFFFE7FF
#define VAL_GPIO_OTHER_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_OTHER_CRH 0x88811888 /* PA15...PA8 */
/*
* Port B setup.
* PB1 - Push pull output 50MHz (LED 1:ON 0:OFF)
* PB9 - Push pull output 50MHz (USB 1:ON 0:OFF)
* ------------------------ Default
* PBx - input with pull-up
*/
#define VAL_GPIO_LED_ODR 0xFFFFFFFF
#define VAL_GPIO_LED_CRL 0x88888838 /* PB7...PB0 */
#define VAL_GPIO_LED_CRH 0x88888838 /* PB15...PB8 */
#define RCC_ENR_IOP_EN (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN)
#define RCC_RSTR_IOP_RST (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST)

View File

@@ -0,0 +1,59 @@
#define BOARD_NAME "NITROKEY-START"
#define BOARD_ID 0xad1e7ebd
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 6
#define STM32_HSECLK 12000000
#define GPIO_LED_BASE GPIOB_BASE
#define GPIO_LED_SET_TO_EMIT 0
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_USB_SET_TO_ENABLE 15
#undef GPIO_OTHER_BASE
/*
* Port A setup.
* PA0 - input with pull-up: AN0 for NeuG
* PA1 - input with pull-up: AN1 for NeuG
* PA2 - floating input
* PA3 - floating input
* PA4 - floating input
* PA5 - floating input
* PA6 - floating input
* PA7 - Push pull output (LED1 1:ON 0:OFF)
* PA8 - floating input (smartcard, SCDSA)
* PA9 - floating input
* PA10 - floating input
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* PA15 - Push pull output (USB_EN 1:ON 0:OFF)
* ------------------------ Default
* PA8 - input with pull-up.
* PA9 - floating input.
* PA10 - floating input.
* PA13 - input with pull-up.
* PA14 - input with pull-up.
* PA15 - Push pull output (USB 1:ON 0:OFF)
*/
#define VAL_GPIO_USB_ODR 0xFFFFE7FF
#define VAL_GPIO_USB_CRL 0x34444488 /* PA7...PA0 */
#define VAL_GPIO_USB_CRH 0x38811444 /* PA15...PA8 */
/*
* Port B setup.
* PB0 - Push pull output (LED2 1:ON 0:OFF)
* ------------------------ Default
* PBx - input with pull-up.
*/
#define VAL_GPIO_LED_ODR 0xFFFFFFFF
#define VAL_GPIO_LED_CRL 0x88888883 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x88888888 /* PA15...PA8 */
#define RCC_ENR_IOP_EN \
(RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN)
#define RCC_RSTR_IOP_RST \
(RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | RCC_APB2RSTR_AFIORST)
#define AFIO_MAPR_SOMETHING AFIO_MAPR_SWJ_CFG_JTAGDISABLE

View File

@@ -1,11 +1,17 @@
#define FLASH_PAGE_SIZE 1024
#define BOARD_NAME "Olimex STM32-H103"
#define BOARD_ID 0xf92bb594
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HSECLK 8000000
#define GPIO_USB_CLEAR_TO_ENABLE 11
#define GPIO_LED_BASE GPIOC_BASE
#define GPIO_LED_CLEAR_TO_EMIT 12
#define GPIO_USB_BASE GPIOC_BASE
#define GPIO_USB_CLEAR_TO_ENABLE 11
#undef GPIO_OTHER_BASE
/*
* Port C setup.
@@ -18,12 +24,9 @@
* ------------------------ Default
* PCx - input with pull-up
*/
#define VAL_GPIO_ODR 0xFFFFFFFF
#define VAL_GPIO_CRL 0x44888888 /* PC7...PC0 */
#define VAL_GPIO_CRH 0x88837888 /* PC15...PC8 */
#define GPIO_USB_BASE GPIOC_BASE
#define GPIO_LED_BASE GPIOC_BASE
#define VAL_GPIO_LED_ODR 0xFFFFFFFF
#define VAL_GPIO_LED_CRL 0x44888888 /* PC7...PC0 */
#define VAL_GPIO_LED_CRH 0x88837888 /* PC15...PC8 */
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPCEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPCRST

33
board/board-st-dongle.h Normal file
View File

@@ -0,0 +1,33 @@
#define BOARD_NAME "ST Dongle"
/* echo -n "ST Dongle" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */
#define BOARD_ID 0x2cd4e471
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HSECLK 8000000
#define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_SET_TO_EMIT 9
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_USB_SET_TO_ENABLE 15
#undef GPIO_OTHER_BASE
/*
* Port A setup.
* PA0 - input with pull-up. AN0
* PA1 - input with pull-up. AN1
* PA9 - Push pull output 50MHz (LED 1:ON 0:OFF)
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* PA15 - Push pull output 50MHz (USB 1:ON 0:OFF)
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_LED_ODR 0xFFFFE7FF
#define VAL_GPIO_LED_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x38811838 /* PA15...PA8 */
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPAEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPARST

View File

@@ -0,0 +1,45 @@
#define BOARD_NAME "ST Nucleo F103"
#define BOARD_ID 0x9b87c16d
/*
* Please add X3 and USB cable to ST Nucleo F103.
*
* Solder X3 XTAL of 8MHz (and put C33 and C34 of 22pF).
* Solder the bridges for R35 and R37, since it's 0 ohm.
*
* (Optional) Remove SB54 and SB55.
*
* At CN10, connect USB cable
* Vbus RED --> 10 NC ----------> CN7 (6 E5V)
* D+ GREEN --> 12 PA11 ---[1K5]--> CN6 (4 3V3)
* D- WHITE --> 14 PA12
* GND BLACK --> 20 GND
*/
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HSECLK 8000000
#define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_SET_TO_EMIT 5
#undef GPIO_USB_BASE /* No external DISCONNECT/RENUM circuit. */
#undef GPIO_OTHER_BASE
/*
* Port A setup.
* PA0 - input with pull-up. AN0
* PA1 - input with pull-up. AN1
* PA5 - Push pull output 50MHz (LED 1:ON 0:OFF)
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_LED_ODR 0xFFFFE7FF
#define VAL_GPIO_LED_CRL 0x88388888 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x88811888 /* PA15...PA8 */
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPAEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPARST

View File

@@ -1,11 +1,16 @@
#define FLASH_PAGE_SIZE 1024
#define BOARD_NAME "STBee Mini"
#define BOARD_ID 0x1f341961
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 6
#define STM32_HSECLK 12000000
#define GPIO_USB_SET_TO_ENABLE 14
#define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_CLEAR_TO_EMIT 13
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_USB_SET_TO_ENABLE 14
#if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DIAL_SUPPORT)
#define HAVE_7SEGLED 1
@@ -49,19 +54,20 @@
* PA14 - Push pull output (USB ENABLE 0:DISABLE 1:ENABLE)
* PA15 - Open Drain output (LED2 0:ON 1:OFF)
*/
#define VAL_GPIO_ODR 0xFFFFE77F
#define VAL_GPIO_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_CRH 0x63611888 /* PA15...PA8 */
#define VAL_GPIO_LED_ODR 0xFFFFE77F
#define VAL_GPIO_LED_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x63611888 /* PA15...PA8 */
#define GPIO_OTHER_BASE GPIOB_BASE
/*
* Port B setup.
* PB0 - Push pull output (LED 1:ON 0:OFF)
* ------------------------ Default
* PBx - input with pull-up.
*/
#define VAL_GPIO_LED_ODR 0xFFFFFFFF
#define VAL_GPIO_LED_CRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIO_LED_CRH 0x66666666 /* PB15...PB8 */
#define VAL_GPIO_OTHER_ODR 0xFFFFFFFF
#define VAL_GPIO_OTHER_CRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIO_OTHER_CRH 0x66666666 /* PB15...PB8 */
/* Port B setup. */
#define GPIOB_CIR 0
@@ -93,23 +99,15 @@
* PA14 - Push pull output (USB ENABLE 0:DISABLE 1:ENABLE)
* PA15 - Open Drain output (LED2 0:ON 1:OFF)
*/
#define VAL_GPIO_ODR 0xFFFFE7FF
#define VAL_GPIO_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_CRH 0x63611888 /* PA15...PA8 */
#define VAL_GPIO_LED_ODR 0xFFFFE7FF
#define VAL_GPIO_LED_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x63611888 /* PA15...PA8 */
#undef GPIO_OTHER_BASE
#define RCC_ENR_IOP_EN (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN)
#define RCC_RSTR_IOP_RST (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_AFIORST)
#endif
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_LED_BASE GPIOA_BASE
#define AFIO_MAPR_SOMETHING AFIO_MAPR_SWJ_CFG_DISABLE
/* NeuG settings for ADC2. */
#define NEUG_ADC_SETTING2_SMPR1 0
#define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5) \
| ADC_SMPR2_SMP_AN2(ADC_SAMPLE_1P5)
#define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN1) \
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN2)
#define NEUG_ADC_SETTING2_NUM_CHANNELS 2

View File

@@ -1,11 +1,15 @@
#define FLASH_PAGE_SIZE 2048
#define BOARD_NAME "STBee"
#define BOARD_ID 0x945c37e8
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 6
#define STM32_HSECLK 12000000
#define GPIO_USB_CLEAR_TO_ENABLE 3
#define GPIO_LED_BASE GPIOD_BASE
#define GPIO_LED_CLEAR_TO_EMIT 4
#define GPIO_USB_BASE GPIOD_BASE
#define GPIO_USB_CLEAR_TO_ENABLE 3
#define GPIO_OTHER_BASE GPIOA_BASE
/*
* Port A setup.
@@ -25,18 +29,6 @@
* PD3 - Push pull output (USB_DISC 1:USB-DISABLE 0:USB-ENABLE) 2MHz
* PD4 - Open Drain output 2MHz (LED1).
*/
#define VAL_GPIO_ODR 0xFFFFFFFF
#define VAL_GPIO_CRL 0x88862888 /* PD7...PD0 */
#define VAL_GPIO_CRH 0x88888888 /* PD15...PD8 */
#define GPIO_USB_BASE GPIOD_BASE
#define GPIO_LED_BASE GPIOD_BASE
#define GPIO_OTHER_BASE GPIOA_BASE
/* NeuG settings for ADC2. */
#define NEUG_ADC_SETTING2_SMPR1 ADC_SMPR1_SMP_AN10(ADC_SAMPLE_1P5) \
| ADC_SMPR1_SMP_AN11(ADC_SAMPLE_1P5)
#define NEUG_ADC_SETTING2_SMPR2 0
#define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN10) \
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN11)
#define NEUG_ADC_SETTING2_NUM_CHANNELS 2
#define VAL_GPIO_LED_ODR 0xFFFFFFFF
#define VAL_GPIO_LED_CRL 0x88862888 /* PD7...PD0 */
#define VAL_GPIO_LED_CRH 0x88888888 /* PD15...PD8 */

View File

@@ -0,0 +1,56 @@
#define BOARD_NAME "STM32 Primer2"
#define BOARD_ID 0x21e5798d
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 6
#define STM32_HSECLK 12000000
#define GPIO_LED_BASE GPIOE_BASE
#define GPIO_LED_SET_TO_EMIT 0
#define GPIO_USB_BASE GPIOD_BASE
#define GPIO_USB_CLEAR_TO_ENABLE 3
#define GPIO_OTHER_BASE GPIOA_BASE
/*
* Port A setup.
* PA0 - input with pull-up. AN0
* PA1 - input with pull-up. AN1
* PA8 - Input with pull-down (PBUTTON).
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_OTHER_ODR 0xFFFFE6FF
#define VAL_GPIO_OTHER_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_OTHER_CRH 0x88811888 /* PA15...PA8 */
/*
* Port D setup.
* PD3 - Push pull output 50MHz (USB 1:ON 0:OFF)
* ------------------------ Default
* PDx - input with pull-up
*/
#define VAL_GPIO_USB_ODR 0xFFFFFFFF
#define VAL_GPIO_USB_CRL 0x88883888 /* PD7...PD0 */
#define VAL_GPIO_USB_CRH 0x88888888 /* PD15...PD8 */
/*
* Port E setup.
* PE0 - Push pull output (LED 1:ON 0:OFF)
* PE1 - Push pull output (LED 1:ON 0:OFF)
* PE3 - Input with pull-down (JOYSTICK L).
* PE4 - Input with pull-down (JOYSTICK R).
* PE5 - Input with pull-down (JOYSTICK U).
* PE6 - Input with pull-down (JOYSTICK D).
* ------------------------ Default
* PEx - input with pull-up
*/
#define VAL_GPIO_LED_ODR 0xFFFFFF87
#define VAL_GPIO_LED_CRL 0x88888833 /* PE7...PE0 */
#define VAL_GPIO_LED_CRH 0x88888888 /* PE15...PE8 */
#define RCC_ENR_IOP_EN \
(RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_IOPEEN)
#define RCC_RSTR_IOP_RST \
(RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPDRST | RCC_APB2RSTR_IOPERST)

View File

@@ -0,0 +1,48 @@
#define BOARD_NAME "STM32F0 Discovery"
#define BOARD_ID 0xde4b4bc1
/*
* Running at 48MHz with HSI as clock source.
*
*/
#define MCU_STM32F0 1
/* __ARM_ARCH_6M__ */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 12
#define STM32_HSICLK 8000000
#define GPIO_LED_BASE GPIOC_BASE
#define GPIO_LED_SET_TO_EMIT 8
#define GPIO_OTHER_BASE GPIOA_BASE /* USER BUTTON */
/*
* Port C setup.
* PC9 - LED3 (LED 1:ON 0:OFF)
* PC8 - LED4 (LED 1:ON 0:OFF)
*/
#define VAL_GPIO_LED_MODER 0x00050000 /* Output Pin9 and Pin8 */
#define VAL_GPIO_LED_OTYPER 0x00000000 /* Push-Pull */
#define VAL_GPIO_LED_OSPEEDR 0x000f0000 /* High speed: Pin9 and Pin8 */
#define VAL_GPIO_LED_PUPDR 0x00000000 /* No pull-up/pull-down */
#if 0
#define RCC_ENR_IOP_EN (RCC_AHBENR_IOPAEN | RCC_AHBENR_IOPCEN)
#define RCC_RSTR_IOP_RST (RCC_AHBRSTR_IOPARST | RCC_AHBRSTR_IOPCRST)
#else
#define RCC_ENR_IOP_EN RCC_AHBENR_IOPCEN
#define RCC_RSTR_IOP_RST RCC_AHBRSTR_IOPCRST
#endif
/* ??? NeuG settings for ADC2 is default (PA0: Analog IN0, PA1: Analog IN1). */
/*
* Port A setup.
* PA0 - USER Button
*/
#define VAL_GPIO_OTHER_MODER 0x00000000 /* Input Pin0 */
#define VAL_GPIO_OTHER_OTYPER 0x00000000 /* Push-Pull */
#define VAL_GPIO_OTHER_OSPEEDR 0x00000000
#define VAL_GPIO_OTHER_PUPDR 0x00000000 /* No pull-up/pull-down */

View File

@@ -1,11 +1,47 @@
#define FLASH_PAGE_SIZE 1024
#define BOARD_NAME "STM8S Discovery"
#define BOARD_ID 0x2f0976bb
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HSECLK 8000000
#undef GPIO_USB_CLEAR_TO_ENABLE
#define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_SET_TO_EMIT 8
#undef GPIO_USB_BASE /* No external DISCONNECT/RENUM circuit. */
#define GPIO_OTHER_BASE GPIOB_BASE
/*
* Port A setup.
* PA0 - input with pull-up. AN0
* PA1 - input with pull-up. AN1
* PA8 - Push pull output 10MHz (LED 1:ON 0:OFF)
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_LED_ODR 0xFFFFE7FF
#define VAL_GPIO_LED_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x88811881 /* PA15...PA8 */
#define RCC_ENR_IOP_EN \
(RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN)
#define RCC_RSTR_IOP_RST \
(RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | RCC_APB2RSTR_AFIORST)
/*
* Port B setup.
* PB4 - (TIM3_CH1) input with pull-up
* PB5 - (TIM3_CH2) input with pull-up, connected to CIR module
* Everything input with pull-up except:
* PB0 - (TIM3_CH3) input with pull-down
*/
#define VAL_GPIO_OTHER_ODR 0xFFFFFFFE
#define VAL_GPIO_OTHER_CRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIO_OTHER_CRH 0x88888888 /* PB15...PB8 */
/* For pin-cir settings of Gnuk */
#define TIMx TIM3
@@ -21,39 +57,3 @@
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM3RST
#define AFIO_MAPR_SOMETHING AFIO_MAPR_TIM3_REMAP_PARTIALREMAP
/* Remap (PB4, PB5) -> (TIM3_CH1, TIM3_CH2) */
/*
* Port A setup.
* PA0 - input with pull-up. AN0
* PA1 - input with pull-up. AN1
* PA8 - Push pull output 10MHz (LED 1:ON 0:OFF)
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_ODR 0xFFFFE7FF
#define VAL_GPIO_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_CRH 0x88811881 /* PA15...PA8 */
#define GPIO_USB_BASE GPIOA_BASE
#define GPIO_LED_BASE GPIOA_BASE
#define RCC_ENR_IOP_EN \
(RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN)
#define RCC_RSTR_IOP_RST \
(RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | RCC_APB2RSTR_AFIORST)
/* NeuG settings for ADC2 is default (PA0: Analog IN0, PA1: Analog IN1). */
#define GPIO_OTHER_BASE GPIOB_BASE
/*
* Port B setup.
* PB4 - (TIM3_CH1) input with pull-up
* PB5 - (TIM3_CH2) input with pull-up, connected to CIR module
* Everything input with pull-up except:
* PB0 - (TIM3_CH3) input with pull-down
*/
#define VAL_GPIO_OTHER_ODR 0xFFFFFFFE
#define VAL_GPIO_OTHER_CRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIO_OTHER_CRH 0x88888888 /* PB15...PB8 */

713
chopstx.c
View File

@@ -1,7 +1,7 @@
/*
* chopstx.c - Threads and only threads.
*
* Copyright (C) 2013, 2014 Flying Stone Technology
* Copyright (C) 2013, 2014, 2015 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Chopstx, a thread library for embedded.
@@ -34,8 +34,8 @@
/*
* Thread priority: higer has higher precedence.
*/
#if !defined(CHX_PRIO_MAIN)
#define CHX_PRIO_MAIN 1
#if !defined(CHX_PRIO_MAIN_INIT)
#define CHX_PRIO_MAIN_INIT 1
#endif
#if !defined(CHX_FLAGS_MAIN)
#define CHX_FLAGS_MAIN 0
@@ -61,6 +61,15 @@
#define CPU_EXCEPTION_PRIORITY_CLEAR 0
#if defined(__ARM_ARCH_6M__)
#define CPU_EXCEPTION_PRIORITY_SVC 0x00
#define CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED 0x40
/* ... */
#define CPU_EXCEPTION_PRIORITY_SYSTICK CPU_EXCEPTION_PRIORITY_INTERRUPT
#define CPU_EXCEPTION_PRIORITY_INTERRUPT 0x80
#define CPU_EXCEPTION_PRIORITY_PENDSV 0xc0
#elif defined(__ARM_ARCH_7M__)
#define CPU_EXCEPTION_PRIORITY_SVC 0x30
#define CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED 0x40
@@ -68,7 +77,126 @@
#define CPU_EXCEPTION_PRIORITY_SYSTICK CPU_EXCEPTION_PRIORITY_INTERRUPT
#define CPU_EXCEPTION_PRIORITY_INTERRUPT 0xb0
#define CPU_EXCEPTION_PRIORITY_PENDSV 0xc0
#else
#error "no support for this arch"
#endif
/*
* Lower layer architecture specific functions.
*
* system tick and interrupt
*/
/*
* System tick
*/
/* SysTick registers. */
static volatile uint32_t *const SYST_CSR = (uint32_t *const)0xE000E010;
static volatile uint32_t *const SYST_RVR = (uint32_t *const)0xE000E014;
static volatile uint32_t *const SYST_CVR = (uint32_t *const)0xE000E018;
static void
chx_systick_reset (void)
{
*SYST_RVR = 0;
*SYST_CVR = 0;
*SYST_CSR = 7;
}
static void
chx_systick_reload (uint32_t ticks)
{
*SYST_RVR = ticks;
*SYST_CVR = 0; /* write (any) to clear the counter to reload. */
*SYST_RVR = 0;
}
static uint32_t
chx_systick_get (void)
{
return *SYST_CVR;
}
#ifndef MHZ
#define MHZ 72
#endif
static uint32_t usec_to_ticks (uint32_t usec)
{
return usec * MHZ;
}
/*
* Interrupt Handling
*/
/* NVIC: Nested Vectored Interrupt Controller. */
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 NVIC = (struct NVIC *const)0xE000E100;
#define NVIC_ISER(n) (NVIC->ISER[n >> 5])
#define NVIC_ICER(n) (NVIC->ICER[n >> 5])
#define NVIC_ICPR(n) (NVIC->ICPR[n >> 5])
#define NVIC_IPR(n) (NVIC->IPR[n >> 2])
#define USB_LP_CAN1_RX0_IRQn 20
static void
chx_enable_intr (uint8_t irq_num)
{
NVIC_ISER (irq_num) = 1 << (irq_num & 0x1f);
}
static void
chx_clr_intr (uint8_t irq_num)
{ /* Clear pending interrupt. */
NVIC_ICPR (irq_num) = 1 << (irq_num & 0x1f);
}
static void
chx_disable_intr (uint8_t irq_num)
{
NVIC_ICER (irq_num) = 1 << (irq_num & 0x1f);
}
static void
chx_set_intr_prio (uint8_t n)
{
unsigned int sh = (n & 3) << 3;
NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh))
| (CPU_EXCEPTION_PRIORITY_INTERRUPT << sh);
}
static volatile uint32_t *const ICSR = (uint32_t *const)0xE000ED04;
/* Priority control. */
static uint32_t *const AIRCR = (uint32_t *const)0xE000ED0C;
static uint32_t *const SHPR2 = (uint32_t *const)0xE000ED1C;
static uint32_t *const SHPR3 = (uint32_t *const)0xE000ED20;
static void
chx_prio_init (void)
{
*AIRCR = 0x05FA0000 | ( 5 << 8); /* PRIGROUP = 5, 2-bit:2-bit. */
*SHPR2 = (CPU_EXCEPTION_PRIORITY_SVC << 24);
*SHPR3 = ((CPU_EXCEPTION_PRIORITY_SYSTICK << 24)
| (CPU_EXCEPTION_PRIORITY_PENDSV << 16));
}
/**
* chx_fatal - Fatal error point.
* @err_code: Error code
@@ -112,7 +240,7 @@ static struct chx_queue q_join;
/* Forward declaration(s). */
static void chx_request_preemption (void);
static void chx_request_preemption (uint16_t prio);
static void chx_timer_dequeue (struct chx_thread *tp);
static void chx_timer_insert (struct chx_thread *tp, uint32_t usec);
@@ -152,44 +280,6 @@ struct chx_stack_regs {
#define INITIAL_XPSR 0x01000000 /* T=1 */
/*
* NVIC: Nested Vectored Interrupt Controller
*/
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 NVIC = (struct NVIC *const)0xE000E100;
#define NVIC_ISER(n) (NVIC->ISER[n >> 5])
#define NVIC_ICER(n) (NVIC->ICER[n >> 5])
#define NVIC_ICPR(n) (NVIC->ICPR[n >> 5])
#define NVIC_IPR(n) (NVIC->IPR[n >> 2])
#define USB_LP_CAN1_RX0_IRQn 20
/*
* SysTick registers.
*/
static volatile uint32_t *const SYST_CSR = (uint32_t *const)0xE000E010;
static volatile uint32_t *const SYST_RVR = (uint32_t *const)0xE000E014;
static volatile uint32_t *const SYST_CVR = (uint32_t *const)0xE000E018;
#define MHZ 72
static uint32_t usec_to_ticks (uint32_t usec)
{
return usec * MHZ;
}
/**************/
struct chx_thread {
@@ -200,7 +290,8 @@ struct chx_thread {
uint32_t flag_got_cancel : 1;
uint32_t flag_join_req : 1;
uint32_t flag_sched_rr : 1;
uint32_t : 8;
uint32_t flag_cancelable : 1;
uint32_t : 7;
uint32_t prio_orig : 8;
uint32_t prio : 8;
uint32_t v;
@@ -214,8 +305,12 @@ chx_cpu_sched_lock (void)
{
if (running->prio < CHOPSTX_PRIO_INHIBIT_PREEMPTION)
{
#if defined(__ARM_ARCH_6M__)
asm volatile ("cpsid i" : : : "memory");
#else
register uint32_t tmp = CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED;
asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory");
#endif
}
}
@@ -224,8 +319,12 @@ chx_cpu_sched_unlock (void)
{
if (running->prio < CHOPSTX_PRIO_INHIBIT_PREEMPTION)
{
#if defined(__ARM_ARCH_6M__)
asm volatile ("cpsie i" : : : "memory");
#else
register uint32_t tmp = CPU_EXCEPTION_PRIORITY_CLEAR;
asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory");
#endif
}
}
@@ -278,7 +377,7 @@ ll_pop (void *head)
static void
ll_prio_push (struct chx_thread *tp0, void *head)
{
struct chx_thread *l = (struct chx_thread *)head;
struct chx_thread *l = (struct chx_thread *)head;
struct chx_thread *tp;
for (tp = l->next; tp != l; tp = tp->next)
@@ -310,7 +409,7 @@ enum {
THREAD_READY,
THREAD_WAIT_MTX,
THREAD_WAIT_CND,
THREAD_WAIT_TIME,
THREAD_WAIT_TIME,
THREAD_WAIT_INT,
THREAD_JOIN,
/**/
@@ -365,171 +464,11 @@ idle (void)
}
/* Registers on stack (PSP): r0, r1, r2, r3, r12, lr, pc, xpsr */
static void __attribute__ ((naked, used))
sched (void)
{
register struct chx_thread *tp asm ("r0");
tp = chx_ready_pop ();
if (tp && tp->flag_sched_rr)
{
chx_spin_lock (&q_timer.lock);
chx_timer_insert (tp, PREEMPTION_USEC);
chx_spin_unlock (&q_timer.lock);
}
asm volatile (/* Now, r0 points to the thread to be switched. */
/* Put it to *running. */
"ldr r1, =running\n\t"
/* Update running. */
"str r0, [r1]\n\t"
"cbz r0, 1f\n\t"
/**/
"add r0, #8\n\t"
"ldm r0!, {r4, r5, r6, r7}\n\t"
"ldr r8, [r0], #4\n\t"
"ldr r9, [r0], #4\n\t"
"ldr r10, [r0], #4\n\t"
"ldr r11, [r0], #4\n\t"
"ldr r1, [r0], #4\n\t"
"msr PSP, r1\n\t"
"ldrb r1, [r0, #3]\n\t" /* ->PRIO field. */
"cmp r1, #247\n\t"
"bhi 0f\n\t" /* Leave interrupt disabled if >= 248 */
/**/
"mov r0, #0\n\t"
"msr BASEPRI, r0\n" /* Unmask interrupts. */
/**/
"0:\n\t"
"sub r0, #3\n\t" /* EXC_RETURN to a thread with PSP */
"bx r0\n"
"1:\n\t"
/* Spawn an IDLE thread. */
"ldr r0, =__main_stack_end__\n\t"
"msr MSP, r0\n\t"
"mov r0, #0\n\t"
"mov r1, #0\n\t"
"ldr r2, =idle\n\t" /* PC = idle */
"mov r3, #0x01000000\n\t" /* xPSR = T-flag set (Thumb) */
"push {r0, r1, r2, r3}\n\t"
"mov r0, #0\n\t"
"mov r1, #0\n\t"
"mov r2, #0\n\t"
"mov r3, #0\n\t"
"push {r0, r1, r2, r3}\n"
/**/
"mov r0, #0\n\t"
"msr BASEPRI, r0\n\t" /* Unmask interrupts. */
/**/
"sub r0, #7\n\t" /* EXC_RETURN to a thread with MSP */
"bx r0\n"
: /* no output */ : "r" (tp) : "memory");
}
void __attribute__ ((naked))
preempt (void)
{
register struct chx_thread *tp asm ("r0");
tp = (struct chx_thread *)CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED;
asm ("msr BASEPRI, r0\n\t"
"ldr r1, =running\n\t"
"ldr r0, [r1]\n\t"
"cbnz r0, 0f\n\t"
/* It's idle which was preempted. Discard saved registers on stack. */
"ldr r1, =__main_stack_end__\n\t"
"msr MSP, r1\n\t"
"b sched\n"
"0:\n\t"
"add r1, r0, #8\n\t"
/* Save registers onto CHX_THREAD struct. */
"stm r1!, {r4, r5, r6, r7}\n\t"
"mov r2, r8\n\t"
"mov r3, r9\n\t"
"mov r4, r10\n\t"
"mov r5, r11\n\t"
"mrs r6, PSP\n\t" /* r13(=SP) in user space. */
"stm r1!, {r2, r3, r4, r5, r6}"
: "=r" (tp)
: "r" (tp)
: "r1", "r2", "r3", "r4", "r5", "r6", "cc", "memory");
if (tp)
{
if (tp->flag_sched_rr)
{
if (tp->state == THREAD_RUNNING)
{
chx_timer_dequeue (tp);
chx_ready_enqueue (tp);
}
/*
* It may be THREAD_READY after chx_timer_expired.
* Then, do nothing.
*/
}
else
chx_ready_push (tp);
running = NULL;
}
asm volatile ("b sched"
: /* no output */: /* no input */ : "memory");
}
/*
* System call: switch to another thread.
* There are two cases:
* ORIG_R0=0 (SLEEP): Current RUNNING thread is already connected to
* something (mutex, cond, intr, etc.)
* ORIG_R0=1 (YIELD): Current RUNNING thread is active,
* it is needed to be enqueued to READY queue.
*/
void __attribute__ ((naked))
svc (void)
{
register struct chx_thread *tp asm ("r0");
register uint32_t orig_r0 asm ("r1");
asm ("ldr r1, =running\n\t"
"ldr r0, [r1]\n\t"
"add r1, r0, #8\n\t"
/* Save registers onto CHX_THREAD struct. */
"stm r1!, {r4, r5, r6, r7}\n\t"
"mov r2, r8\n\t"
"mov r3, r9\n\t"
"mov r4, r10\n\t"
"mov r5, r11\n\t"
"mrs r6, PSP\n\t" /* r13(=SP) in user space. */
"stm r1!, {r2, r3, r4, r5, r6}\n\t"
"ldr r1, [r6]"
: "=r" (tp), "=r" (orig_r0)
: /* no input */
: "r2", "r3", "r4", "r5", "r6", "memory");
if (orig_r0) /* yield */
{
if (tp->flag_sched_rr)
chx_timer_dequeue (tp);
chx_ready_enqueue (tp);
running = NULL;
}
asm volatile ("b sched"
: /* no output */: /* no input */ : "memory");
}
static void
chx_set_timer (struct chx_thread *q, uint32_t ticks)
{
if (q == (struct chx_thread *)&q_timer)
{
*SYST_RVR = ticks;
*SYST_CVR = 0; /* write (any) to clear the counter to reload. */
*SYST_RVR = 0;
}
chx_systick_reload (ticks);
else
q->v = ticks;
}
@@ -537,9 +476,9 @@ chx_set_timer (struct chx_thread *q, uint32_t ticks)
static void
chx_timer_insert (struct chx_thread *tp, uint32_t usec)
{
uint32_t ticks = usec_to_ticks (usec);
uint32_t next_ticks = *SYST_CVR;
struct chx_thread *q;
uint32_t ticks = usec_to_ticks (usec);
uint32_t next_ticks = chx_systick_get ();
for (q = q_timer.next; q != (struct chx_thread *)&q_timer; q = q->next)
{
@@ -579,7 +518,7 @@ chx_timer_dequeue (struct chx_thread *tp)
chx_set_timer (tp_prev, 0); /* Cancel timer*/
else
{ /* Update timer. */
uint32_t next_ticks = *SYST_CVR + tp->v;
uint32_t next_ticks = chx_systick_get () + tp->v;
chx_set_timer (tp_prev, next_ticks);
}
@@ -634,42 +573,12 @@ chx_timer_expired (void)
}
}
if (running == NULL || (uint16_t)running->prio < prio)
chx_request_preemption ();
chx_request_preemption (prio);
chx_spin_unlock (&q_timer.lock);
}
static void
chx_enable_intr (uint8_t irq_num)
{
NVIC_ISER (irq_num) = 1 << (irq_num & 0x1f);
}
static void
chx_clr_intr (uint8_t irq_num)
{ /* Clear pending interrupt. */
NVIC_ICPR (irq_num) = 1 << (irq_num & 0x1f);
}
static void
chx_disable_intr (uint8_t irq_num)
{
NVIC_ICER (irq_num) = 1 << (irq_num & 0x1f);
}
static void
chx_set_intr_prio (uint8_t n)
{
unsigned int sh = (n & 3) << 3;
NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh))
| (CPU_EXCEPTION_PRIORITY_INTERRUPT << sh);
}
static chopstx_intr_t *intr_top;
static volatile uint32_t *const ICSR = (uint32_t *const)0xE000ED04;
static struct chx_spinlock intr_lock;
void
chx_handle_intr (void)
@@ -681,6 +590,7 @@ chx_handle_intr (void)
"sub %0, #16" /* Exception # - 16 = interrupt number. */
: "=r" (irq_num) : /* no input */ : "memory");
chx_disable_intr (irq_num);
chx_spin_lock (&intr_lock);
for (intr = intr_top; intr; intr = intr->next)
if (intr->irq_num == irq_num)
break;
@@ -691,18 +601,16 @@ chx_handle_intr (void)
if (intr->tp != running && intr->tp->state == THREAD_WAIT_INT)
{
chx_ready_enqueue (intr->tp);
if (running == NULL || running->prio < intr->tp->prio)
chx_request_preemption ();
chx_request_preemption (intr->tp->prio);
}
}
chx_spin_unlock (&intr_lock);
}
void
chx_systick_init (void)
{
*SYST_RVR = 0;
*SYST_CVR = 0;
*SYST_CSR = 7;
chx_systick_reset ();
if ((CHX_FLAGS_MAIN & CHOPSTX_SCHED_RR))
{
@@ -714,20 +622,12 @@ chx_systick_init (void)
}
}
static uint32_t *const AIRCR = (uint32_t *const)0xE000ED0C;
static uint32_t *const SHPR2 = (uint32_t *const)0xE000ED1C;
static uint32_t *const SHPR3 = (uint32_t *const)0xE000ED20;
chopstx_t chopstx_main;
void
chx_init (struct chx_thread *tp)
{
*AIRCR = 0x05FA0000 | ( 5 << 8); /* PRIGROUP = 5, 2-bit:2-bit. */
*SHPR2 = (CPU_EXCEPTION_PRIORITY_SVC << 24);
*SHPR3 = ((CPU_EXCEPTION_PRIORITY_SYSTICK << 24)
| (CPU_EXCEPTION_PRIORITY_PENDSV << 16));
chx_prio_init ();
memset (&tp->tc, 0, sizeof (tp->tc));
q_ready.next = q_ready.prev = (struct chx_thread *)&q_ready;
q_timer.next = q_timer.prev = (struct chx_thread *)&q_timer;
@@ -737,28 +637,53 @@ chx_init (struct chx_thread *tp)
tp->mutex_list = NULL;
tp->clp = NULL;
tp->state = THREAD_RUNNING;
tp->flag_got_cancel = tp->flag_join_req = 0;
tp->flag_got_cancel = tp->flag_join_req = tp->flag_cancelable = 0;
tp->flag_sched_rr = (CHX_FLAGS_MAIN & CHOPSTX_SCHED_RR)? 1 : 0;
tp->flag_detached = (CHX_FLAGS_MAIN & CHOPSTX_DETACHED)? 1 : 0;
tp->prio_orig = CHX_PRIO_MAIN;
tp->prio_orig = CHX_PRIO_MAIN_INIT;
tp->prio = 0;
tp->v = 0;
running = tp;
if (CHX_PRIO_MAIN >= CHOPSTX_PRIO_INHIBIT_PREEMPTION)
if (CHX_PRIO_MAIN_INIT >= CHOPSTX_PRIO_INHIBIT_PREEMPTION)
chx_cpu_sched_lock ();
tp->prio = CHX_PRIO_MAIN;
tp->prio = CHX_PRIO_MAIN_INIT;
chopstx_main = (chopstx_t)tp;
}
static void
chx_request_preemption (void)
/**
* chopstx_main_init - initialize main thread
* @prio: priority
*
* Initialize main thread with @prio.
* The thread main is created with priority CHX_PRIO_MAIN_INIT,
* and it runs with that priority until this routine will is called.
*/
void
chopstx_main_init (chopstx_prio_t prio)
{
*ICSR = (1 << 28);
asm volatile ("" : : : "memory");
struct chx_thread *tp = (struct chx_thread *)chopstx_main;
tp->prio_orig = prio;
if (prio >= CHOPSTX_PRIO_INHIBIT_PREEMPTION)
chx_cpu_sched_lock ();
tp->prio = prio;
}
static void
chx_request_preemption (uint16_t prio)
{
if (running == NULL || (uint16_t)running->prio < prio)
{
*ICSR = (1 << 28);
asm volatile ("" : : : "memory");
}
}
#define CHX_SLEEP 0
@@ -858,7 +783,7 @@ extern void cause_link_time_error_unexpected_size_of_struct_chx_thread (void);
* @thread_entry: Entry function of new thread
* @arg: Argument to the thread entry function
*
* Create a thread.
* Create a thread. Returns thread ID.
*/
chopstx_t
chopstx_create (uint32_t flags_and_prio,
@@ -875,24 +800,24 @@ chopstx_create (uint32_t flags_and_prio,
if (stack_size < sizeof (struct chx_thread) + 8 * sizeof (uint32_t))
chx_fatal (CHOPSTX_ERR_THREAD_CREATE);
stack = (void *)(stack_addr + stack_size - sizeof (struct chx_thread)
- sizeof (struct chx_stack_regs));
memset (stack, 0, sizeof (struct chx_stack_regs));
tp = (struct chx_thread *)(stack + sizeof (struct chx_stack_regs));
p = (struct chx_stack_regs *)stack;
p->reg[REG_R0] = (uint32_t)arg;
p->reg[REG_LR] = (uint32_t)chopstx_exit;
p->reg[REG_PC] = (uint32_t)thread_entry;
p->reg[REG_XPSR] = INITIAL_XPSR;
tp = (struct chx_thread *)(stack + sizeof (struct chx_stack_regs));
memset (&tp->tc, 0, sizeof (tp->tc));
tp->tc.reg[REG_SP] = (uint32_t)stack;
tp->next = tp->prev = tp;
tp->mutex_list = NULL;
tp->clp = NULL;
tp->state = THREAD_EXITED;
tp->flag_got_cancel = tp->flag_join_req = 0;
tp->flag_got_cancel = tp->flag_join_req = tp->flag_cancelable = 0;
tp->flag_sched_rr = (flags_and_prio & CHOPSTX_SCHED_RR)? 1 : 0;
tp->flag_detached = (flags_and_prio & CHOPSTX_DETACHED)? 1 : 0;
tp->prio_orig = tp->prio = prio;
@@ -927,6 +852,7 @@ chopstx_usec_wait_var (uint32_t *var)
asm volatile ("mov %0, %1" : "=r" (r8) : "r" (usec_p));
while (1)
{
chopstx_testcancel ();
chx_cpu_sched_lock ();
if (!r8) /* awakened */
break;
@@ -1095,6 +1021,7 @@ chopstx_cond_wait (chopstx_cond_t *cond, chopstx_mutex_t *mutex)
{
struct chx_thread *tp = running;
chopstx_testcancel ();
chx_cpu_sched_lock ();
if (mutex)
@@ -1191,8 +1118,10 @@ chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num)
chx_cpu_sched_lock ();
chx_disable_intr (irq_num);
chx_set_intr_prio (irq_num);
chx_spin_lock (&intr_lock);
intr->next = intr_top;
intr_top = intr;
chx_spin_unlock (&intr_lock);
chx_cpu_sched_unlock ();
}
@@ -1210,6 +1139,7 @@ chopstx_release_irq (chopstx_intr_t *intr0)
chx_cpu_sched_lock ();
chx_enable_intr (intr0->irq_num);
chx_spin_lock (&intr_lock);
intr_prev = intr_top;
for (intr = intr_top; intr; intr = intr->next)
if (intr == intr0)
@@ -1219,16 +1149,18 @@ chopstx_release_irq (chopstx_intr_t *intr0)
intr_top = intr_top->next;
else
intr_prev->next = intr->next;
chx_spin_unlock (&intr_lock);
chx_cpu_sched_unlock ();
}
static void
chopstx_release_irq_thread (struct chx_thread *tp)
chx_release_irq_thread (struct chx_thread *tp)
{
chopstx_intr_t *intr, *intr_prev;
chx_cpu_sched_lock ();
chx_spin_lock (&intr_lock);
intr_prev = intr_top;
for (intr = intr_top; intr; intr = intr->next)
if (intr->tp == tp)
@@ -1242,6 +1174,7 @@ chopstx_release_irq_thread (struct chx_thread *tp)
else
intr_prev->next = intr->next;
}
chx_spin_unlock (&intr_lock);
chx_cpu_sched_unlock ();
}
@@ -1255,6 +1188,7 @@ chopstx_release_irq_thread (struct chx_thread *tp)
void
chopstx_intr_wait (chopstx_intr_t *intr)
{
chopstx_testcancel ();
chx_cpu_sched_lock ();
if (intr->ready == 0)
{
@@ -1326,7 +1260,7 @@ chopstx_exit (void *retval)
{
clp->routine (clp->arg);
clp = clp->next;
}
}
/* Release all mutexes this thread still holds. */
for (m = running->mutex_list; m; m = m_next)
@@ -1340,7 +1274,7 @@ chopstx_exit (void *retval)
chx_cpu_sched_unlock ();
}
chopstx_release_irq_thread (running);
chx_release_irq_thread (running);
chx_exit (retval);
}
@@ -1439,6 +1373,12 @@ chopstx_cancel (chopstx_t thd)
/* Assume it's UP, it's *never*: tp->state==RUNNING on SMP??? */
chx_cpu_sched_lock ();
tp->flag_got_cancel = 1;
if (!tp->flag_cancelable)
{
chx_cpu_sched_unlock ();
return;
}
/* Cancellation points: cond_wait, intr_wait, and usec_wait. */
if (tp->state == THREAD_WAIT_CND || tp->state == THREAD_WAIT_INT
|| tp->state == THREAD_WAIT_TIME)
@@ -1467,7 +1407,7 @@ chopstx_cancel (chopstx_t thd)
/**
* chopstx_testcancel - catch pending cancellation request
*
*
* Calling chopstx_testcancel creates a cancellation point.
* No return value. If the thread is canceled, this function
* does not return.
@@ -1475,6 +1415,235 @@ chopstx_cancel (chopstx_t thd)
void
chopstx_testcancel (void)
{
if (running->flag_got_cancel)
if (running->flag_cancelable && running->flag_got_cancel)
chopstx_exit ((void *)CHOPSTX_EXIT_CANCELED_IN_SYNC);
}
/**
* chopstx_setcancelstate - set cancelability state
* @cancel_disable: 0 to enable cancelation, otherwise disabled.
*
* Calling chopstx_setcancelstate sets cancelability state.
*
* Returns old state which is 0 when it was enabled.
*/
int
chopstx_setcancelstate (int cancel_disable)
{
int old_state = !running->flag_cancelable;
running->flag_cancelable = (cancel_disable == 0);
chopstx_testcancel ();
return old_state;
}
/*
* Lower layer architecture specific exception handling entries.
*
*/
/* Registers on stack (PSP): r0, r1, r2, r3, r12, lr, pc, xpsr */
static void __attribute__ ((naked, used))
sched (void)
{
register struct chx_thread *tp asm ("r0");
tp = chx_ready_pop ();
if (tp && tp->flag_sched_rr)
{
chx_spin_lock (&q_timer.lock);
chx_timer_insert (tp, PREEMPTION_USEC);
chx_spin_unlock (&q_timer.lock);
}
asm volatile (/* Now, r0 points to the thread to be switched. */
/* Put it to *running. */
"ldr r1, =running\n\t"
/* Update running. */
"str r0, [r1]\n\t"
#if defined(__ARM_ARCH_6M__)
"cmp r0, #0\n\t"
"beq 1f\n\t"
#else
"cbz r0, 1f\n\t"
#endif
/**/
"add r0, #8\n\t"
"ldm r0!, {r4, r5, r6, r7}\n\t"
#if defined(__ARM_ARCH_6M__)
"ldm r0!, {r1, r2, r3}\n\t"
"mov r8, r1\n\t"
"mov r9, r2\n\t"
"mov r10, r3\n\t"
"ldm r0!, {r1, r2}\n\t"
"mov r11, r1\n\t"
"msr PSP, r2\n\t"
#else
"ldr r8, [r0], #4\n\t"
"ldr r9, [r0], #4\n\t"
"ldr r10, [r0], #4\n\t"
"ldr r11, [r0], #4\n\t"
"ldr r1, [r0], #4\n\t"
"msr PSP, r1\n\t"
#endif
"ldrb r1, [r0, #3]\n\t" /* ->PRIO field. */
"cmp r1, #247\n\t"
"bhi 0f\n\t" /* Leave interrupt disabled if >= 248 */
/**/
/* Unmask interrupts. */
"mov r0, #0\n\t"
#if defined(__ARM_ARCH_6M__)
"cpsie i\n"
#else
"msr BASEPRI, r0\n"
#endif
/**/
"0:\n\t"
"sub r0, #3\n\t" /* EXC_RETURN to a thread with PSP */
"bx r0\n"
"1:\n\t"
/* Spawn an IDLE thread. */
"ldr r0, =__main_stack_end__\n\t"
"msr MSP, r0\n\t"
"mov r0, #0\n\t"
"mov r1, #0\n\t"
"ldr r2, =idle\n\t" /* PC = idle */
#if defined(__ARM_ARCH_6M__)
"mov r3, #0x010\n\t"
"lsl r3, r3, #20\n\t" /* xPSR = T-flag set (Thumb) */
#else
"mov r3, #0x01000000\n\t" /* xPSR = T-flag set (Thumb) */
#endif
"push {r0, r1, r2, r3}\n\t"
"mov r0, #0\n\t"
"mov r1, #0\n\t"
"mov r2, #0\n\t"
"mov r3, #0\n\t"
"push {r0, r1, r2, r3}\n"
/**/
/* Unmask interrupts. */
"mov r0, #0\n\t"
#if defined(__ARM_ARCH_6M__)
"cpsie i\n\t"
#else
"msr BASEPRI, r0\n\t"
#endif
/**/
"sub r0, #7\n\t" /* EXC_RETURN to a thread with MSP */
"bx r0\n"
: /* no output */ : "r" (tp) : "memory");
}
void __attribute__ ((naked))
preempt (void)
{
register struct chx_thread *tp asm ("r0");
tp = (struct chx_thread *)CPU_EXCEPTION_PRIORITY_INHIBIT_SCHED;
asm (
#if defined(__ARM_ARCH_6M__)
"cpsid i\n\t"
#else
"msr BASEPRI, r0\n\t"
#endif
"ldr r1, =running\n\t"
"ldr r0, [r1]\n\t"
#if defined(__ARM_ARCH_6M__)
"cmp r0, #0\n\t"
"bne 0f\n\t"
#else
"cbnz r0, 0f\n\t"
#endif
/* It's idle which was preempted. Discard saved registers on stack. */
"ldr r1, =__main_stack_end__\n\t"
"msr MSP, r1\n\t"
"b sched\n"
"0:\n\t"
#if defined(__ARM_ARCH_6M__)
"add r1, r0, #4\n\t"
"add r1, #4\n\t"
#else
"add r1, r0, #8\n\t"
#endif
/* Save registers onto CHX_THREAD struct. */
"stm r1!, {r4, r5, r6, r7}\n\t"
"mov r2, r8\n\t"
"mov r3, r9\n\t"
"mov r4, r10\n\t"
"mov r5, r11\n\t"
"mrs r6, PSP\n\t" /* r13(=SP) in user space. */
"stm r1!, {r2, r3, r4, r5, r6}"
: "=r" (tp)
: "r" (tp)
: "r1", "r2", "r3", "r4", "r5", "r6", "cc", "memory");
if (tp)
{
if (tp->flag_sched_rr)
{
if (tp->state == THREAD_RUNNING)
{
chx_timer_dequeue (tp);
chx_ready_enqueue (tp);
}
/*
* It may be THREAD_READY after chx_timer_expired.
* Then, do nothing.
*/
}
else
chx_ready_push (tp);
running = NULL;
}
asm volatile ("b sched"
: /* no output */: /* no input */ : "memory");
}
/*
* System call: switch to another thread.
* There are two cases:
* ORIG_R0=0 (SLEEP): Current RUNNING thread is already connected to
* something (mutex, cond, intr, etc.)
* ORIG_R0=1 (YIELD): Current RUNNING thread is active,
* it is needed to be enqueued to READY queue.
*/
void __attribute__ ((naked))
svc (void)
{
register struct chx_thread *tp asm ("r0");
register uint32_t orig_r0 asm ("r1");
asm ("ldr r1, =running\n\t"
"ldr r0, [r1]\n\t"
#if defined(__ARM_ARCH_6M__)
"add r1, r0, #4\n\t"
"add r1, #4\n\t"
#else
"add r1, r0, #8\n\t"
#endif
/* Save registers onto CHX_THREAD struct. */
"stm r1!, {r4, r5, r6, r7}\n\t"
"mov r2, r8\n\t"
"mov r3, r9\n\t"
"mov r4, r10\n\t"
"mov r5, r11\n\t"
"mrs r6, PSP\n\t" /* r13(=SP) in user space. */
"stm r1!, {r2, r3, r4, r5, r6}\n\t"
"ldr r1, [r6]"
: "=r" (tp), "=r" (orig_r0)
: /* no input */
: "r2", "r3", "r4", "r5", "r6", "memory");
if (orig_r0) /* yield */
{
if (tp->flag_sched_rr)
chx_timer_dequeue (tp);
chx_ready_enqueue (tp);
running = NULL;
}
asm volatile ("b sched"
: /* no output */: /* no input */ : "memory");
}

View File

@@ -31,6 +31,8 @@ typedef uint8_t chopstx_prio_t;
extern chopstx_t chopstx_main;
void chopstx_main_init (chopstx_prio_t);
/* NOTE: This signature is different to PTHREAD's one. */
chopstx_t
chopstx_create (uint32_t flags_and_prio,
@@ -82,7 +84,6 @@ void chopstx_cond_broadcast (chopstx_cond_t *cond);
typedef struct chx_intr {
struct chx_intr *next;
struct chx_spinlock lock;
struct chx_thread *tp;
uint32_t ready;
uint8_t irq_num;
@@ -118,6 +119,9 @@ enum {
void chopstx_cancel (chopstx_t thd);
void chopstx_testcancel (void);
/* NOTE: This signature is different to PTHREAD's one. */
int chopstx_setcancelstate (int);
struct chx_cleanup {
struct chx_cleanup *next;
void (*routine) (void *);

368
clk_gpio_init.c Normal file
View File

@@ -0,0 +1,368 @@
/*
* clk_gpio_init.c - Clock and GPIO initialization.
*
* Copyright (C) 2015 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Chopstx, a thread library for embedded.
*
* Chopstx 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 3 of the License, or
* (at your option) any later version.
*
* Chopstx 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, see <http://www.gnu.org/licenses/>.
*
* As additional permission under GNU GPL version 3 section 7, you may
* distribute non-source form of the Program without the copy of the
* GNU GPL normally required by section 4, provided you inform the
* receipents of GNU GPL by a written offer.
*
*/
#define STM32_SW_HSI (0 << 0)
#define STM32_SW_PLL (2 << 0)
#define STM32_PLLSRC_HSI (0 << 16)
#define STM32_PLLSRC_HSE (1 << 16)
#define STM32_PLLXTPRE_DIV1 (0 << 17)
#define STM32_PLLXTPRE_DIV2 (1 << 17)
#define STM32_HPRE_DIV1 (0 << 4)
#define STM32_PPRE1_DIV1 (0 << 8)
#define STM32_PPRE1_DIV2 (4 << 8)
#define STM32_PPRE2_DIV1 (0 << 11)
#define STM32_PPRE2_DIV2 (4 << 11)
#define STM32_ADCPRE_DIV4 (1 << 14)
#define STM32_ADCPRE_DIV6 (2 << 14)
#define STM32_USBPRE_DIV1P5 (0 << 22)
#define STM32_MCO_NOCLOCK (0 << 24)
#if defined(MCU_STM32F0)
#define STM32_PPRE1 STM32_PPRE1_DIV1
#define STM32_PLLSRC STM32_PLLSRC_HSI
#define STM32_FLASHBITS 0x00000011
#define STM32_PLLCLKIN (STM32_HSICLK / 2)
#else
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_FLASHBITS 0x00000012
#define STM32_PLLCLKIN (STM32_HSECLK / 1)
#endif
#define STM32_SW STM32_SW_PLL
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE2 STM32_PPRE2_DIV1
#define STM32_ADCPRE STM32_ADCPRE_DIV6
#define STM32_MCOSEL STM32_MCO_NOCLOCK
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
#define STM32_SYSCLK STM32_PLLCLKOUT
#define STM32_HCLK (STM32_SYSCLK / 1)
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct RCC {
volatile uint32_t CR;
volatile uint32_t CFGR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
#if defined(MCU_STM32F0)
volatile uint32_t AHBRSTR;
volatile uint32_t CFGR2;
volatile uint32_t CFGR3;
volatile uint32_t CR2;
#endif
};
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
static struct RCC *const RCC = ((struct RCC *const)RCC_BASE);
#define RCC_APB1ENR_USBEN 0x00800000
#define RCC_APB1RSTR_USBRST 0x00800000
#define RCC_CR_HSION 0x00000001
#define RCC_CR_HSIRDY 0x00000002
#define RCC_CR_HSITRIM 0x000000F8
#define RCC_CR_HSEON 0x00010000
#define RCC_CR_HSERDY 0x00020000
#define RCC_CR_PLLON 0x01000000
#define RCC_CR_PLLRDY 0x02000000
#define RCC_CFGR_SWS 0x0000000C
#define RCC_CFGR_SWS_HSI 0x00000000
#define RCC_AHBENR_CRCEN 0x0040
#if defined(MCU_STM32F0)
#define RCC_AHBRSTR_IOPARST 0x00020000
#define RCC_AHBRSTR_IOPBRST 0x00040000
#define RCC_AHBRSTR_IOPCRST 0x00080000
#define RCC_AHBRSTR_IOPDRST 0x00100000
#define RCC_AHBRSTR_IOPFRST 0x00400000
#define RCC_AHBENR_IOPAEN 0x00020000
#define RCC_AHBENR_IOPBEN 0x00040000
#define RCC_AHBENR_IOPCEN 0x00080000
#define RCC_AHBENR_IOPDEN 0x00100000
#define RCC_AHBENR_IOPFEN 0x00400000
#define RCC_APB2RSTR_SYSCFGRST 0x00000001
#define RCC_APB2ENR_SYSCFGEN 0x00000001
#else
#define RCC_APB2RSTR_AFIORST 0x00000001
#define RCC_APB2RSTR_IOPARST 0x00000004
#define RCC_APB2RSTR_IOPBRST 0x00000008
#define RCC_APB2RSTR_IOPCRST 0x00000010
#define RCC_APB2RSTR_IOPDRST 0x00000020
#define RCC_APB2RSTR_IOPERST 0x00000040
#define RCC_APB2RSTR_IOPFRST 0x00000080
#define RCC_APB2RSTR_IOPGRST 0x00000100
#define RCC_APB2ENR_AFIOEN 0x00000001
#define RCC_APB2ENR_IOPAEN 0x00000004
#define RCC_APB2ENR_IOPBEN 0x00000008
#define RCC_APB2ENR_IOPCEN 0x00000010
#define RCC_APB2ENR_IOPDEN 0x00000020
#define RCC_APB2ENR_IOPEEN 0x00000040
#define RCC_APB2ENR_IOPFEN 0x00000080
#define RCC_APB2ENR_IOPGEN 0x00000100
#endif
#if defined(MCU_STM32F0)
struct SYSCFG {
volatile uint32_t CFGR1;
uint32_t dummy0;
volatile uint32_t EXTICR[4];
volatile uint32_t CFGR2;
};
#define SYSCFG_CFGR1_MEM_MODE 0x03
#define SYSCFG_BASE (APBPERIPH_BASE + 0x00010000)
static struct SYSCFG *const SYSCFG = ((struct SYSCFG *const) SYSCFG_BASE);
#endif
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = ((struct FLASH *const) FLASH_R_BASE);
static void __attribute__((used))
clock_init (void)
{
/* HSI setup */
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY))
;
/* Reset HSEON, HSEBYP, CSSON, and PLLON, not touching RCC_CR_HSITRIM */
RCC->CR &= (RCC_CR_HSITRIM | RCC_CR_HSION);
RCC->CFGR = 0;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
;
#if !defined(MCU_STM32F0)
/* HSE setup */
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY))
;
#endif
/* PLL setup */
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
;
/* Clock settings */
RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE
| STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
/*
* We don't touch RCC->CR2, RCC->CFGR2, RCC->CFGR3, and RCC->CIR.
*/
/* Flash setup */
FLASH->ACR = STM32_FLASHBITS;
/* CRC */
RCC->AHBENR |= RCC_AHBENR_CRCEN;
/* Switching on the configured clock source. */
RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
;
#if defined(MCU_STM32F0)
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
RCC->APB2RSTR = RCC_APB2RSTR_SYSCFGRST;
RCC->APB2RSTR = 0;
# if defined(HAVE_SYS_H)
/* Use vectors on RAM */
SYSCFG->CFGR1 = (SYSCFG->CFGR1 & ~SYSCFG_CFGR1_MEM_MODE) | 3;
# endif
#endif
}
#if defined(MCU_STM32F0)
struct GPIO {
volatile uint32_t MODER;
volatile uint16_t OTYPER;
uint16_t dummy0;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint16_t IDR;
uint16_t dummy1;
volatile uint16_t ODR;
uint16_t dummy2;
volatile uint16_t BSRR;
uint16_t dummy3;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint16_t BRR;
uint16_t dummy4;
};
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (AHB2PERIPH_BASE + 0x0400)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (AHB2PERIPH_BASE + 0x0800)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (AHB2PERIPH_BASE + 0x0C00)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
#else
struct AFIO
{
volatile uint32_t EVCR;
volatile uint32_t MAPR;
volatile uint32_t EXTICR[4];
uint32_t RESERVED0;
volatile uint32_t MAPR2;
};
#define AFIO_BASE 0x40010000
static struct AFIO *const AFIO = (struct AFIO *const)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE 0x02000000
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)
#endif
static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
#ifdef GPIO_USB_BASE
static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE);
#endif
#ifdef GPIO_OTHER_BASE
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
#endif
static void __attribute__((used))
gpio_init (void)
{
/* Enable GPIO clock. */
#if defined(MCU_STM32F0)
RCC->AHBENR |= RCC_ENR_IOP_EN;
RCC->AHBRSTR = RCC_RSTR_IOP_RST;
RCC->AHBRSTR = 0;
#else
RCC->APB2ENR |= RCC_ENR_IOP_EN;
RCC->APB2RSTR = RCC_RSTR_IOP_RST;
RCC->APB2RSTR = 0;
#endif
#if defined(MCU_STM32F0)
GPIO_LED->OSPEEDR = VAL_GPIO_LED_OSPEEDR;
GPIO_LED->OTYPER = VAL_GPIO_LED_OTYPER;
GPIO_LED->MODER = VAL_GPIO_LED_MODER;
GPIO_LED->PUPDR = VAL_GPIO_LED_PUPDR;
#ifdef GPIO_OTHER_BASE
GPIO_OTHER->OSPEEDR = VAL_GPIO_OTHER_OSPEEDR;
GPIO_OTHER->OTYPER = VAL_GPIO_OTHER_OTYPER;
GPIO_OTHER->MODER = VAL_GPIO_OTHER_MODER;
GPIO_OTHER->PUPDR = VAL_GPIO_OTHER_PUPDR;
#endif
#else
#ifdef AFIO_MAPR_SOMETHING
AFIO->MAPR |= AFIO_MAPR_SOMETHING;
#endif
/* LED is mandatory. If it's on an independent port, we configure it. */
GPIO_LED->ODR = VAL_GPIO_LED_ODR;
GPIO_LED->CRH = VAL_GPIO_LED_CRH;
GPIO_LED->CRL = VAL_GPIO_LED_CRL;
/* If there is USB enabler pin and it's independent, we configure it. */
#if defined(GPIO_USB_BASE) && GPIO_USB_BASE != GPIO_LED_BASE
GPIO_USB->ODR = VAL_GPIO_USB_ODR;
GPIO_USB->CRH = VAL_GPIO_USB_CRH;
GPIO_USB->CRL = VAL_GPIO_USB_CRL;
#endif
#ifdef GPIO_OTHER_BASE
GPIO_OTHER->ODR = VAL_GPIO_OTHER_ODR;
GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH;
GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL;
#endif
#endif
}

View File

@@ -7,6 +7,16 @@ When it detects a coding error, this function will be called to
stop further execution of code. It never returns.
@end deftypefun
@subheading chopstx_main_init
@anchor{chopstx_main_init}
@deftypefun {void} {chopstx_main_init} (chopstx_prio_t @var{prio})
@var{prio}: priority
Initialize main thread with @var{prio}.
The thread main is created with priority CHX_PRIO_MAIN_INIT,
and it runs with that priority until this routine will is called.
@end deftypefun
@subheading chopstx_create
@anchor{chopstx_create}
@deftypefun {chopstx_t} {chopstx_create} (uint32_t @var{flags_and_prio}, uint32_t @var{stack_addr}, size_t @var{stack_size}, voidfunc @var{thread_entry}, void * @var{arg})
@@ -20,7 +30,7 @@ stop further execution of code. It never returns.
@var{arg}: Argument to the thread entry function
Create a thread.
Create a thread. Returns thread ID.
@end deftypefun
@subheading chopstx_usec_wait_var
@@ -28,8 +38,8 @@ Create a thread.
@deftypefun {void} {chopstx_usec_wait_var} (uint32_t * @var{var})
@var{var}: Pointer to usec
Sleep for micro second specified by @var{var}.
Another thread can clear @var{var} on condition (to avoid this thread going into sleep).
Sleep for micro seconds, specified by @var{var}.
Another thread can clear @var{var} to stop the caller going into sleep.
@end deftypefun
@subheading chopstx_usec_wait
@@ -95,7 +105,7 @@ Wake up a thread waiting on @var{cond}.
@deftypefun {void} {chopstx_cond_broadcast} (chopstx_cond_t * @var{cond})
@var{cond}: Condition Variable
Wake up all thread winting on @var{cond}.
Wake up all threads waiting on @var{cond}.
@end deftypefun
@subheading chopstx_claim_irq
@@ -167,7 +177,7 @@ Waits for the thread of @var{thd} to terminate.
@deftypefun {void} {chopstx_wakeup_usec_wait} (chopstx_t @var{thd})
@var{thd}: Thread to be awakened
Canceling the timer, wakup the sleeping thread for it.
Canceling the timer, wake up the sleeping thread.
No return value.
@end deftypefun
@@ -176,7 +186,7 @@ No return value.
@deftypefun {void} {chopstx_cancel} (chopstx_t @var{thd})
@var{thd}: Thread to be canceled
This function requests a cancellation th the thread @var{thd}.
This function requests a cancellation of a thread @var{thd}.
No return value.
@end deftypefun
@@ -189,3 +199,13 @@ No return value. If the thread is canceled, this function
does not return.
@end deftypefun
@subheading chopstx_setcancelstate
@anchor{chopstx_setcancelstate}
@deftypefun {int} {chopstx_setcancelstate} (int @var{cancel_disable})
@var{cancel_disable}: 0 to enable cancelation, otherwise disabled.
Calling chopstx_setcancelstate sets cancelability state.
Returns old state which is 0 when it was enabled.
@end deftypefun

View File

@@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename chopstx.info
@set VERSION 0.04
@set VERSION 0.09
@settitle Chopstx Reference Manual
@c Unify some of the indices.
@syncodeindex tp fn
@@ -11,7 +11,7 @@
This manual is for Chopstx (version @value{VERSION}).
@noindent
Copyright @copyright{} 2013 Flying Stone Technology @*
Copyright @copyright{} 2013, 2015 Flying Stone Technology @*
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -83,8 +83,8 @@ Indexes
@node Introduction
@chapter Introduction
Chopstx is an RT thread library for ARM Cortex-M3, specifically,
STM32F103.
Chopstx is an RT thread library for ARM Cortex-M0 and Cortex-M3.
Specifically, it is used for STM32F030 and STM32F103.
While most RTOSes come with many features, drivers, and stacks,
Chopstx just offers a RT thread library.

284
entry.c
View File

@@ -1,7 +1,7 @@
/*
* entry.c - Entry routine when reset and interrupt vectors.
*
* Copyright (C) 2013, 2014 Flying Stone Technology
* Copyright (C) 2013, 2014, 2015 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Chopstx, a thread library for embedded.
@@ -34,236 +34,19 @@
#define INLINE __attribute__ ((used))
#include "sys.h"
#include "board.h"
#undef STM32F10X_MD /* Prepare for high density device, too. */
#else
#include "board.h"
#define STM32_SW_HSI (0 << 0)
#define STM32_SW_PLL (2 << 0)
#define STM32_PLLSRC_HSI (0 << 16)
#define STM32_PLLSRC_HSE (1 << 16)
#define STM32_PLLXTPRE_DIV1 (0 << 17)
#define STM32_PLLXTPRE_DIV2 (1 << 17)
#define STM32_HPRE_DIV1 (0 << 4)
#define STM32_PPRE1_DIV1 (0 << 8)
#define STM32_PPRE1_DIV2 (4 << 8)
#define STM32_PPRE2_DIV1 (0 << 11)
#define STM32_PPRE2_DIV2 (4 << 11)
#define STM32_ADCPRE_DIV4 (1 << 14)
#define STM32_ADCPRE_DIV6 (2 << 14)
#define STM32_USBPRE_DIV1P5 (0 << 22)
#define STM32_MCO_NOCLOCK (0 << 24)
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_FLASHBITS 0x00000012
#define STM32_PLLCLKIN (STM32_HSECLK / 1)
#define STM32_SW STM32_SW_PLL
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE2 STM32_PPRE2_DIV1
#define STM32_ADCPRE STM32_ADCPRE_DIV6
#define STM32_MCOSEL STM32_MCO_NOCLOCK
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
#define STM32_SYSCLK STM32_PLLCLKOUT
#define STM32_HCLK (STM32_SYSCLK / 1)
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct RCC {
volatile uint32_t CR;
volatile uint32_t CFGR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
};
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
static struct RCC *const RCC = ((struct RCC *const)RCC_BASE);
#define RCC_APB1ENR_USBEN 0x00800000
#define RCC_APB1RSTR_USBRST 0x00800000
#define RCC_CR_HSION 0x00000001
#define RCC_CR_HSIRDY 0x00000002
#define RCC_CR_HSITRIM 0x000000F8
#define RCC_CR_HSEON 0x00010000
#define RCC_CR_HSERDY 0x00020000
#define RCC_CR_PLLON 0x01000000
#define RCC_CR_PLLRDY 0x02000000
#define RCC_CFGR_SWS 0x0000000C
#define RCC_CFGR_SWS_HSI 0x00000000
#define RCC_AHBENR_CRCEN 0x0040
#define RCC_APB2RSTR_AFIORST 0x00000001
#define RCC_APB2RSTR_IOPARST 0x00000004
#define RCC_APB2RSTR_IOPBRST 0x00000008
#define RCC_APB2RSTR_IOPCRST 0x00000010
#define RCC_APB2RSTR_IOPDRST 0x00000020
#define RCC_APB2ENR_AFIOEN 0x00000001
#define RCC_APB2ENR_IOPAEN 0x00000004
#define RCC_APB2ENR_IOPBEN 0x00000008
#define RCC_APB2ENR_IOPCEN 0x00000010
#define RCC_APB2ENR_IOPDEN 0x00000020
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = ((struct FLASH *const) FLASH_R_BASE);
static void __attribute__((used))
clock_init (void)
{
/* HSI setup */
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY))
;
/* Reset HSEON, HSEBYP, CSSON, and PLLON, not touching RCC_CR_HSITRIM */
RCC->CR &= (RCC_CR_HSITRIM | RCC_CR_HSION);
RCC->CFGR = 0;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
;
/* HSE setup */
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY))
;
/* PLL setup */
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
;
/* Clock settings */
RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE
| STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
/*
* We don't touch RCC->CR2, RCC->CFGR2, RCC->CFGR3, and RCC->CIR.
*/
/* Flash setup */
FLASH->ACR = STM32_FLASHBITS;
/* CRC */
RCC->AHBENR |= RCC_AHBENR_CRCEN;
/* Switching on the configured clock source. */
RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
;
}
struct AFIO
{
volatile uint32_t EVCR;
volatile uint32_t MAPR;
volatile uint32_t EXTICR[4];
uint32_t RESERVED0;
volatile uint32_t MAPR2;
};
#define AFIO_BASE 0x40010000
static struct AFIO *const AFIO = (struct AFIO *const)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
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_LED = ((struct GPIO *const) GPIO_LED_BASE);
#ifdef GPIO_USB_BASE
static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE);
#endif
#ifdef GPIO_OTHER_BASE
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
#include "clk_gpio_init.c"
#endif
static void __attribute__((used))
gpio_init (void)
{
/* Enable GPIO clock. */
RCC->APB2ENR |= RCC_ENR_IOP_EN;
RCC->APB2RSTR = RCC_RSTR_IOP_RST;
RCC->APB2RSTR = 0;
#ifdef AFIO_MAPR_SOMETHING
AFIO->MAPR |= AFIO_MAPR_SOMETHING;
#ifdef MAKE_ENTRY_PUBLIC
#define STATIC_ENTRY
#else
#define STATIC_ENTRY static
#endif
GPIO_USB->ODR = VAL_GPIO_ODR;
GPIO_USB->CRH = VAL_GPIO_CRH;
GPIO_USB->CRL = VAL_GPIO_CRL;
#if GPIO_USB_BASE != GPIO_LED_BASE
GPIO_LED->ODR = VAL_GPIO_LED_ODR;
GPIO_LED->CRH = VAL_GPIO_LED_CRH;
GPIO_LED->CRL = VAL_GPIO_LED_CRL;
#endif
#ifdef GPIO_OTHER_BASE
GPIO_OTHER->ODR = VAL_GPIO_OTHER_ODR;
GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH;
GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL;
#endif
}
#endif
extern uint8_t __main_stack_end__;
extern void svc (void);
extern void preempt (void);
@@ -277,7 +60,18 @@ static void nmi (void)
static void hard_fault (void)
{
#if defined(__ARM_ARCH_6M__)
register uint32_t primask;
asm ("mrs %0, PRIMASK" : "=r" (primask));
if (primask)
asm volatile ("b svc");
else
for (;;);
#else
for (;;);
#endif
}
static void mem_manage (void)
@@ -302,10 +96,15 @@ static void none (void)
#define C_S_SUB(arg0, arg1, arg2) arg0 #arg1 arg2
#define COMPOSE_STATEMENT(arg0,arg1,arg2) C_S_SUB (arg0, arg1, arg2)
#if defined(__ARM_ARCH_6M__)
__attribute__ ((used,section(".bss.startup.0")))
uint32_t vectors_in_ram[48];
#endif
/*
* This routine only changes PSP and not MSP.
*/
static __attribute__ ((naked,section(".text.startup.0")))
STATIC_ENTRY __attribute__ ((naked,section(".text.startup.0")))
void entry (void)
{
asm volatile ("bl clock_init\n\t"
@@ -316,7 +115,12 @@ void entry (void)
"0:\n\t"
"cmp r1, r2\n\t"
"beq 1f\n\t"
#if defined(__ARM_ARCH_6M__)
"str r0, [r1]\n\t"
"add r1, #4\n\t"
#else
"str r0, [r1], #4\n\t"
#endif
"b 0b\n"
"1:\n\t"
/* Copy data section. */
@@ -326,8 +130,15 @@ void entry (void)
"2:\n\t"
"cmp r1, r2\n\t"
"beq 3f\n\t"
#if defined(__ARM_ARCH_6M__)
"ldr r0, [r3]\n\t"
"str r0, [r1]\n\t"
"add r3, #4\n\t"
"add r1, #4\n\t"
#else
"ldr r0, [r3], #4\n\t"
"str r0, [r1], #4\n\t"
#endif
"b 2b\n"
"3:\n\t"
/* Switch to PSP. */
@@ -341,8 +152,10 @@ void entry (void)
"bl chx_systick_init\n\t"
"bl gpio_init\n\t"
/* Enable interrupts. */
#if defined(__ARM_ARCH_7M__)
"mov r0, #0\n\t"
"msr BASEPRI, r0\n\t"
#endif
"cpsie i\n\t"
/* Call main. */
"mov r1, r0\n\t"
@@ -386,12 +199,25 @@ handler vector_table[] __attribute__ ((section(".startup.vectors"))) = {
chx_handle_intr /* DMA1 CH6 */, chx_handle_intr /* DMA1 CH7 */,
chx_handle_intr /* ADC1_2 */, chx_handle_intr /* USB HP */,
/* 0x90 */
chx_handle_intr, /* USB LP */
/* ... and more. CAN, EXT9_5, TIMx, I2C, SPI, USART, EXT15_10 */
chx_handle_intr /* USB LP */, chx_handle_intr /* CAN */,
/* ... and more. EXT9_5, TIMx, I2C, SPI, USART, EXT15_10 */
chx_handle_intr, chx_handle_intr,
/* 0xA0 */
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
/* 0xc0 */
#if !defined(__ARM_ARCH_6M__)
/* STM32F0 doesn't have more. */
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr,
#endif
#if !defined(STM32F10X_MD)
/* High-density chips have more; RTCAlarm, USBWakeup, ... , DMA2_Channel4_5 */
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr,
#endif
};

1
example-cdc/board.h Symbolic link
View File

@@ -0,0 +1 @@
../board/board-fst-01.h

View File

@@ -14,9 +14,6 @@ MEMORY
ram : org = 0x20000000, len = 20k
}
__flash_start__ = 0x08001000;
__flash_end__ = 0x08020000;
__ram_start__ = ORIGIN(ram);
__ram_size__ = 20k;
__ram_end__ = __ram_start__ + __ram_size__;
@@ -25,15 +22,17 @@ SECTIONS
{
. = 0;
.sys : ALIGN(16) SUBALIGN(16)
.sys : ALIGN(4) SUBALIGN(4)
{
_sys = .;
KEEP(*(.vectors))
_sys = .;
KEEP(*(.vectors))
. = ALIGN(16);
*(.sys.version)
KEEP(*(.sys.version))
KEEP(*(.sys.board_id))
KEEP(*(.sys.board_name))
build/sys.o(.text)
build/sys.o(.text.*)
build/sys.o(.rodata)
build/sys.o(.rodata)
build/sys.o(.rodata.*)
. = ALIGN(1024);
*(.sys.0)
@@ -59,6 +58,7 @@ SECTIONS
*(.glue_7t)
*(.glue_7)
*(.gcc*)
. = ALIGN(8);
} > flash
.ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash

View File

@@ -1,7 +1,7 @@
/*
* sys.c - system routines for the initial page for STM32F103.
*
* Copyright (C) 2013, 2014 Flying Stone Technology
* Copyright (C) 2013, 2014, 2015 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* Copying and distribution of this file, with or without modification,
@@ -17,53 +17,13 @@
#include <stdlib.h>
#include "board.h"
#include "clk_gpio_init.c"
#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
#define STM32_SW_HSI (0 << 0)
#define STM32_SW_PLL (2 << 0)
#define STM32_PLLSRC_HSI (0 << 16)
#define STM32_PLLSRC_HSE (1 << 16)
#define STM32_PLLXTPRE_DIV1 (0 << 17)
#define STM32_PLLXTPRE_DIV2 (1 << 17)
#define STM32_HPRE_DIV1 (0 << 4)
#define STM32_PPRE1_DIV1 (0 << 8)
#define STM32_PPRE1_DIV2 (4 << 8)
#define STM32_PPRE2_DIV1 (0 << 11)
#define STM32_PPRE2_DIV2 (4 << 11)
#define STM32_ADCPRE_DIV4 (1 << 14)
#define STM32_ADCPRE_DIV6 (2 << 14)
#define STM32_USBPRE_DIV1P5 (0 << 22)
#define STM32_MCO_NOCLOCK (0 << 24)
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_FLASHBITS 0x00000012
#define STM32_PLLCLKIN (STM32_HSECLK / 1)
#define STM32_SW STM32_SW_PLL
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE2 STM32_PPRE2_DIV1
#define STM32_ADCPRE STM32_ADCPRE_DIV6
#define STM32_MCOSEL STM32_MCO_NOCLOCK
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
#define STM32_SYSCLK STM32_PLLCLKOUT
#define STM32_HCLK (STM32_SYSCLK / 1)
struct NVIC {
uint32_t ISER[8];
uint32_t unused1[24];
@@ -93,191 +53,6 @@ nvic_enable_vector (uint32_t n, uint32_t prio)
NVIC_ISER (n) = 1 << (n & 0x1F);
}
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct RCC {
volatile uint32_t CR;
volatile uint32_t CFGR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
};
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
static struct RCC *const RCC = ((struct RCC *const)RCC_BASE);
#define RCC_APB1ENR_USBEN 0x00800000
#define RCC_APB1RSTR_USBRST 0x00800000
#define RCC_CR_HSION 0x00000001
#define RCC_CR_HSIRDY 0x00000002
#define RCC_CR_HSITRIM 0x000000F8
#define RCC_CR_HSEON 0x00010000
#define RCC_CR_HSERDY 0x00020000
#define RCC_CR_PLLON 0x01000000
#define RCC_CR_PLLRDY 0x02000000
#define RCC_CFGR_SWS 0x0000000C
#define RCC_CFGR_SWS_HSI 0x00000000
#define RCC_AHBENR_CRCEN 0x0040
#define RCC_APB2RSTR_AFIORST 0x00000001
#define RCC_APB2RSTR_IOPARST 0x00000004
#define RCC_APB2RSTR_IOPBRST 0x00000008
#define RCC_APB2RSTR_IOPCRST 0x00000010
#define RCC_APB2RSTR_IOPDRST 0x00000020
#define RCC_APB2ENR_AFIOEN 0x00000001
#define RCC_APB2ENR_IOPAEN 0x00000004
#define RCC_APB2ENR_IOPBEN 0x00000008
#define RCC_APB2ENR_IOPCEN 0x00000010
#define RCC_APB2ENR_IOPDEN 0x00000020
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = ((struct FLASH *const) FLASH_R_BASE);
static void
clock_init (void)
{
/* HSI setup */
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY))
;
/* Reset HSEON, HSEBYP, CSSON, and PLLON, not touching RCC_CR_HSITRIM */
RCC->CR &= (RCC_CR_HSITRIM | RCC_CR_HSION);
RCC->CFGR = 0;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
;
/* HSE setup */
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY))
;
/* PLL setup */
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
;
/* Clock settings */
RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE
| STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
/*
* We don't touch RCC->CR2, RCC->CFGR2, RCC->CFGR3, and RCC->CIR.
*/
/* Flash setup */
FLASH->ACR = STM32_FLASHBITS;
/* CRC */
RCC->AHBENR |= RCC_AHBENR_CRCEN;
/* Switching on the configured clock source. */
RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
;
}
struct AFIO
{
volatile uint32_t EVCR;
volatile uint32_t MAPR;
volatile uint32_t EXTICR[4];
uint32_t RESERVED0;
volatile uint32_t MAPR2;
};
#define AFIO_BASE 0x40010000
static struct AFIO *const AFIO = (struct AFIO *const)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
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_LED = ((struct GPIO *const) GPIO_LED_BASE);
#ifdef GPIO_USB_BASE
static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE);
#endif
#ifdef GPIO_OTHER_BASE
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
#endif
static void
gpio_init (void)
{
/* Enable GPIO clock. */
RCC->APB2ENR |= RCC_ENR_IOP_EN;
RCC->APB2RSTR = RCC_RSTR_IOP_RST;
RCC->APB2RSTR = 0;
#ifdef AFIO_MAPR_SOMETHING
AFIO->MAPR |= AFIO_MAPR_SOMETHING;
#endif
GPIO_USB->ODR = VAL_GPIO_ODR;
GPIO_USB->CRH = VAL_GPIO_CRH;
GPIO_USB->CRL = VAL_GPIO_CRL;
#if GPIO_USB_BASE != GPIO_LED_BASE
GPIO_LED->ODR = VAL_GPIO_LED_ODR;
GPIO_LED->CRH = VAL_GPIO_LED_CRH;
GPIO_LED->CRL = VAL_GPIO_LED_CRL;
#endif
#ifdef GPIO_OTHER_BASE
GPIO_OTHER->ODR = VAL_GPIO_OTHER_ODR;
GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH;
GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL;
#endif
}
static void
usb_cable_config (int enable)
{
@@ -468,16 +243,19 @@ flash_check_blank (const uint8_t *p_start, size_t size)
return 1;
}
extern uint8_t __flash_start__, __flash_end__;
#define FLASH_START_ADDR 0x08000000 /* Fixed for all STM32F1. */
#define FLASH_OFFSET 0x1000 /* First pages are not-writable. */
#define FLASH_START (FLASH_START_ADDR+FLASH_OFFSET)
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
#define FLASH_SIZE_REG ((uint16_t *)0x1ffff7e0)
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__;
uint32_t flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
if (dst_addr < flash_start || dst_addr + len > flash_end)
if (dst_addr < FLASH_START || dst_addr + len > flash_end)
return 0;
while (len)
@@ -530,17 +308,21 @@ flash_protect (void)
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__;
uint32_t addr = FLASH_START;
uint32_t end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
uint32_t page_size = 1024;
int r;
if (((*CHIP_ID_REG) & 0xfff) == 0x0414)
page_size = 2048;
while (addr < end)
{
r = flash_erase_page (addr);
if (r != 0)
break;
addr += FLASH_PAGE_SIZE;
addr += page_size;
}
if (addr >= end)
@@ -640,7 +422,13 @@ handler vector[] __attribute__ ((section(".vectors"))) = {
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,
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
/* sys version: "2.1" */
'2', 0, '.', 0, '1', 0,
};
const uint32_t __attribute__((section(".sys.board_id")))
sys_board_id = BOARD_ID;
const uint8_t __attribute__((section(".sys.board_name")))
sys_board_name[] = BOARD_NAME;

View File

@@ -1,4 +1,19 @@
#define BOARD_ID_CQ_STARM 0xc5480875
#define BOARD_ID_FST_01_00 0x613870a9
#define BOARD_ID_FST_01 0x696886af
#define BOARD_ID_MAPLE_MINI 0x7a445272
#define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594
#define BOARD_ID_STBEE_MINI 0x1f341961
#define BOARD_ID_STBEE 0x945c37e8
#define BOARD_ID_STM32_PRIMER2 0x21e5798d
#define BOARD_ID_STM8S_DISCOVERY 0x2f0976bb
#define BOARD_ID_ST_DONGLE 0x2cd4e471
#define BOARD_ID_ST_NUCLEO_F103 0x9b87c16d
#define BOARD_ID_NITROKEY_START 0xad1e7ebd
extern const uint8_t sys_version[8];
extern const uint32_t sys_board_id;
extern const uint8_t sys_board_name[];
typedef void (*handler)(void);
extern handler vector[16];

View File

@@ -36,7 +36,7 @@ static const uint8_t vcom_device_desc[18] = {
};
/* Configuration Descriptor tree for a CDC.*/
static const uint8_t vcom_configuration_desc[67] = {
static const uint8_t vcom_config_desc[67] = {
9,
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
/* Configuration Descriptor.*/
@@ -167,28 +167,34 @@ usb_cb_device_reset (void)
usb_lld_set_configuration (0);
/* Current Feature initialization */
usb_lld_set_feature (vcom_configuration_desc[7]);
usb_lld_set_feature (vcom_config_desc[7]);
usb_lld_reset ();
/* Initialize Endpoint 0 */
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
chopstx_mutex_lock (&usb_mtx);
connected = 0;
bDeviceState = ATTACHED;
chopstx_cond_signal (&cnd_usb);
chopstx_mutex_unlock (&usb_mtx);
}
#define CDC_CTRL_DTR 0x0001
void
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t index, uint16_t len)
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
{
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
&& index == 0 && USB_SETUP_SET (req) && len == 0
&& req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
&& USB_SETUP_SET (req) && req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
{
/* Open/close the connection. */
chopstx_mutex_lock (&usb_mtx);
connected = (value != 0)? 1 : 0;
connected = ((value & CDC_CTRL_DTR) != 0)? 1 : 0;
chopstx_cond_signal (&cnd_usb);
chopstx_mutex_unlock (&usb_mtx);
}
@@ -211,22 +217,17 @@ static struct line_coding line_coding = {
static int
vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value, uint16_t len)
vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
{
(void)value;
if (USB_SETUP_GET (req))
{
if (req_no == USB_CDC_REQ_GET_LINE_CODING
&& len == sizeof (line_coding))
{
usb_lld_set_data_to_send (&line_coding, sizeof (line_coding));
return USB_SUCCESS;
}
if (req_no == USB_CDC_REQ_GET_LINE_CODING)
return usb_lld_reply_request (&line_coding, sizeof(line_coding), detail);
}
else /* USB_SETUP_SET (req) */
{
if (req_no == USB_CDC_REQ_SET_LINE_CODING
&& len == sizeof (line_coding))
&& detail->len == sizeof (line_coding))
{
usb_lld_set_data_to_recv (&line_coding, sizeof (line_coding));
return USB_SUCCESS;
@@ -239,38 +240,29 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value, uint16_t len)
}
int
usb_cb_setup (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len)
usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
{
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
(void)len;
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
if (index == 0)
return vcom_port_data_setup (req, req_no, value, len);
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && detail->index == 0)
return vcom_port_data_setup (req, req_no, detail);
return USB_UNSUPPORT;
}
int
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
uint16_t index)
struct control_info *detail)
{
(void)index;
if (rcp != DEVICE_RECIPIENT)
return USB_UNSUPPORT;
if (desc_type == DEVICE_DESCRIPTOR)
{
usb_lld_set_data_to_send (vcom_device_desc, sizeof (vcom_device_desc));
return USB_SUCCESS;
}
return usb_lld_reply_request (vcom_device_desc, sizeof (vcom_device_desc),
detail);
else if (desc_type == CONFIG_DESCRIPTOR)
{
usb_lld_set_data_to_send (vcom_configuration_desc,
sizeof (vcom_configuration_desc));
return USB_SUCCESS;
}
return usb_lld_reply_request (vcom_config_desc, sizeof (vcom_config_desc),
detail);
else if (desc_type == STRING_DESCRIPTOR)
{
const uint8_t *str;
@@ -298,8 +290,7 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
return USB_UNSUPPORT;
}
usb_lld_set_data_to_send (str, size);
return USB_SUCCESS;
return usb_lld_reply_request (str, size, detail);
}
return USB_UNSUPPORT;
@@ -374,9 +365,11 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
}
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
{
static uint8_t zero = 0;
const uint8_t zero = 0;
uint16_t interface = detail->index;
uint16_t alt = detail->value;
if (interface >= NUM_INTERFACES)
return USB_UNSUPPORT;
@@ -393,8 +386,7 @@ int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
}
case USB_GET_INTERFACE:
usb_lld_set_data_to_send (&zero, 1);
return USB_SUCCESS;
return usb_lld_reply_request (&zero, 1, detail);
default:
case USB_QUERY_INTERFACE:

View File

@@ -55,15 +55,19 @@ enum
USB_SUCCESS = 1,
};
struct control_info {
uint16_t value;
uint16_t index;
uint16_t len;
};
void usb_cb_device_reset (void);
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len);
int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t index, uint16_t len);
int usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail);
int usb_cb_interface (uint8_t cmd, struct control_info *detail);
int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
uint16_t index);
struct control_info *detail);
int usb_cb_handle_event (uint8_t event_type, uint16_t value);
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t value);
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value);
enum {
USB_EVENT_ADDRESS,
@@ -89,51 +93,30 @@ enum DEVICE_STATE
CONFIGURED
};
void usb_lld_init (uint8_t feature);
void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n);
void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n);
void usb_lld_stall_tx (int ep_num);
void usb_lld_stall_rx (int ep_num);
int usb_lld_tx_data_len (int ep_num);
void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len);
void usb_lld_tx_enable (int ep_num, size_t len);
void usb_lld_write (uint8_t ep_num, const void *buf, size_t len);
int usb_lld_reply_request (const void *buf, size_t buflen,
struct control_info *ctrl);
void usb_lld_rx_enable (int ep_num);
int usb_lld_rx_data_len (int ep_num);
void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len);
void usb_lld_reset (void);
void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
int ep_rx_addr, int ep_tx_addr,
int ep_rx_memory_size);
void usb_lld_set_configuration (uint8_t config);
uint8_t usb_lld_current_configuration (void);
void usb_lld_set_feature (uint8_t feature);
void usb_lld_set_data_to_recv (const void *p, size_t len);
extern void usb_lld_init (uint8_t feature);
void usb_lld_prepare_shutdown (void);
void usb_lld_shutdown (void);
extern void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n);
extern void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n);
extern void usb_lld_stall_tx (int ep_num);
extern void usb_lld_stall_rx (int ep_num);
extern int usb_lld_tx_data_len (int ep_num);
extern void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len);
extern void usb_lld_tx_enable (int ep_num, size_t len);
extern void usb_lld_write (uint8_t ep_num, const void *buf, size_t len);
extern void usb_lld_rx_enable (int ep_num);
extern int usb_lld_rx_data_len (int ep_num);
extern void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len);
extern void usb_lld_reset (void);
extern void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
int ep_rx_addr, int ep_tx_addr,
int ep_rx_memory_size);
extern void usb_lld_set_configuration (uint8_t config);
extern uint8_t usb_lld_current_configuration (void);
extern void usb_lld_set_feature (uint8_t feature);
extern void usb_lld_set_data_to_send (const void *p, size_t len);
extern inline void usb_lld_set_data_to_recv (void *p, size_t len)
{
usb_lld_set_data_to_send ((const void *)p, len);
}
extern void usb_lld_prepare_shutdown (void);
extern void usb_lld_shutdown (void);
extern void usb_interrupt_handler (void);
void usb_interrupt_handler (void);

View File

@@ -1,9 +1,6 @@
#include <stdint.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#include "sys.h"
#include "usb_lld.h"
@@ -49,33 +46,27 @@ enum FEATURE_SELECTOR
struct DATA_INFO
{
uint16_t len;
uint16_t offset;
uint8_t *addr;
uint16_t len;
uint8_t require_zlp;
};
struct CONTROL_INFO
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
};
struct DEVICE_INFO
{
uint8_t current_configuration;
uint8_t current_feature;
uint8_t state;
/**/
uint8_t bmRequestType;
uint8_t bRequest;
/**/
uint16_t value;
};
static struct CONTROL_INFO control_info;
static struct DEVICE_INFO device_info;
static struct DATA_INFO data_info;
static struct CONTROL_INFO *const ctrl_p = &control_info;
static struct DEVICE_INFO *const dev_p = &device_info;
static struct DATA_INFO *const data_p = &data_info;
@@ -412,16 +403,14 @@ static void handle_datastage_out (void)
{
if (data_p->addr && data_p->len)
{
uint8_t *buf;
uint32_t len = st103_get_rx_count (ENDP0);
if (len > data_p->len)
len = data_p->len;
buf = data_p->addr + data_p->offset;
usb_lld_from_pmabuf (buf, st103_get_rx_addr (ENDP0), len);
usb_lld_from_pmabuf (data_p->addr, st103_get_rx_addr (ENDP0), len);
data_p->len -= len;
data_p->offset += len;
data_p->addr += len;
}
if (data_p->len == 0)
@@ -440,13 +429,12 @@ static void handle_datastage_out (void)
static void handle_datastage_in (void)
{
uint32_t len = USB_MAX_PACKET_SIZE;;
const uint8_t *buf;
if ((data_p->len == 0) && (dev_p->state == LAST_IN_DATA))
{
if (data_p->require_zlp == TRUE)
if (data_p->require_zlp)
{
data_p->require_zlp = FALSE;
data_p->require_zlp = 0;
/* No more data to send. Send empty packet */
st103_set_tx_count (ENDP0, 0);
@@ -467,40 +455,33 @@ static void handle_datastage_in (void)
if (len > data_p->len)
len = data_p->len;
buf = (const uint8_t *)data_p->addr + data_p->offset;
usb_lld_to_pmabuf (buf, st103_get_tx_addr (ENDP0), len);
usb_lld_to_pmabuf (data_p->addr, st103_get_tx_addr (ENDP0), len);
data_p->len -= len;
data_p->offset += len;
data_p->addr += len;
st103_set_tx_count (ENDP0, len);
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
}
typedef int (*HANDLER) (uint8_t req,
uint16_t value, uint16_t index, uint16_t length);
typedef int (*HANDLER) (uint8_t req, struct control_info *detail);
static int std_none (uint8_t req,
uint16_t value, uint16_t index, uint16_t length)
static int std_none (uint8_t req, struct control_info *detail)
{
(void)req; (void)value; (void)index; (void)length;
(void)req; (void)detail;
return USB_UNSUPPORT;
}
static int std_get_status (uint8_t req,
uint16_t value, uint16_t index, uint16_t length)
static int std_get_status (uint8_t req, struct control_info *detail)
{
static uint16_t status_info;
uint8_t rcp = req & RECIPIENT;
uint16_t status_info = 0;
status_info = 0; /* Reset Status Information */
data_p->addr = (uint8_t *)&status_info;
if (value != 0 || length != 2 || (index >> 8) != 0
if (detail->value != 0 || detail->len != 2 || (detail->index >> 8) != 0
|| (req & REQUEST_DIR) == 0)
return USB_UNSUPPORT;
if (rcp == DEVICE_RECIPIENT)
{
if (index == 0)
if (detail->index == 0)
{
/* Get Device Status */
uint8_t feature = dev_p->current_feature;
@@ -517,8 +498,7 @@ static int std_get_status (uint8_t req,
else /* Self-powered */
status_info &= ~1;
data_p->len = 2;
return USB_SUCCESS;
return usb_lld_reply_request (&status_info, 2, detail);
}
}
else if (rcp == INTERFACE_RECIPIENT)
@@ -528,22 +508,21 @@ static int std_get_status (uint8_t req,
if (dev_p->current_configuration == 0)
return USB_UNSUPPORT;
r = usb_cb_interface (USB_QUERY_INTERFACE, index, 0);
r = usb_cb_interface (USB_QUERY_INTERFACE, detail);
if (r != USB_SUCCESS)
return USB_UNSUPPORT;
data_p->len = 2;
return USB_SUCCESS;
return usb_lld_reply_request (&status_info, 2, detail);
}
else if (rcp == ENDPOINT_RECIPIENT)
{
uint8_t endpoint = (index & 0x0f);
uint8_t endpoint = (detail->index & 0x0f);
uint16_t status;
if ((index & 0x70) || endpoint == ENDP0)
if ((detail->index & 0x70) || endpoint == ENDP0)
return USB_UNSUPPORT;
if ((index & 0x80))
if ((detail->index & 0x80))
{
status = st103_ep_get_tx_status (endpoint);
if (status == 0) /* Disabled */
@@ -560,15 +539,13 @@ static int std_get_status (uint8_t req,
status_info |= 1; /* OUT Endpoint stalled */
}
data_p->len = 2;
return USB_SUCCESS;
return usb_lld_reply_request (&status_info, 2, detail);
}
return USB_UNSUPPORT;
}
static int std_clear_feature (uint8_t req, uint16_t value,
uint16_t index, uint16_t length)
static int std_clear_feature (uint8_t req, struct control_info *detail)
{
uint8_t rcp = req & RECIPIENT;
@@ -577,10 +554,10 @@ static int std_clear_feature (uint8_t req, uint16_t value,
if (rcp == DEVICE_RECIPIENT)
{
if (length != 0 || index != 0)
if (detail->len != 0 || detail->index != 0)
return USB_UNSUPPORT;
if (value == DEVICE_REMOTE_WAKEUP)
if (detail->value == DEVICE_REMOTE_WAKEUP)
{
dev_p->current_feature &= ~(1 << 5);
return USB_SUCCESS;
@@ -588,17 +565,17 @@ static int std_clear_feature (uint8_t req, uint16_t value,
}
else if (rcp == ENDPOINT_RECIPIENT)
{
uint8_t endpoint = (index & 0x0f);
uint8_t endpoint = (detail->index & 0x0f);
uint16_t status;
if (dev_p->current_configuration == 0)
return USB_UNSUPPORT;
if (length != 0 || (index >> 8) != 0 || value != ENDPOINT_STALL
|| endpoint == ENDP0)
if (detail->len != 0 || (detail->index >> 8) != 0
|| detail->value != ENDPOINT_STALL || endpoint == ENDP0)
return USB_UNSUPPORT;
if ((index & 0x80))
if ((detail->index & 0x80))
status = st103_ep_get_tx_status (endpoint);
else
status = st103_ep_get_rx_status (endpoint);
@@ -606,7 +583,7 @@ static int std_clear_feature (uint8_t req, uint16_t value,
if (status == 0) /* Disabled */
return USB_UNSUPPORT;
if (index & 0x80) /* IN endpoint */
if (detail->index & 0x80) /* IN endpoint */
st103_ep_clear_dtog_tx (endpoint);
else /* OUT endpoint */
st103_ep_clear_dtog_rx (endpoint);
@@ -618,8 +595,7 @@ static int std_clear_feature (uint8_t req, uint16_t value,
return USB_UNSUPPORT;
}
static int std_set_feature (uint8_t req, uint16_t value,
uint16_t index, uint16_t length)
static int std_set_feature (uint8_t req, struct control_info *detail)
{
uint8_t rcp = req & RECIPIENT;
@@ -628,10 +604,10 @@ static int std_set_feature (uint8_t req, uint16_t value,
if (rcp == DEVICE_RECIPIENT)
{
if (length != 0 || index != 0)
if (detail->len != 0 || detail->index != 0)
return USB_UNSUPPORT;
if (value == DEVICE_REMOTE_WAKEUP)
if (detail->value == DEVICE_REMOTE_WAKEUP)
{
dev_p->current_feature |= 1 << 5;
// event??
@@ -640,16 +616,17 @@ static int std_set_feature (uint8_t req, uint16_t value,
}
else if (rcp == ENDPOINT_RECIPIENT)
{
uint8_t endpoint = (index & 0x0f);
uint8_t endpoint = (detail->index & 0x0f);
uint32_t status;
if (dev_p->current_configuration == 0)
return USB_UNSUPPORT;
if (length != 0 || (index >> 8) != 0 || value != 0 || endpoint == ENDP0)
if (detail->len != 0 || (detail->index >> 8) != 0
|| detail->value != 0 || endpoint == ENDP0)
return USB_UNSUPPORT;
if ((index & 0x80))
if ((detail->index & 0x80))
status = st103_ep_get_tx_status (endpoint);
else
status = st103_ep_get_rx_status (endpoint);
@@ -657,7 +634,7 @@ static int std_set_feature (uint8_t req, uint16_t value,
if (status == 0) /* Disabled */
return USB_UNSUPPORT;
if (index & 0x80)
if (detail->index & 0x80)
/* IN endpoint */
st103_ep_set_tx_status (endpoint, EP_TX_STALL);
else
@@ -671,77 +648,59 @@ static int std_set_feature (uint8_t req, uint16_t value,
return USB_UNSUPPORT;
}
static int std_set_address (uint8_t req, uint16_t value,
uint16_t index, uint16_t length)
static int std_set_address (uint8_t req, struct control_info *detail)
{
uint8_t rcp = req & RECIPIENT;
if ((req & REQUEST_DIR) == 1)
return USB_UNSUPPORT;
if (rcp == DEVICE_RECIPIENT)
{
if (length == 0 && value <= 127 && index == 0
&& dev_p->current_configuration == 0)
return USB_SUCCESS;
}
if (rcp == DEVICE_RECIPIENT && detail->len == 0 && detail->value <= 127
&& detail->index == 0 && dev_p->current_configuration == 0)
return USB_SUCCESS;
return USB_UNSUPPORT;
}
static int std_get_descriptor (uint8_t req, uint16_t value,
uint16_t index, uint16_t length)
static int std_get_descriptor (uint8_t req, struct control_info *detail)
{
uint8_t rcp = req & RECIPIENT;
if ((req & REQUEST_DIR) == 0)
return USB_UNSUPPORT;
(void)length;
return usb_cb_get_descriptor (rcp, (value >> 8), (value & 0xff), index);
return usb_cb_get_descriptor (rcp, (detail->value >> 8),
(detail->value & 0xff), detail);
}
static int std_get_configuration (uint8_t req, uint16_t value,
uint16_t index, uint16_t length)
static int std_get_configuration (uint8_t req, struct control_info *detail)
{
uint8_t rcp = req & RECIPIENT;
(void)detail;
if ((req & REQUEST_DIR) == 0)
return USB_UNSUPPORT;
(void)value; (void)index; (void)length;
if (rcp == DEVICE_RECIPIENT)
{
data_p->addr = &dev_p->current_configuration;
data_p->len = 1;
return USB_SUCCESS;
}
return usb_lld_reply_request (&dev_p->current_configuration, 1, detail);
return USB_UNSUPPORT;
}
static int std_set_configuration (uint8_t req, uint16_t value,
uint16_t index, uint16_t length)
static int std_set_configuration (uint8_t req, struct control_info *detail)
{
uint8_t rcp = req & RECIPIENT;
if ((req & REQUEST_DIR) == 1)
return USB_UNSUPPORT;
if (rcp == DEVICE_RECIPIENT && index == 0 && length == 0)
{
int r;
r = usb_cb_handle_event (USB_EVENT_CONFIG, value);
if (r == USB_SUCCESS)
return USB_SUCCESS;
}
if (rcp == DEVICE_RECIPIENT && detail->index == 0 && detail->len == 0)
return usb_cb_handle_event (USB_EVENT_CONFIG, detail->value);
return USB_UNSUPPORT;
}
static int std_get_interface (uint8_t req, uint16_t value,
uint16_t index, uint16_t length)
static int std_get_interface (uint8_t req, struct control_info *detail)
{
uint8_t rcp = req & RECIPIENT;
@@ -750,74 +709,61 @@ static int std_get_interface (uint8_t req, uint16_t value,
if (rcp == INTERFACE_RECIPIENT)
{
if (value != 0 || (index >> 8) != 0 || length != 1)
if (detail->value != 0 || (detail->index >> 8) != 0 || detail->len != 1)
return USB_UNSUPPORT;
if (dev_p->current_configuration == 0)
return USB_UNSUPPORT;
return usb_cb_interface (USB_GET_INTERFACE, index, 0);
return usb_cb_interface (USB_GET_INTERFACE, detail);
}
return USB_UNSUPPORT;
}
static int std_set_interface (uint8_t req, uint16_t value,
uint16_t index, uint16_t length)
static int std_set_interface (uint8_t req, struct control_info *detail)
{
uint8_t rcp = req & RECIPIENT;
if ((req & REQUEST_DIR) == 1)
if ((req & REQUEST_DIR) == 1 || rcp != INTERFACE_RECIPIENT
|| detail->len != 0 || (detail->index >> 8) != 0
|| (detail->value >> 8) != 0 || dev_p->current_configuration != 0)
return USB_UNSUPPORT;
if (rcp == INTERFACE_RECIPIENT)
{
int r;
if (length != 0 || (index >> 8) != 0 || (value >> 8) != 0)
return USB_UNSUPPORT;
if (dev_p->current_configuration != 0)
return USB_UNSUPPORT;
r = usb_cb_interface (USB_SET_INTERFACE, index, value);
if (r == USB_SUCCESS)
return USB_SUCCESS;
}
return USB_UNSUPPORT;
return usb_cb_interface (USB_SET_INTERFACE, detail);
}
static void handle_setup0 (void)
{
const uint16_t *pw;
struct control_info ctrl;
uint16_t w;
uint8_t req;
uint8_t req_no;
int r = USB_UNSUPPORT;
HANDLER handler;
pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(st103_get_rx_addr (ENDP0) * 2));
w = *pw++;
ctrl_p->bmRequestType = w & 0xff;
ctrl_p->bRequest = req = w >> 8;
dev_p->bmRequestType = w & 0xff;
dev_p->bRequest = req_no = w >> 8;
pw++;
ctrl_p->wValue = *pw++;
ctrl.value = *pw++;
pw++;
ctrl_p->wIndex = *pw++;
ctrl.index = *pw++;
pw++;
ctrl_p->wLength = *pw;
ctrl.len = *pw;
data_p->addr = NULL;
data_p->len = 0;
data_p->offset = 0;
data_p->require_zlp = 0;
if ((ctrl_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST)
if ((dev_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST)
{
if (req < TOTAL_REQUEST)
if (req_no < TOTAL_REQUEST)
{
switch (req)
switch (req_no)
{
case 0: handler = std_get_status; break;
case 1: handler = std_clear_feature; break;
@@ -831,44 +777,30 @@ static void handle_setup0 (void)
default: handler = std_none; break;
}
r = (*handler) (ctrl_p->bmRequestType,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
r = (*handler) (dev_p->bmRequestType, &ctrl);
}
}
else
r = usb_cb_setup (ctrl_p->bmRequestType, req,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
r = usb_cb_setup (dev_p->bmRequestType, req_no, &ctrl);
if (r != USB_SUCCESS)
dev_p->state = STALLED;
else
{
if (USB_SETUP_GET (ctrl_p->bmRequestType))
if (USB_SETUP_SET (dev_p->bmRequestType))
{
uint32_t len = ctrl_p->wLength;
/* Restrict the data length to be the one host asks for */
if (data_p->len > len)
data_p->len = len;
if ((data_p->len % USB_MAX_PACKET_SIZE) == 0)
data_p->require_zlp = TRUE;
dev_p->value = ctrl.value;
if (ctrl.len == 0)
{
dev_p->state = WAIT_STATUS_IN;
st103_set_tx_count (ENDP0, 0);
st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID);
}
else
data_p->require_zlp = FALSE;
dev_p->state = IN_DATA;
handle_datastage_in ();
}
else if (ctrl_p->wLength == 0)
{
dev_p->state = WAIT_STATUS_IN;
st103_set_tx_count (ENDP0, 0);
st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID);
}
else
{
dev_p->state = OUT_DATA;
st103_ep_set_rx_status (ENDP0, EP_RX_VALID);
{
dev_p->state = OUT_DATA;
st103_ep_set_rx_status (ENDP0, EP_RX_VALID);
}
}
}
}
@@ -879,17 +811,16 @@ static void handle_in0 (void)
handle_datastage_in ();
else if (dev_p->state == WAIT_STATUS_IN)
{
if ((ctrl_p->bRequest == SET_ADDRESS) &&
((ctrl_p->bmRequestType & (REQUEST_TYPE | RECIPIENT))
if ((dev_p->bRequest == SET_ADDRESS) &&
((dev_p->bmRequestType & (REQUEST_TYPE | RECIPIENT))
== (STANDARD_REQUEST | DEVICE_RECIPIENT)))
{
st103_set_daddr (ctrl_p->wValue);
usb_cb_handle_event (USB_EVENT_ADDRESS, ctrl_p->wValue);
st103_set_daddr (dev_p->value);
usb_cb_handle_event (USB_EVENT_ADDRESS, dev_p->value);
}
else
usb_cb_ctrl_write_finish (ctrl_p->bmRequestType,
ctrl_p->bRequest, ctrl_p->wValue,
ctrl_p->wIndex, ctrl_p->wLength);
usb_cb_ctrl_write_finish (dev_p->bmRequestType, dev_p->bRequest,
dev_p->value);
dev_p->state = STALLED;
}
@@ -1111,7 +1042,7 @@ void usb_lld_set_feature (uint8_t feature)
dev_p->current_feature = feature;
}
void usb_lld_set_data_to_send (const void *p, size_t len)
void usb_lld_set_data_to_recv (const void *p, size_t len)
{
data_p->addr = (uint8_t *)p;
data_p->len = len;
@@ -1189,3 +1120,49 @@ void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n)
*d = (w & 0xff);
}
}
/*
* BUF: Pointer to data memory. Data memory should not be allocated
* on stack when BUFLEN > USB_MAX_PACKET_SIZE.
*
* BUFLEN: size of the data.
*/
int
usb_lld_reply_request (const void *buf, size_t buflen, struct control_info *ctl)
{
uint32_t len_asked = ctl->len;
uint32_t len;
data_p->addr = (void *)buf;
data_p->len = buflen;
/* Restrict the data length to be the one host asks for */
if (data_p->len > len_asked)
data_p->len = len_asked;
if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
data_p->require_zlp = 1;
if (data_p->len < USB_MAX_PACKET_SIZE)
{
len = data_p->len;
dev_p->state = LAST_IN_DATA;
}
else
{
len = USB_MAX_PACKET_SIZE;
dev_p->state = IN_DATA;
}
if (len)
{
usb_lld_to_pmabuf (data_p->addr, st103_get_tx_addr (ENDP0), len);
data_p->len -= len;
data_p->addr += len;
}
st103_set_tx_count (ENDP0, len);
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
return USB_SUCCESS;
}

42
example-fsm-55/Makefile Normal file
View File

@@ -0,0 +1,42 @@
# Makefile for Hacker Emblem application of Chopstx
PROJECT = hacker-emblem
CHOPSTX = ..
LDSCRIPT= hacker-emblem.ld
CSRC = sys.c hh.c
# Hacker Emblem and "Happy Hacking!" demonstration
# CSRC = sys.c hh.c
# Debian logo demonstration
# CSRC = sys.c debian-logo.c
# "Hiroshi & Ayumi with Tulip" demonstration
# CSRC = sys.c hiroshi-ayumi.c
###################################
CROSS = arm-none-eabi-
CC = $(CROSS)gcc
LD = $(CROSS)gcc
OBJCOPY = $(CROSS)objcopy
MCU = cortex-m0 # -save-temps
CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DMAKE_ENTRY_PUBLIC \
-DFREE_STANDING -DMHZ=48 -DUSE_WFI_FOR_IDLE
OPT = -O3 -Os -g
LIBS =
####################
include ../rules.mk
board.h:
@echo Please make a symbolic link \'board.h\' to a file in ../board;
@exit 1
sys.c: board.h
distclean: clean
rm -f board.h

17
example-fsm-55/README Normal file
View File

@@ -0,0 +1,17 @@
FSM-55 LED Matrix Display Board is a simple board to play 5x5 LED
Display. Please see the product page:
http://www.seeedstudio.com/depot/FSM55-LED-Matrix-Display-p-2121.html
There are three demonstrations and default is Hacker Emblem and "Happy
Hacking!". Please edit CSRC variable in the Makefile to select other
applications.
The file stlink-v2.cfg can be used for ST-Link/V2 with OpenOCD. You
can flash by typing:
$ openocd -f ./stlink-v2.cfg -c "program build/hacker-emblem.elf; reset run; shutdown"
Thanks to Kiwamu Okabe who kindly tested OpenOCD and wrote the
configuration.

1
example-fsm-55/board.h Symbolic link
View File

@@ -0,0 +1 @@
../board/board-fsm-55.h

View File

@@ -0,0 +1,473 @@
#include <stdint.h>
#include <stdlib.h>
#include <chopstx.h>
#include "board.h"
static uint8_t main_finished;
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct GPIO {
volatile uint32_t MODER;
volatile uint16_t OTYPER;
uint16_t dummy0;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint16_t IDR;
uint16_t dummy1;
volatile uint16_t ODR;
uint16_t dummy2;
volatile uint16_t BSRR;
uint16_t dummy3;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint16_t BRR;
uint16_t dummy4;
};
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
static chopstx_mutex_t mtx;
static chopstx_cond_t cnd0, cnd1;
#define BUTTON_PUSHED 1
static uint8_t button_state;
static uint8_t
user_button (void)
{
return button_state;
}
static uint8_t l_data[5];
#define LED_FULL ((0x1f << 20)|(0x1f << 15)|(0x1f << 10)|(0x1f << 5)|0x1f)
static void
set_led_display (uint32_t data)
{
l_data[0] = (data >> 0) & 0x1f;
l_data[1] = (data >> 5) & 0x1f;
l_data[2] = (data >> 10) & 0x1f;
l_data[3] = (data >> 15) & 0x1f;
l_data[4] = (data >> 20) & 0x1f;
}
static void
scroll_led_display (uint8_t row)
{
l_data[0] = (l_data[0] << 1) | ((row >> 0) & 1);
l_data[1] = (l_data[1] << 1) | ((row >> 1) & 1);
l_data[2] = (l_data[2] << 1) | ((row >> 2) & 1);
l_data[3] = (l_data[3] << 1) | ((row >> 3) & 1);
l_data[4] = (l_data[4] << 1) | ((row >> 4) & 1);
}
static void
wait_for (uint32_t usec)
{
chopstx_usec_wait (usec);
}
static void
led_prepare_row (uint8_t col)
{
uint16_t data = 0x1f;
data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5;
data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6;
data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7;
data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9;
data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10;
GPIO_LED->ODR = data;
}
static void
led_enable_column (uint8_t col)
{
GPIO_LED->BRR = (1 << col);
}
static void *
led (void *arg)
{
(void)arg;
chopstx_mutex_lock (&mtx);
chopstx_cond_wait (&cnd0, &mtx);
chopstx_mutex_unlock (&mtx);
while (!main_finished)
{
int i;
for (i = 0; i < 5; i++)
{
led_prepare_row (i);
led_enable_column (i);
wait_for (1000);
}
}
GPIO_LED->ODR = 0x0000; /* Off all LEDs. */
GPIO_LED->OSPEEDR = 0;
GPIO_LED->OTYPER = 0;
GPIO_LED->MODER = 0; /* Input mode. */
GPIO_OTHER->PUPDR = 0x0000; /* No pull-up. */
return NULL;
}
static uint8_t get_button_sw (void) { return (GPIO_OTHER->IDR & 1) == 0; }
static void *
button (void *arg)
{
uint8_t last_button = 0;
(void)arg;
chopstx_mutex_lock (&mtx);
chopstx_cond_wait (&cnd1, &mtx);
chopstx_mutex_unlock (&mtx);
while (!main_finished)
{
uint8_t button = get_button_sw ();
if (last_button == button && button != button_state)
{
wait_for (1000);
button = get_button_sw ();
if (last_button == button)
button_state = button;
}
wait_for (2000);
last_button = button;
}
return NULL;
}
#define PRIO_LED 3
#define PRIO_BUTTON 2
extern uint8_t __process1_stack_base__, __process1_stack_size__;
extern uint8_t __process2_stack_base__, __process2_stack_size__;
const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__;
const size_t __stacksize_led = (size_t)&__process1_stack_size__;
const uint32_t __stackaddr_button = (uint32_t)&__process2_stack_base__;
const size_t __stacksize_button = (size_t)&__process2_stack_size__;
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
static uint32_t logo55[] = {
DATA55 (0x00, 0x00, 0x00, 0x00, 0x00),
DATA55 (0x00, 0x00, 0x04, 0x00, 0x00),
DATA55 (0x00, 0x00, 0x04, 0x02, 0x00),
DATA55 (0x00, 0x00, 0x05, 0x02, 0x00),
DATA55 (0x00, 0x01, 0x05, 0x02, 0x00),
DATA55 (0x02, 0x01, 0x05, 0x02, 0x00),
DATA55 (0x06, 0x01, 0x05, 0x02, 0x00),
DATA55 (0x0e, 0x01, 0x05, 0x02, 0x00),
DATA55 (0x0e, 0x11, 0x05, 0x02, 0x00),
DATA55 (0x0e, 0x11, 0x15, 0x02, 0x00),
DATA55 (0x0e, 0x11, 0x15, 0x12, 0x00),
DATA55 (0x0e, 0x11, 0x15, 0x12, 0x08),
DATA55 (0x0e, 0x11, 0x15, 0x12, 0x08),
DATA55 (0x0e, 0x11, 0x16, 0x10, 0x0c),
DATA55 (0x0e, 0x11, 0x16, 0x10, 0x0c),
DATA55 (0x0e, 0x11, 0x16, 0x10, 0x0e),
DATA55 (0x0c, 0x12, 0x14, 0x10, 0x0f),
DATA55 (0x0c, 0x12, 0x14, 0x11, 0x0e),
DATA55 (0x08, 0x14, 0x15, 0x11, 0x0e),
DATA55 (0x08, 0x15, 0x15, 0x11, 0x0e),
DATA55 (0x01, 0x09, 0x15, 0x11, 0x0e),
DATA55 (0x02, 0x09, 0x15, 0x11, 0x0e),
DATA55 (0x06, 0x01, 0x0d, 0x11, 0x0e),
DATA55 (0x0e, 0x01, 0x0d, 0x11, 0x0e),
DATA55 (0x1e, 0x01, 0x0d, 0x11, 0x0e),
DATA55 (0x0e, 0x11, 0x05, 0x09, 0x06),
DATA55 (0x0e, 0x11, 0x15, 0x05, 0x02),
DATA55 (0x0e, 0x11, 0x15, 0x15, 0x02),
DATA55 (0x0e, 0x11, 0x15, 0x12, 0x10),
DATA55 (0x0e, 0x11, 0x15, 0x12, 0x08),
DATA55 (0x0e, 0x11, 0x15, 0x12, 0x08),
};
#define DATA55V(x0,x1,x2,x3,x4) (x0<<0)|(x1<<5)|(x2<<10)|(x3<< 15)|(x4<< 20)
#define CHAR_SPC 0
#define CHAR_H 1
#define CHAR_A 2
#define CHAR_P 3
#define CHAR_Y 4
#define CHAR_C 5
#define CHAR_K 6
#define CHAR_I 7
#define CHAR_N 8
#define CHAR_G 9
#define CHAR_EXC 10
#define CHAR_W 11
#define CHAR_h 12
#define CHAR_t 13
#define CHAR_AP 14
#define CHAR_s 15
#define CHAR_U 16
#define CHAR_QT 17
#define CHAR_o 18
#define CHAR_X 19
#define CHAR_D 20
#define CHAR_e 21
#define CHAR_b 22
#define CHAR_i 23
#define CHAR_a 24
#define CHAR_n 25
static uint8_t hh[] = {
CHAR_H, CHAR_A, CHAR_P, CHAR_P, CHAR_Y,
CHAR_SPC,
CHAR_H, CHAR_A, CHAR_C, CHAR_K, CHAR_I, CHAR_N, CHAR_G,
CHAR_EXC,
CHAR_SPC, CHAR_SPC, CHAR_SPC,
};
static uint8_t debian[] = {
CHAR_SPC,
CHAR_D, CHAR_e, CHAR_b, CHAR_i, CHAR_a, CHAR_n,
CHAR_SPC, CHAR_SPC,
};
struct { uint8_t width; uint32_t data; } chargen[] = {
{ 3, 0 }, /* SPACE */
{ 4, DATA55V (0x1f, 0x04, 0x04, 0x1f, 0x00) }, /* H */
{ 3, DATA55V (0x17, 0x15, 0x0f, 0x00, 0x00) }, /* A */
{ 4, DATA55V (0x1f, 0x14, 0x14, 0x08, 0x00) }, /* P */
{ 4, DATA55V (0x19, 0x05, 0x05, 0x1e, 0x00) }, /* Y */
{ 4, DATA55V (0x0e, 0x11, 0x11, 0x0a, 0x00) }, /* C */
{ 4, DATA55V (0x1f, 0x04, 0x0c, 0x13, 0x00) }, /* K */
{ 3, DATA55V (0x11, 0x1f, 0x11, 0x00, 0x00) }, /* I */
{ 4, DATA55V (0x1f, 0x08, 0x06, 0x1f, 0x00) }, /* N */
{ 4, DATA55V (0x0e, 0x11, 0x15, 0x07, 0x00) }, /* G */
{ 2, DATA55V (0x1d, 0x1c, 0x00, 0x00, 0x00) }, /* ! */
{ 5, DATA55V (0x1e, 0x01, 0x0e, 0x01, 0x1e) }, /* W */
{ 3, DATA55V (0x1f, 0x04, 0x07, 0x00, 0x00) }, /* h */
{ 4, DATA55V (0x08, 0x1e, 0x09, 0x09, 0x00) }, /* t */
{ 3, DATA55V (0x04, 0x18, 0x18, 0x00, 0x00) }, /* ' */
{ 4, DATA55V (0x09, 0x15, 0x15, 0x12, 0x00) }, /* s */
{ 4, DATA55V (0x1e, 0x01, 0x01, 0x1e, 0x00) }, /* U */
{ 4, DATA55V (0x08, 0x10, 0x15, 0x08, 0x00) }, /* ? */
{ 4, DATA55V (0x06, 0x09, 0x09, 0x06, 0x00) }, /* o */
{ 5, DATA55V (0x11, 0x0a, 0x04, 0x0a, 0x11) }, /* X */
{ 4, DATA55V (0x1f, 0x11, 0x11, 0x0e, 0x00) }, /* D */
{ 4, DATA55V (0x0e, 0x15, 0x15, 0x0d, 0x00) }, /* e */
{ 4, DATA55V (0x1f, 0x05, 0x05, 0x06, 0x00) }, /* b */
{ 1, DATA55V (0x17, 0x00, 0x00, 0x00, 0x00) }, /* i */
{ 4, DATA55V (0x02, 0x15, 0x15, 0x0f, 0x00) }, /* a */
{ 4, DATA55V (0x1f, 0x08, 0x10, 0x1f, 0x00) }, /* n */
};
#define REPEAT_COUNT 10
static int
logo_display (void)
{
unsigned int i;
uint8_t state = 0;
for (i = 0; i < SIZE55 (logo55); i++)
{
if (user_button ())
{
set_led_display (LED_FULL);
state = 1;
}
else if (state == 1)
return 0;
else
set_led_display (logo55[i]);
wait_for (350*1000);
}
return 1;
}
static int
text_display (uint8_t kind)
{
unsigned int i, j;
uint8_t *text;
uint8_t len;
uint8_t state = 0;
if (kind)
{
text = debian;
len = sizeof (debian);
}
else
{
text = hh;
len = sizeof (hh);
}
#if 0
set_led_display (0);
#endif
for (i = 0; i < len; i++)
{
for (j = 0; j < chargen[text[i]].width; j++)
{
if (user_button ())
{
set_led_display (LED_FULL);
state = 1;
}
else if (state == 1)
return 0;
else
scroll_led_display ((chargen[text[i]].data >> j * 5) & 0x1f);
wait_for (120*1000);
}
if (user_button ())
{
set_led_display (LED_FULL);
state = 1;
}
else if (state == 1)
return 0;
else
scroll_led_display (0);
wait_for (120*1000);
}
return 1;
}
static void setup_scr_sleepdeep (void);
int
main (int argc, const char *argv[])
{
chopstx_t led_thd;
chopstx_t button_thd;
uint8_t happy = 1;
uint8_t count = 0;
(void)argc;
(void)argv;
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd1);
led_thd = chopstx_create (PRIO_LED, __stackaddr_led,
__stacksize_led, led, NULL);
button_thd = chopstx_create (PRIO_BUTTON, __stackaddr_button,
__stacksize_button, button, NULL);
chopstx_usec_wait (200*1000);
chopstx_mutex_lock (&mtx);
chopstx_cond_signal (&cnd0);
chopstx_cond_signal (&cnd1);
chopstx_mutex_unlock (&mtx);
wait_for (100*1000);
if (user_button ())
{
/* Wait button release. */
while (user_button ())
wait_for (100*1000);
happy = 0;
goto do_text;
}
while (count++ < REPEAT_COUNT)
{
if (!logo_display ())
break;
do_text:
if (!text_display (happy))
break;
}
main_finished = 1;
chopstx_join (button_thd, NULL);
chopstx_join (led_thd, NULL);
setup_scr_sleepdeep ();
for (;;)
asm volatile ("wfi" : : : "memory");
return 0;
}
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 SCB_SCR_SLEEPDEEP (1 << 2)
struct PWR
{
volatile uint32_t CR;
volatile uint32_t CSR;
};
#define PWR_CR_PDDS 0x0002
#define PWR_CR_CWUF 0x0004
#define PWR_BASE (APBPERIPH_BASE + 0x00007000)
#define PWR ((struct PWR *) PWR_BASE)
static void setup_scr_sleepdeep (void)
{
PWR->CR |= PWR_CR_CWUF;
PWR->CR |= PWR_CR_PDDS;
SCB->SCR |= SCB_SCR_SLEEPDEEP;
}

View File

@@ -0,0 +1,594 @@
.....
.....
.....
.....
.....
.....
.....
..o..
.....
.....
.....
.....
..o..
...o.
.....
.....
.....
..o.o
...o.
.....
.....
....o
..o.o
...o.
.....
...o.
....o
..o.o
...o.
.....
..oo.
....o
..o.o
...o.
.....
.ooo.
....o
..o.o
...o.
.....
.ooo.
o...o
..o.o
...o.
.....
.ooo.
o...o
o.o.o
...o.
.....
.ooo.
o...o
o.o.o
o..o.
.....
.ooo.
o...o
o.o.o
o..o.
.o...
.ooo.
o...o
o.o.o
o..o.
.o...
.ooo.
o...o
o.oo.
o....
.oo..
.ooo.
o...o
o.oo.
o....
.ooo.
.oo..
o..o.
o.o..
o....
.oooo
.oo..
o..o.
o.o..
o...o
.ooo.
.oo..
o.o..
o.o.o
o...o
.ooo.
.o...
o.o.o
o.o.o
o...o
.ooo.
....o
.o..o
o.o.o
o...o
.ooo.
...o.
....o
.oo.o
o...o
.ooo.
.ooo.
....o
.oo.o
o...o
.ooo.
oooo.
....o
.oo.o
o...o
.ooo.
.ooo.
o...o
..o.o
.o..o
..oo.
.ooo.
o...o
o.o.o
..o.o
...o.
.ooo.
o...o
o.o.o
o.o.o
...o.
.ooo.
o...o
o.o.o
o..o.
o....
.ooo.
o...o
o.o.o
o..o.
.o...
.ooo.
o...o
o.o.o
o..o.
.o...
ooo.
o..o
o..o
o..o
ooo.
.oo.
o..o
oooo
o...
.ooo
o...
o...
oooo
o..o
ooo.
o
.
o
o
o
.oo.
...o
.ooo
o..o
oooo
....
oooo
o..o
o..o
o..o
..... 00
..... 00
..... 00
..... 00
..... 00
..... 00
..... 00
..o.. 04
..... 00
..... 00
..... 00
..... 00
..o.. 04
...o. 02
..... 00
..... 00
..... 00
..o.o 05
...o. 02
..... 00
..... 00
....o 01
..o.o 05
...o. 02
..... 00
...o. 02
....o 01
..o.o 05
...o. 02
..... 00
..oo. 06
....o 01
..o.o 05
...o. 02
..... 00
.ooo. 0e
....o 01
..o.o 05
...o. 02
..... 00
.ooo. 0e
o...o 11
..o.o 05
...o. 02
..... 00
.ooo. 0e
o...o 11
o.o.o 15
...o. 02
..... 00
.ooo. 0e
o...o 11
o.o.o 15
o..o. 12
..... 00
.ooo. 0e
o...o 11
o.o.o 15
o..o. 12
.o... 08
.ooo. 0e
o...o 11
o.o.o 15
o..o. 12
.o... 08
.ooo. 0e
o...o 11
o.oo. 16
o.... 10
.oo.. 0c
.ooo. 0e
o...o 11
o.oo. 16
o.... 10
.ooo. 0e
.oo.. 0c
o..o. 12
o.o.. 14
o.... 10
.oooo 0f
.oo.. 0c
o..o. 12
o.o.. 14
o...o 11
.ooo. 0e
.o... 08
o.o.. 14
o.o.o 15
o...o 11
.ooo. 0e
.o... 08
o.o.o 15
o.o.o 15
o...o 11
.ooo. 0e
...o. 02
.o..o 09
o.o.o 15
o...o 11
.ooo. 0e
....o 01
.o..o 09
o.o.o 15
o...o 11
.ooo. 0e
...o. 02
.o..o 09
o.o.o 15
o...o 11
.ooo. 0e
..oo. 06
....o 01
.oo.o 0d
o...o 11
.ooo. 0e
.ooo. 0e
....o 01
.oo.o 0d
o...o 11
.ooo. 0e
oooo. 1e
....o 01
.oo.o 0d
o...o 11
.ooo. 0e
.ooo. 0e
o...o 11
..o.o 05
.o..o 09
..oo. 06
.ooo. 0e
o...o 11
o.o.o 15
..o.o 05
...o. 02
.ooo. 0e
o...o 11
o.o.o 15
o.o.o 15
...o. 02
.ooo. 0e
o...o 11
o.o.o 15
o..o. 12
o.... 10
.ooo. 0e
o...o 11
o.o.o 15
o..o. 12
.o... 08
.ooo. 0e
o...o 11
o.o.o 15
o..o. 12
.o... 08
ooo.
o..o
o..o
o..o
ooo.
.oo.
o..o
oooo
o...
.ooo
o...
o...
oooo
o..o
ooo.
o
.
o
o
o
.oo.
...o
.ooo
o..o
.ooo
o.oo
oo.o
o..o
o..o
o..o
00
00
00
00
00
00
00
04
00
00
00
00
04
02
00
00
00
05
02
00
00
01
05
02
00
02
01
05
02
00
06
01
05
02
00
0e
01
05
02
00
0e
11
05
02
00
0e
11
15
02
00
0e
11
15
12
00
0e
11
15
12
08
0e
11
15
12
08
0e
11
16
10
0e
0c
12
14
11
0e
0c
14
15
11
0e
08
15
15
11
0e
02
09
15
11
0e
06
01
0d
11
0e
0e
01
1d
11
0e
1e
01
0d
11
0e
0e
11
05
09
0e
0e
11
15
05
06
0e
11
15
15
02
0e
11
15
13
08
0e
11
15
12
08
0e
11
15
12
08

54
example-fsm-55/gnu.txt Normal file
View File

@@ -0,0 +1,54 @@
o...o
o.o.o
o.o.o
o.o.o
.o.o.
o..
o..
ooo
o.o
o.o
.o..
oooo
.o..
.o..
..oo
.oo
.oo
o..
...
...
....
.ooo
o...
.oo.
...o
ooo.
o..o
o..o
o..o
o..o
.oo.
.oo.
o..o
..o.
....
..o.
....
.oo.
o..o
o..o
.oo.
o...o
.o.o.
..o..
.o.o.
o...o

View File

@@ -0,0 +1,125 @@
/*
* ST32F0 memory setup.
*/
__main_stack_size__ = 0x0100; /* Exception handlers */
__process0_stack_size__ = 0x0100; /* Main program */
__process1_stack_size__ = 0x0100; /* first thread program */
__process2_stack_size__ = 0x0100; /* second thread program */
__process3_stack_size__ = 0x0100; /* third thread program */
MEMORY
{
flash : org = 0x08000000, len = 16k
ram : org = 0x20000000, len = 4k
}
__ram_start__ = ORIGIN(ram);
__ram_size__ = 4k;
__ram_end__ = __ram_start__ + __ram_size__;
SECTIONS
{
. = 0;
_text = .;
.text : ALIGN(16) SUBALIGN(16)
{
KEEP(*(.vectors))
. = ALIGN(16);
*(.text.startup.*)
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
*(.glue_7t)
*(.glue_7)
*(.gcc*)
. = ALIGN(8);
} > flash
/DISCARD/ :
{
*(.startup.vectors)
*(.bss.startup.0)
}
.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;
.process_stack :
{
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
. = ALIGN(8);
__process3_stack_end__ = .;
__process2_stack_base__ = .;
. += __process2_stack_size__;
. = ALIGN(8);
__process2_stack_end__ = .;
__process1_stack_base__ = .;
. += __process1_stack_size__;
. = ALIGN(8);
__process1_stack_end__ = .;
__process0_stack_base__ = .;
. += __process0_stack_size__;
. = ALIGN(8);
__process0_stack_end__ = .;
} > ram
.main_stack :
{
. = ALIGN(8);
__main_stack_base__ = .;
. += __main_stack_size__;
. = ALIGN(8);
__main_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 = .;
}
__heap_base__ = _end;
__heap_end__ = __ram_end__;

461
example-fsm-55/hh.c Normal file
View File

@@ -0,0 +1,461 @@
#include <stdint.h>
#include <stdlib.h>
#include <chopstx.h>
#include "board.h"
static uint8_t main_finished;
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct GPIO {
volatile uint32_t MODER;
volatile uint16_t OTYPER;
uint16_t dummy0;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint16_t IDR;
uint16_t dummy1;
volatile uint16_t ODR;
uint16_t dummy2;
volatile uint16_t BSRR;
uint16_t dummy3;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint16_t BRR;
uint16_t dummy4;
};
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
static chopstx_mutex_t mtx;
static chopstx_cond_t cnd0, cnd1;
#define BUTTON_PUSHED 1
static uint8_t button_state;
static uint8_t
user_button (void)
{
return button_state;
}
static uint8_t l_data[5];
#define LED_FULL ((0x1f << 20)|(0x1f << 15)|(0x1f << 10)|(0x1f << 5)|0x1f)
static void
set_led_display (uint32_t data)
{
l_data[0] = (data >> 0) & 0x1f;
l_data[1] = (data >> 5) & 0x1f;
l_data[2] = (data >> 10) & 0x1f;
l_data[3] = (data >> 15) & 0x1f;
l_data[4] = (data >> 20) & 0x1f;
}
static void
scroll_led_display (uint8_t row)
{
l_data[0] = (l_data[0] << 1) | ((row >> 0) & 1);
l_data[1] = (l_data[1] << 1) | ((row >> 1) & 1);
l_data[2] = (l_data[2] << 1) | ((row >> 2) & 1);
l_data[3] = (l_data[3] << 1) | ((row >> 3) & 1);
l_data[4] = (l_data[4] << 1) | ((row >> 4) & 1);
}
static void
wait_for (uint32_t usec)
{
chopstx_usec_wait (usec);
}
static void
led_prepare_row (uint8_t col)
{
uint16_t data = 0x1f;
data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5;
data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6;
data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7;
data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9;
data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10;
GPIO_LED->ODR = data;
}
static void
led_enable_column (uint8_t col)
{
GPIO_LED->BRR = (1 << col);
}
static void *
led (void *arg)
{
(void)arg;
chopstx_mutex_lock (&mtx);
chopstx_cond_wait (&cnd0, &mtx);
chopstx_mutex_unlock (&mtx);
while (!main_finished)
{
int i;
for (i = 0; i < 5; i++)
{
led_prepare_row (i);
led_enable_column (i);
wait_for (1000);
}
}
GPIO_LED->ODR = 0x0000; /* Off all LEDs. */
GPIO_LED->OSPEEDR = 0;
GPIO_LED->OTYPER = 0;
GPIO_LED->MODER = 0; /* Input mode. */
GPIO_OTHER->PUPDR = 0x0000; /* No pull-up. */
return NULL;
}
static uint8_t get_button_sw (void) { return (GPIO_OTHER->IDR & 1) == 0; }
static void *
button (void *arg)
{
uint8_t last_button = 0;
(void)arg;
chopstx_mutex_lock (&mtx);
chopstx_cond_wait (&cnd1, &mtx);
chopstx_mutex_unlock (&mtx);
while (!main_finished)
{
uint8_t button = get_button_sw ();
if (last_button == button && button != button_state)
{
wait_for (1000);
button = get_button_sw ();
if (last_button == button)
button_state = button;
}
wait_for (2000);
last_button = button;
}
return NULL;
}
#define PRIO_LED 3
#define PRIO_BUTTON 2
extern uint8_t __process1_stack_base__, __process1_stack_size__;
extern uint8_t __process2_stack_base__, __process2_stack_size__;
const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__;
const size_t __stacksize_led = (size_t)&__process1_stack_size__;
const uint32_t __stackaddr_button = (uint32_t)&__process2_stack_base__;
const size_t __stacksize_button = (size_t)&__process2_stack_size__;
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
static uint32_t l55[] = {
DATA55 (0x08, 0x04, 0x1c, 0x00, 0x00),
DATA55 (0x00, 0x14, 0x0c, 0x08, 0x00),
DATA55 (0x00, 0x04, 0x14, 0x0c, 0x00),
DATA55 (0x00, 0x08, 0x06, 0x0c, 0x00),
DATA55 (0x00, 0x04, 0x02, 0x0e, 0x00),
DATA55 (0x00, 0x00, 0x0a, 0x06, 0x04),
DATA55 (0x00, 0x00, 0x02, 0x0a, 0x06),
DATA55 (0x00, 0x00, 0x04, 0x03, 0x06),
DATA55 (0x00, 0x00, 0x02, 0x01, 0x07),
DATA55 (0x02, 0x00, 0x00, 0x05, 0x03),
DATA55 (0x03, 0x00, 0x00, 0x01, 0x05),
DATA55 (0x03, 0x00, 0x00, 0x02, 0x11),
DATA55 (0x13, 0x00, 0x00, 0x01, 0x10),
DATA55 (0x11, 0x01, 0x00, 0x00, 0x12),
DATA55 (0x12, 0x11, 0x00, 0x00, 0x10),
DATA55 (0x18, 0x11, 0x00, 0x00, 0x01),
DATA55 (0x08, 0x19, 0x00, 0x00, 0x10),
DATA55 (0x09, 0x18, 0x10, 0x00, 0x00),
DATA55 (0x08, 0x09, 0x18, 0x00, 0x00),
DATA55 (0x10, 0x0c, 0x18, 0x00, 0x00),
};
#define DATA55V(x0,x1,x2,x3,x4) (x0<<0)|(x1<<5)|(x2<<10)|(x3<< 15)|(x4<< 20)
#define CHAR_SPC 0
#define CHAR_H 1
#define CHAR_A 2
#define CHAR_P 3
#define CHAR_Y 4
#define CHAR_C 5
#define CHAR_K 6
#define CHAR_I 7
#define CHAR_N 8
#define CHAR_G 9
#define CHAR_EXC 10
#define CHAR_W 11
#define CHAR_h 12
#define CHAR_t 13
#define CHAR_AP 14
#define CHAR_s 15
#define CHAR_U 16
#define CHAR_QT 17
#define CHAR_o 18
#define CHAR_X 19
static uint8_t hh[] = {
CHAR_H, CHAR_A, CHAR_P, CHAR_P, CHAR_Y,
CHAR_SPC,
CHAR_H, CHAR_A, CHAR_C, CHAR_K, CHAR_I, CHAR_N, CHAR_G,
CHAR_EXC,
CHAR_SPC, CHAR_SPC, CHAR_SPC,
};
static uint8_t gnu[] = {
CHAR_W, CHAR_h, CHAR_A, CHAR_t, CHAR_AP, CHAR_s, CHAR_SPC,
CHAR_G, CHAR_N, CHAR_U, CHAR_QT,
CHAR_SPC, CHAR_SPC,
CHAR_G, CHAR_N, CHAR_U, CHAR_AP, CHAR_s, CHAR_SPC,
CHAR_N, CHAR_o, CHAR_t, CHAR_SPC,
CHAR_U, CHAR_N, CHAR_I, CHAR_X,
CHAR_EXC,
CHAR_SPC, CHAR_SPC,
};
struct { uint8_t width; uint32_t data; } chargen[] = {
{ 3, 0 }, /* SPACE */
{ 4, DATA55V (0x1f, 0x04, 0x04, 0x1f, 0x00) }, /* H */
{ 3, DATA55V (0x17, 0x15, 0x0f, 0x00, 0x00) }, /* A */
{ 4, DATA55V (0x1f, 0x14, 0x14, 0x08, 0x00) }, /* P */
{ 4, DATA55V (0x19, 0x05, 0x05, 0x1e, 0x00) }, /* Y */
{ 4, DATA55V (0x0e, 0x11, 0x11, 0x0a, 0x00) }, /* C */
{ 4, DATA55V (0x1f, 0x04, 0x0c, 0x13, 0x00) }, /* K */
{ 3, DATA55V (0x11, 0x1f, 0x11, 0x00, 0x00) }, /* I */
{ 4, DATA55V (0x1f, 0x08, 0x06, 0x1f, 0x00) }, /* N */
{ 4, DATA55V (0x0e, 0x11, 0x15, 0x07, 0x00) }, /* G */
{ 2, DATA55V (0x1d, 0x1c, 0x00, 0x00, 0x00) }, /* ! */
{ 5, DATA55V (0x1e, 0x01, 0x0e, 0x01, 0x1e) }, /* W */
{ 3, DATA55V (0x1f, 0x04, 0x07, 0x00, 0x00) }, /* h */
{ 4, DATA55V (0x08, 0x1e, 0x09, 0x09, 0x00) }, /* t */
{ 3, DATA55V (0x04, 0x18, 0x18, 0x00, 0x00) }, /* ' */
{ 4, DATA55V (0x09, 0x15, 0x15, 0x12, 0x00) }, /* s */
{ 4, DATA55V (0x1e, 0x01, 0x01, 0x1e, 0x00) }, /* U */
{ 4, DATA55V (0x08, 0x10, 0x15, 0x08, 0x00) }, /* ? */
{ 4, DATA55V (0x06, 0x09, 0x09, 0x06, 0x00) }, /* o */
{ 5, DATA55V (0x11, 0x0a, 0x04, 0x0a, 0x11) }, /* X */
{ 4, DATA55V (0x1f, 0x11, 0x11, 0x0e, 0x00) }, /* D */
{ 4, DATA55V (0x0e, 0x15, 0x15, 0x0d, 0x00) }, /* e */
{ 4, DATA55V (0x1f, 0x05, 0x05, 0x06, 0x00) }, /* b */
{ 1, DATA55V (0x17, 0x00, 0x00, 0x00, 0x00) }, /* i */
{ 4, DATA55V (0x02, 0x15, 0x15, 0x0f, 0x00) }, /* a */
{ 4, DATA55V (0x0f, 0x08, 0x08, 0x0f, 0x00) }, /* n */
};
#define REPEAT_COUNT 10
static int
life_display (void)
{
unsigned int i;
uint8_t count = 0;
uint8_t state = 0;
while (count++ < REPEAT_COUNT)
for (i = 0; i < SIZE55 (l55); i++)
{
if (user_button ())
{
set_led_display (LED_FULL);
state = 1;
}
else if (state == 1)
return 0;
else
set_led_display (l55[i]);
wait_for (350*1000);
}
return 1;
}
static int
text_display (uint8_t kind)
{
unsigned int i, j;
uint8_t *text;
uint8_t len;
uint8_t count = 0;
uint8_t state = 0;
if (kind)
{
text = hh;
len = sizeof (hh);
}
else
{
text = gnu;
len = sizeof (gnu);
}
set_led_display (0);
while (count++ < REPEAT_COUNT)
for (i = 0; i < len; i++)
{
for (j = 0; j < chargen[text[i]].width; j++)
{
if (user_button ())
{
set_led_display (LED_FULL);
state = 1;
}
else if (state == 1)
return 0;
else
scroll_led_display ((chargen[text[i]].data >> j * 5) & 0x1f);
wait_for (120*1000);
}
if (user_button ())
{
set_led_display (LED_FULL);
state = 1;
}
else if (state == 1)
return 0;
else
scroll_led_display (0);
wait_for (120*1000);
}
return 1;
}
static void setup_scr_sleepdeep (void);
int
main (int argc, const char *argv[])
{
chopstx_t led_thd;
chopstx_t button_thd;
uint8_t happy = 1;
(void)argc;
(void)argv;
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd1);
led_thd = chopstx_create (PRIO_LED, __stackaddr_led,
__stacksize_led, led, NULL);
button_thd = chopstx_create (PRIO_BUTTON, __stackaddr_button,
__stacksize_button, button, NULL);
chopstx_usec_wait (200*1000);
chopstx_mutex_lock (&mtx);
chopstx_cond_signal (&cnd0);
chopstx_cond_signal (&cnd1);
chopstx_mutex_unlock (&mtx);
wait_for (100*1000);
if (user_button ())
{
/* Wait button release. */
while (user_button ())
wait_for (100*1000);
happy = 0;
goto do_text;
}
while (1)
{
if (life_display ())
break;
do_text:
if (text_display (happy))
break;
}
main_finished = 1;
chopstx_join (button_thd, NULL);
chopstx_join (led_thd, NULL);
setup_scr_sleepdeep ();
for (;;)
asm volatile ("wfi" : : : "memory");
return 0;
}
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 SCB_SCR_SLEEPDEEP (1 << 2)
struct PWR
{
volatile uint32_t CR;
volatile uint32_t CSR;
};
#define PWR_CR_PDDS 0x0002
#define PWR_CR_CWUF 0x0004
#define PWR_BASE (APBPERIPH_BASE + 0x00007000)
#define PWR ((struct PWR *) PWR_BASE)
static void setup_scr_sleepdeep (void)
{
PWR->CR |= PWR_CR_CWUF;
PWR->CR |= PWR_CR_PDDS;
SCB->SCR |= SCB_SCR_SLEEPDEEP;
}

59
example-fsm-55/hh.txt Normal file
View File

@@ -0,0 +1,59 @@
o..o
o..o
oooo
o..o
o..o
oo.
..o
ooo
o.o
ooo
ooo.
o..o
ooo.
o...
o...
o..o
o..o
.ooo
...o
ooo.
.oo.
o..o
o...
o..o
.oo.
o..o
o.o.
ooo.
o..o
o..o
ooo
.o.
.o.
.o.
ooo
o..o
oo.o
o.oo
o.oo
o..o
.oo.
o...
o.oo
o..o
.ooo
oo
oo
oo
..
o.

View File

@@ -0,0 +1,385 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <chopstx.h>
#include "board.h"
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct GPIO {
volatile uint32_t MODER;
volatile uint16_t OTYPER;
uint16_t dummy0;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint16_t IDR;
uint16_t dummy1;
volatile uint16_t ODR;
uint16_t dummy2;
volatile uint16_t BSRR;
uint16_t dummy3;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint16_t BRR;
uint16_t dummy4;
};
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
#define GPIO_SPEAKER_PIN 1
static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
static chopstx_mutex_t mtx;
static chopstx_cond_t cnd;
static uint8_t
user_button (void)
{
return (GPIO_OTHER->IDR & 1) == 0;
}
static uint8_t l_data[5];
static void
set_led_display (uint32_t data)
{
l_data[0] = (data >> 0) & 0x1f;
l_data[1] = (data >> 5) & 0x1f;
l_data[2] = (data >> 10) & 0x1f;
l_data[3] = (data >> 15) & 0x1f;
l_data[4] = (data >> 20) & 0x1f;
}
static void
wait_for (uint32_t usec)
{
chopstx_usec_wait (usec);
}
static void
led_prepare_row (uint8_t col)
{
uint16_t data = 0x1f;
data |= ((l_data[0] & (1 << col)) ? 1 : 0) << 5;
data |= ((l_data[1] & (1 << col)) ? 1 : 0) << 6;
data |= ((l_data[2] & (1 << col)) ? 1 : 0) << 7;
data |= ((l_data[3] & (1 << col)) ? 1 : 0) << 9;
data |= ((l_data[4] & (1 << col)) ? 1 : 0) << 10;
GPIO_LED->ODR = data;
}
static void
led_enable_column (uint8_t col)
{
GPIO_LED->BRR = (1 << col);
}
#define PRIO_LED 3
extern uint8_t __process1_stack_base__, __process1_stack_size__;
const uint32_t stackaddr_led = (uint32_t)&__process1_stack_base__;
const size_t stacksize_led = (size_t)&__process1_stack_size__;
static void *
led (void *arg)
{
(void)arg;
chopstx_mutex_lock (&mtx);
chopstx_cond_wait (&cnd, &mtx);
chopstx_mutex_unlock (&mtx);
while (1)
{
int i;
for (i = 0; i < 5; i++)
{
led_prepare_row (i);
led_enable_column (i);
wait_for (1000);
}
}
return NULL;
}
#define PRIO_SPK 4
extern uint8_t __process2_stack_base__, __process2_stack_size__;
const uint32_t stackaddr_spk = (uint32_t)&__process2_stack_base__;
const size_t stacksize_spk = (size_t)&__process2_stack_size__;
static chopstx_mutex_t spk_mtx;
static chopstx_cond_t spk_cnd;
static chopstx_cond_t spk_cnd_no_tone;
static uint8_t tone;
#define NO_TONE 255
static uint16_t tone_table[] = {
568, /* a = 880Hz */
/* 536, */
506, /* b */
478, /* c */
/* 451, */
426, /* d */
/* 402, */
379, /* e */
358, /* f*/
/* 338, */
319, /* g */
/* 301, */
284, /* A = 1760Hz */
/* 268 */
253, /* B */
239, /* C */
};
static void
change_tone (uint8_t t)
{
chopstx_mutex_lock (&spk_mtx);
tone = t;
chopstx_cond_signal (&spk_cnd_no_tone);
chopstx_cond_wait (&spk_cnd, &spk_mtx);
chopstx_mutex_unlock (&spk_mtx);
}
static void *
spk (void *arg)
{
(void)arg;
while (1)
{
uint8_t t;
uint16_t w;
chopstx_mutex_lock (&spk_mtx);
t = tone;
chopstx_cond_signal (&spk_cnd);
if (t == NO_TONE)
{
chopstx_cond_wait (&spk_cnd_no_tone, &spk_mtx);
t = tone;
}
chopstx_mutex_unlock (&spk_mtx);
w = tone_table[t]*5/3;
GPIO_OTHER->BSRR = (1 << GPIO_SPEAKER_PIN);
wait_for (w);
GPIO_OTHER->BRR = (1 << GPIO_SPEAKER_PIN);
wait_for (w);
}
return NULL;
}
#define PRIO_MUSIC 2
extern uint8_t __process3_stack_base__, __process3_stack_size__;
const uint32_t stackaddr_music = (uint32_t)&__process3_stack_base__;
const size_t stacksize_music = (size_t)&__process3_stack_size__;
#define C 0
#define D 1
#define E 2
#define F 3
#define G 4
#define A 5
#define B 6
#if 0 /* twinkle stars */
static const char *musical_score =
"c4c4g4g4A4A4g2f4f4e4e4d4d4c2"
"g4g4f4f4e4e4d2g4g4f4f4e4e4d2"
"c4c4g4g4A4A4g2f4f4e4e4d4d4c2";
#else /* tulip */
static const char *musical_score =
"c4d4e2c4d4e2g4e4d4c4d4e4d2"
"c4d4e2c4d4e2g4e4d4c4d4e4c2"
"g4g4e4g4A4A4g2e4e4d4d4c2";
#endif
static int get_t_and_l (char *tp, char *lp)
{
static unsigned int i = 0;
char tl, ll;
tl = musical_score[i++];
ll = musical_score[i++];
if (tl >= 'a')
*tp = tl - 'a';
else
*tp = tl - 'A' + 7;
*lp = ll - '0';
if (i >= strlen (musical_score))
{
i = 0;
return 0;
}
else
return 1;
}
#define WAIT_FOR_NO_TONE (1000*20)
#define WAIT_FOR_TONE (1000000*3/2)
static void *
music (void *arg)
{
(void)arg;
chopstx_mutex_init (&spk_mtx);
chopstx_cond_init (&spk_cnd);
chopstx_cond_init (&spk_cnd_no_tone);
chopstx_create (PRIO_SPK, stackaddr_spk, stacksize_spk, spk, NULL);
while (1)
{
char t, l;
int r;
r = get_t_and_l (&t, &l);
change_tone (NO_TONE);
wait_for (WAIT_FOR_NO_TONE);
change_tone (t);
wait_for (WAIT_FOR_TONE / l);
if (!r)
{
change_tone (NO_TONE);
wait_for (WAIT_FOR_TONE * 3);
}
}
return NULL;
}
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
static uint32_t image0[] = {
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x01,0x00,0x00,0x00),
DATA55 (0x01,0x03,0x01,0x01,0x00),
DATA55 (0x02,0x06,0x02,0x02,0x01),
DATA55 (0x05,0x0d,0x05,0x05,0x03),
DATA55 (0x0b,0x1a,0x0a,0x0a,0x06),
DATA55 (0x16,0x14,0x14,0x14,0x0c),
DATA55 (0x0d,0x08,0x09,0x08,0x19),
DATA55 (0x1b,0x11,0x12,0x10,0x13),
DATA55 (0x17,0x03,0x04,0x00,0x07),
DATA55 (0x0f,0x06,0x09,0x01,0x0e),
DATA55 (0x1e,0x0c,0x12,0x02,0x1c),
DATA55 (0x1d,0x19,0x05,0x05,0x18),
DATA55 (0x1a,0x12,0x0a,0x0a,0x11),
DATA55 (0x14,0x04,0x14,0x14,0x03),
DATA55 (0x08,0x08,0x08,0x09,0x06),
DATA55 (0x10,0x10,0x10,0x12,0x0c),
DATA55 (0x00,0x00,0x00,0x04,0x18),
DATA55 (0x00,0x00,0x00,0x08,0x10),
DATA55 (0x00,0x00,0x00,0x10,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
};
static uint32_t image1[] = {
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x01,0x00,0x00,0x00,0x01),
DATA55 (0x03,0x00,0x00,0x01,0x03),
DATA55 (0x07,0x01,0x01,0x03,0x06),
DATA55 (0x0f,0x02,0x02,0x06,0x0c),
DATA55 (0x1f,0x05,0x05,0x0c,0x18),
DATA55 (0x1e,0x0a,0x0a,0x18,0x11),
DATA55 (0x1d,0x14,0x14,0x10,0x03),
DATA55 (0x1b,0x08,0x08,0x00,0x07),
DATA55 (0x17,0x11,0x11,0x01,0x0f),
DATA55 (0x0e,0x02,0x02,0x02,0x1f),
DATA55 (0x1c,0x04,0x04,0x04,0x1e),
DATA55 (0x19,0x08,0x09,0x08,0x1d),
DATA55 (0x13,0x10,0x13,0x10,0x1b),
DATA55 (0x07,0x00,0x07,0x00,0x17),
DATA55 (0x0f,0x00,0x0f,0x00,0x0f),
DATA55 (0x1e,0x00,0x1e,0x00,0x1e),
DATA55 (0x1c,0x00,0x1c,0x00,0x1c),
DATA55 (0x18,0x00,0x18,0x00,0x18),
DATA55 (0x10,0x00,0x10,0x00,0x10),
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
DATA55 (0x00,0x00,0x00,0x00,0x00),
};
int
main (int argc, const char *argv[])
{
uint8_t state = 0;
(void)argc;
(void)argv;
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd);
chopstx_create (PRIO_LED, stackaddr_led, stacksize_led, led, NULL);
chopstx_create (PRIO_MUSIC, stackaddr_music, stacksize_music, music, NULL);
chopstx_usec_wait (200*1000);
chopstx_mutex_lock (&mtx);
chopstx_cond_signal (&cnd);
chopstx_mutex_unlock (&mtx);
while (1)
{
unsigned int i;
if (state)
for (i = 0; i < SIZE55 (image1); i++)
{
if (user_button ())
state = 0;
set_led_display (image1[i]);
wait_for (200*1000);
}
else
for (i = 0; i < SIZE55 (image0); i++)
{
if (user_button ())
state = 1;
set_led_display (image0[i]);
wait_for (200*1000);
}
}
return 0;
}

119
example-fsm-55/l55.txt Normal file
View File

@@ -0,0 +1,119 @@
_*___ 08
__*__ 04
***__ 1c
_____ 00
_____ 00
_____ 00
*_*__ 14
_**__ 0c
_*___ 08
_____ 00
_____ 00
__*__ 04
*_*__ 14
_**__ 0c
_____ 00
_____ 00
_*__ 08
__**_ 06
_**__ 0c
_____ 00
_____ 00
__*__ 04
___*_ 02
_***_ 0e
_____ 00
_____ 00
_____ 00
_*_*_ 0a
__**_ 06
__*__ 04
_____ 00
_____ 00
___*_ 02
_*_*_ 0a
__**_ 06
_____ 00
_____ 00
__*__ 04
___** 03
__**_ 06
_____ 00
_____ 00
__*_ 02
____* 01
__*** 07
___*_ 02
_____ 00
_____ 00
__*_* 05
___** 03
___** 03
_____ 00
_____ 00
____* 01
__*_* 05
___** 03
_____ 00
_____ 00
_ _*_ 02
*___* 11
*__** 13
_____ 00
_____ 00
____* 01
*____ 10
*___* 11
____* 01
_____ 00
_____ 00
*__*_ 12
*__*_ 12
*___* 11
_____ 00
_____ 00
*____ 10
**___ 18
*___* 11
_____ 00
_____ 00
____* 01
_*___ 08
**__* 19
_____ 00
_____ 00
*____ 10
_*__* 09
**___ 18
*____ 10
_____ 00
_____ 00
_*___ 08
_*__* 09
**___ 18
_____ 00
_____ 00
*____ 10
_**__ 0c
**___ 18
_____ 00
_____ 00

287
example-fsm-55/name.txt Normal file
View File

@@ -0,0 +1,287 @@
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
____* 01
_____ 00
_____ 00
_____ 00
____* 01
___** 03
____* 01
____* 01
_____ 00
___*_ 02
__**_ 06
___*_ 02
___*_ 02
____* 01
__*_* 05
_**_* 0d
__*_* 05
__*_* 05
___** 03
_*_** 0b
**_*_ 1a
_*_*_ 0a
_*_*_ 0a
__**_ 06
*_**_ 16
*_*__ 14
*_*__ 14
*_*__ 14
_**__ 0c
_**_* 0d
_*___ 08
_*__* 09
_*___ 08
**__* 19
**_** 1b
*___* 11
*__*_ 12
*____ 10
*__** 13
*_*** 17
___** 03
__*__ 04
_____ 00
__*** 07
_**** 0f
__**_ 06
_*__* 09
____* 01
_***_ 0e
****_ 1e
_**__ 0c
*__*_ 12
___*_ 02
***__ 1c
***_* 1d
**__* 19
__*_* 05
__*_* 05
**___ 18
**_*_ 1a
*__*_ 12
_*_*_ 0a
_*_*_ 0a
*___* 11
*_*__ 14
__*__ 04
*_*__ 14
*_*__ 14
___** 03
_*___ 08
_*___ 08
_*___ 08
_*__* 09
__**_ 06
*____ 10
*____ 10
*____ 10
*__*_ 12
_**__ 0c
_____ 00
_____ 00
_____ 00
__*__ 04
**___ 18
_____ 00
_____ 00
_____ 00
_*___ 08
*____ 10
_____ 00
_____ 00
_____ 00
*____ 10
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
____* 01
_____ 00
_____ 00
_____ 00
____* 01
___** 03
_____ 00
_____ 00
____* 01
___** 03
__*** 07
____* 01
____* 01
___** 03
__**_ 06
_**** 0f
___*_ 02
___*_ 02
__**_ 06
_**__ 0c
***** 1f
__*_* 05
__*_* 05
_**__ 0c
**___ 18
****_ 1e
_*_*_ 0a
_*_*_ 0a
**___ 18
*___* 11
***_* 1d
*_*__ 14
*_*__ 14
*____ 10
___** 03
**_** 1b
_*___ 08
_*___ 08
_____ 00
__*** 07
*_*** 17
*___* 11
*___* 11
____* 01
_**** 0f
_***_ 0e
___*_ 02
___*_ 02
___*_ 02
***** 1f
***__ 1c
__*__ 04
__*__ 04
__*__ 04
****_ 1e
**__* 19
_*___ 08
_*__* 09
_*___ 08
***_* 1d
*__** 13
*____ 10
*__** 13
*____ 10
**_** 1b
__*** 07
_____ 00
__*** 07
_____ 00
*_*** 17
_**** 0f
_____ 00
_**** 0f
_____ 00
_**** 0f
****_ 1e
_____ 00
****_ 1e
_____ 00
****_ 1e
***__ 1c
_____ 00
***__ 1c
_____ 00
***__ 1c
**___ 18
_____ 00
**___ 18
_____ 00
**___ 18
*____ 10
_____ 00
*____ 10
_____ 00
*____ 10
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00
_____ 00

View File

@@ -0,0 +1,12 @@
# Contributed by Kiwamu Okabe
source [find interface/stlink-v2.cfg]
transport select hla_swd
# The STM32F030F4P6 is a *tightly* constrained chip; the work area size must be
# similarly constrained.
set WORKAREASIZE 0x1000
source [find target/stm32f0x.cfg]
# use hardware reset, connect under reset
reset_config srst_only srst_nogate connect_assert_srst

118
example-fsm-55/sys.c Normal file
View File

@@ -0,0 +1,118 @@
/*
* sys.c - No system routines, but only RESET handler for STM32F030.
*
* Copyright (C) 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.
*
*/
#include <stdint.h>
#include <stdlib.h>
static void __attribute__ ((naked))
reset (void)
{
asm volatile ("cpsid i\n\t" /* Mask all interrupts. */
"mov r0, pc\n\t" /* r0 = PC & ~0x0fff */
"mov r1, #0x10\n\t"
"lsl r1, #8\n\t"
"sub r1, r1, #1\n\t"
"bic r0, r0, r1\n\t"
"ldr r2, [r0]\n\t"
"msr MSP, r2\n\t" /* Main (exception handler) stack. */
"b entry\n\t"
: /* no output */ : /* no input */ : "memory");
/* Never reach here. */
}
extern uint8_t __main_stack_end__;
extern void svc (void);
extern void preempt (void);
extern void chx_timer_expired (void);
extern void chx_handle_intr (void);
static void nmi (void)
{
for (;;);
}
static void __attribute__ ((naked))
hard_fault (void)
{
register uint32_t primask;
asm ("mrs %0, PRIMASK" : "=r" (primask));
if (primask)
asm volatile ("b svc");
else
for (;;);
}
static void mem_manage (void)
{
for (;;);
}
static void bus_fault (void)
{
for (;;);
}
static void usage_fault (void)
{
for (;;);
}
static void none (void)
{
}
typedef void (*handler)(void);
extern uint8_t __main_stack_end__;
handler vector[] __attribute__ ((section(".vectors"))) = {
(handler)&__main_stack_end__,
reset,
nmi, /* nmi */
hard_fault, /* hard fault */
/* 0x10 */
mem_manage, /* mem manage */
bus_fault, /* bus fault */
usage_fault, /* usage fault */
none,
/* 0x20 */
none, none, none, /* reserved */
svc, /* SVCall */
none, /* Debug */
none, /* reserved */
preempt, /* PendSV */
chx_timer_expired, /* SysTick */
/* 0x40 */
chx_handle_intr /* WWDG */, chx_handle_intr /* PVD */,
chx_handle_intr /* TAMPER */, chx_handle_intr /* RTC */,
chx_handle_intr /* FLASH */, chx_handle_intr /* RCC */,
chx_handle_intr /* EXTI0 */, chx_handle_intr /* EXTI1 */,
/* 0x60 */
chx_handle_intr /* EXTI2 */, chx_handle_intr /* EXTI3 */,
chx_handle_intr /* EXTI4 */, chx_handle_intr /* DMA1 CH1 */,
chx_handle_intr /* DMA1 CH2 */, chx_handle_intr /* DMA1 CH3 */,
chx_handle_intr /* DMA1 CH4 */, chx_handle_intr /* DMA1 CH5 */,
/* 0x80 */
chx_handle_intr /* DMA1 CH6 */, chx_handle_intr /* DMA1 CH7 */,
chx_handle_intr /* ADC1_2 */, chx_handle_intr /* USB HP */,
/* 0x90 */
chx_handle_intr /* USB LP */, chx_handle_intr /* CAN */,
/* ... and more. EXT9_5, TIMx, I2C, SPI, USART, EXT15_10 */
chx_handle_intr, chx_handle_intr,
/* 0xA0 */
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
/* 0xc0 */
};

View File

@@ -2,9 +2,14 @@
PROJECT = sample
### Currently, it's for STM32F0 Discovery.
### Please change lines started with '###' for Cortex-M3 board.
CHOPSTX = ..
LDSCRIPT= sample.ld
CSRC = sys.c aes-constant-ft.c sample.c
### LDSCRIPT= sample.ld.m3
CSRC = sys.c sample.c
### CSRC = sys.c aes-constant-ft.c sample.c
###################################
CROSS = arm-none-eabi-
@@ -12,10 +17,11 @@ CC = $(CROSS)gcc
LD = $(CROSS)gcc
OBJCOPY = $(CROSS)objcopy
MCU = cortex-m3
### MCU = cortex-m3
MCU = cortex-m0
CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DHAVE_SYS_H -DFREE_STANDING
# DEFS = -DFREE_STANDING -DHAVE_SYS_H -DBUSY_LOOP -DCHX_FLAGS_MAIN=CHOPSTX_SCHED_RR
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
LIBS =

1
example-led/board.h Symbolic link
View File

@@ -0,0 +1 @@
../board/board-stm32f0-discovery.h

View File

@@ -1,8 +1,8 @@
/*
* ST32F103 memory setup.
* ST32F0 memory setup.
*/
__main_stack_size__ = 0x0100; /* Exception handlers */
__process0_stack_size__ = 0x0100; /* Main program */
__process0_stack_size__ = 0x0100; /* Main program */
__process1_stack_size__ = 0x0100; /* first thread program */
__process2_stack_size__ = 0x0100; /* second thread program */
__process3_stack_size__ = 0x0100; /* third thread program */
@@ -14,9 +14,6 @@ MEMORY
ram : org = 0x20000000, len = 20k
}
__flash_start__ = 0x08001000;
__flash_end__ = 0x08020000;
__ram_start__ = ORIGIN(ram);
__ram_size__ = 20k;
__ram_end__ = __ram_start__ + __ram_size__;
@@ -25,21 +22,25 @@ SECTIONS
{
. = 0;
.sys : ALIGN(16) SUBALIGN(16)
.sys : ALIGN(4) SUBALIGN(4)
{
_sys = .;
KEEP(*(.vectors))
_sys = .;
KEEP(*(.vectors))
. = ALIGN(16);
*(.sys.version)
KEEP(*(.sys.version))
KEEP(*(.sys.board_id))
KEEP(*(.sys.board_name))
build/sys.o(.text)
build/sys.o(.text.*)
build/sys.o(.rodata)
build/sys.o(.rodata)
build/sys.o(.rodata.*)
. = ALIGN(1024);
/*
*(.sys.0)
*(.sys.1)
*(.sys.2)
} > flash0
*/
} > flash0 =0xffffffff
_text = .;
@@ -59,6 +60,7 @@ SECTIONS
*(.glue_7t)
*(.glue_7)
*(.gcc*)
. = ALIGN(8);
} > flash
.ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash
@@ -78,21 +80,28 @@ SECTIONS
_etext = .;
_textdata = _etext;
.vectors_in_ram :
{
. = ALIGN(8);
__vector_ram_addr__ = .;
KEEP(*(.bss.startup.*))
} > ram
.process_stack :
{
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
. = ALIGN(8);
__process_stack3_end__ = .;
__process3_stack_end__ = .;
__process2_stack_base__ = .;
. += __process2_stack_size__;
. = ALIGN(8);
__process_stack2_end__ = .;
__process2_stack_end__ = .;
__process1_stack_base__ = .;
. += __process1_stack_size__;
. = ALIGN(8);
__process_stack1_end__ = .;
__process1_stack_end__ = .;
__process0_stack_base__ = .;
. += __process0_stack_size__;
. = ALIGN(8);

142
example-led/sample.ld.m3 Normal file
View File

@@ -0,0 +1,142 @@
/*
* ST32F103 memory setup.
*/
__main_stack_size__ = 0x0100; /* Exception handlers */
__process0_stack_size__ = 0x0100; /* Main program */
__process1_stack_size__ = 0x0100; /* first thread program */
__process2_stack_size__ = 0x0100; /* second thread program */
__process3_stack_size__ = 0x0100; /* third thread program */
MEMORY
{
flash0 : org = 0x08000000, len = 4k
flash : org = 0x08000000+0x1000, len = 60k
ram : org = 0x20000000, len = 20k
}
__ram_start__ = ORIGIN(ram);
__ram_size__ = 20k;
__ram_end__ = __ram_start__ + __ram_size__;
SECTIONS
{
. = 0;
.sys : ALIGN(4) SUBALIGN(4)
{
_sys = .;
KEEP(*(.vectors))
. = ALIGN(16);
KEEP(*(.sys.version))
KEEP(*(.sys.board_id))
KEEP(*(.sys.board_name))
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;
.process_stack :
{
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
. = ALIGN(8);
__process3_stack_end__ = .;
__process2_stack_base__ = .;
. += __process2_stack_size__;
. = ALIGN(8);
__process2_stack_end__ = .;
__process1_stack_base__ = .;
. += __process1_stack_size__;
. = ALIGN(8);
__process1_stack_end__ = .;
__process0_stack_base__ = .;
. += __process0_stack_size__;
. = ALIGN(8);
__process0_stack_end__ = .;
} > ram
.main_stack :
{
. = ALIGN(8);
__main_stack_base__ = .;
. += __main_stack_size__;
. = ALIGN(8);
__main_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 = .;
}
__heap_base__ = _end;
__heap_end__ = __ram_end__;

View File

@@ -1,7 +1,7 @@
/*
* sys.c - system routines for the initial page for STM32F103.
* sys.c - system routines for the initial page for STM32F030 / STM32F103.
*
* Copyright (C) 2013, 2014 Flying Stone Technology
* Copyright (C) 2013, 2014, 2015 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* Copying and distribution of this file, with or without modification,
@@ -17,53 +17,13 @@
#include <stdlib.h>
#include "board.h"
#include "clk_gpio_init.c"
#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
#define STM32_SW_HSI (0 << 0)
#define STM32_SW_PLL (2 << 0)
#define STM32_PLLSRC_HSI (0 << 16)
#define STM32_PLLSRC_HSE (1 << 16)
#define STM32_PLLXTPRE_DIV1 (0 << 17)
#define STM32_PLLXTPRE_DIV2 (1 << 17)
#define STM32_HPRE_DIV1 (0 << 4)
#define STM32_PPRE1_DIV1 (0 << 8)
#define STM32_PPRE1_DIV2 (4 << 8)
#define STM32_PPRE2_DIV1 (0 << 11)
#define STM32_PPRE2_DIV2 (4 << 11)
#define STM32_ADCPRE_DIV4 (1 << 14)
#define STM32_ADCPRE_DIV6 (2 << 14)
#define STM32_USBPRE_DIV1P5 (0 << 22)
#define STM32_MCO_NOCLOCK (0 << 24)
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_FLASHBITS 0x00000012
#define STM32_PLLCLKIN (STM32_HSECLK / 1)
#define STM32_SW STM32_SW_PLL
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE2 STM32_PPRE2_DIV1
#define STM32_ADCPRE STM32_ADCPRE_DIV6
#define STM32_MCOSEL STM32_MCO_NOCLOCK
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
#define STM32_SYSCLK STM32_PLLCLKOUT
#define STM32_HCLK (STM32_SYSCLK / 1)
struct NVIC {
uint32_t ISER[8];
uint32_t unused1[24];
@@ -93,191 +53,6 @@ nvic_enable_vector (uint32_t n, uint32_t prio)
NVIC_ISER (n) = 1 << (n & 0x1F);
}
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct RCC {
volatile uint32_t CR;
volatile uint32_t CFGR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
};
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
static struct RCC *const RCC = ((struct RCC *const)RCC_BASE);
#define RCC_APB1ENR_USBEN 0x00800000
#define RCC_APB1RSTR_USBRST 0x00800000
#define RCC_CR_HSION 0x00000001
#define RCC_CR_HSIRDY 0x00000002
#define RCC_CR_HSITRIM 0x000000F8
#define RCC_CR_HSEON 0x00010000
#define RCC_CR_HSERDY 0x00020000
#define RCC_CR_PLLON 0x01000000
#define RCC_CR_PLLRDY 0x02000000
#define RCC_CFGR_SWS 0x0000000C
#define RCC_CFGR_SWS_HSI 0x00000000
#define RCC_AHBENR_CRCEN 0x0040
#define RCC_APB2RSTR_AFIORST 0x00000001
#define RCC_APB2RSTR_IOPARST 0x00000004
#define RCC_APB2RSTR_IOPBRST 0x00000008
#define RCC_APB2RSTR_IOPCRST 0x00000010
#define RCC_APB2RSTR_IOPDRST 0x00000020
#define RCC_APB2ENR_AFIOEN 0x00000001
#define RCC_APB2ENR_IOPAEN 0x00000004
#define RCC_APB2ENR_IOPBEN 0x00000008
#define RCC_APB2ENR_IOPCEN 0x00000010
#define RCC_APB2ENR_IOPDEN 0x00000020
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = ((struct FLASH *const) FLASH_R_BASE);
static void
clock_init (void)
{
/* HSI setup */
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY))
;
/* Reset HSEON, HSEBYP, CSSON, and PLLON, not touching RCC_CR_HSITRIM */
RCC->CR &= (RCC_CR_HSITRIM | RCC_CR_HSION);
RCC->CFGR = 0;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
;
/* HSE setup */
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY))
;
/* PLL setup */
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
;
/* Clock settings */
RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE
| STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
/*
* We don't touch RCC->CR2, RCC->CFGR2, RCC->CFGR3, and RCC->CIR.
*/
/* Flash setup */
FLASH->ACR = STM32_FLASHBITS;
/* CRC */
RCC->AHBENR |= RCC_AHBENR_CRCEN;
/* Switching on the configured clock source. */
RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
;
}
struct AFIO
{
volatile uint32_t EVCR;
volatile uint32_t MAPR;
volatile uint32_t EXTICR[4];
uint32_t RESERVED0;
volatile uint32_t MAPR2;
};
#define AFIO_BASE 0x40010000
static struct AFIO *const AFIO = (struct AFIO *const)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
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_LED = ((struct GPIO *const) GPIO_LED_BASE);
#ifdef GPIO_USB_BASE
static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE);
#endif
#ifdef GPIO_OTHER_BASE
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
#endif
static void
gpio_init (void)
{
/* Enable GPIO clock. */
RCC->APB2ENR |= RCC_ENR_IOP_EN;
RCC->APB2RSTR = RCC_RSTR_IOP_RST;
RCC->APB2RSTR = 0;
#ifdef AFIO_MAPR_SOMETHING
AFIO->MAPR |= AFIO_MAPR_SOMETHING;
#endif
GPIO_USB->ODR = VAL_GPIO_ODR;
GPIO_USB->CRH = VAL_GPIO_CRH;
GPIO_USB->CRL = VAL_GPIO_CRL;
#if GPIO_USB_BASE != GPIO_LED_BASE
GPIO_LED->ODR = VAL_GPIO_LED_ODR;
GPIO_LED->CRH = VAL_GPIO_LED_CRH;
GPIO_LED->CRL = VAL_GPIO_LED_CRL;
#endif
#ifdef GPIO_OTHER_BASE
GPIO_OTHER->ODR = VAL_GPIO_OTHER_ODR;
GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH;
GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL;
#endif
}
static void
usb_cable_config (int enable)
{
@@ -468,16 +243,25 @@ flash_check_blank (const uint8_t *p_start, size_t size)
return 1;
}
extern uint8_t __flash_start__, __flash_end__;
#define FLASH_START_ADDR 0x08000000 /* Fixed for all STM32F0/F1. */
#define FLASH_OFFSET 0x1000 /* First pages are not-writable
when protected. */
#if defined(__ARM_ARCH_6M__)
#define FLASH_SIZE_REG ((uint16_t *)0x1ffff7cc)
#define CHIP_ID_REG ((uint32_t *)0x40015800)
#else
#define FLASH_SIZE_REG ((uint16_t *)0x1ffff7e0)
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
#endif
#define FLASH_START (FLASH_START_ADDR+FLASH_OFFSET)
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__;
uint32_t flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
if (dst_addr < flash_start || dst_addr + len > flash_end)
if (dst_addr < FLASH_START || dst_addr + len > flash_end)
return 0;
while (len)
@@ -530,17 +314,21 @@ flash_protect (void)
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__;
uint32_t addr = FLASH_START;
uint32_t end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
uint32_t page_size = 1024;
int r;
if (((*CHIP_ID_REG) & 0xfff) == 0x0414)
page_size = 2048;
while (addr < end)
{
r = flash_erase_page (addr);
if (r != 0)
break;
addr += FLASH_PAGE_SIZE;
addr += page_size;
}
if (addr >= end)
@@ -588,12 +376,33 @@ nvic_system_reset (void)
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.
*/
#if defined(__ARM_ARCH_6M__)
asm volatile ("cpsid i\n\t" /* Mask all interrupts. */
"ldr r0, 1f\n\t" /* r0 = RAM start */
"mov r1, pc\n\t" /* r1 = (PC + 0x1000) & ~0x0fff */
"mov r2, #0x10\n\t"
"lsl r2, #8\n\t"
"add r1, r1, r2\n\t"
"sub r2, r2, #1\n\t"
"bic r1, r1, r2\n\t"
"mov r2, #188\n"
"2:\n\t" /* Copy vectors. It will be enabled later by clock_init. */
"ldr r3, [r1, r2]\n\t"
"str r3, [r0, r2]\n\t"
"sub r2, #4\n\t"
"bcs 2b\n\t"
"msr MSP, r3\n\t" /* Main (exception handler) stack. */
"ldr r0, [r1, #4]\n\t" /* Reset handler. */
"bx r0\n\t"
".align 2\n"
"1: .word 0x20000000"
: /* no output */ : /* no input */ : "memory");
#else
extern const unsigned long *FT0, *FT1, *FT2;
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 */
@@ -609,11 +418,11 @@ reset (void)
".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));
#endif
/* Never reach here. */
}
typedef void (*handler)(void);
@@ -640,7 +449,13 @@ handler vector[] __attribute__ ((section(".vectors"))) = {
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,
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
/* sys version: "2.1" */
'2', 0, '.', 0, '1', 0,
};
const uint32_t __attribute__((section(".sys.board_id")))
sys_board_id = BOARD_ID;
const uint8_t __attribute__((section(".sys.board_name")))
sys_board_name[] = BOARD_NAME;

View File

@@ -1,4 +1,23 @@
#if defined(__ARM_ARCH_6M__)
#define BOARD_ID_STM32F0_DISCOVERY 0xde4b4bc1
#define BOARD_ID_FSM_55 0x83433c76
#else
#define BOARD_ID_CQ_STARM 0xc5480875
#define BOARD_ID_FST_01_00 0x613870a9
#define BOARD_ID_FST_01 0x696886af
#define BOARD_ID_MAPLE_MINI 0x7a445272
#define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594
#define BOARD_ID_STBEE_MINI 0x1f341961
#define BOARD_ID_STBEE 0x945c37e8
#define BOARD_ID_STM32_PRIMER2 0x21e5798d
#define BOARD_ID_STM8S_DISCOVERY 0x2f0976bb
#define BOARD_ID_ST_DONGLE 0x2cd4e471
#define BOARD_ID_ST_NUCLEO_F103 0x9b87c16d
#endif
extern const uint8_t sys_version[8];
extern const uint32_t sys_board_id;
extern const uint8_t sys_board_name[];
typedef void (*handler)(void);
extern handler vector[16];

40
example-primer2/Makefile Normal file
View File

@@ -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

18
example-primer2/README Normal file
View File

@@ -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.

View File

@@ -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

388
example-primer2/lcd.c Normal file
View File

@@ -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);
}

148
example-primer2/lcd.ld Normal file
View File

@@ -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__;

266
example-primer2/main.c Normal file
View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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[]);

83
example-primer2/st7732.h Normal file
View File

@@ -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

467
example-primer2/sys.c Normal file
View File

@@ -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,
};

115
example-primer2/sys.h Normal file
View File

@@ -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]) ();
}