83 Commits

Author SHA1 Message Date
NIIBE Yutaka
8dabbe6e1c Version 1.7. 2017-12-19 09:33:27 +09:00
NIIBE Yutaka
0a68140530 Prepare 1.7 release. 2017-12-18 14:45:41 +09:00
NIIBE Yutaka
ce3cd63144 USB-USART improvement: flush buffer, send_break, use callbacks. 2017-12-18 13:53:01 +09:00
NIIBE Yutaka
199db97025 USB-USART supports notification of serial error. 2017-12-18 11:11:25 +09:00
NIIBE Yutaka
1533284ace USB-USART config setup support. 2017-12-17 11:52:17 +09:00
NIIBE Yutaka
0e9737eb61 Fix priority setting of USART (serial needs tight timing). 2017-12-16 17:17:58 +09:00
NIIBE Yutaka
265fb971c0 Fix USART for overrun error. 2017-12-16 17:01:58 +09:00
NIIBE Yutaka
26d5bb0115 Remove debug output for USART example. 2017-12-16 16:20:12 +09:00
NIIBE Yutaka
bf1ac08e6c Fix usb-cdc.c in USART example. 2017-12-16 16:14:43 +09:00
NIIBE Yutaka
530ddcfeda Fix timer expiration. 2017-12-16 15:00:55 +09:00
NIIBE Yutaka
19b0590c1f USART fix handle_tx_ready, tweak priority of the sample. 2017-12-16 14:33:40 +09:00
NIIBE Yutaka
72210e4250 Fix USART README and Alternate input config. 2017-12-15 22:18:22 +09:00
NIIBE Yutaka
61892c85b0 Fix USART rb_read. 2017-12-15 21:48:54 +09:00
NIIBE Yutaka
75e6b06dd5 Fix USART driver. 2017-12-15 18:11:25 +09:00
NIIBE Yutaka
dd190c8207 Add link for example-usb-serial. 2017-12-15 17:07:50 +09:00
NIIBE Yutaka
22039ee717 Modify USB<->USART example. 2017-12-15 16:00:59 +09:00
NIIBE Yutaka
cb628fe317 Fix rough edges of USART driver. 2017-12-15 15:18:17 +09:00
NIIBE Yutaka
f3cc662548 Remove bb.c. 2017-12-15 15:08:39 +09:00
NIIBE Yutaka
b58dd05c9d USART access functions implemented. 2017-12-15 15:07:13 +09:00
NIIBE Yutaka
7b1c442d88 USART: Main implemented. 2017-12-15 13:51:55 +09:00
NIIBE Yutaka
b4b9aace03 Add ring buffer for USART. 2017-12-15 09:46:28 +09:00
NIIBE Yutaka
741aba1997 Add ChangeLog. 2017-12-14 20:41:54 +09:00
NIIBE Yutaka
022666402c Start writing USART driver of STM32. 2017-12-14 20:34:24 +09:00
NIIBE Yutaka
69677aecd4 Change ADC setting of ST Nucleo STM32F103. 2017-12-14 20:31:28 +09:00
NIIBE Yutaka
bc35bc81cf APB -> APB1. 2017-12-14 19:04:16 +09:00
NIIBE Yutaka
499e575528 Fix bb. 2017-12-14 19:04:01 +09:00
NIIBE Yutaka
9f9aeae4bf Add bb.c, bb.h. 2017-12-14 15:47:18 +09:00
NIIBE Yutaka
ecd90b1b99 Testing loopback from ttyACM0 <-> ttyACM1. 2017-12-14 15:46:38 +09:00
NIIBE Yutaka
39e53ae747 Rename serial->cdc for no confusion between USART. 2017-12-14 12:24:59 +09:00
NIIBE Yutaka
9b9d40c16b No line editing. 2017-12-14 12:10:27 +09:00
NIIBE Yutaka
1eff465303 Modification to support multiple serial lines. 2017-12-14 11:25:14 +09:00
NIIBE Yutaka
de895e6b65 Add another interface. 2017-12-14 10:55:55 +09:00
NIIBE Yutaka
d4cca9f0dc It's not TTY but USB to serial driver. 2017-12-14 10:19:01 +09:00
NIIBE Yutaka
de9eb6f1e7 Try to support multiple serial lines. 2017-12-14 10:16:53 +09:00
NIIBE Yutaka
2c14f21b20 Copied from example-cde (except README). 2017-12-14 09:34:16 +09:00
NIIBE Yutaka
9e527b0532 Version 1.6. 2017-11-24 13:41:22 +09:00
NIIBE Yutaka
817167dbcc Update example-fsm-55. 2017-11-21 13:51:29 +09:00
NIIBE Yutaka
63974743b4 Forgotten example-led/stack-def.h. 2017-11-21 13:16:50 +09:00
NIIBE Yutaka
14c4256337 Update example-led. 2017-11-20 10:14:34 +09:00
NIIBE Yutaka
8c4ea854cb Fix for Cortex-M0. 2017-11-20 10:12:55 +09:00
NIIBE Yutaka
a610821458 Fix example-fsm-55. 2017-11-18 10:40:48 +09:00
NIIBE Yutaka
3071929c62 More change for clock setting. 2017-11-17 15:32:51 +09:00
NIIBE Yutaka
14cb38e56f More clean up. 2017-11-17 14:55:59 +09:00
NIIBE Yutaka
a362f32cdd Factor out RCC definition into stm32.h (common for STM32F0/STM32F1). 2017-11-17 14:33:16 +09:00
NIIBE Yutaka
e684e853c8 Fix for MKL27Z. 2017-11-17 11:45:18 +09:00
NIIBE Yutaka
2b98dc3de8 Update example-fsm-55. 2017-11-17 11:44:56 +09:00
NIIBE Yutaka
44054415c8 MCU specific sleep feature is now defined in MCU specific file. 2017-11-17 11:43:05 +09:00
NIIBE Yutaka
66b4eb3058 Update mcu/stm32f103.h. 2017-11-17 11:36:08 +09:00
NIIBE Yutaka
b72154f47b Factor out mcu/cortex-m.h. 2017-11-17 11:34:28 +09:00
NIIBE Yutaka
378201a1c7 Call chx_sleep_mode change. 2017-11-17 11:28:05 +09:00
NIIBE Yutaka
1a7bd3e202 Add MCU_STM32F1. 2017-11-17 11:25:57 +09:00
NIIBE Yutaka
b34b9b6440 Use HSI clock on sleep mode for STM32F103. 2017-11-16 13:04:08 +09:00
NIIBE Yutaka
d745c9fdb9 Only sleep mode can be used for USB suspend on STM32F103. 2017-11-16 12:19:25 +09:00
NIIBE Yutaka
3552fc5615 chopstx_poll: Use const pointer for the third argument. 2017-11-16 09:15:03 +09:00
NIIBE Yutaka
621dff7cb3 Fix for Cortex-M0. 2017-11-16 09:02:16 +09:00
NIIBE Yutaka
83643c53ca Use event instead of interrupt (STM32F103 USB). 2017-11-16 08:39:30 +09:00
NIIBE Yutaka
040f389449 Add INTR_REQ_USB_WAKEUP. 2017-11-15 17:51:08 +09:00
NIIBE Yutaka
44273a70fc USB driver for STM32F103 update for USB suspend/resume support. 2017-11-15 17:23:02 +09:00
NIIBE Yutaka
7257f30636 Use deep sleep API for example-fsm-55. 2017-11-15 17:09:47 +09:00
NIIBE Yutaka
941a8f6fbd Add chx_sleep_mode. 2017-11-15 17:09:30 +09:00
NIIBE Yutaka
13926ac05a Fix Cortex-M0 version. 2017-11-15 16:47:26 +09:00
NIIBE Yutaka
bbe09de209 Fix example-fsm-55 and documentation. 2017-11-15 10:46:49 +09:00
NIIBE Yutaka
f161928b0b Support sleep on idle. 2017-11-15 10:22:30 +09:00
NIIBE Yutaka
035057db24 Fix USB driver for STM32F103. 2017-11-15 09:34:13 +09:00
NIIBE Yutaka
5ac8a1f251 Fix example-fraucheky. 2017-11-14 11:30:20 +09:00
NIIBE Yutaka
168af852a5 Support USB suspend/resume defined in USB 2.0 spec. 2017-11-14 11:17:49 +09:00
NIIBE Yutaka
e398fc9689 Modify place where INTR_REQ_USB is defined. 2017-11-13 11:44:53 +09:00
NIIBE Yutaka
5a08752b9c Fix cancellation (svc and ->v handling). 2017-11-10 16:09:46 +09:00
NIIBE Yutaka
b572e3f8e0 Fix timeout. 2017-11-10 16:09:32 +09:00
NIIBE Yutaka
55b011a721 Fix use of noreturn attribute. 2017-10-11 17:01:53 +09:00
NIIBE Yutaka
c191d86bf2 GNU/Linux USB driver shutdown support. 2017-10-10 21:02:29 +09:00
NIIBE Yutaka
96d2a81331 Version 1.5.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-10-10 13:53:58 +09:00
NIIBE Yutaka
fa7cecc0b4 Support --debug option for exacmple-cdc-gnu-linux. 2017-10-10 12:18:35 +09:00
NIIBE Yutaka
a34937453c New: debug option. 2017-10-10 12:16:03 +09:00
NIIBE Yutaka
dd54b5ff20 Fix example-cdc. 2017-10-10 12:07:02 +09:00
NIIBE Yutaka
c08044e22b Fix sys for STM32F103. 2017-09-29 13:50:06 +09:00
NIIBE Yutaka
5b7c5a9996 Use flash routines in example-cdc-gnu-linux. 2017-09-27 19:24:08 +09:00
NIIBE Yutaka
bc39f0e582 update flash routines for GNU/Linux. 2017-09-27 19:07:14 +09:00
NIIBE Yutaka
e671a539b0 Fix flash routines on GNU/Linux.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-09-08 20:56:23 +09:00
NIIBE Yutaka
2c9191c4b3 Implement flash ROM emulation on GNU/LInux.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-09-08 20:44:56 +09:00
NIIBE Yutaka
af5982507f Define threads stack size by stack-def.h.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-09-05 14:34:25 +09:00
NIIBE Yutaka
a1b993c2e2 Minor changes for SYS.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-09-04 15:23:35 +09:00
NIIBE Yutaka
e73d14ca27 Add muc/sys-gnu-linux.*.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-09-04 15:23:02 +09:00
84 changed files with 4556 additions and 774 deletions

View File

@@ -48,6 +48,7 @@ NIIBE Yutaka:
Under contract of g10 Code GmbH, wrote:
mcu/usb-usbip.c
contrib/usart-stm32f103.c
Paul Fertser:
Added Blue Pill support.

190
ChangeLog
View File

@@ -1,3 +1,193 @@
2017-12-19 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.7.
* doc/chopstx.texi (VERSION): 1.7.
2017-12-18 NIIBE Yutaka <gniibe@fsij.org>
* contrib/usart-stm32f103.c: New.
* example-usb-serial: New example.
2017-12-16 NIIBE Yutaka <gniibe@fsij.org>
* chopstx.c (chx_timer_expired): Bug fix of wake up.
(chx_mutex_unlock): Avoid non-deterministic thing.
2017-12-14 NIIBE Yutaka <gniibe@fsij.org>
* board/board-st-nucleo-f103.h: Update.
* mcu/sys-stm32f103.h (BOARD_ID_FST_01G): New.
* contrib/adc-stm32f103.c (get_adc_config): Add a case for
BOARD_ID_FST_01G and BOARD_ID_ST_NUCLEO_F103.
2017-11-24 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.6.
* doc/chopstx.texi (VERSION): 1.6.
* doc/chopstx-api.texi: Regenerated.
2017-11-21 NIIBE Yutaka <gniibe@fsij.org>
* example-fsm-55: Update using stack-def.h.
2017-11-20 NIIBE Yutaka <gniibe@fsij.org>
* example-led: Update using stack-def.h.
* chopstx-cortex-m.c [__ARM_ARCH_6M__] (chx_sched): Fix.
2017-11-18 NIIBE Yutaka <gniibe@fsij.org>
* example-fsm-55/hh.c (main): Just return.
2017-11-17 NIIBE Yutaka <gniibe@fsij.org>
* mcu/chx-stm32f103.c (configure_clock): Change prescaler on
sleep.
* mcu/clk_gpio_init-stm32.c (clock_init): Don't turn on CRC
module.
* mcu/clk_gpio_init-stm32.c (STM32_*): Move to...
* mcu/stm32.h (STM32_*): ... this header file.
* mcu/stm32f103.h, mcu/clk_gpio_init-stm32.c (RCC): Move to...
* mcu/stm32.h (RCC): ... this header file.
* example-fsm-55: Update for new sleep API.
* rules.mk (CSRC): Add mcu/chx-$(CHIP).c.
* chopstx-cortex-m.c (idle, chx_sleep_mode): Remove.
(chx_sched, preempt): Call chx_idle.
* mcu/chx-mkl27z.c, mcu/chx-stm32f0.c, mcu/chx-stm32f103.c: New.
* mcu/stm32.h: New.
* chopstx-gnu-linux.c (chx_sleep_mode): Move to...
* mcu/chx-gnu-linux.c: Here.
* mcu/stm32f103.h (DBGMCU): New.
* mcu/cortex-m.h: New.
* mcu/sys-stm32f0.c, mcu/sys-stm32f103.c: Use mcu/cortex-m.h.
* chopstx.c (chopstx_conf_idle): Call chx_sleep_mode before
changing chx_allow_sleep.
* board/board-blue-pill.h, board/board-cq-starm.h,
board/board-fst-01-00.h, board/board-fst-01.h,
board/board-fst-01g.h, board/board-maple-mini.h,
board/board-nitrokey-start.h, board/board-olimex-stm32-h103.h,
board/board-st-dongle.h, board/board-st-nucleo-f103.h,
board/board-stbee-mini.h, board/board-stbee.h,
board/board-stm32-primer2.h: Add MCU_STM32F1.
2017-11-16 NIIBE Yutaka <gniibe@fsij.org>
* chopstx.h (chopstx_poll): API change.
* chopstx.c (chopstx_poll): Use const pointer.
* chopstx-cortex-m.c (idle): Support WFE.
[!MCU_STM32F0] (chx_sleep_mode): Clock feed by HSI.
2017-11-15 NIIBE Yutaka <gniibe@fsij.org>
* chopstx.c (chopstx_conf_idle): Call chx_sleep_mode.
* chopstx-cortex-m.c (chx_sleep_mode): New.
* chopstx-gnu-linux.c (chx_sleep_mode): New.
2017-11-15 NIIBE Yutaka <gniibe@fsij.org>
* example-fsm-55/hh.c (main): Add call to chopstx_conf_idle.
* example-fsm-55/Makefile (DEFS): Remove USE_WFI_FOR_IDLE.
* chopstx.c (chx_init): Initialize sleep lock.
(chopstx_conf_idle): New.
* chopstx-cortex-m.c (idle): Support sleep.
* mcu/usb-stm32f103.c (usb_lld_event_handler): Fix suspend/resume.
2017-11-14 NIIBE Yutaka <gniibe@fsij.org>
* usb_lld.h (DEVICE_STATE): Add prefix USB_DEVICE_STATE_.
(USB_DEVICE_STATE_DEFAULT): New.
* mcu/usb-stm32f103.c (usb_lld_init): Suspend/resume init.
(usb_lld_event_handler): Add suspend/resume support.
* example-cdc/usb-cdc.c: Follow the change of usb_lld.h.
* example-cdc-gnu-linux/usb-cdc.c: Ditto.
* example-fs-bb48/usb-cdc.c: Ditto.
* example-fraucheky/main.c: Ditto.
* example-fraucheky/Makefile (USE_SYS): Add for debug.
2017-11-13 NIIBE Yutaka <gniibe@fsij.org>
* mcu/usb-stm32f103.c (usb_lld_init): Set up interrupt on errors.
* usb_lld.h (USB_EVENT_DEVICE_WAKEUP): New.
(INTR_REQ_USB): Define here.
* mcu/usb-usbip.c, example-cdc/usb-cdc.c,
example-fraucheky/main.c, example-fs-bb48/usb-cdc.c: Change
for INTR_REQ_USB.
2017-11-10 NIIBE Yutaka <gniibe@fsij.org>
* chopstx-cortex-m.c (svc): Replace stack top to TP.
(chx_sched): Return ->v correctly.
* chopstx.c (chx_timer_expired): Fix timeout.
2017-10-11 NIIBE Yutaka <gniibe@fsij.org>
* mcu/sys-stm32f103.h (nonreturn_handler0, nonreturn_handler1): New.
2017-10-10 NIIBE Yutaka <gniibe@fsij.org>
* mcu/usb-usbip.c (usbip_run_server): Shutdown support.
(usb_lld_shutdown): Shutdown glace-fully.
2017-10-10 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.5.
* doc/chopstx.texi (VERSION): 1.5.
* doc/chopstx-api.texi: Regenerated.
2017-10-09 NIIBE Yutaka <gniibe@fsij.org>
* example-cdc-gnu-linux/sample.c (main): Support debug option.
* mcu/sys-gnu-linux.h (debug): New.
* mcu/sys-gnu-linux.c: Use debug.
* mcu/usb-usbip.c: Use debug.
* example-cdc/sample.ld (.process_stack, .main_stack): Add NOLOAD.
2017-09-29 NIIBE Yutaka <gniibe@fsij.org>
* mcu/sys-stm32f103.c (flash_program_halfword, flash_erase_page)
(flash_write, flash_erase_all_and_exec): Use uintptr_t.
2017-09-08 NIIBE Yutaka <gniibe@fsij.org>
* mcu/sys-gnu-linux.c: Flash emulation implemented.
2017-09-05 NIIBE Yutaka <gniibe@fsij.org>
* example-cdc: Use stack-def.h.
* example-cdc/stack-def.h: New.
2017-09-04 NIIBE Yutaka <gniibe@fsij.org>
* mcu/sys-stm32f103.h (nvic_system_reset): Add noreturn attribute.
* sys.h: Add mcu/sys-gnu-linux.h.
* mcu/sys-gnu-linux.c: New.
* mcu/sys-gnu-linux.h: New.
2017-08-11 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.4.

58
NEWS
View File

@@ -1,6 +1,64 @@
NEWS - Noteworthy changes
* Major changes in Chopstx 1.7
Released 2017-12-19
** Fix: timer wakeup
Timer expiration had a bug. When it is waken up, the wake up doesn't
handle as a timer expiration when there are multiple threads on same
timing of expire. It confuses as if it were forced wakeup.
** New driver: USART for STM32.
USART driver for STM32 is added.
* Major changes in Chopstx 1.6
Released 2017-11-24
** Fix cancellation
In Chopstx 1.4 and 1.5, cancellation doesn't work for real MCU. This
is due to the change of chx_sched interface, introduced for GNU/Linux
emulation. This bug is fixed.
** New feature: sleep mode
New function chopstx_conf_idle is added to support sleep. Note that
use of sleep by this feature requires careful preparation. For
example, enabling sleep, a board with no RESET pin cannot be debugged
by JTAG/SWD. Setting of DBGMCU_CR (0xE0042004) is required beforehand
(hardware default is zero).
** API change: chopstx_poll
This is a kind of clarification. The third argument is now an array
of constant pointers. We don't touch the array itself, just use it.
This allows having the array in read-only memory and can contribute
less use of RAM.
** USB API changes
INTR_REQ_USB is now defined by usb_lld.h. Enumeration type of
DEVICE_STATE now has USB_DEVICE_STATE_ prefix.
** USB driver change
USB suspend and wakeup events are supported for STM32F103.
* Major changes in Chopstx 1.5
Released 2017-10-10
** Stack size definition by stack-def.h
Stack size of each thread was used to be defined in ldscript.
While emulation on GNU/Linux doesn't use ldscript, it is better
to put those definitions in independent header file. Please see
example-cdc/stack-def.h and example-cdc/sample.ld.
** More support for emulation on GNU/Linux
We have SYS driver for emulation on GNU/Linux. It has flash ROM
emulation.
* Major changes in Chopstx 1.4
Released 2017-08-11

26
README
View File

@@ -1,6 +1,6 @@
Chopstx - Threads and only Threads
Version 1.4
2017-08-11
Version 1.7
2017-12-19
Niibe Yutaka
Flying Stone Technology
@@ -11,12 +11,24 @@ Chopstx is an RT thread library for STM32F103 (ARM Cortex-M3),
STM32F030 (ARM Cortex-M0), MKL27Z (ARM Cortex-M0plus), and
emulation on GNU/Linux.
While most RTOSes come with many features, drivers, and stacks,
Chopstx just offers a simple RT thread library.
While most RTOSes come with many features, drivers, and protocol
stacks, 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.
While threads are important, we don't need more threads than
necessary. Chopstx provides a feature of poll, so that we can
minimize use of threads.
Note that this library is _not_ related to the hand game:
https://en.wikipedia.org/wiki/Chopsticks_(hand_game)
Thanks to Yao Wei and Enrico Zini for giving me an opportunity
visiting the wiki page above.
License
=======
@@ -30,8 +42,8 @@ Example code
============
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:
blinker and USB CDC-ACM device. For STM32F103, you can build it USB
CDC-ACM demo by:
$ cd example-cdc
$ ln -sf ../board/board-olimex-stm32-h103.h board.h
@@ -47,7 +59,7 @@ Future Works
============
Convenience function to determine the bottom of thread stack,
configuration of thread size by comiler's output would be next things
configuration of thread size by compiler's output would be next things
to be done.
Experimental SMP port for Cortex-A7 is under development. For SMP,

View File

@@ -1 +1 @@
release/1.4
release/1.7

View File

@@ -3,6 +3,7 @@
/* echo -n "Blue Pill" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */
#define BOARD_ID 0xa1099d43
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "CQ STARM"
#define BOARD_ID 0xc5480875
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "FST-01-00"
#define BOARD_ID 0x613870a9
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -2,6 +2,7 @@
#define BOARD_ID 0x696886af
/* echo -n "FST-01" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -2,6 +2,7 @@
#define BOARD_ID 0x8801277f
/* echo -n "FST-01G" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "Maple Mini"
#define BOARD_ID 0x7a445272
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "NITROKEY-START"
#define BOARD_ID 0xad1e7ebd
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "Olimex STM32-H103"
#define BOARD_ID 0xf92bb594
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
@@ -30,11 +31,3 @@
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPCEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPCRST
/* 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

View File

@@ -2,6 +2,7 @@
/* echo -n "ST Dongle" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */
#define BOARD_ID 0x2cd4e471
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -16,6 +16,7 @@
* GND BLACK --> 20 GND
*/
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
@@ -25,21 +26,40 @@
#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
#define GPIO_OTHER_BASE GPIOB_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)
* PA0 - Input with pull-up USART2-CTS
* PA1 - Alternate function push pull output 2MHz USART2-RTS
* PA2 - Alternate function push pull output 2MHz USART2-TX
* PA3 - Input with pull-up USART2-RX
* PA4 - Alternate function push pull output 2MHz USART2-CK
* PA5 - Push pull output 2MHz (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_CRL 0x882A8AA8 /* 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
/*
* Port B setup.
* PB0 - input with pull-up: AN8 for NeuG
* PB1 - input with pull-up: AN9 for NeuG
* PB10 - Alternate function push pull output 2MHz USART3-TX
* PB11 - Input with pull-up USART3-RX
* PB12 - Alternate function push pull output 2MHz USART3-CK
* PB13 - Input with pull-up USART3-CTS
* PB14 - Alternate function push pull output 2MHz USART3-RTS
* ------------------------ Default
* PBx - input with pull-up.
*/
#define VAL_GPIO_OTHER_ODR 0xFFFFFFFF
#define VAL_GPIO_OTHER_CRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIO_OTHER_CRH 0x8A8A8A88 /* 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

@@ -1,6 +1,7 @@
#define BOARD_NAME "STBee Mini"
#define BOARD_ID 0x1f341961
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -1,6 +1,9 @@
#define BOARD_NAME "STBee"
#define BOARD_ID 0x945c37e8
#define MCU_STM32F1 1
/* High-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 6
#define STM32_HSECLK 12000000

View File

@@ -1,6 +1,9 @@
#define BOARD_NAME "STM32 Primer2"
#define BOARD_ID 0x21e5798d
#define MCU_STM32F1 1
/* High-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 6
#define STM32_HSECLK 12000000

View File

@@ -1,8 +1,6 @@
#define BOARD_NAME "STM32F0 Discovery"
#define BOARD_ID 0xde4b4bc1
#define MCU_STM32F0 1
/*
* Running at 48MHz with HSI as clock source.
*

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "STM8S Discovery"
#define BOARD_ID 0x2f0976bb
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -229,18 +229,6 @@ chx_cpu_sched_unlock (void)
}
static void __attribute__((naked, used))
idle (void)
{
#if defined(USE_WFI_FOR_IDLE)
for (;;)
asm volatile ("wfi" : : : "memory");
#else
for (;;);
#endif
}
void
chx_handle_intr (void)
{
@@ -299,7 +287,7 @@ chx_request_preemption (uint16_t prio)
*
* Returns:
* 1 on wakeup by others.
* 0 on normal wakeup.
* 0 on normal wakeup (timer expiration, lock aquirement).
* -1 on cancellation.
*/
static uintptr_t __attribute__ ((naked, noinline))
@@ -309,25 +297,24 @@ chx_sched (uint32_t yield)
#if defined(__ARM_ARCH_7M__)
asm volatile (
"svc #0\n\t"
"bx lr"
"svc #0"
: "=r" (tp) : "0" (yield): "memory");
#else
register uint32_t arg_yield asm ("r1");
/* Build stack data as if it were an exception entry. */
/*
* r0: 0 scratch
* r0: TP scratch
* r1: 0 scratch
* r2: 0 scratch
* r3: 0 scratch
* r12: 0 scratch
* lr as-is
* pc: return address (= lr)
* pc: return address (= .L_CONTEXT_SWITCH_FINISH)
* psr: INITIAL_XPSR scratch
*/
asm ("mov r1, lr\n\t"
"mov r2, r1\n\t"
"ldr r2, =.L_CONTEXT_SWITCH_FINISH\n\t"
"mov r3, #128\n\t"
"lsl r3, #17\n\t"
"push {r1, r2, r3}\n\t"
@@ -335,16 +322,16 @@ chx_sched (uint32_t yield)
"mov r2, r1\n\t"
"mov r3, r1\n\t"
"push {r1, r2, r3}\n\t"
"push {r1, r2}"
: /* no output*/
: /* no input */
: "r1", "r2", "r3", "memory");
/* Save registers onto CHX_THREAD struct. */
asm ("mov r1, r0\n\t"
"mov r1, r0\n\t"
"ldr r2, =running\n\t"
"ldr r0, [r2]\n\t"
"add r0, #20\n\t"
"push {r0, r3}"
: "=r" (tp), "=r" (arg_yield)
: "0" (yield)
: "r2", "r3", "memory");
/* Save registers onto CHX_THREAD struct. */
asm ("add r0, #20\n\t"
"stm r0!, {r4, r5, r6, r7}\n\t"
"mov r2, r8\n\t"
"mov r3, r9\n\t"
@@ -353,8 +340,8 @@ chx_sched (uint32_t yield)
"mov r6, sp\n\t"
"stm r0!, {r2, r3, r4, r5, r6}\n\t"
"sub r0, #56"
: "=r" (tp), "=r" (arg_yield)
: "0" (yield)
: /* no output */
: "r" (tp)
: "r2", "r3", "r4", "r5", "r6", "r7", "memory");
if (arg_yield)
@@ -383,7 +370,7 @@ chx_sched (uint32_t yield)
/* Spawn an IDLE thread. */
"ldr r1, =__main_stack_end__\n\t"
"mov sp, r1\n\t"
"ldr r0, =idle\n\t" /* PC = idle */
"ldr r0, =chx_idle\n\t" /* PC = idle */
/**/
/* Unmask interrupts. */
"cpsie i\n\t"
@@ -391,11 +378,7 @@ chx_sched (uint32_t yield)
/* Normal context switch */
"0:\n\t"
"add r0, #16\n\t" /* ->V */
"ldr r1, [r0]\n\t"
"str r1, [sp]\n\t"
/**/
"add r0, #4\n\t"
"add r0, #20\n\t"
"ldm r0!, {r4, r5, r6, r7}\n\t"
"ldm r0!, {r1, r2, r3}\n\t"
"mov r8, r1\n\t"
@@ -455,12 +438,17 @@ chx_sched (uint32_t yield)
"mov r12, r0\n\t"
"pop {r0, r1, r2, r3}\n\t"
"add sp, #12\n\t"
"pop {pc}"
"pop {pc}\n\t"
".L_CONTEXT_SWITCH_FINISH:"
: "=r" (tp) /* Return value in R0 */
: "0" (tp)
: "memory");
#endif
asm volatile ("bx lr"
: "=r" (tp)
: "0" (tp->v)
: "memory");
return (uintptr_t)tp;
}
@@ -631,7 +619,7 @@ preempt (void)
"mov r3, #0\n\t"
"stm r0!, {r1, r2, r3}\n\t"
"stm r0!, {r1, r2, r3}\n\t"
"ldr r1, =idle\n\t" /* PC = idle */
"ldr r1, =chx_idle\n\t" /* PC = idle */
"mov r2, #0x010\n\t"
"lsl r2, r2, #20\n\t" /* xPSR = T-flag set (Thumb) */
"stm r0!, {r1, r2}\n\t"
@@ -675,7 +663,8 @@ svc (void)
"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]"
"ldr r1, [r6]\n\t"
"str r0, [r6]"
: "=r" (tp), "=r" (orig_r0)
: /* no input */
: "r2", "r3", "r4", "r5", "r6", "memory");
@@ -697,10 +686,6 @@ svc (void)
}
asm volatile (
"cbz r0, 0f\n\t"
"ldr r1, [r0, #16]\n\t" /* ->V */
"str r1, [sp]\n\t"
"0:\n\t"
"b .L_CONTEXT_SWITCH"
: /* no output */ : "r" (tp) : "memory");
}

View File

@@ -79,7 +79,11 @@ chx_fatal (uint32_t err_code)
#include "chopstx-cortex-m.h"
#endif
/* RUNNING: the current thread. */
/* ALLOW_SLEEP for the idle thread. */
int chx_allow_sleep;
static struct chx_spinlock chx_enable_sleep_lock;
/* RUNNING: the current thread. */
struct chx_thread *running;
struct chx_queue {
@@ -382,6 +386,7 @@ chx_timer_expired (void)
{
uint32_t next_tick = tp->v;
tp->v = (uintptr_t)0;
chx_ready_enqueue (tp);
if (tp == running) /* tp->flag_sched_rr == 1 */
prio = MAX_PRIO;
@@ -398,6 +403,7 @@ chx_timer_expired (void)
tp = tp_next)
{
next_tick = tp->v;
tp->v = (uintptr_t)0;
tp_next = (struct chx_thread *)tp->next;
ll_dequeue ((struct chx_pq *)tp);
chx_ready_enqueue (tp);
@@ -440,6 +446,7 @@ chx_init (struct chx_thread *tp)
{
chx_prio_init ();
chx_init_arch (tp);
chx_spin_init (&chx_enable_sleep_lock);
q_ready.q.next = q_ready.q.prev = (struct chx_pq *)&q_ready.q;
chx_spin_init (&q_ready.lock);
@@ -569,6 +576,7 @@ chx_mutex_unlock (chopstx_mutex_t *mutex)
uint16_t newprio = running->prio_orig;
chopstx_mutex_t *m;
tp->v = (uintptr_t)0;
chx_ready_enqueue (tp);
/* Examine mutexes we hold, and determine new priority for running. */
@@ -1316,7 +1324,7 @@ chx_proxy_init (struct chx_px *px, uint32_t *cp)
* Returns number of active descriptors.
*/
int
chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[])
chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
{
uint32_t counter = 0;
int i;
@@ -1469,3 +1477,38 @@ chopstx_setpriority (chopstx_prio_t prio_new)
return prio_orig;
}
/**
* chopstx_conf_idle - Configure IDLE thread
* @enable_sleep: Enable sleep on idle or not
*
* If @enable_sleep is > 0, allow sleep for the idle thread.
*
* Behavior of @enable_sleep >= 1 depends on MCU.
*
* For STM32F0, 1 for Sleep (CPU clock OFF only), 2 for Stop (Wakeup
* by EXTI, voltage regulator on), 3 for Stop (Wakeup by EXTI, voltage
* regulator low-power), 4 for Standby (Wakeup by RESET, voltage
* regulator off).
*
* For STM32F103, 1 for normal sleep, and 2 for sleep with lower 8MHz
* clock.
*
* Return previous value of @enable_sleep.
*/
extern void chx_sleep_mode (int enable_sleep);
int
chopstx_conf_idle (int enable_sleep)
{
int r;
chx_spin_lock (&chx_enable_sleep_lock);
r = chx_allow_sleep;
chx_sleep_mode (enable_sleep);
chx_allow_sleep = enable_sleep;
chx_spin_unlock (&chx_enable_sleep_lock);
return r;
}

View File

@@ -1,7 +1,7 @@
/*
* chopstx.h - Threads and only threads.
*
* Copyright (C) 2013, 2016 Flying Stone Technology
* Copyright (C) 2013, 2016, 2017 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Chopstx, a thread library for embedded.
@@ -158,6 +158,9 @@ void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num);
void chopstx_intr_wait (chopstx_intr_t *intr); /* DEPRECATED */
int chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[]);
int chopstx_poll (uint32_t *usec_p, int n,
struct chx_poll_head *const pd_array[]);
int chopstx_conf_idle (int enable_sleep);
#define CHOPSTX_THREAD_SIZE 64

View File

@@ -32,6 +32,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <chopstx.h>
#include <mcu/stm32.h>
#include <mcu/stm32f103.h>
#include "adc.h"
@@ -144,6 +145,7 @@ get_adc_config (uint32_t config[4])
config[2] = ADC_SQR1_NUM_CH(2);
switch (SYS_BOARD_ID)
{
case BOARD_ID_FST_01G:
case BOARD_ID_FST_01:
config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
@@ -169,13 +171,20 @@ get_adc_config (uint32_t config[4])
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN2);
break;
case BOARD_ID_ST_NUCLEO_F103:
config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN8(ADC_SAMPLE_1P5)
| ADC_SMPR2_SMP_AN9(ADC_SAMPLE_1P5);
config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN8)
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN9);
break;
case BOARD_ID_CQ_STARM:
case BOARD_ID_FST_01_00:
case BOARD_ID_MAPLE_MINI:
case BOARD_ID_STM32_PRIMER2:
case BOARD_ID_STM8S_DISCOVERY:
case BOARD_ID_ST_DONGLE:
case BOARD_ID_ST_NUCLEO_F103:
case BOARD_ID_NITROKEY_START:
default:
config[0] = 0;

624
contrib/usart-stm32f103.c Normal file
View File

@@ -0,0 +1,624 @@
/*
* usart-stm32.c - USART driver for STM32F103 (USART2 and USART3)
*
* Copyright (C) 2017 g10 Code GmbH
* 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.
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <chopstx.h>
#include <mcu/stm32.h>
#include <contrib/usart.h>
struct USART {
volatile uint32_t SR;
volatile uint32_t DR;
volatile uint32_t BRR;
volatile uint32_t CR1;
volatile uint32_t CR2;
volatile uint32_t CR3;
volatile uint32_t GTPR;
};
#define USART2_BASE (APB1PERIPH_BASE + 0x4400)
#define USART3_BASE (APB1PERIPH_BASE + 0x4800)
static struct USART *const USART2 = (struct USART *)USART2_BASE;
static struct USART *const USART3 = (struct USART *)USART3_BASE;
#define USART_SR_CTS (1 << 9)
#define USART_SR_LBD (1 << 8)
#define USART_SR_TXE (1 << 7)
#define USART_SR_TC (1 << 6)
#define USART_SR_RXNE (1 << 5)
#define USART_SR_IDLE (1 << 4)
#define USART_SR_ORE (1 << 3)
#define USART_SR_NE (1 << 2)
#define USART_SR_FE (1 << 1)
#define USART_SR_PE (1 << 0)
#define USART_CR1_UE (1 << 13)
#define USART_CR1_M (1 << 12)
#define USART_CR1_WAKE (1 << 11)
#define USART_CR1_PCE (1 << 10)
#define USART_CR1_PS (1 << 9)
#define USART_CR1_PEIE (1 << 8)
#define USART_CR1_TXEIE (1 << 7)
#define USART_CR1_TCIE (1 << 6)
#define USART_CR1_RXNEIE (1 << 5)
#define USART_CR1_IDLEIE (1 << 4)
#define USART_CR1_TE (1 << 3)
#define USART_CR1_RE (1 << 2)
#define USART_CR1_RWU (1 << 1)
#define USART_CR1_SBK (1 << 0)
static struct USART *
get_usart_dev (uint8_t dev_no)
{
if (dev_no == 2)
return USART2;
else if (dev_no == 3)
return USART3;
return NULL;
}
/* We assume 36MHz f_PCLK */
struct brr_setting {
uint8_t baud_spec;
uint16_t brr_value;
};
#define NUM_BAUD (int)(sizeof (brr_table) / sizeof (struct brr_setting))
static const struct brr_setting brr_table[] = {
{ B600, (3750 << 4)},
{ B1200, (1875 << 4)},
{ B2400, ( 937 << 4)|8},
{ B9600, ( 234 << 4)|6},
{ B19200, ( 117 << 4)|3},
{ B57600, ( 39 << 4)|1},
{ B115200, ( 19 << 4)|8},
{ B230400, ( 9 << 4)|12},
{ B460800, ( 4 << 4)|14},
{ B921600, ( 2 << 4)|7},
};
static void *usart_main (void *arg);
static struct usart_stat usart2_stat;
static struct usart_stat usart3_stat;
int
usart_config (uint8_t dev_no, uint32_t config_bits)
{
struct USART *USARTx = get_usart_dev (dev_no);
uint8_t baud_spec = (config_bits & MASK_BAUD);
int i;
uint32_t cr1_config = (USART_CR1_UE | USART_CR1_RXNEIE
| USART_CR1_TE | USART_CR1_RE);
/* TXEIE will be enabled when putting char */
/* No CTSIE, PEIE, TCIE, IDLEIE, LBDIE */
if (USARTx == NULL)
return -1;
/* Disable USART before configure. */
USARTx->CR1 &= ~USART_CR1_UE;
if (((config_bits & MASK_CS) == CS7 && (config_bits & PARENB))
|| ((config_bits & MASK_CS) == CS8 && (config_bits & PARENB) == 0))
cr1_config &= ~USART_CR1_M;
else if ((config_bits & MASK_CS) == CS8)
cr1_config |= USART_CR1_M;
else
return -1;
if ((config_bits & PARENB) == 0)
cr1_config &= ~USART_CR1_PCE;
else
cr1_config |= USART_CR1_PCE;
if ((config_bits & PARODD) == 0)
cr1_config &= ~USART_CR1_PS;
else
cr1_config |= USART_CR1_PS;
if ((config_bits & MASK_STOP) == STOP0B5)
USARTx->CR2 = (0x1 << 12);
else if ((config_bits & MASK_STOP) == STOP1B)
USARTx->CR2 = (0x0 << 12);
else if ((config_bits & MASK_STOP) == STOP1B5)
USARTx->CR2 = (0x3 << 12);
else /* if ((config_bits & MASK_STOP) == STOP2B) */
USARTx->CR2 = (0x2 << 12);
for (i = 0; i < NUM_BAUD; i++)
if (brr_table[i].baud_spec == baud_spec)
break;
if (i >= NUM_BAUD)
return -1;
USARTx->BRR = brr_table[i].brr_value;
if ((config_bits & MASK_FLOW))
USARTx->CR3 = (1 << 9) | (1 << 8);
else
USARTx->CR3 = 0;
USARTx->CR1 = cr1_config;
return 0;
}
static int (*ss_notify_callback) (uint8_t dev_no, uint16_t notify_bits);
void
usart_init (uint16_t prio, uintptr_t stack_addr, size_t stack_size,
int (*cb) (uint8_t dev_no, uint16_t notify_bits))
{
ss_notify_callback = cb;
usart2_stat.dev_no = 2;
usart3_stat.dev_no = 3;
/* Enable USART2 and USART3 clocks, and strobe reset. */
RCC->APB1ENR |= ((1 << 18) | (1 << 17));
RCC->APB1RSTR = ((1 << 18) | (1 << 17));
RCC->APB1RSTR = 0;
usart_config (2, B115200 | CS8 | STOP1B);
usart_config (3, B115200 | CS8 | STOP1B);
chopstx_create (prio, stack_addr, stack_size, usart_main, NULL);
}
/*
* Ring buffer
*/
#define MAX_RB_BUF 1024
struct rb {
uint8_t *buf;
chopstx_mutex_t m;
chopstx_cond_t data_available;
chopstx_cond_t space_available;
uint32_t head :10;
uint32_t tail :10;
uint32_t size :10;
uint32_t full : 1;
uint32_t empty : 1;
};
/*
* Note: size = 1024 can still work, regardless of the limit of 10-bit.
*/
static void
rb_init (struct rb *rb, uint8_t *p, uint16_t size)
{
rb->buf = p;
rb->size = size;
chopstx_mutex_init (&rb->m);
chopstx_cond_init (&rb->data_available);
chopstx_cond_init (&rb->space_available);
rb->head = rb->tail = 0;
rb->full = 0;
rb->empty = 1;
}
static void
rb_add (struct rb *rb, uint8_t v)
{
rb->buf[rb->tail++] = v;
if (rb->tail == rb->size)
rb->tail = 0;
if (rb->tail == rb->head)
rb->full = 1;
rb->empty = 0;
}
static uint8_t
rb_del (struct rb *rb)
{
uint32_t v = rb->buf[rb->head++];
if (rb->head == rb->size)
rb->head = 0;
if (rb->head == rb->tail)
rb->empty = 1;
rb->full = 0;
return v;
}
/*
* Application: consumer
* Hardware: generator
*/
static int
rb_ll_put (struct rb *rb, uint8_t v)
{
int r;
chopstx_mutex_lock (&rb->m);
if (rb->full)
r = -1;
else
{
r = 0;
rb_add (rb, v);
chopstx_cond_signal (&rb->data_available);
}
chopstx_mutex_unlock (&rb->m);
return r;
}
/*
* Application: generator
* Hardware: consumer
*/
static int
rb_ll_get (struct rb *rb)
{
int r;
chopstx_mutex_lock (&rb->m);
if (rb->empty)
r = -1;
else
{
r = rb_del (rb);
chopstx_cond_signal (&rb->space_available);
}
chopstx_mutex_unlock (&rb->m);
return r;
}
static void
rb_ll_flush (struct rb *rb)
{
chopstx_mutex_lock (&rb->m);
while (!rb->empty)
rb_del (rb);
chopstx_cond_signal (&rb->space_available);
chopstx_mutex_unlock (&rb->m);
}
/*
* Application: consumer
* Hardware: generator
*/
static int
rb_read (struct rb *rb, uint8_t *buf, uint16_t buflen)
{
int i = 0;
chopstx_mutex_lock (&rb->m);
while (rb->empty)
chopstx_cond_wait (&rb->data_available, &rb->m);
while (i < buflen)
{
buf[i++] = rb_del (rb);
if (rb->empty)
break;
}
chopstx_cond_signal (&rb->space_available);
chopstx_mutex_unlock (&rb->m);
return i;
}
/*
* Application: generator
* Hardware: consumer
*/
static void
rb_write (struct rb *rb, uint8_t *buf, uint16_t buflen)
{
int i = 0;
chopstx_mutex_lock (&rb->m);
do
{
while (rb->full)
chopstx_cond_wait (&rb->space_available, &rb->m);
while (i < buflen)
{
rb_add (rb, buf[i++]);
if (rb->full)
{
chopstx_cond_signal (&rb->data_available);
break;
}
}
}
while (i < buflen);
if (i)
chopstx_cond_signal (&rb->data_available);
chopstx_mutex_unlock (&rb->m);
}
static int
rb_empty_check (void *arg)
{
struct rb *rb = arg;
return rb->empty == 0;
}
static void
rb_get_prepare_poll (struct rb *rb, chopstx_poll_cond_t *poll_desc)
{
poll_desc->type = CHOPSTX_POLL_COND;
poll_desc->ready = 0;
poll_desc->cond = &rb->data_available;
poll_desc->mutex = &rb->m;
poll_desc->check = rb_empty_check;
poll_desc->arg = rb;
}
#define INTR_REQ_USART2 38
#define INTR_REQ_USART3 39
static uint8_t buf_usart2_rb_a2h[256];
static uint8_t buf_usart2_rb_h2a[512];
static uint8_t buf_usart3_rb_a2h[256];
static uint8_t buf_usart3_rb_h2a[512];
static struct chx_intr usart2_intr;
static struct chx_intr usart3_intr;
static struct rb usart2_rb_a2h;
static struct rb usart2_rb_h2a;
static struct rb usart3_rb_a2h;
static struct rb usart3_rb_h2a;
static chopstx_poll_cond_t usart2_app_write_event;
static chopstx_poll_cond_t usart3_app_write_event;
static struct chx_poll_head *usart_poll[4];
/* Global variables so that it can be easier to debug. */
static int usart2_tx_ready;
static int usart3_tx_ready;
#define UART_STATE_BITMAP_RX_CARRIER (1 << 0)
#define UART_STATE_BITMAP_TX_CARRIER (1 << 1)
#define UART_STATE_BITMAP_BREAK (1 << 2)
#define UART_STATE_BITMAP_RINGSIGNAL (1 << 3)
#define UART_STATE_BITMAP_FRAMING (1 << 4)
#define UART_STATE_BITMAP_PARITY (1 << 5)
#define UART_STATE_BITMAP_OVERRUN (1 << 6)
static int
handle_intr (struct USART *USARTx, struct rb *rb2a, struct usart_stat *stat)
{
int tx_ready = 0;
uint32_t r = USARTx->SR;
int notify_bits = 0;
if ((r & USART_SR_TXE))
{
tx_ready = 1;
USARTx->CR1 &= ~USART_CR1_TXEIE;
}
if ((r & USART_SR_RXNE))
{
uint32_t data = USARTx->DR;
/* DR register should be accessed even if data is not used.
* Its read-access has side effect of clearing error flags.
*/
asm volatile ("" : : "r" (data) : "memory");
if ((r & USART_SR_NE))
stat->err_rx_noise++;
else if ((r & USART_SR_FE))
{
/* NOTE: Noway to distinguish framing error and break */
stat->rx_break++;
notify_bits |= UART_STATE_BITMAP_BREAK;
}
else if ((r & USART_SR_PE))
{
stat->err_rx_parity++;
notify_bits |= UART_STATE_BITMAP_PARITY;
}
else
{
if ((r & USART_SR_ORE))
{
stat->err_rx_overrun++;
notify_bits |= UART_STATE_BITMAP_OVERRUN;
}
/* XXX: if CS is 7-bit, mask it, or else parity bit in upper layer */
if (rb_ll_put (rb2a, (data & 0xff)) < 0)
stat->err_rx_overflow++;
else
stat->rx++;
}
}
else if ((r & USART_SR_ORE))
{ /* Clear ORE */
uint32_t data = USARTx->DR;
asm volatile ("" : : "r" (data) : "memory");
stat->err_rx_overrun++;
notify_bits |= UART_STATE_BITMAP_OVERRUN;
}
if (notify_bits)
{
if ((*ss_notify_callback) (stat->dev_no, notify_bits))
stat->err_notify_overflow++;
}
return tx_ready;
}
static int
handle_tx_ready (struct USART *USARTx, struct rb *rb2h,
struct usart_stat *stat)
{
int tx_ready = 1;
int c = rb_ll_get (rb2h);
if (c >= 0)
{
uint32_t r;
USARTx->DR = (c & 0xff);
stat->tx++;
r = USARTx->SR;
if ((r & USART_SR_TXE) == 0)
{
tx_ready = 0;
USARTx->CR1 |= USART_CR1_TXEIE;
}
}
return tx_ready;
}
static void *
usart_main (void *arg)
{
(void)arg;
usart2_tx_ready = 1;
usart3_tx_ready = 1;
chopstx_claim_irq (&usart2_intr, INTR_REQ_USART2);
chopstx_claim_irq (&usart3_intr, INTR_REQ_USART3);
rb_init (&usart2_rb_a2h, buf_usart2_rb_a2h, sizeof buf_usart2_rb_a2h);
rb_init (&usart2_rb_h2a, buf_usart2_rb_h2a, sizeof buf_usart2_rb_h2a);
rb_init (&usart3_rb_a2h, buf_usart3_rb_a2h, sizeof buf_usart3_rb_a2h);
rb_init (&usart3_rb_h2a, buf_usart3_rb_h2a, sizeof buf_usart3_rb_h2a);
rb_get_prepare_poll (&usart2_rb_a2h, &usart2_app_write_event);
rb_get_prepare_poll (&usart3_rb_a2h, &usart3_app_write_event);
while (1)
{
int n = 0;
usart_poll[n++] = (struct chx_poll_head *)&usart2_intr;
usart_poll[n++] = (struct chx_poll_head *)&usart3_intr;
if (usart2_tx_ready)
usart_poll[n++] = (struct chx_poll_head *)&usart2_app_write_event;
else
usart2_app_write_event.ready = 0;
if (usart3_tx_ready)
usart_poll[n++] = (struct chx_poll_head *)&usart3_app_write_event;
else
usart3_app_write_event.ready = 0;
chopstx_poll (NULL, n, usart_poll);
if (usart2_intr.ready)
usart2_tx_ready = handle_intr (USART2, &usart2_rb_h2a, &usart2_stat);
if (usart3_intr.ready)
usart3_tx_ready = handle_intr (USART3, &usart3_rb_h2a, &usart3_stat);
if (usart2_tx_ready && usart2_app_write_event.ready)
usart2_tx_ready = handle_tx_ready (USART2,
&usart2_rb_a2h, &usart2_stat);
if (usart3_tx_ready && usart3_app_write_event.ready)
usart3_tx_ready = handle_tx_ready (USART3,
&usart3_rb_a2h, &usart3_stat);
}
return NULL;
}
int
usart_read (uint8_t dev_no, char *buf, uint16_t buflen)
{
struct rb *rb;
if (dev_no == 2)
rb = &usart2_rb_h2a;
else if (dev_no == 3)
rb = &usart3_rb_h2a;
else
return -1;
if (buf == NULL && buflen == 0)
{
rb_ll_flush (rb);
return 0;
}
else
return rb_read (rb, (uint8_t *)buf, buflen);
}
int
usart_write (uint8_t dev_no, char *buf, uint16_t buflen)
{
struct rb *rb;
if (dev_no == 2)
rb = &usart2_rb_a2h;
else if (dev_no == 3)
rb = &usart3_rb_a2h;
else
return -1;
if (buf == NULL && buflen == 0)
rb_ll_flush (rb);
else
rb_write (rb, (uint8_t *)buf, buflen);
return 0;
}
const struct usart_stat *
usart_stat (uint8_t dev_no)
{
if (dev_no == 2)
return &usart2_stat;
else if (dev_no == 3)
return &usart3_stat;
else
return NULL;
}
int
usart_send_break (uint8_t dev_no)
{
struct USART *USARTx = get_usart_dev (dev_no);
if (USARTx == NULL)
return -1;
if ((USARTx->CR1 & 0x01))
return 1; /* Busy sending break, which was requested before. */
USARTx->CR1 |= 0x01;
return 0;
}

66
contrib/usart.h Normal file
View File

@@ -0,0 +1,66 @@
#define B0 0 /* POSIX to hang up */
/* POSIX supports B75 to B300 */
#define B600 16
#define B1200 17
#define B2400 19
#define B9600 21
#define B19200 22
#define B57600 24
#define B115200 25
#define B230400 26
#define B460800 27
#define B921600 28
#define MASK_BAUD 0x3f
/* POSIX supports 5, 6. USB suppots 16 */
#define CS7 (2 << 6)
#define CS8 (3 << 6)
#define MASK_CS (0x7 << 6)
#define STOP0B5 (0 << 9) /* USART Hardware only */
#define STOP1B (1 << 9) /* USB, POSIX */
#define STOP1B5 (2 << 9) /* USB */
#define STOP2B (3 << 9) /* USB, POSIX */
#define MASK_STOP (0x3 << 9)
#define PARENB (1 << 11)
#define PARODD (2 << 11)
#define MASK_PAR (0x7 << 11)
/* USB 0: none, 1: odd, 2: even, 3: mark, 4: space */
#define CRTSCTS (1 << 14)
#define MASK_FLOW (0x1 << 14)
/*
BAUD_BITS 6
CS_BITS 3
STOP_BITS 2
PAR_BITS 3
*/
/* USB: SET_CONTROL_LINE_STATE
DTR RTS */
/* USB: SERIAL_STATE
DSR DCD RI */
struct usart_stat {
uint8_t dev_no;
uint32_t tx;
uint32_t rx;
uint32_t rx_break;
uint32_t err_notify_overflow;
uint32_t err_rx_overflow; /* software side */
uint32_t err_rx_overrun; /* hardware side */
uint32_t err_rx_noise;
uint32_t err_rx_parity;
};
void usart_init (uint16_t prio, uintptr_t stack_addr, size_t stack_size,
int (*ss_notify_callback) (uint8_t dev_no, uint16_t notify_bits));
int usart_config (uint8_t dev_no, uint32_t config_bits);
int usart_read (uint8_t dev_no, char *buf, uint16_t buflen);
int usart_write (uint8_t dev_no, char *buf, uint16_t buflen);
const struct usart_stat *usart_stat (uint8_t dev_no);
int usart_send_break (uint8_t dev_no);

View File

@@ -9,7 +9,7 @@ stop further execution of code. It never returns.
@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})
@deftypefun {chopstx_t} {chopstx_create} (uint32_t @var{flags_and_prio}, uintptr_t @var{stack_addr}, size_t @var{stack_size}, voidfunc @var{thread_entry}, void * @var{arg})
@var{flags_and_prio}: Flags and priority
@var{stack_addr}: Stack address
@@ -176,7 +176,7 @@ Returns old state which is 0 when it was enabled.
@subheading chopstx_poll
@anchor{chopstx_poll}
@deftypefun {int} {chopstx_poll} (uint32_t * @var{usec_p}, int @var{n}, struct chx_poll_head * [] @var{pd_array})
@deftypefun {int} {chopstx_poll} (uint32_t * @var{usec_p}, int @var{n}, struct chx_poll_head *const [] @var{pd_array})
@var{usec_p}: Pointer to usec for timeout. Forever if NULL.
@var{n}: Number of poll descriptors
@@ -201,3 +201,23 @@ which starts its execution with priority of CHX_PRIO_MAIN_INIT, and
let it change its priority after initialization of other threads.
@end deftypefun
@subheading chx_sleep_mode
@anchor{chx_sleep_mode}
@deftypefun {extern void} {chx_sleep_mode} (int @var{enable_sleep})
@var{enable_sleep}: Enable sleep on idle or not
If @var{enable_sleep} is > 0, allow sleep for the idle thread.
Behavior of @var{enable_sleep} >= 1 depends on MCU.
For STM32F0, 1 for Sleep (CPU clock OFF only), 2 for Stop (Wakeup
by EXTI, voltage regulator on), 3 for Stop (Wakeup by EXTI, voltage
regulator low-power), 4 for Standby (Wakeup by RESET, voltage
regulator off).
For STM32F103, 1 for normal sleep, and 2 for sleep with lower 8MHz
clock.
Return previous value of @var{enable_sleep}.
@end deftypefun

View File

@@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename chopstx.info
@set VERSION 1.4
@set VERSION 1.7
@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, 2015, 2016 Flying Stone Technology @*
Copyright @copyright{} 2013, 2015, 2016, 2017 Flying Stone Technology @*
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -59,6 +59,9 @@ section entitled ``Copying''.
@menu
* Introduction:: What is Chopstx.
* Threads and only Threads:: Threads and only Threads.
* Poll or Pole:: Poll or Pole.
* Note (Use of sleep mode):: Use it carefully.
* API:: API.
Appendix
@@ -83,16 +86,76 @@ Indexes
@node Introduction
@chapter Introduction
Chopstx is an RT thread library for ARM Cortex-M0, Cortex-M0plus and
Cortex-M3. Specifically, it is used for STM32F030, MKL27Z and
STM32F103.
Chopstx is an RT thread library for ARM Cortex-M0, Cortex-M0plus,
Cortex-M3 and GNU/Linux emulation. Specifically, it is used for
STM32F030, MKL27Z, STM32F103 and as a command on GNU/Linux.
While most RTOSes come with many features, drivers, and stacks,
Chopstx just offers a RT thread library.
Chopstx just offers an RT thread library.
With Chopstx, interrupt handling is also done by a thread. This
enables coherent code for ease of maintenance.
While threads are important, we don't need more threads than
necessary. Chopstx provides a feature of poll, so that we can
minimize use of threads.
@node Threads and only Threads
@chapter Threads and only Threads
Chopstx doesn't use the feature of (prioritized) nested vector
interrupt mechanism at all. All interrupts are equally handled by a
single entry of chx_handle_intr which just wakes up corresponding
thread. This is the feature of Chopstx.
Nested vector interrupt machanism would be useful for interrupt-driven
programming style for specific application targets, or, some other
programing style like the one with spl of Unix. Some engineers
(especially, hardware side) still seem to believe that it is a good
feature to have. But from the view point of programming and
maintenance of software, this is one of the most difficult part with
little benefit, if any.
With traditional interrupt handling, a demarcation of what should be
done by interrupt handler, bottom half, and thead is crucial for
applications' performance. And because the demarcation should be done
at an early stage of an application development, it has a tendency,
many parts are getting demanding higher priority. Amount of code for
higher priority interrupt hander is getting bigger and bigger, while
losing performance.
On the other hand, ``Threads (and only Threads)'' programming style
gives us best flexibility and it can make an application more
predictable, deterministic and easy to maintain.
There are some applications, like square wave generator, which are not
suited to this programming style; Another programming style can
support more performance (frequency). In general, such an example is
best suited by hardware (not software).
@node Poll or Pole
@chapter Poll or Pole
Chopstx provides the @code{chopstx_poll} function to wait on multiple events.
Using @code{chopstx_poll}, we can write an application by event-driven
programming style, with minimum number of threads, avoiding
complicated dependency between threads.
@node Note (Use of sleep mode)
@chapter Note (Use of sleep mode)
Calling the chopstx_conf_idle function (> 0) to allow the idle thread
going to sleep. MCU will be in sleep mode when no threads are
running. By setting relevant bits of system registers, MCU will be
able to be into stop or stand-by mode, which is MCU dependent.
If you use this sleep feature, please consider and implement your
program carefully. Enabling sleep, it may result a bricked board; A
board with no RESET pin cannot be debugged by JTAG/SWD.
@node API
@chapter API

35
entry.c
View File

@@ -205,23 +205,23 @@ handler vector_table[] __attribute__ ((section(".startup.vectors"))) = {
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 */,
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 */,
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 */,
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 /* USB LP */, chx_handle_intr /* CAN RX1 */,
chx_handle_intr /* CAN SCE */, chx_handle_intr /* EXT9_5 */,
/* 0xa0 */
/* ... and more. TIMx, I2C, SPI, USART... */
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 */
@@ -229,15 +229,16 @@ handler vector_table[] __attribute__ ((section(".startup.vectors"))) = {
/* 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,
/* 0xe0 */
chx_handle_intr /* EXT15_10 */, chx_handle_intr /* RTCAlarm */,
chx_handle_intr /* USBWakeup */, chx_handle_intr,
#endif
#if !defined(STM32F10X_MD)
/* High-density chips have more; RTCAlarm, USBWakeup, ... , DMA2_Channel4_5 */
/* High-density chips have more; ... 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,
#endif
};
#endif

View File

@@ -6,12 +6,12 @@ PROJECT = sample
CHOPSTX = ..
LDSCRIPT=
CSRC = sample.c usb-cdc.c
CSRC = sample.c usb-cdc.c command.c
CHIP=gnu-linux
# USE_SYS = yes
USE_SYS =
USE_SYS = yes
USE_USB = yes
USE_ADC = yes
EMULATION=yes
###################################
@@ -22,7 +22,7 @@ OBJCOPY = $(CROSS)objcopy
MCU = none
CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DGNU_LINUX_EMULATION
DEFS = -DGNU_LINUX_EMULATION -DUSE_SYS_BOARD_ID
OPT = -g # -O3 -Os
LIBS = -lpthread
@@ -34,3 +34,10 @@ board.h:
@exit 1
distclean: clean
build/flash.data: Makefile
@echo 'Generating 8192-byte flash.data'
@/bin/echo -n -e '\xff\xff\xff\xff\xff\xff\xff\xff' >$@
@for i in $(shell seq 1023); do /bin/echo -n -e '\xff\xff\xff\xff\xff\xff\xff\xff' >>$@; done

View File

@@ -1,3 +1,9 @@
(0) Build and generate initial flash data
$ make
$ make build/flash.data
(1) preparation as root
Don't run ModemManager

View File

@@ -0,0 +1,579 @@
#include <string.h>
#include <stdint.h>
#include <chopstx.h>
#include "tty.h"
#include "config.h"
#ifdef ADC_SUPPORT
#include "adc.h"
static int adc_initialized = 0;
#endif
#include "board.h"
#include "sys.h"
struct command_table
{
const char *name;
void (*handler) (struct tty *tty, const char *line);
};
/*
* Put a line (or lines) to TTY.
* LINE should be terminated with newline.
*/
static void
put_line (struct tty *tty, const char *line)
{
tty_send (tty, line, strlen (line));
}
static const char *help_string =
"mdb ADDR [COUNT]; memory display byte\r\n"
"mwh ADDR VALUE [COUNT]; memory write halfword\r\n"
"fes ADDR [COUNT]; flash erase sector\r\n"
"fwh ADDR VALUE [COUNT]; flash write halfword\r\n"
#ifdef CRC32_SUPPORT
"crc32 string; CRC32 calc string\r\n"
#endif
#ifdef ADC_SUPPORT
"adc; get 256-byte from ADC\r\n"
#endif
"sysinfo; system information\r\n"
"help\r\n";
static char hexchar (uint8_t x)
{
x &= 0x0f;
if (x <= 0x09)
return '0' + x;
else if (x <= 0x0f)
return 'a' + x - 10;
else
return '?';
}
#ifdef TOUCH_SUPPORT
static char *
compose_decimal (char *s, int value)
{
uint32_t v;
int col = 1000000000;
int d;
int digit_output = 0;
if (value < 0)
{
*s++ = '-';
v = 1 + ~((uint32_t)value);
}
else
v = (uint32_t)value;
while (col >= 10)
{
if (v >= (uint32_t)col)
{
d = v / col;
v = v - d * col;
*s++ = d + '0';
digit_output = 1;
}
else if (digit_output)
*s++ = '0';
col = col / 10;
}
*s++ = v + '0';
return s;
}
#endif
char *
compose_hex_ptr (char *s, uintptr_t v)
{
s[0] = hexchar (v >> 60);
s[1] = hexchar (v >> 56);
s[2] = hexchar (v >> 52);
s[3] = hexchar (v >> 48);
s[4] = hexchar (v >> 44);
s[5] = hexchar (v >> 40);
s[6] = hexchar (v >> 36);
s[7] = hexchar (v >> 32);
s[8] = hexchar (v >> 28);
s[9] = hexchar (v >> 24);
s[10] = hexchar (v >> 20);
s[11] = hexchar (v >> 16);
s[12] = hexchar (v >> 12);
s[13] = hexchar (v >> 8);
s[14] = hexchar (v >> 4);
s[15] = hexchar (v);
return s+16;
}
static char *
compose_hex (char *s, uint32_t v)
{
s[0] = hexchar (v >> 28);
s[1] = hexchar (v >> 24);
s[2] = hexchar (v >> 20);
s[3] = hexchar (v >> 16);
s[4] = hexchar (v >> 12);
s[5] = hexchar (v >> 8);
s[6] = hexchar (v >> 4);
s[7] = hexchar (v);
return s+8;
}
static char *
compose_hex_byte (char *s, uint8_t v)
{
s[0] = hexchar (v >> 4);
s[1] = hexchar (v);
return s+2;
}
static const char *
get_hex (struct tty *tty, const char *s, uintptr_t *v_p)
{
uintptr_t v = 0;
char c;
if (s[0] == '0' && s[1] == 'x')
s = s + 2;
while (1)
{
c = *s++;
if (c == 0)
{
s--;
break;
}
if (c == ' ')
break;
v = (v << 4);
if (c >= '0' && c <= '9')
v += (c - '0');
else if (c >= 'a' && c <= 'f')
v += (c - 'a') + 10;
else if (c >= 'A' && c <= 'F')
v += (c - 'A') + 10;
else
{
put_line (tty, "hex error\r\n");
return NULL;
}
}
*v_p = v;
return s;
}
#ifdef TOUCH_SUPPORT
#define TOUCH_VALUE_HIGH 100
#define TOUCH_VALUE_LOW 50
static void
cmd_button (struct tty *tty, const char *line)
{
int i = 0;
extern uint16_t touch_get (void);
uint16_t v0 = 0;
int touched = 0;
(void)line;
put_line (tty, "Please touch the bear.\r\n");
while (i < 16)
{
uint16_t v = touch_get ();
v0 = (v0 * 2 + v)/3;
if (touched == 0 && v0 > TOUCH_VALUE_HIGH)
{
tty_send (tty, "!", 1);
touched = 1;
}
else if (touched == 1 && v0 < TOUCH_VALUE_LOW)
{
tty_send (tty, ".", 1);
touched = 0;
i++;
}
chopstx_usec_wait (10*1000);
}
tty_send (tty, "\r\n", 2);
}
static void
cmd_touch (struct tty *tty, const char *line)
{
int i;
extern uint16_t touch_get (void);
(void)line;
put_line (tty, "Please touch the bear.\r\n");
for (i = 0; i < 20; i++)
{
uint16_t v;
char output[8];
char *s;
chopstx_usec_wait (1000*1000);
v = touch_get ();
s = compose_decimal (output, v);
*s++ = '\r';
*s++ = '\n';
tty_send (tty, output, s - output);
}
}
#endif
static void
cmd_mdb (struct tty *tty, const char *line)
{
int i;
uintptr_t addr = 0;
int count = 0;
char c;
const char *s = line;
s = get_hex (tty, s, &addr);
addr &= ~3;
if (s == NULL)
return;
if (*s == 0)
count = 1;
else
{
while (1)
{
c = *s++;
if (c == 0 || c == ' ')
break;
count = count * 10;
if (c >= '0' && c <= '9')
count += c - '0';
else
{
put_line (tty, "mdb error\r\n");
return;
}
}
}
i = 0;
while (i < count)
{
uint8_t v;
char output[68];
char *s;
s = compose_hex_ptr (output, addr);
*s++ = ':';
*s++ = ' ';
while (1)
{
v = *(uint8_t *)addr;
s = compose_hex_byte (s, v);
i++;
addr += 1;
if (i >= count || (i % 16) == 0)
break;
*s++ = ' ';
}
*s++ = '\r';
*s++ = '\n';
tty_send (tty, output, s - output);
}
}
static void
cmd_mwh (struct tty *tty, const char *line)
{
(void)tty;
(void)line;
put_line (tty, "mwh not yet supported\r\n");
}
static void
cmd_fes (struct tty *tty, const char *line)
{
int i;
uintptr_t addr = 0;
int count = 0;
char c;
const char *s = line;
s = get_hex (tty, s, &addr);
if (s == NULL)
return;
if (*s == 0)
count = 1;
else
{
while (1)
{
c = *s++;
if (c == 0 || c == ' ')
break;
count = count * 10;
if (c >= '0' && c <= '9')
count += c - '0';
else
{
put_line (tty, "fww error\r\n");
return;
}
}
}
for (i = 0; i < count; i++)
{
flash_erase_page (addr);
addr += 1024;
}
}
static void
cmd_fwh (struct tty *tty, const char *line)
{
int i;
uintptr_t addr = 0;
uintptr_t d;
uint16_t value = 0;
int count = 0;
char c;
const char *s = line;
s = get_hex (tty, s, &addr);
if (s == NULL)
return;
if (*s == 0)
return;
s = get_hex (tty, s, &d);
value = (uint16_t)d;
if (s == NULL)
return;
if (*s == 0)
count = 1;
else
{
while (1)
{
c = *s++;
if (c == 0 || c == ' ')
break;
count = count * 10;
if (c >= '0' && c <= '9')
count += c - '0';
else
{
put_line (tty, "fww error\r\n");
return;
}
}
}
for (i = 0; i < count; i++)
{
flash_program_halfword (addr, value);
addr += 4;
}
}
#ifdef CRC32_SUPPORT
static unsigned int crc_value;
static void
cmd_crc32 (struct tty *tty, const char *line)
{
uint32_t v;
char string[10];
char *s;
crc32_init (&crc_value);
while (*line)
crc32_u8 (&crc_value, *line++);
v = crc_value ^ 0xffffffff;
s = compose_hex (string, v);
*s++ = '\r';
*s++ = '\n';
tty_send (tty, string, sizeof (string));
}
#endif
#ifdef ADC_SUPPORT
static void
cmd_adc (struct tty *tty, const char *line)
{
int i;
char output[73];
char *s;
(void)line;
if (!adc_initialized)
{
if (adc_init ())
{
put_line (tty, "adc_init error\r\n");
return;
}
else
{
adc_start ();
adc_initialized = 1;
}
}
adc_start_conversion (0, 64);
adc_wait_completion ();
i = 0;
s = output;
while (1)
{
s = compose_hex (s, adc_buf[i]);
i++;
if ((i % 8))
*s++ = ' ';
else
{
*s++ = '\r';
*s++ = '\n';
tty_send (tty, output, s - output);
s = output;
if (i >= 64)
break;
}
}
}
#endif
static void
cmd_sysinfo (struct tty *tty, const char *line)
{
char output[73];
char *s;
int i;
(void)line;
memcpy (output, "SYS version: ", 13);
s = output + 13;
*s++ = sys_version[2];
*s++ = sys_version[4];
*s++ = sys_version[6];
*s++ = '\r';
*s++ = '\n';
tty_send (tty, output, s - output);
memcpy (output, "Board ID: ", 10);
s = output + 10;
s = compose_hex (s, sys_board_id);
*s++ = '\r';
*s++ = '\n';
tty_send (tty, output, s - output);
memcpy (output, "Board name: ", 12);
s = output + 12;
for (i = 0; i < (int)sizeof (output) - 2; i ++)
if ((*s = sys_board_name[i]) == 0)
break;
else
s++;
*s++ = '\r';
*s++ = '\n';
tty_send (tty, output, s - output);
}
static void
cmd_help (struct tty *tty, const char *line)
{
(void)line;
put_line (tty, help_string);
}
struct command_table command_table[] = {
#ifdef TOUCH_SUPPORT
{ "button", cmd_button },
{ "touch", cmd_touch },
#endif
{ "mdb", cmd_mdb },
{ "mwh", cmd_mwh },
{ "fes", cmd_fes },
{ "fwh", cmd_fwh },
#ifdef CRC32_SUPPORT
{ "crc32", cmd_crc32 },
#endif
#ifdef ADC_SUPPORT
{ "adc", cmd_adc },
#endif
{ "sysinfo", cmd_sysinfo },
{ "help", cmd_help },
};
#define N_CMDS (int)(sizeof (command_table) / sizeof (struct command_table))
/*
* Dispatch a command parsing LINE.
* Line is NULL terminated with no newline.
*/
void
cmd_dispatch (struct tty *tty, const char *line)
{
int i;
const char *p;
unsigned int n = 0;
p = line;
while (*p)
{
if (*p++ == ' ')
break;
n++;
}
for (i = 0; i < N_CMDS; i++)
if (n == strlen (command_table[i].name)
&& strncmp ((const char *)line, command_table[i].name, n) == 0)
break;
if (i != N_CMDS)
(*command_table[i].handler) (tty, p);
else
{
char crlf[] = { '\r', '\n' };
put_line (tty, "No such command: ");
tty_send (tty, line, n);
tty_send (tty, crlf, sizeof (crlf));
}
}

View File

@@ -0,0 +1,2 @@
void cmd_dispatch (struct tty *tty, const char *line);
char * compose_hex_ptr (char *s, uintptr_t v);

View File

@@ -0,0 +1,2 @@
#undef CRC32_SUPPORT
#define ADC_SUPPORT

View File

@@ -5,33 +5,15 @@
#include <chopstx.h>
#include "sys.h"
#include "usb_lld.h"
#include "tty.h"
#include "command.h"
#include <unistd.h>
#include <stdio.h>
static void
set_led (int on)
{
#if 0
/* For debugging, no output of LED. */
#if 1
if (on)
write (1, "********\x08\x08\x08\x08\x08\x08\x08\x08", 16);
else
write (1, " \x08\x08\x08\x08\x08\x08\x08\x08", 16);
#else
if (on)
puts ("!");
else
puts ("");
#endif
#else
(void)on;
#endif
}
static chopstx_mutex_t mtx;
static chopstx_cond_t cnd0;
static chopstx_cond_t cnd1;
@@ -114,9 +96,10 @@ main (int argc, const char *argv[])
{
struct tty *tty;
uint8_t count;
uintptr_t addr;
(void)argc;
(void)argv;
if (argc >= 2 && !strncmp (argv[1], "--debug=", 8))
debug = strtol (&argv[1][8], NULL, 10);
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0);
@@ -134,6 +117,9 @@ main (int argc, const char *argv[])
chopstx_cond_signal (&cnd1);
chopstx_mutex_unlock (&mtx);
addr = flash_init ("flash.data");
flash_unlock ();
u = 1;
tty = tty_open ();
@@ -145,6 +131,7 @@ main (int argc, const char *argv[])
{
char s[LINEBUFSIZE];
connection_loop:
u = 1;
tty_wait_connection (tty);
@@ -157,39 +144,52 @@ main (int argc, const char *argv[])
memcpy (s, "xx: Hello, World with Chopstx!\r\n", 32);
s[0] = hexchar (count >> 4);
s[1] = hexchar (count & 0x0f);
count++;
puts("send hello");
if (tty_send (tty, s, 32) < 0)
continue;
s[0] = hexchar (count >> 4);
s[1] = hexchar (count & 0x0f);
s[2] = ':';
s[3] = ' ';
compose_hex_ptr (s+4, addr);
s[20] = '\r';
s[21] = '\n';
count++;
if (tty_send (tty, s, 22) < 0)
continue;
while (1)
{
int size;
uint32_t usec;
puts("recv msg");
usec = 3000000; /* 3.0 seconds */
size = tty_recv (tty, s + 4, &usec);
if (size < 0)
/* Prompt */
if (tty_send (tty, "> ", 2) < 0)
break;
if (size)
usec = 3000000; /* 3.0 seconds */
while (1)
{
size--;
int size = tty_recv (tty, s, &usec);
u ^= 1;
puts("send msg");
s[0] = hexchar (size >> 4);
s[1] = hexchar (size & 0x0f);
s[2] = ':';
s[3] = ' ';
s[size + 4] = '\r';
s[size + 5] = '\n';
if (tty_send (tty, s, size + 6) < 0)
if (size < 0)
goto connection_loop;
if (size == 1)
/* Do nothing but prompt again. */
break;
else if (size)
{
/* Newline into NUL */
s[size - 1] = 0;
cmd_dispatch (tty, (char *)s);
break;
}
}
u ^= 1;
}
}

View File

@@ -244,7 +244,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = ATTACHED;
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -414,7 +414,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED;
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -427,7 +427,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -629,8 +629,6 @@ usb_rx_ready (uint8_t ep_num, uint16_t len)
static void *tty_main (void *arg);
#include <signal.h>
#define INTR_REQ_USB SIGUSR1
#define PRIO_TTY 4
static char __process3_stack_base__[4096];
@@ -647,7 +645,7 @@ tty_open (void)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = UNCONNECTED;
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -734,7 +732,7 @@ tty_main (void *arg)
* OK.
*/
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
continue;
@@ -790,7 +788,7 @@ tty_main (void *arg)
}
chopstx_mutex_lock (&t->mtx);
if (t->device_state == CONFIGURED && t->flag_connected
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
&& t->flag_send_ready)
{
uint8_t line[32];
@@ -814,7 +812,7 @@ void
tty_wait_configured (struct tty *t)
{
chopstx_mutex_lock (&t->mtx);
while (t->device_state != CONFIGURED)
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
chopstx_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx);
}

View File

@@ -61,14 +61,14 @@ blk (void *arg)
#define PRIO_PWM 3
#define PRIO_BLK 2
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
#define STACK_ADDR_PWM ((uint32_t)__process1_stack_base__)
#define STACK_SIZE_PWM ((uint32_t)__process1_stack_size__)
#define STACK_ADDR_BLK ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_BLK ((uint32_t)__process2_stack_size__)
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#include "stack-def.h"
#define STACK_ADDR_PWM ((uint32_t)process1_base)
#define STACK_SIZE_PWM (sizeof process1_base)
#define STACK_ADDR_BLK ((uint32_t)process2_base)
#define STACK_SIZE_BLK (sizeof process2_base)
static char hexchar (uint8_t x)

View File

@@ -1,11 +1,6 @@
/*
* ST32F103 memory setup.
*/
__main_stack_size__ = 0x0100; /* Idle+Exception handlers */
__process0_stack_size__ = 0x0400; /* Main program */
__process1_stack_size__ = 0x0200; /* first thread program */
__process2_stack_size__ = 0x0200; /* second thread program */
__process3_stack_size__ = 0x0200; /* third thread program */
MEMORY
{
@@ -78,34 +73,21 @@ SECTIONS
_etext = .;
_textdata = _etext;
.process_stack :
.process_stack (NOLOAD) :
{
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
*(.process_stack.3)
*(.process_stack.2)
*(.process_stack.1)
*(.process_stack.0)
. = 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 :
.main_stack (NOLOAD) :
{
. = ALIGN(8);
__main_stack_base__ = .;
. += __main_stack_size__;
*(.main_stack)
. = ALIGN(8);
__main_stack_end__ = .;
} > ram
.data :

24
example-cdc/stack-def.h Normal file
View File

@@ -0,0 +1,24 @@
#if defined(STACK_MAIN)
/* Idle+Exception handlers */
char __main_stack_end__[0] __attribute__ ((section(".main_stack")));
char main_base[0x0100] __attribute__ ((section(".main_stack")));
/* Main program */
char __process0_stack_end__[0] __attribute__ ((section(".process_stack.0")));
char process0_base[0x0400] __attribute__ ((section(".process_stack.0")));
#endif
/* First thread program */
#if defined(STACK_PROCESS_1)
char process1_base[0x0200] __attribute__ ((section(".process_stack.1")));
#endif
/* Second thread program */
#if defined(STACK_PROCESS_2)
char process2_base[0x0200] __attribute__ ((section(".process_stack.2")));
#endif
/* Third thread program */
#if defined(STACK_PROCESS_3)
char process3_base[0x0200] __attribute__ ((section(".process_stack.3")));
#endif

View File

@@ -248,7 +248,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = ATTACHED;
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -417,7 +417,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (i, 0);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED;
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -430,7 +430,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (i, 1);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -639,12 +639,12 @@ usb_rx_ready (uint8_t ep_num, uint16_t len)
static void *tty_main (void *arg);
#define INTR_REQ_USB 20
#define PRIO_TTY 4
extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
#define STACK_ADDR_TTY ((uint32_t)__process3_stack_base__)
#define STACK_SIZE_TTY ((uint32_t)__process3_stack_size__)
#define STACK_PROCESS_3
#include "stack-def.h"
#define STACK_ADDR_TTY ((uint32_t)process3_base)
#define STACK_SIZE_TTY (sizeof process3_base)
struct tty *
tty_open (void)
@@ -656,7 +656,7 @@ tty_open (void)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = UNCONNECTED;
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -743,7 +743,7 @@ tty_main (void *arg)
* OK.
*/
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
continue;
@@ -799,7 +799,7 @@ tty_main (void *arg)
}
chopstx_mutex_lock (&t->mtx);
if (t->device_state == CONFIGURED && t->flag_connected
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
&& t->flag_send_ready)
{
uint8_t line[32];
@@ -823,7 +823,7 @@ void
tty_wait_configured (struct tty *t)
{
chopstx_mutex_lock (&t->mtx);
while (t->device_state != CONFIGURED)
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
chopstx_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx);
}

View File

@@ -9,7 +9,7 @@ LDSCRIPT=
CSRC = main.c
CHIP=gnu-linux
USE_SYS =
USE_SYS = yes
USE_USB = yes
EMULATION=yes
# USE_ADC = yes

View File

@@ -11,7 +11,7 @@
static chopstx_mutex_t usb_mtx;
static chopstx_cond_t usb_cnd;
static uint32_t bDeviceState = UNCONNECTED; /* USB device status */
static uint32_t bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
extern void EP6_IN_Callback (uint16_t len);
extern void EP6_OUT_Callback (uint16_t len);
@@ -47,7 +47,7 @@ usb_device_reset (struct usb_dev *dev)
/* Notify upper layer. */
chopstx_mutex_lock (&usb_mtx);
bDeviceState = ATTACHED;
bDeviceState = USB_DEVICE_STATE_ATTACHED;
chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx);
}
@@ -95,7 +95,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&usb_mtx);
bDeviceState = CONFIGURED;
bDeviceState = USB_DEVICE_STATE_CONFIGURED;
chopstx_mutex_unlock (&usb_mtx);
}
else if (current_conf != dev->dev_req.value)
@@ -107,7 +107,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&usb_mtx);
bDeviceState = ADDRESSED;
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx);
}
@@ -164,7 +164,6 @@ static void usb_tx_done (uint8_t ep_num, uint16_t len);
static void usb_rx_ready (uint8_t ep_num, uint16_t len);
#define INTR_REQ_USB SIGUSR1
#define PRIO_USB 3
static void *
@@ -207,7 +206,7 @@ usb_main (void *arg)
case USB_EVENT_DEVICE_ADDRESSED:
chopstx_mutex_lock (&usb_mtx);
bDeviceState = ADDRESSED;
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx);
continue;
@@ -305,16 +304,16 @@ main (int argc, char **argv)
chopstx_mutex_init (&usb_mtx);
chopstx_cond_init (&usb_cnd);
bDeviceState = UNCONNECTED;
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
usb_main, NULL);
while (bDeviceState != CONFIGURED)
while (bDeviceState != USB_DEVICE_STATE_CONFIGURED)
chopstx_usec_wait (250*1000);
fraucheky_main ();
chopstx_cancel (usb_thd);
chopstx_join (usb_thd, NULL);
usb_lld_shutdown ();
bDeviceState = UNCONNECTED;
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
return 0;
}

View File

@@ -245,7 +245,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = ATTACHED;
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -409,7 +409,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED;
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -422,7 +422,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -626,7 +626,6 @@ usb_rx_ready (uint8_t ep_num, uint16_t len)
static void *tty_main (void *arg);
#define INTR_REQ_USB 24
#define PRIO_TTY 4
extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
@@ -643,7 +642,7 @@ tty_open (void)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = UNCONNECTED;
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -733,7 +732,7 @@ tty_main (void *arg)
* OK.
*/
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
continue;
@@ -789,7 +788,7 @@ tty_main (void *arg)
}
chopstx_mutex_lock (&t->mtx);
if (t->device_state == CONFIGURED && t->flag_connected
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
&& t->flag_send_ready)
{
uint8_t line[32];
@@ -813,7 +812,7 @@ void
tty_wait_configured (struct tty *t)
{
chopstx_mutex_lock (&t->mtx);
while (t->device_state != CONFIGURED)
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
chopstx_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx);
}

View File

@@ -7,6 +7,8 @@ LDSCRIPT= hacker-emblem.ld
CSRC = reset.c hh.c
CHIP=stm32f0
# Hacker Emblem and "Happy Hacking!" demonstration
# CSRC = reset.c hh.c
@@ -25,7 +27,7 @@ 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
-DFREE_STANDING -DMHZ=48
OPT = -O3 -Os -g
LIBS =

View File

@@ -7,7 +7,7 @@
static uint8_t main_finished;
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
@@ -163,17 +163,19 @@ button (void *arg)
return NULL;
}
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#include "stack-def.h"
#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__[];
#define STACK_ADDR_LED ((uint32_t)process1_base)
#define STACK_SIZE_LED (sizeof process1_base)
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__)
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__)
#define STACK_ADDR_BUTTON ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_BUTTON ((uint32_t)__process2_stack_size__)
#define STACK_ADDR_BUTTON ((uint32_t)process2_base)
#define STACK_SIZE_BUTTON (sizeof process2_base)
#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))
@@ -365,8 +367,6 @@ text_display (uint8_t kind)
}
static void setup_scr_sleepdeep (void);
int
main (int argc, const char *argv[])
{
@@ -378,6 +378,8 @@ main (int argc, const char *argv[])
(void)argc;
(void)argv;
chopstx_conf_idle (1);
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd1);
@@ -418,56 +420,6 @@ main (int argc, const char *argv[])
chopstx_join (button_thd, NULL);
chopstx_join (led_thd, NULL);
setup_scr_sleepdeep ();
for (;;)
asm volatile ("wfi" : : : "memory");
chopstx_conf_idle (4);
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 *)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

@@ -1,12 +1,6 @@
/*
* ST32F0 memory setup.
*/
__main_stack_size__ = 0x0100; /* Idle+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
@@ -61,34 +55,15 @@ SECTIONS
_etext = .;
_textdata = _etext;
.process_stack :
.stacks (NOLOAD) :
{
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
*(.main_stack)
*(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
. = 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 :

View File

@@ -7,7 +7,7 @@
static uint8_t main_finished;
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
@@ -166,14 +166,16 @@ button (void *arg)
#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__[];
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#include "stack-def.h"
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__)
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__)
#define STACK_ADDR_LED ((uint32_t)process1_base)
#define STACK_SIZE_LED (sizeof process1_base)
#define STACK_ADDR_BUTTON ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_BUTTON ((uint32_t)__process2_stack_size__)
#define STACK_ADDR_BUTTON ((uint32_t)process2_base)
#define STACK_SIZE_BUTTON (sizeof process2_base)
#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))
@@ -355,8 +357,6 @@ text_display (uint8_t kind)
}
static void setup_scr_sleepdeep (void);
int
main (int argc, const char *argv[])
{
@@ -366,6 +366,8 @@ main (int argc, const char *argv[])
(void)argc;
(void)argv;
chopstx_conf_idle (1);
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd1);
@@ -406,56 +408,6 @@ main (int argc, const char *argv[])
chopstx_join (button_thd, NULL);
chopstx_join (led_thd, NULL);
setup_scr_sleepdeep ();
for (;;)
asm volatile ("wfi" : : : "memory");
chopstx_conf_idle (4);
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 *)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

@@ -6,7 +6,7 @@
#include "board.h"
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
@@ -86,12 +86,16 @@ led_enable_column (uint8_t col)
}
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#define STACK_PROCESS_3
#include "stack-def.h"
#define PRIO_LED 3
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__)
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__)
#define STACK_ADDR_LED ((uint32_t)process1_base)
#define STACK_SIZE_LED (sizeof process1_base)
static void *
led (void *arg)
@@ -119,10 +123,9 @@ led (void *arg)
#define PRIO_SPK 4
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
#define STACK_ADDR_SPK ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_SPK ((uint32_t)__process2_stack_size__)
#define STACK_ADDR_SPK ((uint32_t)process2_base)
#define STACK_SIZE_SPK (sizeof process2_base)
static chopstx_mutex_t spk_mtx;
static chopstx_cond_t spk_cnd;
@@ -193,10 +196,9 @@ spk (void *arg)
#define PRIO_MUSIC 2
extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
#define STACK_ADDR_MUSIC ((uint32_t)__process3_stack_base__)
#define STACK_SIZE_MUSIC ((uint32_t)__process3_stack_size__)
#define STACK_ADDR_MUSIC ((uint32_t)process3_base)
#define STACK_SIZE_MUSIC (sizeof process3_base)
#define C 0
#define D 1

View File

@@ -0,0 +1,54 @@
#define MAIN_SIZE 0x0080 /* Idle+Exception handlers */
#define SIZE_0 0x0100 /* Main program */
#define SIZE_1 0x0100 /* first thread program */
#define SIZE_2 0x0100 /* second thread program */
#define SIZE_3 0x0100 /* third thread program */
#if defined(STACK_MAIN)
/*
* The terminology of "main" is confusing in ARM architecture.
* Here, "main_base" is for exception handlers.
*/
/* Idle+Exception handlers */
char __main_stack_end__[0] __attribute__ ((section(".main_stack")));
char main_base[MAIN_SIZE] __attribute__ ((section(".main_stack")));
/* Main program */
char __process0_stack_end__[0] __attribute__ ((section(".process_stack.0")));
char process0_base[SIZE_0] __attribute__ ((section(".process_stack.0")));
#endif
/* First thread program */
#if defined(STACK_PROCESS_1)
char process1_base[SIZE_1] __attribute__ ((section(".process_stack.1")));
#endif
/* Second thread program */
#if defined(STACK_PROCESS_2)
char process2_base[SIZE_2] __attribute__ ((section(".process_stack.2")));
#endif
/* Third thread program */
#if defined(STACK_PROCESS_3)
char process3_base[SIZE_3] __attribute__ ((section(".process_stack.3")));
#endif
/* Fourth thread program */
#if defined(STACK_PROCESS_4)
char process4_base[SIZE_4] __attribute__ ((section(".process_stack.4")));
#endif
/* Fifth thread program */
#if defined(STACK_PROCESS_5)
char process5_base[SIZE_5] __attribute__ ((section(".process_stack.5")));
#endif
/* Sixth thread program */
#if defined(STACK_PROCESS_6)
char process6_base[SIZE_6] __attribute__ ((section(".process_stack.6")));
#endif
/* Seventh thread program */
#if defined(STACK_PROCESS_7)
char process7_base[SIZE_7] __attribute__ ((section(".process_stack.7")));
#endif

View File

@@ -72,14 +72,17 @@ blk (void *arg)
#define PRIO_BLK 2
#endif
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#include "stack-def.h"
#define STACK_ADDR_PWM ((uint32_t)__process1_stack_base__)
#define STACK_SIZE_PWM ((uint32_t)__process1_stack_size__)
#define STACK_ADDR_BLK ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_BLK ((uint32_t)__process2_stack_size__)
#define STACK_ADDR_PWM ((uint32_t)process1_base)
#define STACK_SIZE_PWM (sizeof process1_base)
#define STACK_ADDR_BLK ((uint32_t)process2_base)
#define STACK_SIZE_BLK (sizeof process2_base)
int

View File

@@ -1,12 +1,6 @@
/*
* ST32F0 memory setup.
*/
__main_stack_size__ = 0x0100; /* Idle+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
@@ -87,34 +81,15 @@ SECTIONS
KEEP(*(.bss.startup.*))
} > ram
.process_stack :
.stacks (NOLOAD) :
{
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
*(.main_stack)
*(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
. = 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 :

View File

@@ -1,12 +1,6 @@
/*
* ST32F103 memory setup.
*/
__main_stack_size__ = 0x0100; /* Idle+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
@@ -78,34 +72,14 @@ SECTIONS
_etext = .;
_textdata = _etext;
.process_stack :
.stacks (NOLOAD) :
{
*(.main_stack)
*(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
. = 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 :

53
example-led/stack-def.h Normal file
View File

@@ -0,0 +1,53 @@
#define MAIN_SIZE 0x0080 /* Idle+Exception handlers */
#define SIZE_0 0x0100 /* Main program */
#define SIZE_1 0x0100 /* first thread program */
#define SIZE_2 0x0100 /* second thread program */
#if defined(STACK_MAIN)
/*
* The terminology of "main" is confusing in ARM architecture.
* Here, "main_base" is for exception handlers.
*/
/* Idle+Exception handlers */
char __main_stack_end__[0] __attribute__ ((section(".main_stack")));
char main_base[MAIN_SIZE] __attribute__ ((section(".main_stack")));
/* Main program */
char __process0_stack_end__[0] __attribute__ ((section(".process_stack.0")));
char process0_base[SIZE_0] __attribute__ ((section(".process_stack.0")));
#endif
/* First thread program */
#if defined(STACK_PROCESS_1)
char process1_base[SIZE_1] __attribute__ ((section(".process_stack.1")));
#endif
/* Second thread program */
#if defined(STACK_PROCESS_2)
char process2_base[SIZE_2] __attribute__ ((section(".process_stack.2")));
#endif
/* Third thread program */
#if defined(STACK_PROCESS_3)
char process3_base[SIZE_3] __attribute__ ((section(".process_stack.3")));
#endif
/* Fourth thread program */
#if defined(STACK_PROCESS_4)
char process4_base[SIZE_4] __attribute__ ((section(".process_stack.4")));
#endif
/* Fifth thread program */
#if defined(STACK_PROCESS_5)
char process5_base[SIZE_5] __attribute__ ((section(".process_stack.5")));
#endif
/* Sixth thread program */
#if defined(STACK_PROCESS_6)
char process6_base[SIZE_6] __attribute__ ((section(".process_stack.6")));
#endif
/* Seventh thread program */
#if defined(STACK_PROCESS_7)
char process7_base[SIZE_7] __attribute__ ((section(".process_stack.7")));
#endif

View File

@@ -6,7 +6,7 @@
#include "board.h"
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
struct GPIO {

View File

@@ -4,7 +4,7 @@
#include "board.h"
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
struct GPIO {

View File

@@ -0,0 +1,37 @@
# Makefile for example application of Chopstx
PROJECT = sample
CHOPSTX = ..
LDSCRIPT= sample.ld
CSRC = sample.c usb-cdc.c
CHIP=stm32f103
USE_SYS = yes
USE_USB = yes
USE_USART = yes
###################################
CROSS = arm-none-eabi-
CC = $(CROSS)gcc
LD = $(CROSS)gcc
OBJCOPY = $(CROSS)objcopy
MCU = cortex-m3
CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DUSE_SYS3 -DFREE_STANDING
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

22
example-usb-serial/README Normal file
View File

@@ -0,0 +1,22 @@
This is an application example using ST Nucleo F103 board.
SB62 and SB63 should be soldered.
ST-Link/V2 is disconnected (SB13 and SB14).
NOTE:
Using the USB CDC-ACM for serial communication is a kind of wrong,
because it's designed for modem; No way to control CTSRTS.
TIOCGICOUNT
TODO:
* Use of DMA for serial communication
* RS-232 support: GPIO with DTR (out), DCD (in), DSR (in), RI (in)
* serial config setting of CTSRTS?
By vendor specific control?
* stats report control
By vendor specific control?
* Half-duplex support
* Support of other communication mode: smartcard, IrDA, etc.

1
example-usb-serial/board.h Symbolic link
View File

@@ -0,0 +1 @@
../board/board-st-nucleo-f103.h

17
example-usb-serial/cdc.h Normal file
View File

@@ -0,0 +1,17 @@
#define BUFSIZE 64
struct cdc;
void
cdc_init (uint16_t prio, uintptr_t stack_addr, size_t stack_size,
void (*sendbrk_callback) (uint8_t dev_no, uint16_t duration),
void (*config_callback) (uint8_t dev_no,
uint32_t bitrate, uint8_t format,
uint8_t paritytype, uint8_t databits));
void cdc_wait_configured (void);
struct cdc *cdc_open (uint8_t num);
void cdc_wait_connection (struct cdc *);
int cdc_send (struct cdc *s, const char *buf, int count);
int cdc_recv (struct cdc *s, char *buf, uint32_t *timeout);
int cdc_ss_notify (struct cdc *s, uint16_t state_bits);

257
example-usb-serial/sample.c Normal file
View File

@@ -0,0 +1,257 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <chopstx.h>
#include <contrib/usart.h>
#include <usb_lld.h>
#include "cdc.h"
/* For set_led */
#include "board.h"
#include "sys.h"
static void *
blk (void *arg)
{
(void)arg;
while (1)
{
set_led (0);
chopstx_usec_wait (200*1000);
set_led (1);
chopstx_usec_wait (200*1000);
}
return NULL;
}
#define PRIO_USART 4
#define PRIO_CDC2USART 3
#define PRIO_USART2CDC 3
#define PRIO_CDC 2
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#define STACK_PROCESS_3
#define STACK_PROCESS_4
#define STACK_PROCESS_5
#define STACK_PROCESS_6
#include "stack-def.h"
#define STACK_ADDR_CDC ((uintptr_t)process1_base)
#define STACK_SIZE_CDC (sizeof process1_base)
#define STACK_ADDR_USART ((uint32_t)process2_base)
#define STACK_SIZE_USART (sizeof process2_base)
#define STACK_ADDR_CDC2USART0 ((uint32_t)process3_base)
#define STACK_SIZE_CDC2USART0 (sizeof process3_base)
#define STACK_ADDR_USART2CDC0 ((uint32_t)process4_base)
#define STACK_SIZE_USART2CDC0 (sizeof process4_base)
#define STACK_ADDR_CDC2USART1 ((uint32_t)process5_base)
#define STACK_SIZE_CDC2USART1 (sizeof process5_base)
#define STACK_ADDR_USART2CDC1 ((uint32_t)process6_base)
#define STACK_SIZE_USART2CDC1 (sizeof process6_base)
struct cdc_usart {
uint8_t dev_no;
struct cdc *cdc;
};
static void *
usart_to_cdc_loop (void *arg)
{
struct cdc_usart *cdc_usart = arg;
while (1)
{
char s[BUFSIZE];
cdc_wait_connection (cdc_usart->cdc);
/* Flush USART buffers */
usart_read (cdc_usart->dev_no, NULL, 0);
usart_write (cdc_usart->dev_no, NULL, 0);
chopstx_usec_wait (100*1000);
while (1)
{
int size = usart_read (cdc_usart->dev_no, s, BUFSIZE);
if (size > 0)
{
if (cdc_send (cdc_usart->cdc, s, size) < 0)
break;
}
}
}
return NULL;
}
static void *
cdc_to_usart_loop (void *arg)
{
struct cdc_usart *cdc_usart = arg;
while (1)
{
char s[BUFSIZE];
cdc_wait_connection (cdc_usart->cdc);
/* Flush USART buffers */
usart_read (cdc_usart->dev_no, NULL, 0);
usart_write (cdc_usart->dev_no, NULL, 0);
chopstx_usec_wait (50*1000);
/* Send ZLP at the beginning. */
cdc_send (cdc_usart->cdc, s, 0);
while (1)
{
int size;
uint32_t usec = 3000000; /* 3.0 seconds */
size = cdc_recv (cdc_usart->cdc, s, &usec);
if (size < 0)
break;
if (size)
usart_write (cdc_usart->dev_no, s, size);
}
}
return NULL;
}
static struct cdc_usart cdc_usart0;
static struct cdc_usart cdc_usart1;
static int
ss_notify (uint8_t dev_no, uint16_t state_bits)
{
struct cdc *s;
if (dev_no == cdc_usart0.dev_no)
s = cdc_usart0.cdc;
else if (dev_no == cdc_usart1.dev_no)
s = cdc_usart1.cdc;
else
return -1;
return cdc_ss_notify (s, state_bits);
}
static void
send_break (uint8_t dev_no, uint16_t duration)
{
(void)duration; /* Not supported by USART. */
usart_send_break (dev_no);
}
static void
setup_usart_config (uint8_t dev_no, uint32_t bitrate, uint8_t format,
uint8_t paritytype, uint8_t databits)
{
/* Check supported config(s) */
uint32_t config_bits;
if (bitrate == 9600)
config_bits = B9600;
else if (bitrate == 19200)
config_bits = B19200;
else if (bitrate == 57600)
config_bits = B57600;
else if (bitrate == 115200)
config_bits = B115200;
else
{
bitrate = 115200;
config_bits = B115200;
}
if (format == 0)
config_bits |= STOP1B;
else if (format == 1)
config_bits |= STOP1B5;
else if (format == 2)
config_bits |= STOP2B;
else
{
format = 0;
config_bits |= STOP1B;
}
if (paritytype == 0)
config_bits |= 0;
else if (paritytype == 1)
config_bits |= (PARENB | PARODD);
else if (paritytype == 2)
config_bits |= PARENB;
else
{
paritytype = 0;
config_bits |= 0;
}
if (databits == 7)
config_bits |= CS7;
else if (databits == 7)
config_bits |= CS8;
else
{
databits = 8;
config_bits |= CS8;
}
if (databits == 7 && paritytype == 0)
{
databits = 8;
config_bits &= ~MASK_CS;
config_bits |= CS8;
}
usart_config (dev_no, config_bits);
}
int
main (int argc, const char *argv[])
{
(void)argc;
(void)argv;
chopstx_usec_wait (200*1000);
cdc_init (PRIO_CDC, STACK_ADDR_CDC, STACK_SIZE_CDC,
send_break, setup_usart_config);
cdc_wait_configured ();
usart_init (PRIO_USART, STACK_ADDR_USART, STACK_SIZE_USART, ss_notify);
cdc_usart0.cdc = cdc_open (0);
cdc_usart0.dev_no = 2;
cdc_usart1.cdc = cdc_open (1);
cdc_usart1.dev_no = 3;
chopstx_create (PRIO_USART2CDC, STACK_ADDR_USART2CDC0,
STACK_SIZE_USART2CDC0, usart_to_cdc_loop, &cdc_usart0);
chopstx_create (PRIO_USART2CDC, STACK_ADDR_USART2CDC1,
STACK_SIZE_USART2CDC1, usart_to_cdc_loop, &cdc_usart1);
chopstx_create (PRIO_CDC2USART, STACK_ADDR_CDC2USART0,
STACK_SIZE_CDC2USART0, cdc_to_usart_loop, &cdc_usart0);
chopstx_create (PRIO_CDC2USART, STACK_ADDR_CDC2USART1,
STACK_SIZE_CDC2USART1, cdc_to_usart_loop, &cdc_usart1);
blk (NULL);
return 0;
}

View File

@@ -0,0 +1,127 @@
/*
* ST32F103 memory setup.
*/
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 (NOLOAD) :
{
. = ALIGN(8);
*(.process_stack.6)
*(.process_stack.5)
*(.process_stack.4)
*(.process_stack.3)
*(.process_stack.2)
*(.process_stack.1)
*(.process_stack.0)
. = ALIGN(8);
} > ram
.main_stack (NOLOAD) :
{
. = ALIGN(8);
*(.main_stack)
. = ALIGN(8);
} > 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

@@ -0,0 +1,39 @@
#if defined(STACK_MAIN)
/* Idle+Exception handlers */
char __main_stack_end__[0] __attribute__ ((section(".main_stack")));
char main_base[0x0080] __attribute__ ((section(".main_stack")));
/* Main program */
char __process0_stack_end__[0] __attribute__ ((section(".process_stack.0")));
char process0_base[0x0400] __attribute__ ((section(".process_stack.0")));
#endif
/* First thread program */
#if defined(STACK_PROCESS_1)
char process1_base[0x0200] __attribute__ ((section(".process_stack.1")));
#endif
/* Second thread program */
#if defined(STACK_PROCESS_2)
char process2_base[0x0200] __attribute__ ((section(".process_stack.2")));
#endif
/* Third thread program */
#if defined(STACK_PROCESS_3)
char process3_base[0x0200] __attribute__ ((section(".process_stack.3")));
#endif
/* Fourth thread program */
#if defined(STACK_PROCESS_4)
char process4_base[0x0200] __attribute__ ((section(".process_stack.4")));
#endif
/* Fifth thread program */
#if defined(STACK_PROCESS_5)
char process5_base[0x0200] __attribute__ ((section(".process_stack.5")));
#endif
/* Sixth thread program */
#if defined(STACK_PROCESS_6)
char process6_base[0x0200] __attribute__ ((section(".process_stack.6")));
#endif

1034
example-usb-serial/usb-cdc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -57,7 +57,7 @@ In the development of Gnuk, we developed:
It is now maintained as example-cdc/sys.c.
There is another version in example-led/sys.c, which also support
There is another version in example-led/sys.c, which also supports
STM32F030, as well as STM32F103. But, it wouldn't be useful for
STM32F030. In fact, the file example-fsm-55/sys.c has name sys.c
but it doesn't include any system routines.
@@ -74,7 +74,7 @@ Later on, we add another point.
(3) It is good if the executable of Gnuk could be shared among
different boards.
For (1) and (2), we decided put some useful routines and data which is
For (1) and (2), we decided put some useful routines and data which are
not need to be changed.
Now, the first 4KiB of flash ROM consists of:
@@ -84,7 +84,7 @@ Now, the first 4KiB of flash ROM consists of:
SYS consists of:
Internal: reset entry, end of RAM
Internal: reset entry, address of the end of RAM
Data: board identification
Routines: board specific
board independent
@@ -94,7 +94,7 @@ and here is the list of all.
* Internal routines
reset entry
end of RAM
address of the end of RAM
* Board identification

5
mcu/chx-gnu-linux.c Normal file
View File

@@ -0,0 +1,5 @@
void
chx_sleep_mode (int enable_sleep)
{
(void)enable_sleep;
}

23
mcu/chx-mkl27z.c Normal file
View File

@@ -0,0 +1,23 @@
extern int chx_allow_sleep;
void
chx_sleep_mode (int enable_sleep)
{
(void)enable_sleep;
}
void __attribute__((naked))
chx_idle (void)
{
int sleep_enabled;
for (;;)
{
asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep));
if (sleep_enabled)
{
asm volatile ("wfi" : : : "memory");
/* NOTE: it never comes here. Don't add lines after this. */
}
}
}

42
mcu/chx-stm32f0.c Normal file
View File

@@ -0,0 +1,42 @@
#include <stdint.h>
#include <mcu/cortex-m.h>
#define MCU_STM32F0
#include <mcu/stm32.h>
extern int chx_allow_sleep;
void
chx_sleep_mode (int how)
{
PWR->CR |= PWR_CR_CWUF;
PWR->CR &= ~(PWR_CR_PDDS|PWR_CR_LPDS);
if (how == 0 || how == 1 /* Sleep only (not deepsleep) */)
SCB->SCR &= ~SCB_SCR_SLEEPDEEP;
else
{ /* Deepsleep */
/* how == 2: deepsleep but regulator ON */
if (how == 3)
PWR->CR |= PWR_CR_LPDS; /* regulator low-power mode */
else if (how == 4)
PWR->CR |= PWR_CR_PDDS; /* Power down: All OFF */
SCB->SCR |= SCB_SCR_SLEEPDEEP;
}
}
void __attribute__((naked))
chx_idle (void)
{
int sleep_enabled;
for (;;)
{
asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep));
if (sleep_enabled)
{
asm volatile ("wfi" : : : "memory");
/* NOTE: it never comes here. Don't add lines after this. */
}
}
}

88
mcu/chx-stm32f103.c Normal file
View File

@@ -0,0 +1,88 @@
#include <stdint.h>
#include <mcu/stm32.h>
#include <mcu/stm32f103.h>
#include "board.h"
extern int chx_allow_sleep;
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
static void
configure_clock (int high)
{
uint32_t cfg_sw;
uint32_t cfg;
if (high)
{
cfg = STM32_MCO_NOCLOCK | STM32_USBPRE_DIV1P5
| STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC
| STM32_ADCPRE_DIV6 | STM32_PPRE2_DIV1
| STM32_PPRE1_DIV2 | STM32_HPRE_DIV1;
cfg_sw = RCC_CFGR_SW_PLL;
}
else
{
cfg = STM32_MCO_NOCLOCK | STM32_USBPRE_DIV1P5
| STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC
| STM32_ADCPRE_DIV8 | STM32_PPRE2_DIV16
| STM32_PPRE1_DIV16 | STM32_HPRE_DIV8;
cfg_sw = RCC_CFGR_SW_HSI;
}
RCC->CFGR = cfg | cfg_sw;
while ((RCC->CFGR & RCC_CFGR_SWS) != (cfg_sw << 2))
;
}
/*
* When HOW=0 or HOW=1, SYSCLK is PLL (72MHz).
* When HOW=2, SYSCLK will be 1MHz with HSI (8MHz) on sleep.
*
* With lower clock, it can achieve lower power consumption.
*
* Implementation note: Deepsleep is only useful with RTC, Watch Dog,
* or WKUP pin. We can't use deepsleep for USB, it never wakes up.
*
*/
void
chx_sleep_mode (int how)
{
if (how == 0 || how == 1)
configure_clock (1);
/* how == 2: Defer setting to 8MHz clock to the idle function */
}
void __attribute__((naked))
chx_idle (void)
{
int sleep_enabled;
for (;;)
{
asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep));
if (sleep_enabled)
{
asm volatile ("cpsid i" : : : "memory");
if (sleep_enabled == 1)
{
/* Allow JTAG/SWD access on sleep. */
DBGMCU->CR |= DBG_SLEEP;
}
else if (sleep_enabled == 2)
{
DBGMCU->CR &= ~DBG_SLEEP; /* Disable HCLK on sleep */
configure_clock (0);
}
asm volatile ("cpsie i" : : : "memory");
asm volatile ("wfi" : : : "memory");
/* NOTE: it never comes here. Don't add lines after this. */
}
}
}

View File

@@ -26,28 +26,7 @@
*
*/
#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)
#include <mcu/stm32.h>
#if defined(MCU_STM32F0)
#define STM32_PPRE1 STM32_PPRE1_DIV1
@@ -74,85 +53,6 @@
#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 *)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;
@@ -162,7 +62,7 @@ struct SYSCFG {
};
#define SYSCFG_CFGR1_MEM_MODE 0x03
#define SYSCFG_BASE (APBPERIPH_BASE + 0x00010000)
#define SYSCFG_BASE (APB1PERIPH_BASE + 0x00010000)
static struct SYSCFG *const SYSCFG = (struct SYSCFG *)SYSCFG_BASE;
#endif
@@ -218,9 +118,6 @@ clock_init (void)
/* 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))

29
mcu/cortex-m.h Normal file
View File

@@ -0,0 +1,29 @@
/* System Control Block */
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 MMAR;
volatile uint32_t BFAR;
volatile uint32_t AFSR;
volatile uint32_t PFR[2];
volatile uint32_t DFR;
volatile uint32_t AFR;
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 *)SCB_BASE;
#define SCB_SCR_SLEEPDEEP (1 << 2)
#define SCB_AIRCR_SYSRESETREQ 0x04

141
mcu/stm32.h Normal file
View File

@@ -0,0 +1,141 @@
#define PERIPH_BASE 0x40000000
#define APB1PERIPH_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 *)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_CFGR_SW_HSI (0 << 0)
#define RCC_CFGR_SW_HSE (1 << 0)
#define RCC_CFGR_SW_PLL (2 << 0)
#define RCC_CFGR_SW_MASK (3 << 0)
#define RCC_AHBENR_DMA1EN 0x00000001
#define RCC_AHBENR_CRCEN 0x00000040
#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_APB2ENR_ADC1EN 0x00000200
#define RCC_APB2ENR_ADC2EN 0x00000400
#define RCC_APB2ENR_TIM1EN 0x00000800
#define RCC_APB1ENR_TIM2EN 0x00000001
#define RCC_APB1ENR_TIM3EN 0x00000002
#define RCC_APB1ENR_TIM4EN 0x00000004
#define RCC_APB2RSTR_ADC1RST 0x00000200
#define RCC_APB2RSTR_ADC2RST 0x00000400
#define RCC_APB2RSTR_TIM1RST 0x00000800
#define RCC_APB1RSTR_TIM2RST 0x00000001
#define RCC_APB1RSTR_TIM3RST 0x00000002
#define RCC_APB1RSTR_TIM4RST 0x00000004
#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
/* Clock setting values.
* Due to historical reason, it has the prefix of STM32_.
*/
#define STM32_SW_HSI (0 << 0)
#define STM32_SW_HSE (1 << 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_HPRE_DIV8 (10 << 4)
#define STM32_HPRE_DIV16 (11 << 4)
#define STM32_PPRE1_DIV1 (0 << 8)
#define STM32_PPRE1_DIV2 (4 << 8)
#define STM32_PPRE1_DIV16 (7 << 8)
#define STM32_PPRE2_DIV1 (0 << 11)
#define STM32_PPRE2_DIV2 (4 << 11)
#define STM32_PPRE2_DIV16 (7 << 11)
#define STM32_ADCPRE_DIV4 (1 << 14)
#define STM32_ADCPRE_DIV6 (2 << 14)
#define STM32_ADCPRE_DIV8 (3 << 14)
#define STM32_USBPRE_DIV1P5 (0 << 22)
#define STM32_MCO_NOCLOCK (0 << 24)
struct PWR
{
volatile uint32_t CR;
volatile uint32_t CSR;
};
static struct PWR *const PWR = ((struct PWR *)0x40007000);
#define PWR_CR_LPDS 0x0001 /* Low-power deepsleep */
#define PWR_CR_PDDS 0x0002 /* Power down deepsleep */
#define PWR_CR_CWUF 0x0004 /* Clear wakeup flag */

View File

@@ -1,41 +1,3 @@
#define PERIPH_BASE 0x40000000
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
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 *)RCC_BASE;
#define RCC_AHBENR_DMA1EN 0x00000001
#define RCC_AHBENR_CRCEN 0x00000040
#define RCC_APB2ENR_ADC1EN 0x00000200
#define RCC_APB2ENR_ADC2EN 0x00000400
#define RCC_APB2ENR_TIM1EN 0x00000800
#define RCC_APB1ENR_TIM2EN 0x00000001
#define RCC_APB1ENR_TIM3EN 0x00000002
#define RCC_APB1ENR_TIM4EN 0x00000004
#define RCC_APB2RSTR_ADC1RST 0x00000200
#define RCC_APB2RSTR_ADC2RST 0x00000400
#define RCC_APB2RSTR_TIM1RST 0x00000800
#define RCC_APB1RSTR_TIM2RST 0x00000001
#define RCC_APB1RSTR_TIM3RST 0x00000002
#define RCC_APB1RSTR_TIM4RST 0x00000004
#define CRC_CR_RESET 0x00000001
struct CRC {
@@ -182,36 +144,6 @@ static struct DMA *const DMA1 = (struct DMA *)DMA1_BASE;
static struct DMA_Channel *const DMA1_Channel1 =
(struct DMA_Channel *)DMA1_Channel1_BASE;
/* System Control Block */
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];
uint32_t RESERVED0[5];
volatile uint32_t CPACR;
};
#define SCS_BASE 0xE000E000
#define SCB_BASE (SCS_BASE + 0x0D00)
static struct SCB *const SCB = (struct SCB *)SCB_BASE;
/* Timer */
struct TIM
{
@@ -698,3 +630,12 @@ static struct AFIO *const AFIO = (struct AFIO *)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
struct DBGMCU {
volatile uint32_t CR;
};
#define DBGMCU_BASE 0xE0042004
#define DBG_SLEEP 1
static struct DBGMCU *const DBGMCU = (struct DBGMCU *)DBGMCU_BASE;

251
mcu/sys-gnu-linux.c Normal file
View File

@@ -0,0 +1,251 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "board.h"
#include "sys.h"
const uint8_t sys_version[8] = {
3*2+2, /* bLength */
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
/* sys version: "3.0" */
'3', 0, '.', 0, '0', 0,
};
#if defined(USE_SYS3) || defined(USE_SYS_BOARD_ID)
const uint32_t sys_board_id = BOARD_ID;
const uint8_t sys_board_name[] = BOARD_NAME;
#endif
int debug;
void
set_led (int on)
{
if ((debug & DEBUG_LED))
puts (on ? "*": "");
}
static const char *flash_path;
static size_t flash_size;
static void * flash_addr;
static int flash_fd;
uintptr_t
flash_init (const char *f_name)
{
int fd;
struct stat sb;
void *addr;
fd = open (f_name, O_RDONLY);
if (fd < 0)
{
perror ("flash_init: open");
exit (1);
}
if (fstat (fd, &sb) < 0)
{
perror ("flash_init: fstat");
exit (1);
}
addr = mmap (NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED)
{
perror ("flash_init: mmap");
exit (1);
}
if (close (fd) < 0)
{
perror ("flash_init: close");
exit (1);
}
flash_path = f_name;
flash_addr = addr;
flash_size = sb.st_size;
return (uintptr_t)addr;
}
void
flash_unlock (void)
{
int fd;
fd = open (flash_path, O_WRONLY);
if (fd < 0)
{
perror ("flash_unlock: open");
exit (1);
}
flash_fd = fd;
}
int
flash_program_halfword (uintptr_t addr, uint16_t data)
{
off_t offset;
char buf[2];
if ((debug & DEBUG_FLASH))
fprintf (stderr, "flash_program_halfword: addr=%016lx, data=%04x\n",
addr, data);
offset = (off_t)(addr - (uintptr_t)flash_addr);
if (offset < 0 || offset >= (off_t)flash_size)
{
perror ("flash_program_halfword");
return 1;
}
offset = lseek (flash_fd, offset, SEEK_SET);
if (offset == (off_t)-1)
{
perror ("flash_program_halfword");
return 1;
}
buf[0] = (data & 0xff);
buf[1] = (data >> 8);
if (write (flash_fd, buf, 2) != 2)
{
perror ("flash_program_halfword");
return 2;
}
return 0;
}
static const uint8_t erased[] = { [0 ... 1023 ] = 0xff };
int
flash_erase_page (uintptr_t addr)
{
off_t offset;
if ((debug & DEBUG_FLASH))
fprintf (stderr, "flash_erase_page: addr=%016lx\n", addr);
offset = (off_t)(addr - (uintptr_t)flash_addr);
if (offset < 0 || offset >= (off_t)flash_size)
{
perror ("flash_erase_page");
return 1;
}
offset = lseek (flash_fd, offset, SEEK_SET);
if (offset == (off_t)-1)
{
perror ("flash_erase_page");
return 1;
}
if (write (flash_fd, erased, sizeof (erased)) != sizeof (erased))
{
perror ("flash_erase_page");
return 2;
}
return 0;
}
int
flash_check_blank (const uint8_t *p_start, size_t size)
{
const uint8_t *p;
if (p_start < (const uint8_t *)flash_addr
|| p_start + size > (const uint8_t *)flash_addr + flash_size)
{
perror ("flash_check_blank");
return 0;
}
for (p = p_start; p < p_start + size; p++)
if (*p != 0xff)
return 0;
return 1;
}
int
flash_write (uintptr_t dst_addr, const uint8_t *src, size_t len)
{
off_t offset;
if ((debug & DEBUG_FLASH))
fprintf (stderr, "flash_write: addr=%016lx, %p, %zd\n",
dst_addr, src, len);
offset = (off_t)(dst_addr - (uintptr_t)flash_addr);
if (offset < 0 || offset >= (off_t)flash_size)
{
perror ("flash_write");
return 1;
}
offset = lseek (flash_fd, offset, SEEK_SET);
if (offset == (off_t)-1)
{
perror ("flash_write");
return 1;
}
if (write (flash_fd, src, len) != (ssize_t)len)
{
perror ("flash_write");
return 2;
}
return 0;
}
int
flash_protect (void)
{
if ((debug & DEBUG_FLASH))
fprintf (stderr, "flash_protect\n");
return 0;
}
void __attribute__((noreturn))
flash_erase_all_and_exec (void (*entry)(void))
{
(void)entry;
exit (1);
}
void
usb_lld_sys_init (void)
{
}
void
usb_lld_sys_shutdown (void)
{
}
void __attribute__((noreturn))
nvic_system_reset (void)
{
exit (0);
}
void
clock_init (void)
{
}
void
gpio_init (void)
{
}

52
mcu/sys-gnu-linux.h Normal file
View File

@@ -0,0 +1,52 @@
extern const uint8_t sys_version[8];
#if defined(USE_SYS3) || defined(USE_SYS_BOARD_ID)
extern const uint32_t sys_board_id;
extern const uint8_t sys_board_name[];
# define SYS_BOARD_ID sys_board_id
#else
# define SYS_BOARD_ID BOARD_ID
#endif
#define DEBUG_LED (1 << 1)
#define DEBUG_FLASH (1 << 2)
#define DEBUG_USB (1 << 3)
extern int debug;
static inline const uint8_t *
unique_device_id (void)
{
/*
* STM32F103 has 96-bit unique device identifier.
* This routine mimics that.
*/
static const uint8_t id[] = { /* My RSA fingerprint */
0x12, 0x41, 0x24, 0xBD, 0x3B, 0x48, 0x62, 0xAF,
0x7A, 0x0A, 0x42, 0xF1, 0x00, 0xB4, 0x5E, 0xBD,
0x4C, 0xA7, 0xBA, 0xBE
};
return id;
}
void set_led (int on);
uintptr_t flash_init (const char *f_name);
void flash_unlock (void);
int flash_program_halfword (uintptr_t addr, uint16_t data);
int flash_erase_page (uintptr_t addr);
int flash_check_blank (const uint8_t *p_start, size_t size);
int flash_write (uintptr_t dst_addr, const uint8_t *src, size_t len);
int flash_protect (void);
void __attribute__((noreturn))
flash_erase_all_and_exec (void (*entry)(void));
void usb_lld_sys_init (void);
void usb_lld_sys_shutdown (void);
void __attribute__((noreturn))
nvic_system_reset (void);
void clock_init (void);
void gpio_init (void);

View File

@@ -1,7 +1,8 @@
/*
* sys.c - system routines for the initial page for STM32F030 / STM32F103.
* sys-stm32f0.c - system routines for the initial page for STM32F030.
*
* Copyright (C) 2013, 2014, 2015, 2016 Flying Stone Technology
* Copyright (C) 2013, 2014, 2015, 2016, 2017
* Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* Copying and distribution of this file, with or without modification,
@@ -18,6 +19,7 @@
#include "board.h"
#define STM32F0_USE_VECTOR_ON_RAM
#include "mcu/cortex-m.h"
#include "mcu/clk_gpio_init-stm32.c"
@@ -298,38 +300,11 @@ flash_erase_all_and_exec (void (*entry)(void))
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 *)SCB_BASE;
#define SYSRESETREQ 0x04
static void
nvic_system_reset (void)
{
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ);
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
asm volatile ("dsb");
for (;;);
}

View File

@@ -111,7 +111,7 @@ usb_lld_sys_shutdown (void)
(*vector[11]) ();
}
static inline void
static inline void __attribute__((noreturn))
nvic_system_reset (void)
{
(*vector[12]) ();

View File

@@ -1,7 +1,8 @@
/*
* sys.c - system routines for the initial page for STM32F103.
* sys-stm32f103.c - system routines for the initial page for STM32F103.
*
* Copyright (C) 2013, 2014, 2015, 2016 Flying Stone Technology
* Copyright (C) 2013, 2014, 2015, 2016, 2017
* Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* Copying and distribution of this file, with or without modification,
@@ -17,6 +18,7 @@
#include <stdlib.h>
#include "board.h"
#include "mcu/cortex-m.h"
#include "mcu/clk_gpio_init-stm32.c"
@@ -148,7 +150,7 @@ flash_wait_for_last_operation (uint32_t timeout)
#define FLASH_ERASE_TIMEOUT 0x01000000
static int
flash_program_halfword (uint32_t addr, uint16_t data)
flash_program_halfword (uintptr_t addr, uint16_t data)
{
int status;
@@ -170,7 +172,7 @@ flash_program_halfword (uint32_t addr, uint16_t data)
}
static int
flash_erase_page (uint32_t addr)
flash_erase_page (uintptr_t addr)
{
int status;
@@ -210,13 +212,13 @@ flash_check_blank (const uint8_t *p_start, size_t size)
#define FLASH_SIZE_REG ((uint16_t *)0x1ffff7e0)
static int
flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
flash_write (uintptr_t dst_addr, const uint8_t *src, size_t len)
{
int status;
#if defined(STM32F103_OVERRIDE_FLASH_SIZE_KB)
uint32_t flash_end = FLASH_START_ADDR + STM32F103_OVERRIDE_FLASH_SIZE_KB*1024;
uintptr_t flash_end = FLASH_START_ADDR + STM32F103_OVERRIDE_FLASH_SIZE_KB*1024;
#else
uint32_t flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
uintptr_t flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
#endif
if (dst_addr < FLASH_START || dst_addr + len > flash_end)
@@ -272,11 +274,11 @@ flash_protect (void)
static void __attribute__((naked))
flash_erase_all_and_exec (void (*entry)(void))
{
uint32_t addr = FLASH_START;
uintptr_t addr = FLASH_START;
#if defined(STM32F103_OVERRIDE_FLASH_SIZE_KB)
uint32_t end = FLASH_START_ADDR + STM32F103_OVERRIDE_FLASH_SIZE_KB*1024;
uintptr_t end = FLASH_START_ADDR + STM32F103_OVERRIDE_FLASH_SIZE_KB*1024;
#else
uint32_t end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
uintptr_t end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
#endif
uint32_t page_size = 1024;
int r;
@@ -299,38 +301,10 @@ flash_erase_all_and_exec (void (*entry)(void))
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 *)SCB_BASE;
#define SYSRESETREQ 0x04
static void
nvic_system_reset (void)
{
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ);
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
asm volatile ("dsb");
for (;;);
}

View File

@@ -1,6 +1,7 @@
#define BOARD_ID_CQ_STARM 0xc5480875
#define BOARD_ID_FST_01_00 0x613870a9
#define BOARD_ID_FST_01 0x696886af
#define BOARD_ID_FST_01G 0x8801277f
#define BOARD_ID_MAPLE_MINI 0x7a445272
#define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594
#define BOARD_ID_STBEE_MINI 0x1f341961
@@ -21,6 +22,8 @@ extern const uint8_t sys_board_name[];
#endif
typedef void (*handler)(void);
typedef void (*nonreturn_handler0)(void)__attribute__((noreturn));
typedef void (*nonreturn_handler1)(void *)__attribute__((noreturn));
extern handler vector[16];
static inline const uint8_t *
@@ -47,17 +50,17 @@ flash_unlock (void)
}
static inline int
flash_program_halfword (uint32_t addr, uint16_t data)
flash_program_halfword (uintptr_t addr, uint16_t data)
{
int (*func) (uint32_t, uint16_t) = (int (*)(uint32_t, uint16_t))vector[4];
int (*func) (uintptr_t, uint16_t) = (int (*)(uintptr_t, uint16_t))vector[4];
return (*func) (addr, data);
}
static inline int
flash_erase_page (uint32_t addr)
flash_erase_page (uintptr_t addr)
{
int (*func) (uint32_t) = (int (*)(uint32_t))vector[5];
int (*func) (uintptr_t) = (int (*)(uintptr_t))vector[5];
return (*func) (addr);
}
@@ -71,10 +74,10 @@ flash_check_blank (const uint8_t *p_start, size_t size)
}
static inline int
flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
flash_write (uintptr_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];
int (*func) (uintptr_t, const uint8_t *, size_t)
= (int (*)(uintptr_t, const uint8_t *, size_t))vector[7];
return (*func) (dst_addr, src, len);
}
@@ -90,10 +93,9 @@ flash_protect (void)
static inline void __attribute__((noreturn))
flash_erase_all_and_exec (void (*entry)(void))
{
void (*func) (void (*)(void)) = (void (*)(void (*)(void)))vector[9];
nonreturn_handler1 func = (nonreturn_handler1) vector[9] ;
(*func) (entry);
for (;;);
}
static inline void
@@ -108,10 +110,12 @@ usb_lld_sys_shutdown (void)
(*vector[11]) ();
}
static inline void
static inline void __attribute__((noreturn))
nvic_system_reset (void)
{
(*vector[12]) ();
nonreturn_handler0 func = (nonreturn_handler0)vector[12];
(func) ();
}
#ifdef REQUIRE_CLOCK_GPIO_SETTING_IN_SYS

View File

@@ -41,6 +41,7 @@ struct endpoint_ctl {
};
static struct endpoint_ctl ep[16];
#if 0
struct USB_CONF {
const uint8_t PERID; /* Peripheral ID register */
uint8_t rsvd0[3]; /* */
@@ -51,6 +52,7 @@ struct USB_CONF {
volatile uint8_t ADDINFO; /* Peripheral Additional Info register */
};
static struct USB_CONF *const USB_CONF = (struct USB_CONF *)0x40072000;
#endif
struct USB_CTRL0 {
volatile uint8_t OTGCTL; /* OTG Control register */

View File

@@ -1,7 +1,7 @@
/*
* usb-stm32f103.c - USB driver for STM32F103
*
* Copyright (C) 2016 Flying Stone Technology
* Copyright (C) 2016, 2017 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Chopstx, a thread library for embedded.
@@ -339,7 +339,22 @@ void usb_lld_init (struct usb_dev *dev, uint8_t feature)
/* Clear Interrupt Status Register, and enable interrupt for USB */
st103_set_istr (0);
st103_set_cntr (CNTR_CTRM | CNTR_RESETM);
st103_set_cntr (CNTR_CTRM | CNTR_OVRM | CNTR_ERRM
| CNTR_WKUPM | CNTR_SUSPM | CNTR_RESETM);
#if 0
/*
* Since stop mode makes PLL, HSI & HES oscillators stop, USB clock is
* not supplied in stop mode. Thus, USB wakeup can't occur.
*
* So, only sleep mode can be supported with USB, which doesn't
* require use of EXTI.
*/
#include "mcu/stm32f103.h"
/* Setting of EXTI wakeup event to break stop mode. */
EXTI->EMR |= (1 << 18); /* Event mask cleared */
EXTI->RTSR |= (1 << 18); /* Rising trigger selection */
#endif
}
void usb_lld_prepare_shutdown (void)
@@ -367,6 +382,19 @@ usb_lld_event_handler (struct usb_dev *dev)
st103_set_istr (CLR_RESET);
return USB_MAKE_EV (USB_EVENT_DEVICE_RESET);
}
else if ((istr_value & ISTR_WKUP))
{
*CNTR &= ~CNTR_FSUSP;
st103_set_istr (CLR_WKUP);
return USB_MAKE_EV (USB_EVENT_DEVICE_WAKEUP);
}
else if ((istr_value & ISTR_SUSP))
{
*CNTR |= CNTR_FSUSP;
st103_set_istr (CLR_SUSP);
*CNTR |= CNTR_LPMODE;
return USB_MAKE_EV (USB_EVENT_DEVICE_SUSPEND);
}
else
{
if ((istr_value & ISTR_OVR))

View File

@@ -51,6 +51,8 @@
#include <alloca.h>
#include "sys.h" /* for debug */
static pthread_t tid_main;
static pthread_t tid_usbip;
@@ -185,6 +187,7 @@ enum {
USB_INTR_DATA_TRANSFER,
USB_INTR_RESET,
USB_INTR_SUSPEND,
USB_INTR_SHUTDOWN
};
struct usb_controller {
@@ -304,17 +307,22 @@ hc_handle_control_urb (struct urb *urb)
uint16_t remain = urb->len;
uint64_t l;
puts ("hcu 0");
if ((debug & DEBUG_USB))
puts ("hcu 0");
usbc_ep0.urb = urb;
r = control_setup_transaction (urb);
if (r < 0)
goto error;
puts ("hcu 1");
if ((debug & DEBUG_USB))
puts ("hcu 1");
if (urb->dir == USBIP_DIR_OUT)
{ /* Output from host to device. */
printf ("hcu: %d\n", r);
if ((debug & DEBUG_USB))
printf ("hcu: %d\n", r);
while (r == 0)
{
if (remain > 64)
@@ -340,7 +348,9 @@ hc_handle_control_urb (struct urb *urb)
}
else
{ /* Input from device to host. */
puts ("hcu 2");
if ((debug & DEBUG_USB))
puts ("hcu 2");
while (1)
{
if (remain > 64)
@@ -353,28 +363,38 @@ hc_handle_control_urb (struct urb *urb)
if (r < 0)
break;
puts ("hcu 3");
if ((debug & DEBUG_USB))
puts ("hcu 3");
remain -= r;
urb->data_p += r;
if (r < 64)
break;
}
puts ("hcu 4");
if ((debug & DEBUG_USB))
puts ("hcu 4");
if (r >= 0)
{
puts ("hcu 5");
if ((debug & DEBUG_USB))
puts ("hcu 5");
read (usbc_ep0.eventfd, &l, sizeof (l));
r = control_read_status_transaction ();
if (r >= 0)
r = remain;
}
puts ("hcu 6");
if ((debug & DEBUG_USB))
puts ("hcu 6");
}
if (r < 0)
{
error:
fprintf (stderr, "hcu 7 %d\n", r);
if ((debug & DEBUG_USB))
printf ("hcu 7 %d\n", r);
/* recovery. */
usbc_ep0.state = USB_STATE_READY;
}
@@ -393,7 +413,9 @@ hc_handle_control_urb (struct urb *urb)
else
urb->len = 0;
printf ("hu-next: %d (%d)\n", urb->len, urb->seq);
if ((debug & DEBUG_USB))
printf ("hu-next: %d (%d)\n", urb->len, urb->seq);
usbc_ep0.urb = NULL;
return r;
}
@@ -436,6 +458,7 @@ usbip_handle_data_urb (struct urb *urb)
}
static int fd;
static int shutdown_notify_fd;
static pthread_mutex_t fd_mutex;
static void unlink_urb (struct urb *urb);
@@ -452,7 +475,8 @@ usbip_finish_urb (struct urb *urb, int r)
memset (&msg_rep, 0, sizeof (msg_rep));
msg_rep.len = htonl (urb->len);
fprintf (stderr, "ufu: %d (%d)\n", r, urb->seq);
if ((debug & DEBUG_USB))
printf ("ufu: %d (%d)\n", r, urb->seq);
if (r < 0)
msg_rep.status = htonl (r);
@@ -489,7 +513,9 @@ hc_handle_data_urb (struct usb_control *usbc_p)
uint16_t count;
struct urb *urb = usbc_p->urb;
puts ("hc_hdu 0");
if ((debug & DEBUG_USB))
puts ("hc_hdu 0");
if (urb->remain > 64)
count = 64;
else
@@ -497,7 +523,9 @@ hc_handle_data_urb (struct usb_control *usbc_p)
if (urb->dir == USBIP_DIR_OUT)
{ /* Output from host to device. */
puts ("hc_hdu 1");
if ((debug & DEBUG_USB))
puts ("hc_hdu 1");
r = write_data_transaction (usbc_p, urb->ep, urb->data_p, count);
if (r < 0)
return r;
@@ -509,14 +537,17 @@ hc_handle_data_urb (struct usb_control *usbc_p)
{
size_t len = urb->len - urb->remain;
fprintf (stderr, "->data: %lu\n", len);
if ((debug & DEBUG_USB))
printf ("->data: %lu\n", len);
// successfully finished
if (len)
{
char *s = alloca (len + 1);
memcpy (s, urb->data, len);
s[len] = 0;
fprintf (stderr, " : %s\n", s);
if ((debug & DEBUG_USB))
printf (" : %s\n", s);
}
return 0;
}
@@ -525,7 +556,9 @@ hc_handle_data_urb (struct usb_control *usbc_p)
}
else
{ /* Input from device to host. */
puts ("hc_hdu 2");
if ((debug & DEBUG_USB))
puts ("hc_hdu 2");
r = read_data_transaction (usbc_p, urb->ep, urb->data_p, count);
if (r < 0)
return r;
@@ -536,14 +569,17 @@ hc_handle_data_urb (struct usb_control *usbc_p)
{
size_t len = urb->len - urb->remain;
fprintf (stderr, "<-data: %lu %d\n", len, r);
if ((debug & DEBUG_USB))
printf ("<-data: %lu %d\n", len, r);
// successfully finished
if (len)
{
char *s = alloca (len + 1);
memcpy (s, urb->data, len);
s[len] = 0;
fprintf (stderr, " : %s\n", s);
if ((debug & DEBUG_USB))
printf (" : %s\n", s);
}
urb->len = len;
return 0;
@@ -652,8 +688,9 @@ usbip_handle_urb (uint32_t seq)
urb->remain = urb->len = ntohl (msg_cmd.len);
urb->data_p = urb->data;
printf ("URB: dir=%s, ep=%d, len=%d\n", urb->dir==USBIP_DIR_IN? "IN": "OUT",
urb->ep, urb->len);
if ((debug & DEBUG_USB))
printf ("URB: dir=%s, ep=%d, len=%d\n", urb->dir==USBIP_DIR_IN? "IN": "OUT",
urb->ep, urb->len);
if (recv (fd, (char *)urb->setup, sizeof (urb->setup), 0) != sizeof (urb->setup))
{
@@ -663,9 +700,10 @@ usbip_handle_urb (uint32_t seq)
}
if (urb->ep == 0)
printf ("URB: %02x %02x %02x %02x %02x %02x %02x %02x\n",
urb->setup[0], urb->setup[1], urb->setup[2], urb->setup[3],
urb->setup[4], urb->setup[5], urb->setup[6], urb->setup[7]);
if ((debug & DEBUG_USB))
printf ("URB: %02x %02x %02x %02x %02x %02x %02x %02x\n",
urb->setup[0], urb->setup[1], urb->setup[2], urb->setup[3],
urb->setup[4], urb->setup[5], urb->setup[6], urb->setup[7]);
if (urb->dir == USBIP_DIR_OUT && urb->len)
{
@@ -765,7 +803,8 @@ usbip_process_cmd (void)
if (recv (fd, (char *)&msg, sizeof (msg), 0) != sizeof (msg))
{
perror ("msg recv");
if (errno)
perror ("msg recv");
return -1;
}
@@ -777,7 +816,9 @@ usbip_process_cmd (void)
const char *device_list;
size_t device_list_size;
printf ("Device List\n");
if ((debug & DEBUG_USB))
printf ("Device List\n");
if (attached)
{
fprintf (stderr, "REQ list while attached\n");
@@ -808,7 +849,9 @@ usbip_process_cmd (void)
size_t attach_size;
char busid[32];
printf ("Attach device\n");
if ((debug & DEBUG_USB))
printf ("Attach device\n");
if (attached)
{
fprintf (stderr, "REQ attach while attached\n");
@@ -828,7 +871,8 @@ usbip_process_cmd (void)
if (attach
&& (size_t)send (fd, attach, attach_size, 0) == attach_size)
{
printf ("Attach device!\n");
if ((debug & DEBUG_USB))
printf ("Attach device!\n");
attached = 1;
pthread_mutex_unlock (&fd_mutex);
}
@@ -847,7 +891,8 @@ usbip_process_cmd (void)
return -1;
}
printf ("URB SUBMIT! %d\n", msg.seq);
if ((debug & DEBUG_USB))
printf ("URB SUBMIT! %d\n", msg.seq);
usbip_handle_urb (msg.seq);
}
else if (msg.cmd == CMD_URB_UNLINK)
@@ -908,7 +953,8 @@ usbip_process_cmd (void)
if (found)
msg_rep.status = htonl(-ECONNRESET);
printf ("URB UNLINK! %d: %s\n", seq, found?"o":"x");
if ((debug & DEBUG_USB))
printf ("URB UNLINK! %d: %s\n", seq, found?"o":"x");
pthread_mutex_lock (&fd_mutex);
if ((size_t)send (fd, &msg, sizeof (msg), 0) != sizeof (msg))
@@ -940,7 +986,9 @@ usbip_ep_ready (struct usb_control *usbc_p)
if (!usbc_p->urb)
{
puts ("???usbip_ep_ready");
if ((debug & DEBUG_USB))
puts ("???usbip_ep_ready");
return;
}
@@ -994,6 +1042,9 @@ usbip_run_server (void *arg)
const int one = 1;
struct pollfd pollfds[16];
int i;
int r = 0;
(void)arg;
pthread_mutex_init (&usbc.mutex, NULL);
pthread_cond_init (&usbc.cond, NULL);
@@ -1001,7 +1052,6 @@ usbip_run_server (void *arg)
pthread_mutex_init (&fd_mutex, NULL);
pthread_mutex_init (&urb_mutex, NULL);
(void)arg;
if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
{
perror ("socket");
@@ -1030,9 +1080,7 @@ usbip_run_server (void *arg)
exit (1);
}
/* FIXME: We don't use this pollstruct as EP0 is handled
synchronously. */
pollfds[1].fd = usbc_ep0.eventfd;
pollfds[1].fd = shutdown_notify_fd;
pollfds[1].events = POLLIN;
pollfds[1].revents = 0;
@@ -1052,14 +1100,15 @@ usbip_run_server (void *arg)
exit (1);
}
/* Since EP0 is handled synchronously, we don't poll on
* usbc_ep0.eventfd. We poll on socket and shutdown request.
*/
pollfds[0].fd = fd;
pollfds[0].events = POLLIN;
pollfds[0].revents = 0;
for (;;)
{
int r;
for (i = 1; i < 8; i++)
{
if (usbc_ep_in[i].urb)
@@ -1079,7 +1128,7 @@ usbip_run_server (void *arg)
if (poll (pollfds, 16, -1) < 0)
{
if (errno == EINTR)
goto again;
continue;
perror ("poll");
exit (1);
@@ -1088,7 +1137,8 @@ usbip_run_server (void *arg)
if ((pollfds[0].revents & POLLNVAL)
|| (pollfds[0].revents & POLLERR))
{
fprintf (stderr, "Error on USBIP client socket: %d\n", pollfds[0].revents);
fprintf (stderr, "Error on USBIP client socket: %d\n",
pollfds[0].revents);
exit (1);
}
if ((pollfds[0].revents & POLLIN))
@@ -1100,6 +1150,20 @@ usbip_run_server (void *arg)
goto again;
}
if ((pollfds[1].revents & POLLNVAL)
|| (pollfds[1].revents & POLLERR))
{
fprintf (stderr, "Error on USBIP client socket: %d\n",
pollfds[1].revents);
exit (1);
}
if ((pollfds[1].revents & POLLIN))
{
/* Shutdown request */
r = 0;
break;
}
for (i = 1; i < 8; i++)
{
if ((pollfds[i*2].revents & POLLNVAL)
@@ -1110,7 +1174,9 @@ usbip_run_server (void *arg)
}
if ((pollfds[i*2].revents & POLLIN))
{
puts ("poll in read");
if ((debug & DEBUG_USB))
puts ("poll in read");
usbip_ep_ready (&usbc_ep_in[i]);
}
@@ -1122,15 +1188,49 @@ usbip_run_server (void *arg)
}
if ((pollfds[i*2+1].revents & POLLIN))
{
puts ("poll out read");
if ((debug & DEBUG_USB))
puts ("poll out read");
usbip_ep_ready (&usbc_ep_out[i]);
}
}
}
{
struct urb *urb;
pthread_mutex_lock (&urb_mutex);
if ((urb = urb_list))
{
do
{
unlink_urb (urb);
unlink_urb_ep (urb);
free (urb);
}
while ((urb = urb_list));
}
pthread_mutex_unlock (&urb_mutex);
}
close (fd);
close (sock);
exit (0);
close (shutdown_notify_fd);
close (usbc_ep0.eventfd);
for (i = 1; i < 8; i++)
{
close (usbc_ep_in[i].eventfd);
close (usbc_ep_out[i].eventfd);
}
attached = 0;
if (r < 0)
/* It was detach request from client. */
exit (0);
return NULL;
}
@@ -1163,7 +1263,8 @@ control_setup_transaction (struct urb *urb)
r = -EAGAIN;
else
{
fprintf (stderr, "cst error %d\n", usbc_ep0.state);
if ((debug & DEBUG_USB))
printf ("cst error %d\n", usbc_ep0.state);
r = -EPIPE;
}
pthread_mutex_unlock (&usbc_ep0.mutex);
@@ -1187,7 +1288,8 @@ control_write_data_transaction (char *buf, uint16_t count)
{
if (usbc_ep0.len < count)
{
fprintf (stderr, "*** usbc_ep0.len < count");
if ((debug & DEBUG_USB))
printf ("*** usbc_ep0.len < count");
r = -EPIPE;
usbc_ep0.state = USB_STATE_STALL;
}
@@ -1224,9 +1326,12 @@ control_write_status_transaction (void)
pthread_mutex_lock (&usbc_ep0.mutex);
if (usbc_ep0.state == USB_STATE_READY)
{
puts ("control_write_status_transaction");
if ((debug & DEBUG_USB))
puts ("control_write_status_transaction");
if (usbc_ep0.len != 0)
fprintf (stderr, "*** ACK length %d\n", usbc_ep0.len);
if ((debug & DEBUG_USB))
printf ("*** ACK length %d\n", usbc_ep0.len);
usbc_ep0.state = USB_STATE_NAK;
notify_device (USB_INTR_DATA_TRANSFER, 0, USBIP_DIR_IN);
r = 0;
@@ -1255,7 +1360,10 @@ control_read_data_transaction (char *buf, uint16_t count)
if (usbc_ep0.state == USB_STATE_READY)
{
if (usbc_ep0.len > count)
fprintf (stderr, "***c read: length %d > %d\n", usbc_ep0.len, count);
{
if ((debug & DEBUG_USB))
printf ("***c read: length %d > %d\n", usbc_ep0.len, count);
}
else
count = usbc_ep0.len;
@@ -1337,7 +1445,10 @@ read_data_transaction (struct usb_control *usbc_p,
int ep_num, char *buf, uint16_t count)
{
if (usbc_p->len > count)
fprintf (stderr, "*** length %d > %d\n", usbc_p->len, count);
{
if ((debug & DEBUG_USB))
printf ("*** length %d > %d\n", usbc_p->len, count);
}
else
count = usbc_p->len;
@@ -1347,9 +1458,8 @@ read_data_transaction (struct usb_control *usbc_p,
return count;
}
void chx_handle_intr (uint32_t irq_num);
extern void chx_handle_intr (uint32_t irq_num);
#define INTR_REQ_USB SIGUSR1
static void
usb_intr (int signum, siginfo_t *siginfo, void *arg)
@@ -1384,6 +1494,13 @@ usb_lld_init (struct usb_dev *dev, uint8_t feature)
pthread_sigmask (SIG_BLOCK, &sigset, NULL);
shutdown_notify_fd = eventfd (0, EFD_CLOEXEC);
if (shutdown_notify_fd < 0)
{
perror ("eventfd");
exit (1);
}
pthread_mutex_init (&usbc_ep0.mutex, NULL);
usbc_ep0.urb = NULL;
usbc_ep0.eventfd = eventfd (0, EFD_CLOEXEC);
@@ -1445,12 +1562,14 @@ usb_lld_prepare_shutdown (void)
void
usb_lld_shutdown (void)
{
const uint64_t l = 1;
/*
* Stop USBIP server thread.
* Tell USBIP server thread about shutdown.
*/
pthread_cancel (tid_usbip);
write (shutdown_notify_fd, &l, sizeof (l));
pthread_join (tid_usbip, NULL);
/* FIXME: Cancel all URB in the list here. */
notify_device (USB_INTR_SHUTDOWN, 0, 0);
}
static void
@@ -1489,6 +1608,11 @@ usb_lld_event_handler (struct usb_dev *dev)
return USB_MAKE_EV (handle_setup0 (dev));
else if (intr == USB_INTR_DATA_TRANSFER)
return usb_handle_transfer (dev, dir, ep_num);
else if (intr == USB_INTR_SHUTDOWN)
{
if ((debug & DEBUG_USB))
puts ("USB shutdown");
}
return USB_EVENT_OK;
}
@@ -1902,7 +2026,9 @@ static int handle_in0 (struct usb_dev *dev)
== (STANDARD_REQUEST | DEVICE_RECIPIENT)))
{
/* XXX: record the assigned address of this device??? */
printf ("Set Address: %d\n", dev->dev_req.value);
if ((debug & DEBUG_USB))
printf ("Set Address: %d\n", dev->dev_req.value);
r = USB_EVENT_DEVICE_ADDRESSED;
}
else
@@ -1917,7 +2043,9 @@ static int handle_in0 (struct usb_dev *dev)
}
else
{
puts ("handle_in0 error");
if ((debug & DEBUG_USB))
puts ("handle_in0 error");
dev->state = STALLED;
pthread_mutex_lock (&usbc_ep0.mutex);
usbc_ep0.state = USB_STATE_STALL;
@@ -1955,7 +2083,9 @@ static void handle_out0 (struct usb_dev *dev)
* Or else, unexpected state.
* STALL the endpoint, until we receive the next SETUP token.
*/
puts ("handle_out0 error");
if ((debug & DEBUG_USB))
puts ("handle_out0 error");
dev->state = STALLED;
pthread_mutex_lock (&usbc_ep0.mutex);
usbc_ep0.state = USB_STATE_STALL;
@@ -2077,7 +2207,9 @@ usb_lld_current_configuration (struct usb_dev *dev)
void
usb_lld_ctrl_error (struct usb_dev *dev)
{
puts ("ctrl_error");
if ((debug & DEBUG_USB))
puts ("ctrl_error");
dev->state = STALLED;
pthread_mutex_lock (&usbc_ep0.mutex);
usbc_ep0.state = USB_STATE_STALL;
@@ -2134,7 +2266,9 @@ usb_lld_stall_tx (int ep_num)
usbc_p->state = USB_STATE_STALL;
notify_hostcontroller (usbc_p);
pthread_mutex_unlock (&usbc_p->mutex);
printf ("stall tx %d\n", ep_num);
if ((debug & DEBUG_USB))
printf ("stall tx %d\n", ep_num);
}
void
@@ -2146,7 +2280,8 @@ usb_lld_stall_rx (int ep_num)
usbc_p->state = USB_STATE_STALL;
notify_hostcontroller (usbc_p);
pthread_mutex_unlock (&usbc_p->mutex);
printf ("stall rx %d\n", ep_num);
if ((debug & DEBUG_USB))
printf ("stall rx %d\n", ep_num);
}
void
@@ -2161,7 +2296,8 @@ usb_lld_rx_enable_buf (int ep_num, void *buf, size_t len)
notify_hostcontroller (usbc_p);
pthread_mutex_unlock (&usbc_p->mutex);
printf ("usb_lld_rx_enable_buf: %d\n", ep_num);
if ((debug & DEBUG_USB))
printf ("usb_lld_rx_enable_buf: %d\n", ep_num);
}
@@ -2176,5 +2312,6 @@ usb_lld_tx_enable_buf (int ep_num, const void *buf, size_t len)
usbc_p->len = len;
notify_hostcontroller (usbc_p);
pthread_mutex_unlock (&usbc_p->mutex);
printf ("usb_lld_tx_enable_buf: %d %ld\n", ep_num, len);
if ((debug & DEBUG_USB))
printf ("usb_lld_tx_enable_buf: %d %ld\n", ep_num, len);
}

View File

@@ -6,6 +6,12 @@ ifneq ($(USE_EVENTFLAG),)
CSRC += $(CHOPSTX)/eventflag.c
endif
ifeq ($(EMULATION),)
CSRC += $(CHOPSTX)/mcu/chx-$(CHIP).c
else
CSRC += $(CHOPSTX)/mcu/chx-gnu-linux.c
endif
ifneq ($(USE_SYS),)
CSRC += $(CHOPSTX)/mcu/sys-$(CHIP).c
endif
@@ -19,6 +25,9 @@ endif
ifneq ($(USE_ADC),)
CSRC += $(CHOPSTX)/contrib/adc-$(CHIP).c
endif
ifneq ($(USE_USART),)
CSRC += $(CHOPSTX)/contrib/usart-$(CHIP).c
endif
INCDIR += $(CHOPSTX)

4
sys.h
View File

@@ -1,4 +1,6 @@
#if defined(MCU_KINETIS_L)
#if defined(GNU_LINUX_EMULATION)
#include "mcu/sys-gnu-linux.h"
#elif defined(MCU_KINETIS_L)
#include "mcu/sys-mkl27z.h"
#elif defined(MCU_STM32F0)
#include "mcu/sys-stm32f0.h"

View File

@@ -64,6 +64,7 @@ enum {
/* Device reset and suspend. */
USB_EVENT_DEVICE_RESET,
USB_EVENT_DEVICE_SUSPEND,
USB_EVENT_DEVICE_WAKEUP,
/* Device Requests (Control WRITE Transfer): Standard */
USB_EVENT_SET_CONFIGURATION,
USB_EVENT_SET_INTERFACE,
@@ -83,12 +84,13 @@ enum {
};
enum DEVICE_STATE {
UNCONNECTED,
ATTACHED,
POWERED,
SUSPENDED,
ADDRESSED,
CONFIGURED
USB_DEVICE_STATE_UNCONNECTED = 0, /* No USB */
USB_DEVICE_STATE_ATTACHED = 1,
USB_DEVICE_STATE_POWERED = 2,
USB_DEVICE_STATE_DEFAULT = 3,
USB_DEVICE_STATE_ADDRESSED = 4,
USB_DEVICE_STATE_CONFIGURED = 5,
USB_DEVICE_STATE_SUSPEND = 128 /* Or-ed to other states */
};
void usb_lld_init (struct usb_dev *dev, uint8_t feature);
@@ -135,12 +137,15 @@ void usb_lld_prepare_shutdown (void);
void usb_lld_shutdown (void);
#if defined(MCU_KINETIS_L)
#define INTR_REQ_USB 24
void usb_lld_tx_enable_buf (int ep_num, const void *buf, size_t len);
void usb_lld_rx_enable_buf (int ep_num, void *buf, size_t len);
void usb_lld_setup_endp (struct usb_dev *dev, int ep_num, int rx_en, int tx_en);
void usb_lld_stall (int ep_num);
#elif defined(GNU_LINUX_EMULATION)
#include <signal.h>
#define INTR_REQ_USB SIGUSR1
void usb_lld_tx_enable_buf (int ep_num, const void *buf, size_t len);
void usb_lld_rx_enable_buf (int ep_num, void *buf, size_t len);
@@ -148,6 +153,7 @@ void usb_lld_setup_endp (struct usb_dev *dev, int ep_num, int rx_en, int tx_en);
void usb_lld_stall_tx (int ep_num);
void usb_lld_stall_rx (int ep_num);
#else
#define INTR_REQ_USB 20
/* EP_TYPE[1:0] EndPoint TYPE */
#define EP_BULK (0x0000) /* EndPoint BULK */
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */