99 Commits

Author SHA1 Message Date
NIIBE Yutaka
fffb8aa3b3 Version 1.11. 2018-10-02 09:58:45 +09:00
NIIBE Yutaka
0ed2e95ea2 Fix ackbtn clearing the edge detector. 2018-10-01 12:56:41 +09:00
NIIBE Yutaka
02aa678d4c Fix interrupt handling. 2018-10-01 10:10:09 +09:00
NIIBE Yutaka
d25cee5040 Version 1.10. 2018-09-29 11:03:32 +09:00
NIIBE Yutaka
e420168c82 doc: Update chopstx-api.texi. 2018-09-27 15:14:00 +09:00
NIIBE Yutaka
7dc67d2210 Minor change for ackbtn driver. 2018-09-27 12:53:43 +09:00
NIIBE Yutaka
49b0556a24 Add ack-botton driver. 2018-09-27 10:36:36 +09:00
NIIBE Yutaka
43bbdb44dc Fix examples. 2018-09-26 10:47:42 +09:00
NIIBE Yutaka
d4f4f80ad9 New API: chopstx_intr_done. 2018-09-26 10:18:23 +09:00
NIIBE Yutaka
7ad7527e81 Add defninitions of EXTI use for FST-01SZ. 2018-09-25 16:17:26 +09:00
NIIBE Yutaka
951afbad3a Consolidate definitions for STM32F103. 2018-09-21 14:47:16 +09:00
NIIBE Yutaka
2b717c91da Add FST-01SZ support. 2018-09-21 10:37:11 +09:00
NIIBE Yutaka
05732b445a Add MHZ for examples. 2018-08-23 14:36:22 +09:00
NIIBE Yutaka
1cbe0abdee usb: Fix for ZLP. 2018-08-20 12:43:35 +09:00
NIIBE Yutaka
802dbbd639 Version 1.9. 2018-05-09 12:29:52 +09:00
NIIBE Yutaka
2764fc4ea2 Fix flash_protect for GD32F103. 2018-05-08 17:38:39 +09:00
NIIBE Yutaka
f500ac03da Fix for Blue Pill, wait using MHZ. 2018-05-08 13:16:58 +09:00
NIIBE Yutaka
808aa5b186 Fix example-fraucheky. 2018-04-27 05:31:32 +09:00
NIIBE Yutaka
f781ac9e6a Fix usb_device_reset of example-fraucheky. 2018-04-26 21:15:13 +09:00
NIIBE Yutaka
32d0b8200d Add board/board-blue-pill-g.h. 2018-04-26 10:55:08 +09:00
NIIBE Yutaka
05382581e8 More. 2018-01-30 13:52:09 +09:00
NIIBE Yutaka
aa97af66db More update of CI/CD. 2018-01-30 13:49:59 +09:00
NIIBE Yutaka
e6a53c99c4 Update CI/CD setting to generate HTML. 2018-01-30 13:24:34 +09:00
NIIBE Yutaka
cb770e9ae3 Add .gitlab-ci.yml. 2018-01-30 13:07:11 +09:00
NIIBE Yutaka
aa63ac79bc Version 1.8. 2018-01-19 10:12:16 +09:00
NIIBE Yutaka
74cff25b78 Clean up example-usb-serial. 2018-01-18 15:15:42 +09:00
NIIBE Yutaka
5cd4871a94 Fix mcu/stm32f103.h. 2018-01-18 15:12:52 +09:00
Anthony Romano
c0a84627b6 Support IN8 config for ADC. 2018-01-09 09:26:44 +09:00
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
80 changed files with 4016 additions and 778 deletions

15
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,15 @@
image: debian:stable
before_script:
- apt-get update && apt-get -y install texi2html
pages:
stage: deploy
script:
- mkdir -p html && (cd html && texi2html ../doc/chopstx.texi)
- mv html/ public
artifacts:
paths:
- public
only:
- master

12
AUTHORS
View File

@@ -19,7 +19,7 @@ Kenji Rikitake:
Kiwamu Okabe: Kiwamu Okabe:
Wrote an OpenOCD scirpt: Wrote an OpenOCD scirpt:
example-fsm-55/stlink-v2.cfg example-fsm-55/stlink-v2.cfg
Mateusz Zalega: Mateusz Zalega:
Added Nitrokey-Start support. Added Nitrokey-Start support.
@@ -28,7 +28,7 @@ Mateusz Zalega:
NIIBE Yutaka: NIIBE Yutaka:
Wrote the library: Wrote the library:
chopstx.c, entry.c, eventflag.c, chopstx.c, entry.c, eventflag.c,
chopstx.h, eventflag.h chopstx.h, eventflag.h
Wrote the drivers mcu/*: Wrote the drivers mcu/*:
clk_gpio_init-mkl27z.c, clk_gpio_init-stm32.c, clk_gpio_init-mkl27z.c, clk_gpio_init-stm32.c,
sys-stm32f103.c, sys-stm32f030.c, sys-mkl27z.c, sys-stm32f103.c, sys-stm32f030.c, sys-mkl27z.c,
@@ -36,9 +36,10 @@ NIIBE Yutaka:
Drew the logo: Drew the logo:
chopstx.svg, chopstx.png chopstx.svg, chopstx.png
Wrote examples: Wrote examples:
example-led, example-cdc, example-fsm-55, example-fs-bb48 example-led, example-cdc, example-fsm-55, example-fs-bb48,
example-usb-serial
Wrote board/*: Wrote board/*:
board-fst-01.h, board-fst-01-00.h, board-fst-01.h, board-fst-01-00.h,
board-olimex-stm32-h103.h, board-stm8s-discovery.h board-olimex-stm32-h103.h, board-stm8s-discovery.h
board-cq-starm.h, board-stbee-mini.h, board-stbee.h, board-cq-starm.h, board-stbee-mini.h, board-stbee.h,
@@ -47,7 +48,8 @@ NIIBE Yutaka:
board-fs-bb48.h board-fs-bb48.h
Under contract of g10 Code GmbH, wrote: Under contract of g10 Code GmbH, wrote:
mcu/usb-usbip.c mcu/usb-usbip.c
contrib/usart-stm32f103.c
Paul Fertser: Paul Fertser:
Added Blue Pill support. Added Blue Pill support.

269
ChangeLog
View File

@@ -1,3 +1,272 @@
2018-10-02 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.11.
* doc/chopstx.texi (VERSION): 1.11.
2018-10-01 NIIBE Yutaka <gniibe@fsij.org>
* contrib/ackbtn-stm32f103.c (PINCFG_EDGE): New.
(ackbtn_init): Use PINCFG_EDGE bit.
(ackbtn_enable): Configure the edge detector here.
(ackbtn_disable): Disable the edge detector.
* chopstx.c (chopstx_poll): Don't clear ->ready here.
(chx_cond_hook): Set ->ready = 0 when condition does
not meet.
(chopstx_claim_irq): Make sure clearing the interrupt.
(chx_intr_hook): Add the case when ->ready == 1.
(chopstx_intr_done): Set ->ready = 0.
(chx_join_hook): Set ->ready = 0 when it is still alive.
2018-09-29 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.10.
* doc/chopstx.texi (VERSION): 1.10.
2018-09-27 NIIBE Yutaka <gniibe@fsij.org>
* contrib/ackbtn-stm32f103.c: New.
* rules.mk [USE_ACKBTN] (CSRC): Add ack-button support.
2018-09-26 NIIBE Yutaka <gniibe@fsij.org>
Fix for chopstx_intr_done. No spurious interrupts.
* contrib/adc-mkl27z.c (adc_wait_completion): Fix.
* contrib/adc-stm32f103.c (adc_wait_completion): Likewise.
* contrib/usart-stm32f103.c (usart_main): Likewise.
* example-cdc-gnu-linux/usb-cdc.c (tty_main): Likewise.
* example-cdc/usb-cdc.c (tty_main): Likewise.
* example-fraucheky/main.c (usb_main): Likewise.
* example-fs-bb48/touch.c (touch_get): Likewise.
* example-fs-bb48/usb-cdc.c (tty_main): Likewise.
* example-primer2/primer2-ts.c (adc3_conversion): Likewise.
* example-usb-serial/usb-cdc.c (cdc_main): Likewise.
2018-09-26 NIIBE Yutaka <gniibe@fsij.org>
* chopstx.h (chopstx_intr_done): New function.
* chopstx.c (chopstx_intr_done): New function.
(chopstx_poll): Don't call chx_clr_intr.
Ensure data memory barrier for interrupt handling.
* chopstx-cortex-m.c (chx_dmb): New static function.
* chopstx-gnu-linux.c (chx_dmb): Ditto.
2018-09-21 NIIBE Yutaka <gniibe@fsij.org>
* mcu/stm32.h (struct GPIO, struct FLASH): Moved from...
* mcu/clk_gpio_init-stm32.c: ... here.
(AFIO_MAPR_SWJ_CFG_JTAGDISABLE): Move to ...
* mcu/stm32f103.h: ... here.
* mcu/sys-stm32f103.c: Don't include "mcu/cortex-m.h".
* board/board-fst-01sz.h: New.
* mcu/sys-stm32f103.h (BOARD_ID_FST_01SZ): New.
* contrib/adc-stm32f103.c (get_adc_config): Add BOARD_ID_FST_01SZ.
2018-08-20 NIIBE Yutaka <gniibe@fsij.org>
* mcu/usb-stm32f103.c (usb_lld_ctrl_send): Fix for ZLP.
* mcu/usb-usbip.c (usb_lld_ctrl_send): Likewise.
* mcu/usb-mkl27z.c (usb_lld_ctrl_send): Likewise.
2018-05-09 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.9.
* doc/chopstx.texi (VERSION): 1.9.
2018-05-08 NIIBE Yutaka <gniibe@fsij.org>
* board/board-blue-pill.h (GPIO_USB_SET_TO_ENABLE): Remove.
* doc/chopstx.texi (Compile-time macro): New chapter.
* mcu/sys-stm32f103.c (usb_lld_sys_init): Use MHZ.
(flash_protect): Fix for GD32F103.
2018-04-26 NIIBE Yutaka <gniibe@fsij.org>
* board/board-blue-pill-g.h: New. Define STM32_ADCPRE and
STM32_USBPRE for 96MHz clock.
* mcu/stm32.h (STM32_USBPRE_DIV2): New for GD32F103.
* mcu/clk_gpio_init-stm32.c: Allow constants, which are defined by
board.h (STM32_ADCPRE and STM32_USBPRE).
* mcu/chx-stm32f103.c: Use STM32_ADCPRE and STM32_USBPRE.
* mcu/usb-stm32f103.c (usb_lld_init): BTABLE setting at
initialization.
(usb_lld_reset): Not at each reset.
* contrib/adc-stm32f103.c [MCU_STM32F1_GD32F1]: Use continuous
sampling with no DELIBARATELY_DO_IT_WRONG_START_STOP.
(adc_init): Wait after ADC_CR2_ADON.
(adc_start): Likewise. Enabling by ADC_CR2_ADON after all other
registers configuration.
2018-01-19 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.8.
* doc/chopstx.texi (VERSION): 1.8.
2018-01-18 NIIBE Yutaka <gniibe@fsij.org>
* mcu/stm32f103.h: Include stm32.h and cortex-m.h.
2018-01-09 Anthony Romano <romanoanthony061@gmail.com>
* contrib/adc-stm32f103.c: Support IN8 config.
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> 2017-10-10 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.5. * VERSION: 1.5.

119
NEWS
View File

@@ -1,6 +1,117 @@
NEWS - Noteworthy changes NEWS - Noteworthy changes
* Major changes in Chopstx 1.11
Released 2018-10-02
** Support calling chopstx_poll with intr->ready==1
In version <= 1.10, it assumed that all events should be handled after
chopstx_poll, before calling chopstx_poll again. With having
chopstx_intr_done, it's OK now that chopstx_poll can be called again
not examining/handling all poll descriptors, but only parts of them.
** Acknowledge button change
In 1.10, the action was able to be "memorized" by the edge detector.
Now, the edge detector is disabled by ackbtn_disable, and it is
enabled by ackbtn_enable. So, the status is cleared correctly.
** New board support: FST-01SZ
It's still under development. Programming-wise, it will keep same.
* Major changes in Chopstx 1.10
Released 2018-09-29
** Function chopstx_intr_wait is not deprecated, now
Once, it was said that it's deprecated, but it's active again
to match the new function of chopstx_intr_done.
** API change: chopstx_poll, chopstx_intr_wait, chopstx_intr_done
To avoid spurious interrupt, we introduce new function
chopstx_intr_done, which should be called after interrupt handling.
** New driver: Acknowledge button for FST-01SZ
The use case is waiting user's acknowledge. We use EXTI interrupt
feature of STM32.
* Major changes in Chopstx 1.9
Released 2018-05-09
** GD32F103 support
GD32F103 is an alternative implementation of STM32F103 by Giga Device,
which can run at 96MHz.
** Minor USB driver fix for STM32F103/GD32F103
BTABLE setting should be done at initialization, not at USB RESET.
** Minor SYS driver fix for GD32F103
flash_protect should check FLASH_CR_OPTWRE.
** Minor ADC driver change for GD32F103
ADC on GD32F103 is another implementation and its behavior is somewhat
different. It requires waits after enabling. So, we use continuous
sampling, instead of start and stop for each sample. Still, we
observe enough noise (> 4.7 bit/byte) for each ADC sampling.
* Major changes in Chopstx 1.8
Released 2018-01-19
** Minor driver API fix
In version 1.6, part of mcu/stm32f103.h was moved into mcu/cortex-m.h
and mcu/stm32.h. Now, mcu/stm32f103.h automatically includes
mcu/cortex-m.h and mcu/stm32.h, so that it doesn't break existing
applications.
* 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 * Major changes in Chopstx 1.5
Released 2017-10-10 Released 2017-10-10
@@ -302,11 +413,11 @@ Vectored Interrupt Controller (NVIC), in the ARM v7-M Architecture
Reference Manual. The subsection, B3.4.1, Theory of operation, Reference Manual. The subsection, B3.4.1, Theory of operation,
explains how it works. explains how it works.
** gpio_init change ** gpio_init change
Now, gpi_init support AFIO mapping and another GPIO (GPIO_OTHER) Now, gpi_init support AFIO mapping and another GPIO (GPIO_OTHER)
settings. settings.
Local Variables:
mode: outline # Local Variables:
End: # mode: outline
# End:

21
README
View File

@@ -1,14 +1,14 @@
Chopstx - Threads and only Threads Chopstx - Threads and only Threads
Version 1.5 Version 1.11
2017-10-10 2018-10-02
Niibe Yutaka Niibe Yutaka
Flying Stone Technology Flying Stone Technology
What's Chopstx? What's Chopstx?
=============== ===============
Chopstx is an RT thread library for STM32F103 (ARM Cortex-M3), Chopstx is an RT thread library for STM32F103 and GD32F103 (ARM
STM32F030 (ARM Cortex-M0), MKL27Z (ARM Cortex-M0plus), and Cortex-M3), STM32F030 (ARM Cortex-M0), MKL27Z (ARM Cortex-M0plus), and
emulation on GNU/Linux. emulation on GNU/Linux.
While most RTOSes come with many features, drivers, and protocol While most RTOSes come with many features, drivers, and protocol
@@ -17,12 +17,17 @@ stacks, Chopstx just offers a simple RT thread library.
With Chopstx, interrupt handling is also done by a thread. This With Chopstx, interrupt handling is also done by a thread. This
enables coherent code for ease of maintenance. enables coherent code for ease of maintenance.
This library is _not_ related to the hand game: 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) https://en.wikipedia.org/wiki/Chopsticks_(hand_game)
Thanks to Yao Wei and Enrico Zini for giving me the opportunity Thanks to Yao Wei and Enrico Zini for giving me an opportunity
visiting the wiki page. visiting the wiki page above, when my children were playing the game.
License License
@@ -44,6 +49,8 @@ CDC-ACM demo by:
$ ln -sf ../board/board-olimex-stm32-h103.h board.h $ ln -sf ../board/board-olimex-stm32-h103.h board.h
$ make $ make
If you want to try GD32F103, Add -DMHZ=96 to DEFS in Makefile.
For a specific board named FSM-55, an example of LED matrix dynamic For a specific board named FSM-55, an example of LED matrix dynamic
driver is provided. See the directory: example-fsm-55. driver is provided. See the directory: example-fsm-55.

View File

@@ -1 +1 @@
release/1.5 release/1.11

42
board/board-blue-pill-g.h Normal file
View File

@@ -0,0 +1,42 @@
#define BOARD_NAME "Blue Pill GD32F103"
/* http://wiki.stm32duino.com/index.php?title=Blue_Pill */
/* echo -n "Blue Pill GD32F103" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */
#define BOARD_ID 0xed415594
#define MCU_STM32F1_GD32F1 1
#define STM32_USBPRE STM32_USBPRE_DIV2
#define STM32_ADCPRE STM32_ADCPRE_DIV8
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 12
#define STM32_HSECLK 8000000
#define GPIO_LED_BASE GPIOC_BASE
#define GPIO_LED_CLEAR_TO_EMIT 13
#define GPIO_USB_BASE GPIOA_BASE
#undef GPIO_OTHER_BASE
/*
* Port A setup.
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
*
* Port C setup.
* PC13 - Push pull output 50MHz (LED 1:ON 0:OFF)
* ------------------------ Default
* PAx - input with pull-up
* PCx - input with pull-up
*/
#define VAL_GPIO_USB_ODR 0xFFFFE7FF
#define VAL_GPIO_USB_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_USB_CRH 0x88811888 /* PA15...PA8 */
#define VAL_GPIO_LED_ODR 0xFFFFFFFF
#define VAL_GPIO_LED_CRL 0x88888888 /* PC7...PC0 */
#define VAL_GPIO_LED_CRH 0x88388888 /* PC15...PC8 */
#define RCC_ENR_IOP_EN (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN)
#define RCC_RSTR_IOP_RST (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPCRST)

View File

@@ -3,6 +3,7 @@
/* echo -n "Blue Pill" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */ /* echo -n "Blue Pill" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */
#define BOARD_ID 0xa1099d43 #define BOARD_ID 0xa1099d43
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */ #define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
@@ -12,13 +13,14 @@
#define GPIO_LED_BASE GPIOC_BASE #define GPIO_LED_BASE GPIOC_BASE
#define GPIO_LED_CLEAR_TO_EMIT 13 #define GPIO_LED_CLEAR_TO_EMIT 13
#define GPIO_USB_BASE GPIOA_BASE #define GPIO_USB_BASE GPIOA_BASE
#define GPIO_USB_SET_TO_ENABLE 12
#undef GPIO_OTHER_BASE #undef GPIO_OTHER_BASE
/* /*
* Port A setup. * Port A setup.
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM) * PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP) * PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
*
* Port C setup.
* PC13 - Push pull output 50MHz (LED 1:ON 0:OFF) * PC13 - Push pull output 50MHz (LED 1:ON 0:OFF)
* ------------------------ Default * ------------------------ Default
* PAx - input with pull-up * PAx - input with pull-up

View File

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

View File

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

View File

@@ -2,6 +2,7 @@
#define BOARD_ID 0x696886af #define BOARD_ID 0x696886af
/* echo -n "FST-01" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */ /* echo -n "FST-01" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */ #define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
@@ -70,6 +71,7 @@
* Those will be removed soon, once such an driver will be improved * Those will be removed soon, once such an driver will be improved
* in new style. * in new style.
*/ */
#if defined(PINPAD_CIR_SUPPORT)
/* For pin-cir settings of Gnuk */ /* For pin-cir settings of Gnuk */
#define TIMx TIM2 #define TIMx TIM2
#define INTR_REQ_TIM TIM2_IRQ #define INTR_REQ_TIM TIM2_IRQ
@@ -82,3 +84,4 @@
#define ENABLE_RCC_APB1 #define ENABLE_RCC_APB1
#define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN #define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST #define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST
#endif

View File

@@ -2,6 +2,7 @@
#define BOARD_ID 0x8801277f #define BOARD_ID 0x8801277f
/* echo -n "FST-01G" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */ /* echo -n "FST-01G" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */ #define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
@@ -70,7 +71,7 @@
* Those will be removed soon, once such an driver will be improved * Those will be removed soon, once such an driver will be improved
* in new style. * in new style.
*/ */
/* For pin-cir settings of Gnuk */ #if defined(PINPAD_CIR_SUPPORT)
#define TIMx TIM2 #define TIMx TIM2
#define INTR_REQ_TIM TIM2_IRQ #define INTR_REQ_TIM TIM2_IRQ
#define AFIO_EXTICR_INDEX 0 #define AFIO_EXTICR_INDEX 0
@@ -82,3 +83,4 @@
#define ENABLE_RCC_APB1 #define ENABLE_RCC_APB1
#define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN #define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST #define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST
#endif

43
board/board-fst-01sz.h Normal file
View File

@@ -0,0 +1,43 @@
#define BOARD_NAME "FST-01SZ"
#define BOARD_ID 0x7e6fb084
/* echo -n "FST-01SZ" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */
#define MCU_STM32F1_GD32F1 1
#define STM32_USBPRE STM32_USBPRE_DIV2
#define STM32_ADCPRE STM32_ADCPRE_DIV8
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 8
#define STM32_HSECLK 12000000
#define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_SET_TO_EMIT 8
#define GPIO_USB_BASE GPIOA_BASE
#undef GPIO_OTHER_BASE
/*
* Port A setup.
* PA0 - input with pull-up: AN0 for NeuG
* PA1 - input with pull-up: AN1 for NeuG
* PA3 - input with pull-up: Hall effect sensor output
* PA8 - Push pull output 10MHz 0 default (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 0xFFFFE6FF
#define VAL_GPIO_LED_CRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x88811881 /* PA15...PA8 */
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPAEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPARST
/*
* Board specific information other than clock and GPIO initial
* setting should not be in board-*.h, but each driver should include
* such specific information by itself.
*/

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "Olimex STM32-H103" #define BOARD_NAME "Olimex STM32-H103"
#define BOARD_ID 0xf92bb594 #define BOARD_ID 0xf92bb594
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */ #define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
@@ -30,11 +31,3 @@
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPCEN #define RCC_ENR_IOP_EN RCC_APB2ENR_IOPCEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPCRST #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/' */ /* echo -n "ST Dongle" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */
#define BOARD_ID 0x2cd4e471 #define BOARD_ID 0x2cd4e471
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */ #define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

@@ -16,6 +16,7 @@
* GND BLACK --> 20 GND * GND BLACK --> 20 GND
*/ */
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */ #define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
@@ -25,21 +26,40 @@
#define GPIO_LED_BASE GPIOA_BASE #define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_SET_TO_EMIT 5 #define GPIO_LED_SET_TO_EMIT 5
#undef GPIO_USB_BASE /* No external DISCONNECT/RENUM circuit. */ #undef GPIO_USB_BASE /* No external DISCONNECT/RENUM circuit. */
#undef GPIO_OTHER_BASE #define GPIO_OTHER_BASE GPIOB_BASE
/* /*
* Port A setup. * Port A setup.
* PA0 - input with pull-up. AN0 * PA0 - Input with pull-up USART2-CTS
* PA1 - input with pull-up. AN1 * PA1 - Alternate function push pull output 2MHz USART2-RTS
* PA5 - Push pull output 50MHz (LED 1:ON 0:OFF) * 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) * PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP) * PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* ------------------------ Default * ------------------------ Default
* PAx - input with pull-up * PAx - input with pull-up
*/ */
#define VAL_GPIO_LED_ODR 0xFFFFE7FF #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 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_NAME "STBee Mini"
#define BOARD_ID 0x1f341961 #define BOARD_ID 0x1f341961
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */ #define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "STM8S Discovery" #define BOARD_NAME "STM8S Discovery"
#define BOARD_ID 0x2f0976bb #define BOARD_ID 0x2f0976bb
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */ #define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
@@ -43,7 +44,7 @@
#define VAL_GPIO_OTHER_CRH 0x88888888 /* PB15...PB8 */ #define VAL_GPIO_OTHER_CRH 0x88888888 /* PB15...PB8 */
/* For pin-cir settings of Gnuk */ #if defined(PINPAD_CIR_SUPPORT)
#define TIMx TIM3 #define TIMx TIM3
#define INTR_REQ_TIM TIM3_IRQ #define INTR_REQ_TIM TIM3_IRQ
#define AFIO_EXTICR_INDEX 1 #define AFIO_EXTICR_INDEX 1
@@ -57,3 +58,4 @@
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM3RST #define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM3RST
#define AFIO_MAPR_SOMETHING AFIO_MAPR_TIM3_REMAP_PARTIALREMAP #define AFIO_MAPR_SOMETHING AFIO_MAPR_TIM3_REMAP_PARTIALREMAP
/* Remap (PB4, PB5) -> (TIM3_CH1, TIM3_CH2) */ /* Remap (PB4, PB5) -> (TIM3_CH1, TIM3_CH2) */
#endif

View File

@@ -2,7 +2,7 @@
* chopstx-cortex-m.c - Threads and only threads: Arch specific code * chopstx-cortex-m.c - Threads and only threads: Arch specific code
* for Cortex-M0/M3 * for Cortex-M0/M3
* *
* Copyright (C) 2013, 2014, 2015, 2016, 2017 * Copyright (C) 2013, 2014, 2015, 2016, 2017, 2018
* Flying Stone Technology * Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
@@ -28,6 +28,13 @@
* *
*/ */
/* Data Memory Barrier. */
static void
chx_dmb (void)
{
asm volatile ("dmb" : : : "memory");
}
/* Saved registers on the stack. */ /* Saved registers on the stack. */
struct chx_stack_regs { struct chx_stack_regs {
uint32_t reg[8]; /* r0, r1, r2, r3, r12, lr, pc, xpsr */ uint32_t reg[8]; /* r0, r1, r2, r3, r12, lr, pc, xpsr */
@@ -229,18 +236,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 void
chx_handle_intr (void) chx_handle_intr (void)
{ {
@@ -299,7 +294,7 @@ chx_request_preemption (uint16_t prio)
* *
* Returns: * Returns:
* 1 on wakeup by others. * 1 on wakeup by others.
* 0 on normal wakeup. * 0 on normal wakeup (timer expiration, lock aquirement).
* -1 on cancellation. * -1 on cancellation.
*/ */
static uintptr_t __attribute__ ((naked, noinline)) static uintptr_t __attribute__ ((naked, noinline))
@@ -309,25 +304,24 @@ chx_sched (uint32_t yield)
#if defined(__ARM_ARCH_7M__) #if defined(__ARM_ARCH_7M__)
asm volatile ( asm volatile (
"svc #0\n\t" "svc #0"
"bx lr"
: "=r" (tp) : "0" (yield): "memory"); : "=r" (tp) : "0" (yield): "memory");
#else #else
register uint32_t arg_yield asm ("r1"); register uint32_t arg_yield asm ("r1");
/* Build stack data as if it were an exception entry. */ /* Build stack data as if it were an exception entry. */
/* /*
* r0: 0 scratch * r0: TP scratch
* r1: 0 scratch * r1: 0 scratch
* r2: 0 scratch * r2: 0 scratch
* r3: 0 scratch * r3: 0 scratch
* r12: 0 scratch * r12: 0 scratch
* lr as-is * lr as-is
* pc: return address (= lr) * pc: return address (= .L_CONTEXT_SWITCH_FINISH)
* psr: INITIAL_XPSR scratch * psr: INITIAL_XPSR scratch
*/ */
asm ("mov r1, lr\n\t" asm ("mov r1, lr\n\t"
"mov r2, r1\n\t" "ldr r2, =.L_CONTEXT_SWITCH_FINISH\n\t"
"mov r3, #128\n\t" "mov r3, #128\n\t"
"lsl r3, #17\n\t" "lsl r3, #17\n\t"
"push {r1, r2, r3}\n\t" "push {r1, r2, r3}\n\t"
@@ -335,16 +329,16 @@ chx_sched (uint32_t yield)
"mov r2, r1\n\t" "mov r2, r1\n\t"
"mov r3, r1\n\t" "mov r3, r1\n\t"
"push {r1, r2, r3}\n\t" "push {r1, r2, r3}\n\t"
"push {r1, r2}" "mov r1, r0\n\t"
: /* no output*/
: /* no input */
: "r1", "r2", "r3", "memory");
/* Save registers onto CHX_THREAD struct. */
asm ("mov r1, r0\n\t"
"ldr r2, =running\n\t" "ldr r2, =running\n\t"
"ldr r0, [r2]\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" "stm r0!, {r4, r5, r6, r7}\n\t"
"mov r2, r8\n\t" "mov r2, r8\n\t"
"mov r3, r9\n\t" "mov r3, r9\n\t"
@@ -353,8 +347,8 @@ chx_sched (uint32_t yield)
"mov r6, sp\n\t" "mov r6, sp\n\t"
"stm r0!, {r2, r3, r4, r5, r6}\n\t" "stm r0!, {r2, r3, r4, r5, r6}\n\t"
"sub r0, #56" "sub r0, #56"
: "=r" (tp), "=r" (arg_yield) : /* no output */
: "0" (yield) : "r" (tp)
: "r2", "r3", "r4", "r5", "r6", "r7", "memory"); : "r2", "r3", "r4", "r5", "r6", "r7", "memory");
if (arg_yield) if (arg_yield)
@@ -383,7 +377,7 @@ chx_sched (uint32_t yield)
/* Spawn an IDLE thread. */ /* Spawn an IDLE thread. */
"ldr r1, =__main_stack_end__\n\t" "ldr r1, =__main_stack_end__\n\t"
"mov sp, r1\n\t" "mov sp, r1\n\t"
"ldr r0, =idle\n\t" /* PC = idle */ "ldr r0, =chx_idle\n\t" /* PC = idle */
/**/ /**/
/* Unmask interrupts. */ /* Unmask interrupts. */
"cpsie i\n\t" "cpsie i\n\t"
@@ -391,11 +385,7 @@ chx_sched (uint32_t yield)
/* Normal context switch */ /* Normal context switch */
"0:\n\t" "0:\n\t"
"add r0, #16\n\t" /* ->V */ "add r0, #20\n\t"
"ldr r1, [r0]\n\t"
"str r1, [sp]\n\t"
/**/
"add r0, #4\n\t"
"ldm r0!, {r4, r5, r6, r7}\n\t" "ldm r0!, {r4, r5, r6, r7}\n\t"
"ldm r0!, {r1, r2, r3}\n\t" "ldm r0!, {r1, r2, r3}\n\t"
"mov r8, r1\n\t" "mov r8, r1\n\t"
@@ -455,12 +445,17 @@ chx_sched (uint32_t yield)
"mov r12, r0\n\t" "mov r12, r0\n\t"
"pop {r0, r1, r2, r3}\n\t" "pop {r0, r1, r2, r3}\n\t"
"add sp, #12\n\t" "add sp, #12\n\t"
"pop {pc}" "pop {pc}\n\t"
".L_CONTEXT_SWITCH_FINISH:"
: "=r" (tp) /* Return value in R0 */ : "=r" (tp) /* Return value in R0 */
: "0" (tp) : "0" (tp)
: "memory"); : "memory");
#endif #endif
asm volatile ("bx lr"
: "=r" (tp)
: "0" (tp->v)
: "memory");
return (uintptr_t)tp; return (uintptr_t)tp;
} }
@@ -631,7 +626,7 @@ preempt (void)
"mov r3, #0\n\t" "mov r3, #0\n\t"
"stm r0!, {r1, r2, r3}\n\t" "stm r0!, {r1, r2, r3}\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" "mov r2, #0x010\n\t"
"lsl r2, r2, #20\n\t" /* xPSR = T-flag set (Thumb) */ "lsl r2, r2, #20\n\t" /* xPSR = T-flag set (Thumb) */
"stm r0!, {r1, r2}\n\t" "stm r0!, {r1, r2}\n\t"
@@ -675,7 +670,8 @@ svc (void)
"mov r5, r11\n\t" "mov r5, r11\n\t"
"mrs r6, PSP\n\t" /* r13(=SP) in user space. */ "mrs r6, PSP\n\t" /* r13(=SP) in user space. */
"stm r1!, {r2, r3, r4, r5, r6}\n\t" "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) : "=r" (tp), "=r" (orig_r0)
: /* no input */ : /* no input */
: "r2", "r3", "r4", "r5", "r6", "memory"); : "r2", "r3", "r4", "r5", "r6", "memory");
@@ -697,10 +693,6 @@ svc (void)
} }
asm volatile ( 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" "b .L_CONTEXT_SWITCH"
: /* no output */ : "r" (tp) : "memory"); : /* no output */ : "r" (tp) : "memory");
} }

View File

@@ -2,7 +2,7 @@
* chopstx-gnu-linux.c - Threads and only threads: Arch specific code * chopstx-gnu-linux.c - Threads and only threads: Arch specific code
* for GNU/Linux emulation * for GNU/Linux emulation
* *
* Copyright (C) 2017 Flying Stone Technology * Copyright (C) 2017, 2018 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.
@@ -32,6 +32,13 @@
#include <signal.h> #include <signal.h>
#include <sys/time.h> #include <sys/time.h>
/* Data Memory Barrier. */
static void
chx_dmb (void)
{
}
static sigset_t ss_cur; static sigset_t ss_cur;
static void static void

View File

@@ -1,7 +1,7 @@
/* /*
* chopstx.c - Threads and only threads. * chopstx.c - Threads and only threads.
* *
* Copyright (C) 2013, 2014, 2015, 2016, 2017 * Copyright (C) 2013, 2014, 2015, 2016, 2017, 2018
* Flying Stone Technology * Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
@@ -79,7 +79,11 @@ chx_fatal (uint32_t err_code)
#include "chopstx-cortex-m.h" #include "chopstx-cortex-m.h"
#endif #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_thread *running;
struct chx_queue { struct chx_queue {
@@ -382,6 +386,7 @@ chx_timer_expired (void)
{ {
uint32_t next_tick = tp->v; uint32_t next_tick = tp->v;
tp->v = (uintptr_t)0;
chx_ready_enqueue (tp); chx_ready_enqueue (tp);
if (tp == running) /* tp->flag_sched_rr == 1 */ if (tp == running) /* tp->flag_sched_rr == 1 */
prio = MAX_PRIO; prio = MAX_PRIO;
@@ -398,6 +403,7 @@ chx_timer_expired (void)
tp = tp_next) tp = tp_next)
{ {
next_tick = tp->v; next_tick = tp->v;
tp->v = (uintptr_t)0;
tp_next = (struct chx_thread *)tp->next; tp_next = (struct chx_thread *)tp->next;
ll_dequeue ((struct chx_pq *)tp); ll_dequeue ((struct chx_pq *)tp);
chx_ready_enqueue (tp); chx_ready_enqueue (tp);
@@ -440,6 +446,7 @@ chx_init (struct chx_thread *tp)
{ {
chx_prio_init (); chx_prio_init ();
chx_init_arch (tp); 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; q_ready.q.next = q_ready.q.prev = (struct chx_pq *)&q_ready.q;
chx_spin_init (&q_ready.lock); chx_spin_init (&q_ready.lock);
@@ -569,6 +576,7 @@ chx_mutex_unlock (chopstx_mutex_t *mutex)
uint16_t newprio = running->prio_orig; uint16_t newprio = running->prio_orig;
chopstx_mutex_t *m; chopstx_mutex_t *m;
tp->v = (uintptr_t)0;
chx_ready_enqueue (tp); chx_ready_enqueue (tp);
/* Examine mutexes we hold, and determine new priority for running. */ /* Examine mutexes we hold, and determine new priority for running. */
@@ -961,6 +969,7 @@ chx_cond_hook (struct chx_px *px, struct chx_poll_head *pd)
{ /* Condition doesn't met. { /* Condition doesn't met.
* Register the proxy to wait for the condition. * Register the proxy to wait for the condition.
*/ */
pc->ready = 0;
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
chx_spin_lock (&pc->cond->lock); chx_spin_lock (&pc->cond->lock);
ll_prio_enqueue ((struct chx_pq *)px, &pc->cond->q); ll_prio_enqueue ((struct chx_pq *)px, &pc->cond->q);
@@ -990,6 +999,7 @@ chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num)
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
chx_spin_lock (&q_intr.lock); chx_spin_lock (&q_intr.lock);
chx_disable_intr (irq_num); chx_disable_intr (irq_num);
chx_clr_intr (irq_num);
chx_set_intr_prio (irq_num); chx_set_intr_prio (irq_num);
chx_spin_unlock (&q_intr.lock); chx_spin_unlock (&q_intr.lock);
chx_cpu_sched_unlock (); chx_cpu_sched_unlock ();
@@ -1004,10 +1014,19 @@ chx_intr_hook (struct chx_px *px, struct chx_poll_head *pd)
chopstx_testcancel (); chopstx_testcancel ();
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
px->v = intr->irq_num; px->v = intr->irq_num;
chx_spin_lock (&q_intr.lock); if (intr->ready)
ll_prio_enqueue ((struct chx_pq *)px, &q_intr.q); {
chx_enable_intr (intr->irq_num); chx_spin_lock (&px->lock);
chx_spin_unlock (&q_intr.lock); (*px->counter_p)++;
chx_spin_unlock (&px->lock);
}
else
{
chx_spin_lock (&q_intr.lock);
ll_prio_enqueue ((struct chx_pq *)px, &q_intr.q);
chx_enable_intr (intr->irq_num);
chx_spin_unlock (&q_intr.lock);
}
chx_cpu_sched_unlock (); chx_cpu_sched_unlock ();
} }
@@ -1026,6 +1045,26 @@ chopstx_intr_wait (chopstx_intr_t *intr)
} }
/**
* chopstx_intr_done - Finish an IRQ handling
* @intr: Pointer to INTR structure
*
* Finish for the interrupt @intr occurred.
*
*/
void
chopstx_intr_done (chopstx_intr_t *intr)
{
chx_dmb ();
if (intr->ready)
{
chx_clr_intr (intr->irq_num);
intr->ready = 0;
}
}
/** /**
* chopstx_cleanup_push - Register a clean-up * chopstx_cleanup_push - Register a clean-up
* @clp: Pointer to clean-up structure * @clp: Pointer to clean-up structure
@@ -1190,6 +1229,7 @@ chx_join_hook (struct chx_px *px, struct chx_poll_head *pd)
{ /* Not yet exited. { /* Not yet exited.
* Register the proxy to wait for TP's exit. * Register the proxy to wait for TP's exit.
*/ */
pj->ready = 0;
px->v = (uintptr_t)tp; px->v = (uintptr_t)tp;
chx_spin_lock (&q_join.lock); chx_spin_lock (&q_join.lock);
ll_prio_enqueue ((struct chx_pq *)px, &q_join.q); ll_prio_enqueue ((struct chx_pq *)px, &q_join.q);
@@ -1316,7 +1356,7 @@ chx_proxy_init (struct chx_px *px, uint32_t *cp)
* Returns number of active descriptors. * Returns number of active descriptors.
*/ */
int 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; uint32_t counter = 0;
int i; int i;
@@ -1324,6 +1364,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[])
struct chx_poll_head *pd; struct chx_poll_head *pd;
int r = 0; int r = 0;
chx_dmb ();
chopstx_testcancel (); chopstx_testcancel ();
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
@@ -1332,7 +1373,6 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[])
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
pd = pd_array[i]; pd = pd_array[i];
pd->ready = 0;
px[i].ready_p = &pd->ready; px[i].ready_p = &pd->ready;
if (pd->type == CHOPSTX_POLL_COND) if (pd->type == CHOPSTX_POLL_COND)
chx_cond_hook (&px[i], pd); chx_cond_hook (&px[i], pd);
@@ -1376,6 +1416,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[])
while (r == 0); while (r == 0);
} }
chx_dmb ();
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
pd = pd_array[i]; pd = pd_array[i];
@@ -1396,9 +1437,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[])
{ {
struct chx_intr *intr = (struct chx_intr *)pd; struct chx_intr *intr = (struct chx_intr *)pd;
if (intr->ready) if (intr->ready == 0)
chx_clr_intr (intr->irq_num);
else
{ {
chx_spin_lock (&q_intr.lock); chx_spin_lock (&q_intr.lock);
ll_dequeue ((struct chx_pq *)&px[i]); ll_dequeue ((struct chx_pq *)&px[i]);
@@ -1469,3 +1508,38 @@ chopstx_setpriority (chopstx_prio_t prio_new)
return prio_orig; 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. * 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> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.
@@ -155,9 +155,13 @@ typedef struct chx_intr chopstx_intr_t;
void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num); void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num);
void chopstx_intr_wait (chopstx_intr_t *intr); /* DEPRECATED */ void chopstx_intr_wait (chopstx_intr_t *intr);
void chopstx_intr_done (chopstx_intr_t *intr);
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 #define CHOPSTX_THREAD_SIZE 64

View File

@@ -0,0 +1,96 @@
/*
* ackbtn-stm32f103.c - Acknowledge button support for STM32F103
*
* Copyright (C) 2018 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 <string.h>
#include <chopstx.h>
#include <mcu/stm32f103.h>
#include "board.h"
#include "sys.h"
static uint32_t pin_config;
#define PINCFG_EDGE 0x80000000
#define PINCFG_EDGE_RISING PINCFG_EDGE
void
ackbtn_init (chopstx_intr_t *intr)
{
uint8_t irq_num;
uint32_t afio_exticr_index;
uint32_t afio_exticr_extiX_pY;
switch (SYS_BOARD_ID)
{
case BOARD_ID_FST_01SZ:
default:
/* PA3 is connected to a hall sensor DRV5032FA */
afio_exticr_index = 0;
afio_exticr_extiX_pY = AFIO_EXTICR1_EXTI3_PA;
irq_num = EXTI3_IRQ;
pin_config = 0x0008; /* EXTI_PR_PR3 == EXTI_IMR_MR3 == EXTI_RTSR_TR3 */
pin_config |= PINCFG_EDGE_RISING;
break;
}
/* Configure EXTI line */
if (afio_exticr_extiX_pY)
AFIO->EXTICR[afio_exticr_index] |= afio_exticr_extiX_pY;
/* Interrupt is masked, now */
EXTI->IMR &= ~(pin_config & ~PINCFG_EDGE);
chopstx_claim_irq (intr, irq_num);
}
void
ackbtn_enable (void)
{
/* Clear pending interrupt */
EXTI->PR |= (pin_config & ~PINCFG_EDGE);
/* Enable interrupt, clearing the mask */
EXTI->IMR |= (pin_config & ~PINCFG_EDGE);
/* Configure which edge is detected */
if ((pin_config & PINCFG_EDGE))
EXTI->RTSR |= (pin_config & ~PINCFG_EDGE);
else
EXTI->FTSR |= (pin_config & ~PINCFG_EDGE);
}
void
ackbtn_disable (void)
{
/* Disable interrupt having the mask */
EXTI->IMR &= ~(pin_config & ~PINCFG_EDGE);
/* Clear pending interrupt */
/* Disable edge detection */
EXTI->RTSR &= ~(pin_config & ~PINCFG_EDGE);
EXTI->FTSR &= ~(pin_config & ~PINCFG_EDGE);
}

3
contrib/ackbtn.h Normal file
View File

@@ -0,0 +1,3 @@
void ackbtn_init (chopstx_intr_t *intr);
void ackbtn_enable (void);
void ackbtn_disable (void);

View File

@@ -295,19 +295,20 @@ adc_stop (void)
int int
adc_wait_completion (void) adc_wait_completion (void)
{ {
struct chx_poll_head *pd_array[1] = { (struct chx_poll_head *)&adc_intr };
int i; int i;
while (1) while (1)
{ {
/* Wait DMA completion */ /* Wait DMA completion */
chopstx_poll (NULL, 1, pd_array); chopstx_intr_wait (&adc_intr);
DMA0->DSR_BCR = (1 << 24); DMA0->DSR_BCR = (1 << 24);
DMA1->DSR_BCR = (1 << 24); DMA1->DSR_BCR = (1 << 24);
adc_stop_conversion (); adc_stop_conversion ();
chopstx_intr_done (&adc_intr);
for (i = 0; i < adc.count; i++) for (i = 0; i < adc.count; i++)
*adc.p++ = (uint8_t)adc.buf[i]; *adc.p++ = (uint8_t)adc.buf[i];

View File

@@ -3,7 +3,7 @@
* In this ADC driver, there are NeuG specific parts. * In this ADC driver, there are NeuG specific parts.
* You need to modify to use this as generic ADC driver. * You need to modify to use this as generic ADC driver.
* *
* Copyright (C) 2011, 2012, 2013, 2015, 2016 * Copyright (C) 2011, 2012, 2013, 2015, 2016, 2017, 2018
* Free Software Initiative of Japan * Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
@@ -34,6 +34,8 @@
#include <chopstx.h> #include <chopstx.h>
#include <mcu/stm32f103.h> #include <mcu/stm32f103.h>
#include "adc.h" #include "adc.h"
#include "board.h"
#include "sys.h"
#define STM32_ADC_ADC1_DMA_PRIORITY 2 #define STM32_ADC_ADC1_DMA_PRIORITY 2
@@ -46,6 +48,7 @@
#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) #define ADC_SMPR2_SMP_AN0(n) ((n) << 0)
#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) #define ADC_SMPR2_SMP_AN1(n) ((n) << 3)
#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) #define ADC_SMPR2_SMP_AN2(n) ((n) << 6)
#define ADC_SMPR2_SMP_AN8(n) ((n) << 24)
#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) #define ADC_SMPR2_SMP_AN9(n) ((n) << 27)
#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20) #define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
@@ -60,6 +63,7 @@
#define ADC_CHANNEL_IN0 0 #define ADC_CHANNEL_IN0 0
#define ADC_CHANNEL_IN1 1 #define ADC_CHANNEL_IN1 1
#define ADC_CHANNEL_IN2 2 #define ADC_CHANNEL_IN2 2
#define ADC_CHANNEL_IN8 8
#define ADC_CHANNEL_IN9 9 #define ADC_CHANNEL_IN9 9
#define ADC_CHANNEL_IN10 10 #define ADC_CHANNEL_IN10 10
#define ADC_CHANNEL_IN11 11 #define ADC_CHANNEL_IN11 11
@@ -67,7 +71,9 @@
#define ADC_CHANNEL_VREFINT 17 #define ADC_CHANNEL_VREFINT 17
#define DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME #define DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
#ifndef MCU_STM32F1_GD32F1
#define DELIBARATELY_DO_IT_WRONG_START_STOP #define DELIBARATELY_DO_IT_WRONG_START_STOP
#endif
#ifdef DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME #ifdef DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
#define ADC_SAMPLE_VREF ADC_SAMPLE_1P5 #define ADC_SAMPLE_VREF ADC_SAMPLE_1P5
@@ -112,6 +118,8 @@ adc_init (void)
ADC1->CR1 = 0; ADC1->CR1 = 0;
ADC1->CR2 = ADC_CR2_ADON; ADC1->CR2 = ADC_CR2_ADON;
chopstx_usec_wait (1000);
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL; ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0) while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
; ;
@@ -122,6 +130,8 @@ adc_init (void)
ADC2->CR1 = 0; ADC2->CR1 = 0;
ADC2->CR2 = ADC_CR2_ADON; ADC2->CR2 = ADC_CR2_ADON;
chopstx_usec_wait (1000);
ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL; ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
while ((ADC2->CR2 & ADC_CR2_RSTCAL) != 0) while ((ADC2->CR2 & ADC_CR2_RSTCAL) != 0)
; ;
@@ -135,15 +145,13 @@ adc_init (void)
return 0; return 0;
} }
#include "board.h"
#include "sys.h"
static void static void
get_adc_config (uint32_t config[4]) get_adc_config (uint32_t config[4])
{ {
config[2] = ADC_SQR1_NUM_CH(2); config[2] = ADC_SQR1_NUM_CH(2);
switch (SYS_BOARD_ID) switch (SYS_BOARD_ID)
{ {
case BOARD_ID_FST_01G:
case BOARD_ID_FST_01: case BOARD_ID_FST_01:
config[0] = 0; config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
@@ -169,14 +177,22 @@ get_adc_config (uint32_t config[4])
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN2); | ADC_SQR3_SQ2_N(ADC_CHANNEL_IN2);
break; 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_CQ_STARM:
case BOARD_ID_FST_01_00: case BOARD_ID_FST_01_00:
case BOARD_ID_MAPLE_MINI: case BOARD_ID_MAPLE_MINI:
case BOARD_ID_STM32_PRIMER2: case BOARD_ID_STM32_PRIMER2:
case BOARD_ID_STM8S_DISCOVERY: case BOARD_ID_STM8S_DISCOVERY:
case BOARD_ID_ST_DONGLE: case BOARD_ID_ST_DONGLE:
case BOARD_ID_ST_NUCLEO_F103:
case BOARD_ID_NITROKEY_START: case BOARD_ID_NITROKEY_START:
case BOARD_ID_FST_01SZ:
default: default:
config[0] = 0; config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
@@ -202,24 +218,26 @@ adc_start (void)
RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN); RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
| ADC_CR1_SCAN);
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1; ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1;
ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2; ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2;
ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS); ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS);
ADC1->SQR2 = 0; ADC1->SQR2 = 0;
ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3; ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3;
ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
| ADC_CR1_SCAN); | ADC_CR1_SCAN);
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON; ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
chopstx_usec_wait (1000);
ADC2->SMPR1 = config[0]; ADC2->SMPR1 = config[0];
ADC2->SMPR2 = config[1]; ADC2->SMPR2 = config[1];
ADC2->SQR1 = config[2]; ADC2->SQR1 = config[2];
ADC2->SQR2 = 0; ADC2->SQR2 = 0;
ADC2->SQR3 = config[3]; ADC2->SQR3 = config[3];
ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
| ADC_CR1_SCAN);
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
chopstx_usec_wait (1000);
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
/* /*
@@ -298,11 +316,10 @@ int
adc_wait_completion (void) adc_wait_completion (void)
{ {
uint32_t flags; uint32_t flags;
struct chx_poll_head *pd_array[1] = { (struct chx_poll_head *)&adc_intr };
while (1) while (1)
{ {
chopstx_poll (NULL, 1, pd_array); chopstx_intr_wait (&adc_intr);
flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */ flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */
/* /*
* Clear interrupt cause of channel 1. * Clear interrupt cause of channel 1.
@@ -311,6 +328,7 @@ adc_wait_completion (void)
* and TEIF. * and TEIF.
*/ */
DMA1->IFCR = (flags & ~1); DMA1->IFCR = (flags & ~1);
chopstx_intr_done (&adc_intr);
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */ if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
{ {

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

@@ -0,0 +1,630 @@
/*
* 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);
chopstx_intr_done (&usart2_intr);
}
if (usart3_intr.ready)
{
usart3_tx_ready = handle_intr (USART3, &usart3_rb_h2a, &usart3_stat);
chopstx_intr_done (&usart3_intr);
}
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

@@ -107,6 +107,14 @@ Claim interrupt @var{intr} with @var{irq_num}
Wait for the interrupt @var{intr} to be occured. Wait for the interrupt @var{intr} to be occured.
@end deftypefun @end deftypefun
@subheading chopstx_intr_done
@anchor{chopstx_intr_done}
@deftypefun {void} {chopstx_intr_done} (chopstx_intr_t * @var{intr})
@var{intr}: Pointer to INTR structure
Finish for the interrupt @var{intr} occurred.
@end deftypefun
@subheading chopstx_cleanup_push @subheading chopstx_cleanup_push
@anchor{chopstx_cleanup_push} @anchor{chopstx_cleanup_push}
@deftypefun {void} {chopstx_cleanup_push} (struct chx_cleanup * @var{clp}) @deftypefun {void} {chopstx_cleanup_push} (struct chx_cleanup * @var{clp})
@@ -176,7 +184,7 @@ Returns old state which is 0 when it was enabled.
@subheading chopstx_poll @subheading chopstx_poll
@anchor{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{usec_p}: Pointer to usec for timeout. Forever if NULL.
@var{n}: Number of poll descriptors @var{n}: Number of poll descriptors
@@ -201,3 +209,23 @@ which starts its execution with priority of CHX_PRIO_MAIN_INIT, and
let it change its priority after initialization of other threads. let it change its priority after initialization of other threads.
@end deftypefun @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-*- \input texinfo @c -*-texinfo-*-
@c %**start of header @c %**start of header
@setfilename chopstx.info @setfilename chopstx.info
@set VERSION 1.5 @set VERSION 1.11
@settitle Chopstx Reference Manual @settitle Chopstx Reference Manual
@c Unify some of the indices. @c Unify some of the indices.
@syncodeindex tp fn @syncodeindex tp fn
@@ -11,7 +11,7 @@
This manual is for Chopstx (version @value{VERSION}). This manual is for Chopstx (version @value{VERSION}).
@noindent @noindent
Copyright @copyright{} 2013, 2015, 2016 Flying Stone Technology @* Copyright @copyright{} 2013, 2015, 2016, 2017, 2018 Flying Stone Technology @*
@quotation @quotation
Permission is granted to copy, distribute and/or modify this document Permission is granted to copy, distribute and/or modify this document
@@ -59,6 +59,10 @@ section entitled ``Copying''.
@menu @menu
* Introduction:: What is Chopstx. * 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.
* Compile-time macro:: Macro to be defined.
* API:: API. * API:: API.
Appendix Appendix
@@ -83,16 +87,91 @@ Indexes
@node Introduction @node Introduction
@chapter Introduction @chapter Introduction
Chopstx is an RT thread library for ARM Cortex-M0, Cortex-M0plus and Chopstx is an RT thread library for ARM Cortex-M0, Cortex-M0plus,
Cortex-M3. Specifically, it is used for STM32F030, MKL27Z and Cortex-M3 and GNU/Linux emulation. Specifically, it is used for
STM32F103. STM32F030, MKL27Z, STM32F103, GD32F103 and as a command on GNU/Linux.
While most RTOSes come with many features, drivers, and stacks, 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 With Chopstx, interrupt handling is also done by a thread. This
enables coherent code for ease of maintenance. 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 Compile-time macro
@chapter Compile-time macro
Compiling Chopstx, a macro MHZ should be supplied.
For example, when using the makefile rule of chopstx/rules.mk, please
define the make variable DEFS with -DMHZ=72 before inclusion of the rule file.
@subheading MHZ
@anchor{MHZ}
@defmac {MHZ}
Running CPU clock in MHz. Used for chopstx_usec_wait.
@end defmac
@node API @node API
@chapter API @chapter API

35
entry.c
View File

@@ -205,23 +205,23 @@ handler vector_table[] __attribute__ ((section(".startup.vectors"))) = {
preempt, /* PendSV */ preempt, /* PendSV */
chx_timer_expired, /* SysTick */ chx_timer_expired, /* SysTick */
/* 0x40 */ /* 0x40 */
chx_handle_intr /* WWDG */, chx_handle_intr /* PVD */, chx_handle_intr /* WWDG */, chx_handle_intr /* PVD */,
chx_handle_intr /* TAMPER */, chx_handle_intr /* RTC */, chx_handle_intr /* TAMPER */, chx_handle_intr /* RTC */,
chx_handle_intr /* FLASH */, chx_handle_intr /* RCC */, chx_handle_intr /* FLASH */, chx_handle_intr /* RCC */,
chx_handle_intr /* EXTI0 */, chx_handle_intr /* EXTI1 */, chx_handle_intr /* EXTI0 */, chx_handle_intr /* EXTI1 */,
/* 0x60 */ /* 0x60 */
chx_handle_intr /* EXTI2 */, chx_handle_intr /* EXTI3 */, chx_handle_intr /* EXTI2 */, chx_handle_intr /* EXTI3 */,
chx_handle_intr /* EXTI4 */, chx_handle_intr /* DMA1 CH1 */, chx_handle_intr /* EXTI4 */, chx_handle_intr /* DMA1 CH1 */,
chx_handle_intr /* DMA1 CH2 */, chx_handle_intr /* DMA1 CH3 */, chx_handle_intr /* DMA1 CH2 */, chx_handle_intr /* DMA1 CH3 */,
chx_handle_intr /* DMA1 CH4 */, chx_handle_intr /* DMA1 CH5 */, chx_handle_intr /* DMA1 CH4 */, chx_handle_intr /* DMA1 CH5 */,
/* 0x80 */ /* 0x80 */
chx_handle_intr /* DMA1 CH6 */, chx_handle_intr /* DMA1 CH7 */, chx_handle_intr /* DMA1 CH6 */, chx_handle_intr /* DMA1 CH7 */,
chx_handle_intr /* ADC1_2 */, chx_handle_intr /* USB HP */, chx_handle_intr /* ADC1_2 */, chx_handle_intr /* USB HP */,
/* 0x90 */ /* 0x90 */
chx_handle_intr /* USB LP */, chx_handle_intr /* CAN */, chx_handle_intr /* USB LP */, chx_handle_intr /* CAN RX1 */,
/* ... and more. EXT9_5, TIMx, I2C, SPI, USART, EXT15_10 */ chx_handle_intr /* CAN SCE */, chx_handle_intr /* EXT9_5 */,
chx_handle_intr, chx_handle_intr, /* 0xa0 */
/* 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,
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 */ /* 0xc0 */
@@ -229,15 +229,16 @@ handler vector_table[] __attribute__ ((section(".startup.vectors"))) = {
/* STM32F0 doesn't have more. */ /* 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, 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 #endif
#if !defined(STM32F10X_MD) #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, 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
}; };
#endif #endif

View File

@@ -244,7 +244,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0; tty0.flag_connected = 0;
tty0.flag_send_ready = 1; tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0; 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)); memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
} }
@@ -414,7 +414,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++) for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 0); vcom_setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED; tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
} }
@@ -427,7 +427,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++) for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 1); vcom_setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED; tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); 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); static void *tty_main (void *arg);
#include <signal.h>
#define INTR_REQ_USB SIGUSR1
#define PRIO_TTY 4 #define PRIO_TTY 4
static char __process3_stack_base__[4096]; static char __process3_stack_base__[4096];
@@ -647,7 +645,7 @@ tty_open (void)
tty0.flag_connected = 0; tty0.flag_connected = 0;
tty0.flag_send_ready = 1; tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0; 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)); memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0); chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -710,6 +708,7 @@ tty_main (void *arg)
* *
*/ */
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&usb_intr);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)
@@ -734,7 +733,7 @@ tty_main (void *arg)
* OK. * OK.
*/ */
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED; tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
continue; continue;
@@ -790,7 +789,7 @@ tty_main (void *arg)
} }
chopstx_mutex_lock (&t->mtx); 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) && t->flag_send_ready)
{ {
uint8_t line[32]; uint8_t line[32];
@@ -814,7 +813,7 @@ void
tty_wait_configured (struct tty *t) tty_wait_configured (struct tty *t)
{ {
chopstx_mutex_lock (&t->mtx); 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_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx); chopstx_mutex_unlock (&t->mtx);
} }

View File

@@ -10,6 +10,7 @@ CHIP=stm32f103
USE_SYS = yes USE_SYS = yes
USE_USB = yes USE_USB = yes
ENABLE_OUTPUT_HEX=yes
################################### ###################################
CROSS = arm-none-eabi- CROSS = arm-none-eabi-
@@ -19,7 +20,7 @@ OBJCOPY = $(CROSS)objcopy
MCU = cortex-m3 MCU = cortex-m3
CWARN = -Wall -Wextra -Wstrict-prototypes CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DUSE_SYS3 -DFREE_STANDING DEFS = -DUSE_SYS3 -DFREE_STANDING -DMHZ=72
OPT = -O3 -Os -g OPT = -O3 -Os -g
LIBS = LIBS =

View File

@@ -248,7 +248,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0; tty0.flag_connected = 0;
tty0.flag_send_ready = 1; tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0; 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)); memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
} }
@@ -417,7 +417,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++) for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (i, 0); vcom_setup_endpoints_for_interface (i, 0);
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED; tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
} }
@@ -430,7 +430,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++) for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (i, 1); vcom_setup_endpoints_for_interface (i, 1);
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED; tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
} }
@@ -639,7 +639,6 @@ usb_rx_ready (uint8_t ep_num, uint16_t len)
static void *tty_main (void *arg); static void *tty_main (void *arg);
#define INTR_REQ_USB 20
#define PRIO_TTY 4 #define PRIO_TTY 4
#define STACK_PROCESS_3 #define STACK_PROCESS_3
@@ -657,7 +656,7 @@ tty_open (void)
tty0.flag_connected = 0; tty0.flag_connected = 0;
tty0.flag_send_ready = 1; tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0; 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)); memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0); chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -720,6 +719,7 @@ tty_main (void *arg)
* *
*/ */
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&usb_intr);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)
@@ -744,7 +744,7 @@ tty_main (void *arg)
* OK. * OK.
*/ */
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED; tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
continue; continue;
@@ -800,7 +800,7 @@ tty_main (void *arg)
} }
chopstx_mutex_lock (&t->mtx); 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) && t->flag_send_ready)
{ {
uint8_t line[32]; uint8_t line[32];
@@ -824,7 +824,7 @@ void
tty_wait_configured (struct tty *t) tty_wait_configured (struct tty *t)
{ {
chopstx_mutex_lock (&t->mtx); 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_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx); chopstx_mutex_unlock (&t->mtx);
} }

View File

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

View File

@@ -11,13 +11,14 @@
static chopstx_mutex_t usb_mtx; static chopstx_mutex_t usb_mtx;
static chopstx_cond_t usb_cnd; 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_IN_Callback (uint16_t len);
extern void EP6_OUT_Callback (uint16_t len); extern void EP6_OUT_Callback (uint16_t len);
#define MSC_MASS_STORAGE_RESET_COMMAND 0xFF #define MSC_MASS_STORAGE_RESET_COMMAND 0xFF
extern int fraucheky_enabled (void); extern int fraucheky_enabled (void);
extern void fraucheky_init (void);
extern void fraucheky_main (void); extern void fraucheky_main (void);
extern void fraucheky_setup_endpoints_for_interface (struct usb_dev *dev, int stop); extern void fraucheky_setup_endpoints_for_interface (struct usb_dev *dev, int stop);
@@ -41,13 +42,9 @@ usb_device_reset (struct usb_dev *dev)
/* Initialize Endpoint 0. */ /* Initialize Endpoint 0. */
usb_lld_setup_endp (dev, ENDP0, 1, 1); usb_lld_setup_endp (dev, ENDP0, 1, 1);
/* Stop the interface */
for (i = 0; i < NUM_INTERFACES; i++)
setup_endpoints_for_interface (dev, i, 1);
/* Notify upper layer. */ /* Notify upper layer. */
chopstx_mutex_lock (&usb_mtx); chopstx_mutex_lock (&usb_mtx);
bDeviceState = ATTACHED; bDeviceState = USB_DEVICE_STATE_ATTACHED;
chopstx_cond_signal (&usb_cnd); chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx); chopstx_mutex_unlock (&usb_mtx);
} }
@@ -95,7 +92,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++) for (i = 0; i < NUM_INTERFACES; i++)
setup_endpoints_for_interface (dev, i, 0); setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&usb_mtx); chopstx_mutex_lock (&usb_mtx);
bDeviceState = CONFIGURED; bDeviceState = USB_DEVICE_STATE_CONFIGURED;
chopstx_mutex_unlock (&usb_mtx); chopstx_mutex_unlock (&usb_mtx);
} }
else if (current_conf != dev->dev_req.value) else if (current_conf != dev->dev_req.value)
@@ -107,7 +104,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++) for (i = 0; i < NUM_INTERFACES; i++)
setup_endpoints_for_interface (dev, i, 1); setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&usb_mtx); chopstx_mutex_lock (&usb_mtx);
bDeviceState = ADDRESSED; bDeviceState = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&usb_cnd); chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx); chopstx_mutex_unlock (&usb_mtx);
} }
@@ -164,7 +161,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); static void usb_rx_ready (uint8_t ep_num, uint16_t len);
#define INTR_REQ_USB SIGUSR1
#define PRIO_USB 3 #define PRIO_USB 3
static void * static void *
@@ -189,6 +185,7 @@ usb_main (void *arg)
event_handle: event_handle:
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&interrupt);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)
@@ -207,7 +204,7 @@ usb_main (void *arg)
case USB_EVENT_DEVICE_ADDRESSED: case USB_EVENT_DEVICE_ADDRESSED:
chopstx_mutex_lock (&usb_mtx); chopstx_mutex_lock (&usb_mtx);
bDeviceState = ADDRESSED; bDeviceState = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&usb_cnd); chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx); chopstx_mutex_unlock (&usb_mtx);
continue; continue;
@@ -305,16 +302,17 @@ main (int argc, char **argv)
chopstx_mutex_init (&usb_mtx); chopstx_mutex_init (&usb_mtx);
chopstx_cond_init (&usb_cnd); 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_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
usb_main, NULL); usb_main, NULL);
while (bDeviceState != CONFIGURED) fraucheky_init ();
while (bDeviceState != USB_DEVICE_STATE_CONFIGURED)
chopstx_usec_wait (250*1000); chopstx_usec_wait (250*1000);
fraucheky_main (); fraucheky_main ();
chopstx_cancel (usb_thd); chopstx_cancel (usb_thd);
chopstx_join (usb_thd, NULL); chopstx_join (usb_thd, NULL);
usb_lld_shutdown (); usb_lld_shutdown ();
bDeviceState = UNCONNECTED; bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
return 0; return 0;
} }

View File

@@ -74,6 +74,7 @@ touch_get (void)
TPM1->SC = 0; TPM1->SC = 0;
TPM1->CNT = 0xffff; /* Writing causes reset of the counter. */ TPM1->CNT = 0xffff; /* Writing causes reset of the counter. */
chopstx_intr_done (&tpm1_intr);
return v; return v;
} }

View File

@@ -245,7 +245,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0; tty0.flag_connected = 0;
tty0.flag_send_ready = 1; tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0; 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)); memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
} }
@@ -409,7 +409,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++) for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 0); vcom_setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED; tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
} }
@@ -422,7 +422,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++) for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 1); vcom_setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED; tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); 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); static void *tty_main (void *arg);
#define INTR_REQ_USB 24
#define PRIO_TTY 4 #define PRIO_TTY 4
extern uint8_t __process3_stack_base__[], __process3_stack_size__[]; extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
@@ -643,7 +642,7 @@ tty_open (void)
tty0.flag_connected = 0; tty0.flag_connected = 0;
tty0.flag_send_ready = 1; tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0; 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)); memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0); chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -709,6 +708,7 @@ tty_main (void *arg)
* *
*/ */
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&usb_intr);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)
@@ -733,7 +733,7 @@ tty_main (void *arg)
* OK. * OK.
*/ */
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED; tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd); chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx); chopstx_mutex_unlock (&tty0.mtx);
continue; continue;
@@ -789,7 +789,7 @@ tty_main (void *arg)
} }
chopstx_mutex_lock (&t->mtx); 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) && t->flag_send_ready)
{ {
uint8_t line[32]; uint8_t line[32];
@@ -813,7 +813,7 @@ void
tty_wait_configured (struct tty *t) tty_wait_configured (struct tty *t)
{ {
chopstx_mutex_lock (&t->mtx); 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_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx); chopstx_mutex_unlock (&t->mtx);
} }

View File

@@ -7,6 +7,8 @@ LDSCRIPT= hacker-emblem.ld
CSRC = reset.c hh.c CSRC = reset.c hh.c
CHIP=stm32f0
# Hacker Emblem and "Happy Hacking!" demonstration # Hacker Emblem and "Happy Hacking!" demonstration
# CSRC = reset.c hh.c # CSRC = reset.c hh.c
@@ -25,7 +27,7 @@ OBJCOPY = $(CROSS)objcopy
MCU = cortex-m0 # -save-temps MCU = cortex-m0 # -save-temps
CWARN = -Wall -Wextra -Wstrict-prototypes CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DMAKE_ENTRY_PUBLIC \ DEFS = -DMAKE_ENTRY_PUBLIC \
-DFREE_STANDING -DMHZ=48 -DUSE_WFI_FOR_IDLE -DFREE_STANDING -DMHZ=48
OPT = -O3 -Os -g OPT = -O3 -Os -g
LIBS = LIBS =

View File

@@ -7,7 +7,7 @@
static uint8_t main_finished; static uint8_t main_finished;
#define PERIPH_BASE 0x40000000 #define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE #define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) #define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
@@ -163,17 +163,19 @@ button (void *arg)
return NULL; return NULL;
} }
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#include "stack-def.h"
#define PRIO_LED 3 #define PRIO_LED 3
#define PRIO_BUTTON 2 #define PRIO_BUTTON 2
extern uint8_t __process1_stack_base__[], __process1_stack_size__[]; #define STACK_ADDR_LED ((uint32_t)process1_base)
extern uint8_t __process2_stack_base__[], __process2_stack_size__[]; #define STACK_SIZE_LED (sizeof process1_base)
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__) #define STACK_ADDR_BUTTON ((uint32_t)process2_base)
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__) #define STACK_SIZE_BUTTON (sizeof process2_base)
#define STACK_ADDR_BUTTON ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_BUTTON ((uint32_t)__process2_stack_size__)
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0) #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)) #define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
@@ -365,8 +367,6 @@ text_display (uint8_t kind)
} }
static void setup_scr_sleepdeep (void);
int int
main (int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
@@ -378,6 +378,8 @@ main (int argc, const char *argv[])
(void)argc; (void)argc;
(void)argv; (void)argv;
chopstx_conf_idle (1);
chopstx_mutex_init (&mtx); chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0); chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd1); chopstx_cond_init (&cnd1);
@@ -418,56 +420,6 @@ main (int argc, const char *argv[])
chopstx_join (button_thd, NULL); chopstx_join (button_thd, NULL);
chopstx_join (led_thd, NULL); chopstx_join (led_thd, NULL);
setup_scr_sleepdeep (); chopstx_conf_idle (4);
for (;;)
asm volatile ("wfi" : : : "memory");
return 0; 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. * 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 MEMORY
{ {
flash : org = 0x08000000, len = 16k flash : org = 0x08000000, len = 16k
@@ -61,34 +55,15 @@ SECTIONS
_etext = .; _etext = .;
_textdata = _etext; _textdata = _etext;
.process_stack : .stacks (NOLOAD) :
{ {
. = ALIGN(8); . = ALIGN(8);
__process3_stack_base__ = .; *(.main_stack)
. += __process3_stack_size__; *(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
. = ALIGN(8); . = 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 } > ram
.data : .data :

View File

@@ -7,7 +7,7 @@
static uint8_t main_finished; static uint8_t main_finished;
#define PERIPH_BASE 0x40000000 #define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE #define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) #define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
@@ -166,14 +166,16 @@ button (void *arg)
#define PRIO_LED 3 #define PRIO_LED 3
#define PRIO_BUTTON 2 #define PRIO_BUTTON 2
extern uint8_t __process1_stack_base__[], __process1_stack_size__[]; #define STACK_MAIN
extern uint8_t __process2_stack_base__[], __process2_stack_size__[]; #define STACK_PROCESS_1
#define STACK_PROCESS_2
#include "stack-def.h"
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__) #define STACK_ADDR_LED ((uint32_t)process1_base)
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__) #define STACK_SIZE_LED (sizeof process1_base)
#define STACK_ADDR_BUTTON ((uint32_t)__process2_stack_base__) #define STACK_ADDR_BUTTON ((uint32_t)process2_base)
#define STACK_SIZE_BUTTON ((uint32_t)__process2_stack_size__) #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 DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t)) #define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
@@ -355,8 +357,6 @@ text_display (uint8_t kind)
} }
static void setup_scr_sleepdeep (void);
int int
main (int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
@@ -366,6 +366,8 @@ main (int argc, const char *argv[])
(void)argc; (void)argc;
(void)argv; (void)argv;
chopstx_conf_idle (1);
chopstx_mutex_init (&mtx); chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0); chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd1); chopstx_cond_init (&cnd1);
@@ -406,56 +408,6 @@ main (int argc, const char *argv[])
chopstx_join (button_thd, NULL); chopstx_join (button_thd, NULL);
chopstx_join (led_thd, NULL); chopstx_join (led_thd, NULL);
setup_scr_sleepdeep (); chopstx_conf_idle (4);
for (;;)
asm volatile ("wfi" : : : "memory");
return 0; 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" #include "board.h"
#define PERIPH_BASE 0x40000000 #define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE #define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000) #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 #define PRIO_LED 3
extern uint8_t __process1_stack_base__[], __process1_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__)
static void * static void *
led (void *arg) led (void *arg)
@@ -119,10 +123,9 @@ led (void *arg)
#define PRIO_SPK 4 #define PRIO_SPK 4
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
#define STACK_ADDR_SPK ((uint32_t)__process2_stack_base__) #define STACK_ADDR_SPK ((uint32_t)process2_base)
#define STACK_SIZE_SPK ((uint32_t)__process2_stack_size__) #define STACK_SIZE_SPK (sizeof process2_base)
static chopstx_mutex_t spk_mtx; static chopstx_mutex_t spk_mtx;
static chopstx_cond_t spk_cnd; static chopstx_cond_t spk_cnd;
@@ -193,10 +196,9 @@ spk (void *arg)
#define PRIO_MUSIC 2 #define PRIO_MUSIC 2
extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
#define STACK_ADDR_MUSIC ((uint32_t)__process3_stack_base__) #define STACK_ADDR_MUSIC ((uint32_t)process3_base)
#define STACK_SIZE_MUSIC ((uint32_t)__process3_stack_size__) #define STACK_SIZE_MUSIC (sizeof process3_base)
#define C 0 #define C 0
#define D 1 #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 #define PRIO_BLK 2
#endif #endif
extern uint8_t __process1_stack_base__[], __process1_stack_size__[]; #define STACK_MAIN
extern uint8_t __process2_stack_base__[], __process2_stack_size__[]; #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_ADDR_PWM ((uint32_t)process1_base)
#define STACK_SIZE_BLK ((uint32_t)__process2_stack_size__) #define STACK_SIZE_PWM (sizeof process1_base)
#define STACK_ADDR_BLK ((uint32_t)process2_base)
#define STACK_SIZE_BLK (sizeof process2_base)
int int

View File

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

View File

@@ -1,12 +1,6 @@
/* /*
* ST32F103 memory setup. * 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 MEMORY
{ {
flash0 : org = 0x08000000, len = 4k flash0 : org = 0x08000000, len = 4k
@@ -78,34 +72,14 @@ SECTIONS
_etext = .; _etext = .;
_textdata = _etext; _textdata = _etext;
.process_stack : .stacks (NOLOAD) :
{ {
*(.main_stack)
*(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
. = ALIGN(8); . = 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 } > ram
.data : .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" #include "board.h"
#define PERIPH_BASE 0x40000000 #define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE #define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
struct GPIO { struct GPIO {

View File

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

View File

@@ -107,6 +107,10 @@ void adc3_conversion (uint32_t *result)
/* Stop conversion. */ /* Stop conversion. */
ADC3->CR2 &= ~ADC_CR2_JSWSTART; ADC3->CR2 &= ~ADC_CR2_JSWSTART;
#if USE_ADC3_INTR
chopstx_intr_done (&adc3_intr);
#endif
return; return;
} }

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 -DMHZ=72
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

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. */
}
}
}

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

@@ -0,0 +1,92 @@
#include <stdint.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)
#ifndef STM32_ADCPRE
#define STM32_ADCPRE STM32_ADCPRE_DIV6
#endif
#ifndef STM32_USBPRE
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#endif
static void
configure_clock (int high)
{
uint32_t cfg_sw;
uint32_t cfg;
if (high)
{
cfg = STM32_MCO_NOCLOCK | STM32_USBPRE
| STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC
| STM32_ADCPRE | STM32_PPRE2_DIV1
| STM32_PPRE1_DIV2 | STM32_HPRE_DIV1;
cfg_sw = RCC_CFGR_SW_PLL;
}
else
{
cfg = STM32_MCO_NOCLOCK | STM32_USBPRE
| 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

@@ -1,7 +1,7 @@
/* /*
* clk_gpio_init-stm32.c - Clock and GPIO initialization for STM32. * clk_gpio_init-stm32.c - Clock and GPIO initialization for STM32.
* *
* Copyright (C) 2015 Flying Stone Technology * Copyright (C) 2015, 2018 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.
@@ -26,28 +26,11 @@
* *
*/ */
#define STM32_SW_HSI (0 << 0) #if defined(MCU_STM32F0)
#define STM32_SW_PLL (2 << 0) #include <mcu/stm32.h>
#define STM32_PLLSRC_HSI (0 << 16) #else
#define STM32_PLLSRC_HSE (1 << 16) #include <mcu/stm32f103.h>
#endif
#define STM32_PLLXTPRE_DIV1 (0 << 17)
#define STM32_PLLXTPRE_DIV2 (1 << 17)
#define STM32_HPRE_DIV1 (0 << 4)
#define STM32_PPRE1_DIV1 (0 << 8)
#define STM32_PPRE1_DIV2 (4 << 8)
#define STM32_PPRE2_DIV1 (0 << 11)
#define STM32_PPRE2_DIV2 (4 << 11)
#define STM32_ADCPRE_DIV4 (1 << 14)
#define STM32_ADCPRE_DIV6 (2 << 14)
#define STM32_USBPRE_DIV1P5 (0 << 22)
#define STM32_MCO_NOCLOCK (0 << 24)
#if defined(MCU_STM32F0) #if defined(MCU_STM32F0)
#define STM32_PPRE1 STM32_PPRE1_DIV1 #define STM32_PPRE1 STM32_PPRE1_DIV1
@@ -64,9 +47,13 @@
#define STM32_SW STM32_SW_PLL #define STM32_SW STM32_SW_PLL
#define STM32_HPRE STM32_HPRE_DIV1 #define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE2 STM32_PPRE2_DIV1 #define STM32_PPRE2 STM32_PPRE2_DIV1
#ifndef STM32_ADCPRE
#define STM32_ADCPRE STM32_ADCPRE_DIV6 #define STM32_ADCPRE STM32_ADCPRE_DIV6
#endif
#define STM32_MCOSEL STM32_MCO_NOCLOCK #define STM32_MCOSEL STM32_MCO_NOCLOCK
#define STM32_USBPRE STM32_USBPRE_DIV1P5 #ifndef STM32_USBPRE
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#endif
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) #define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) #define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
@@ -74,113 +61,6 @@
#define STM32_HCLK (STM32_SYSCLK / 1) #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;
uint32_t dummy0;
volatile uint32_t EXTICR[4];
volatile uint32_t CFGR2;
};
#define SYSCFG_CFGR1_MEM_MODE 0x03
#define SYSCFG_BASE (APBPERIPH_BASE + 0x00010000)
static struct SYSCFG *const SYSCFG = (struct SYSCFG *)SYSCFG_BASE;
#endif
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = (struct FLASH *)FLASH_R_BASE;
static void __attribute__((used)) static void __attribute__((used))
clock_init (void) clock_init (void)
{ {
@@ -218,9 +98,6 @@ clock_init (void)
/* Flash setup */ /* Flash setup */
FLASH->ACR = STM32_FLASHBITS; FLASH->ACR = STM32_FLASHBITS;
/* CRC */
RCC->AHBENR |= RCC_AHBENR_CRCEN;
/* Switching on the configured clock source. */ /* Switching on the configured clock source. */
RCC->CFGR |= STM32_SW; RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
@@ -239,75 +116,6 @@ clock_init (void)
} }
#if defined(MCU_STM32F0)
struct GPIO {
volatile uint32_t MODER;
volatile uint16_t OTYPER;
uint16_t dummy0;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint16_t IDR;
uint16_t dummy1;
volatile uint16_t ODR;
uint16_t dummy2;
volatile uint16_t BSRR;
uint16_t dummy3;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint16_t BRR;
uint16_t dummy4;
};
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (AHB2PERIPH_BASE + 0x0400)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (AHB2PERIPH_BASE + 0x0800)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (AHB2PERIPH_BASE + 0x0C00)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
#else
struct AFIO
{
volatile uint32_t EVCR;
volatile uint32_t MAPR;
volatile uint32_t EXTICR[4];
uint32_t RESERVED0;
volatile uint32_t MAPR2;
};
#define AFIO_BASE 0x40010000
static struct AFIO *const AFIO = (struct AFIO *)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE 0x02000000
struct GPIO {
volatile uint32_t CRL;
volatile uint32_t CRH;
volatile uint32_t IDR;
volatile uint32_t ODR;
volatile uint32_t BSRR;
volatile uint32_t BRR;
volatile uint32_t LCKR;
};
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define GPIOE ((struct GPIO *) GPIOE_BASE)
#endif
static struct GPIO *const GPIO_LED = (struct GPIO *)GPIO_LED_BASE; static struct GPIO *const GPIO_LED = (struct GPIO *)GPIO_LED_BASE;
#ifdef GPIO_USB_BASE #ifdef GPIO_USB_BASE
static struct GPIO *const GPIO_USB = (struct GPIO *)GPIO_USB_BASE; static struct GPIO *const GPIO_USB = (struct GPIO *)GPIO_USB_BASE;
@@ -347,7 +155,7 @@ gpio_init (void)
AFIO->MAPR |= AFIO_MAPR_SOMETHING; AFIO->MAPR |= AFIO_MAPR_SOMETHING;
#endif #endif
/* LED is mandatory. If it's on an independent port, we configure it. */ /* LED is mandatory. We configure it always. */
GPIO_LED->ODR = VAL_GPIO_LED_ODR; GPIO_LED->ODR = VAL_GPIO_LED_ODR;
GPIO_LED->CRH = VAL_GPIO_LED_CRH; GPIO_LED->CRH = VAL_GPIO_LED_CRH;
GPIO_LED->CRL = VAL_GPIO_LED_CRL; GPIO_LED->CRL = VAL_GPIO_LED_CRL;

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

224
mcu/stm32.h Normal file
View File

@@ -0,0 +1,224 @@
#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_USBPRE_DIV2 (3 << 22) /* Not for STM32, but GD32F103 */
#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 */
#if defined(MCU_STM32F0)
struct GPIO {
volatile uint32_t MODER;
volatile uint16_t OTYPER;
uint16_t dummy0;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint16_t IDR;
uint16_t dummy1;
volatile uint16_t ODR;
uint16_t dummy2;
volatile uint16_t BSRR;
uint16_t dummy3;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint16_t BRR;
uint16_t dummy4;
};
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (AHB2PERIPH_BASE + 0x0400)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (AHB2PERIPH_BASE + 0x0800)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (AHB2PERIPH_BASE + 0x0C00)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
#else
struct GPIO {
volatile uint32_t CRL;
volatile uint32_t CRH;
volatile uint32_t IDR;
volatile uint32_t ODR;
volatile uint32_t BSRR;
volatile uint32_t BRR;
volatile uint32_t LCKR;
};
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define GPIOE ((struct GPIO *) GPIOE_BASE)
#endif
#if defined(MCU_STM32F0)
struct SYSCFG {
volatile uint32_t CFGR1;
uint32_t dummy0;
volatile uint32_t EXTICR[4];
volatile uint32_t CFGR2;
};
#define SYSCFG_CFGR1_MEM_MODE 0x03
#define SYSCFG_BASE (APB1PERIPH_BASE + 0x00010000)
static struct SYSCFG *const SYSCFG = (struct SYSCFG *)SYSCFG_BASE;
#endif
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = (struct FLASH *)FLASH_R_BASE;

View File

@@ -1,40 +1,5 @@
#define PERIPH_BASE 0x40000000 #include <mcu/stm32.h>
#define APB1PERIPH_BASE PERIPH_BASE #include <mcu/cortex-m.h>
#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 #define CRC_CR_RESET 0x00000001
@@ -182,36 +147,6 @@ static struct DMA *const DMA1 = (struct DMA *)DMA1_BASE;
static struct DMA_Channel *const DMA1_Channel1 = static struct DMA_Channel *const DMA1_Channel1 =
(struct DMA_Channel *)DMA1_Channel1_BASE; (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 */ /* Timer */
struct TIM struct TIM
{ {
@@ -639,6 +574,8 @@ static struct EXTI *const EXTI = (struct EXTI *)EXTI_BASE;
#define EXTI0_IRQ 6 #define EXTI0_IRQ 6
#define EXTI1_IRQ 7 #define EXTI1_IRQ 7
#define EXTI2_IRQ 8 #define EXTI2_IRQ 8
#define EXTI3_IRQ 9
#define EXTI4_IRQ 10
#define EXTI9_5_IRQ 23 #define EXTI9_5_IRQ 23
#define TIM2_IRQ 28 #define TIM2_IRQ 28
#define TIM3_IRQ 29 #define TIM3_IRQ 29
@@ -698,3 +635,13 @@ static struct AFIO *const AFIO = (struct AFIO *)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800 #define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000 #define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE 0x02000000
struct DBGMCU {
volatile uint32_t CR;
};
#define DBGMCU_BASE 0xE0042004
#define DBG_SLEEP 1
static struct DBGMCU *const DBGMCU = (struct DBGMCU *)DBGMCU_BASE;

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> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* Copying and distribution of this file, with or without modification, * Copying and distribution of this file, with or without modification,
@@ -18,6 +19,7 @@
#include "board.h" #include "board.h"
#define STM32F0_USE_VECTOR_ON_RAM #define STM32F0_USE_VECTOR_ON_RAM
#include "mcu/cortex-m.h"
#include "mcu/clk_gpio_init-stm32.c" #include "mcu/clk_gpio_init-stm32.c"
@@ -298,38 +300,11 @@ flash_erase_all_and_exec (void (*entry)(void))
for (;;); 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 static void
nvic_system_reset (void) nvic_system_reset (void)
{ {
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ); SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
asm volatile ("dsb"); asm volatile ("dsb");
for (;;); for (;;);
} }

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, 2018
* Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* Copying and distribution of this file, with or without modification, * Copying and distribution of this file, with or without modification,
@@ -80,7 +81,7 @@ usb_lld_sys_init (void)
{ {
usb_lld_sys_shutdown (); usb_lld_sys_shutdown ();
/* Disconnect requires SE0 (>= 2.5uS). */ /* Disconnect requires SE0 (>= 2.5uS). */
wait (300); wait (5*MHZ);
} }
usb_cable_config (1); usb_cable_config (1);
@@ -254,6 +255,9 @@ flash_protect (void)
FLASH->OPTKEYR = FLASH_KEY1; FLASH->OPTKEYR = FLASH_KEY1;
FLASH->OPTKEYR = FLASH_KEY2; FLASH->OPTKEYR = FLASH_KEY2;
while (!(FLASH->CR & FLASH_CR_OPTWRE))
;
FLASH->CR |= FLASH_CR_OPTER; FLASH->CR |= FLASH_CR_OPTER;
FLASH->CR |= FLASH_CR_STRT; FLASH->CR |= FLASH_CR_STRT;
@@ -299,38 +303,10 @@ flash_erase_all_and_exec (void (*entry)(void))
for (;;); 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 static void
nvic_system_reset (void) nvic_system_reset (void)
{ {
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ); SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
asm volatile ("dsb"); asm volatile ("dsb");
for (;;); for (;;);
} }

View File

@@ -1,6 +1,8 @@
#define BOARD_ID_CQ_STARM 0xc5480875 #define BOARD_ID_CQ_STARM 0xc5480875
#define BOARD_ID_FST_01_00 0x613870a9 #define BOARD_ID_FST_01_00 0x613870a9
#define BOARD_ID_FST_01 0x696886af #define BOARD_ID_FST_01 0x696886af
#define BOARD_ID_FST_01G 0x8801277f
#define BOARD_ID_FST_01SZ 0x7e6fb084
#define BOARD_ID_MAPLE_MINI 0x7a445272 #define BOARD_ID_MAPLE_MINI 0x7a445272
#define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594 #define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594
#define BOARD_ID_STBEE_MINI 0x1f341961 #define BOARD_ID_STBEE_MINI 0x1f341961
@@ -21,6 +23,8 @@ extern const uint8_t sys_board_name[];
#endif #endif
typedef void (*handler)(void); typedef void (*handler)(void);
typedef void (*nonreturn_handler0)(void)__attribute__((noreturn));
typedef void (*nonreturn_handler1)(void *)__attribute__((noreturn));
extern handler vector[16]; extern handler vector[16];
static inline const uint8_t * static inline const uint8_t *
@@ -90,10 +94,9 @@ flash_protect (void)
static inline void __attribute__((noreturn)) static inline void __attribute__((noreturn))
flash_erase_all_and_exec (void (*entry)(void)) 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); (*func) (entry);
for (;;);
} }
static inline void static inline void
@@ -111,7 +114,9 @@ usb_lld_sys_shutdown (void)
static inline void __attribute__((noreturn)) static inline void __attribute__((noreturn))
nvic_system_reset (void) nvic_system_reset (void)
{ {
(*vector[12]) (); nonreturn_handler0 func = (nonreturn_handler0)vector[12];
(func) ();
} }
#ifdef REQUIRE_CLOCK_GPIO_SETTING_IN_SYS #ifdef REQUIRE_CLOCK_GPIO_SETTING_IN_SYS

View File

@@ -41,6 +41,7 @@ struct endpoint_ctl {
}; };
static struct endpoint_ctl ep[16]; static struct endpoint_ctl ep[16];
#if 0
struct USB_CONF { struct USB_CONF {
const uint8_t PERID; /* Peripheral ID register */ const uint8_t PERID; /* Peripheral ID register */
uint8_t rsvd0[3]; /* */ uint8_t rsvd0[3]; /* */
@@ -51,6 +52,7 @@ struct USB_CONF {
volatile uint8_t ADDINFO; /* Peripheral Additional Info register */ volatile uint8_t ADDINFO; /* Peripheral Additional Info register */
}; };
static struct USB_CONF *const USB_CONF = (struct USB_CONF *)0x40072000; static struct USB_CONF *const USB_CONF = (struct USB_CONF *)0x40072000;
#endif
struct USB_CTRL0 { struct USB_CTRL0 {
volatile uint8_t OTGCTL; /* OTG Control register */ volatile uint8_t OTGCTL; /* OTG Control register */
@@ -948,11 +950,11 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
data_p->len = buflen; data_p->len = buflen;
/* Restrict the data length to be the one host asks for */ /* Restrict the data length to be the one host asks for */
if (data_p->len > len_asked) if (data_p->len >= len_asked)
data_p->len = len_asked; data_p->len = len_asked;
/* ZLP is only required when host doesn't expect the end of packets. */
data_p->require_zlp = (data_p->len != 0 else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
&& (data_p->len % USB_MAX_PACKET_SIZE) == 0); data_p->require_zlp = 1;
if (data_p->len < USB_MAX_PACKET_SIZE) if (data_p->len < USB_MAX_PACKET_SIZE)
{ {

View File

@@ -1,7 +1,7 @@
/* /*
* usb-stm32f103.c - USB driver for STM32F103 * 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> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.
@@ -339,7 +339,25 @@ void usb_lld_init (struct usb_dev *dev, uint8_t feature)
/* Clear Interrupt Status Register, and enable interrupt for USB */ /* Clear Interrupt Status Register, and enable interrupt for USB */
st103_set_istr (0); st103_set_istr (0);
st103_set_cntr (CNTR_CTRM | CNTR_RESETM);
st103_set_btable ();
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) void usb_lld_prepare_shutdown (void)
@@ -367,6 +385,19 @@ usb_lld_event_handler (struct usb_dev *dev)
st103_set_istr (CLR_RESET); st103_set_istr (CLR_RESET);
return USB_MAKE_EV (USB_EVENT_DEVICE_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 else
{ {
if ((istr_value & ISTR_OVR)) if ((istr_value & ISTR_OVR))
@@ -878,7 +909,6 @@ void usb_lld_reset (struct usb_dev *dev, uint8_t feature)
{ {
usb_lld_set_configuration (dev, 0); usb_lld_set_configuration (dev, 0);
dev->feature = feature; dev->feature = feature;
st103_set_btable ();
st103_set_daddr (0); st103_set_daddr (0);
} }
@@ -1075,10 +1105,10 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
data_p->len = buflen; data_p->len = buflen;
/* Restrict the data length to be the one host asks for */ /* Restrict the data length to be the one host asks for */
if (data_p->len > len_asked) if (data_p->len >= len_asked)
data_p->len = len_asked; data_p->len = len_asked;
/* ZLP is only required when host doesn't expect the end of packets. */
if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0) else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
data_p->require_zlp = 1; data_p->require_zlp = 1;
if (data_p->len < USB_MAX_PACKET_SIZE) if (data_p->len < USB_MAX_PACKET_SIZE)

View File

@@ -187,6 +187,7 @@ enum {
USB_INTR_DATA_TRANSFER, USB_INTR_DATA_TRANSFER,
USB_INTR_RESET, USB_INTR_RESET,
USB_INTR_SUSPEND, USB_INTR_SUSPEND,
USB_INTR_SHUTDOWN
}; };
struct usb_controller { struct usb_controller {
@@ -457,6 +458,7 @@ usbip_handle_data_urb (struct urb *urb)
} }
static int fd; static int fd;
static int shutdown_notify_fd;
static pthread_mutex_t fd_mutex; static pthread_mutex_t fd_mutex;
static void unlink_urb (struct urb *urb); static void unlink_urb (struct urb *urb);
@@ -801,7 +803,8 @@ usbip_process_cmd (void)
if (recv (fd, (char *)&msg, sizeof (msg), 0) != sizeof (msg)) if (recv (fd, (char *)&msg, sizeof (msg), 0) != sizeof (msg))
{ {
perror ("msg recv"); if (errno)
perror ("msg recv");
return -1; return -1;
} }
@@ -1039,6 +1042,9 @@ usbip_run_server (void *arg)
const int one = 1; const int one = 1;
struct pollfd pollfds[16]; struct pollfd pollfds[16];
int i; int i;
int r = 0;
(void)arg;
pthread_mutex_init (&usbc.mutex, NULL); pthread_mutex_init (&usbc.mutex, NULL);
pthread_cond_init (&usbc.cond, NULL); pthread_cond_init (&usbc.cond, NULL);
@@ -1046,7 +1052,6 @@ usbip_run_server (void *arg)
pthread_mutex_init (&fd_mutex, NULL); pthread_mutex_init (&fd_mutex, NULL);
pthread_mutex_init (&urb_mutex, NULL); pthread_mutex_init (&urb_mutex, NULL);
(void)arg;
if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0) if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
{ {
perror ("socket"); perror ("socket");
@@ -1075,9 +1080,7 @@ usbip_run_server (void *arg)
exit (1); exit (1);
} }
/* FIXME: We don't use this pollstruct as EP0 is handled pollfds[1].fd = shutdown_notify_fd;
synchronously. */
pollfds[1].fd = usbc_ep0.eventfd;
pollfds[1].events = POLLIN; pollfds[1].events = POLLIN;
pollfds[1].revents = 0; pollfds[1].revents = 0;
@@ -1097,14 +1100,15 @@ usbip_run_server (void *arg)
exit (1); 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].fd = fd;
pollfds[0].events = POLLIN; pollfds[0].events = POLLIN;
pollfds[0].revents = 0; pollfds[0].revents = 0;
for (;;) for (;;)
{ {
int r;
for (i = 1; i < 8; i++) for (i = 1; i < 8; i++)
{ {
if (usbc_ep_in[i].urb) if (usbc_ep_in[i].urb)
@@ -1124,7 +1128,7 @@ usbip_run_server (void *arg)
if (poll (pollfds, 16, -1) < 0) if (poll (pollfds, 16, -1) < 0)
{ {
if (errno == EINTR) if (errno == EINTR)
goto again; continue;
perror ("poll"); perror ("poll");
exit (1); exit (1);
@@ -1146,6 +1150,20 @@ usbip_run_server (void *arg)
goto again; 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++) for (i = 1; i < 8; i++)
{ {
if ((pollfds[i*2].revents & POLLNVAL) if ((pollfds[i*2].revents & POLLNVAL)
@@ -1178,9 +1196,41 @@ usbip_run_server (void *arg)
} }
} }
{
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 (fd);
close (sock); 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; return NULL;
} }
@@ -1408,9 +1458,8 @@ read_data_transaction (struct usb_control *usbc_p,
return count; 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 static void
usb_intr (int signum, siginfo_t *siginfo, void *arg) usb_intr (int signum, siginfo_t *siginfo, void *arg)
@@ -1445,6 +1494,13 @@ usb_lld_init (struct usb_dev *dev, uint8_t feature)
pthread_sigmask (SIG_BLOCK, &sigset, NULL); 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); pthread_mutex_init (&usbc_ep0.mutex, NULL);
usbc_ep0.urb = NULL; usbc_ep0.urb = NULL;
usbc_ep0.eventfd = eventfd (0, EFD_CLOEXEC); usbc_ep0.eventfd = eventfd (0, EFD_CLOEXEC);
@@ -1506,12 +1562,14 @@ usb_lld_prepare_shutdown (void)
void void
usb_lld_shutdown (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); pthread_join (tid_usbip, NULL);
/* FIXME: Cancel all URB in the list here. */ notify_device (USB_INTR_SHUTDOWN, 0, 0);
} }
static void static void
@@ -1550,6 +1608,11 @@ usb_lld_event_handler (struct usb_dev *dev)
return USB_MAKE_EV (handle_setup0 (dev)); return USB_MAKE_EV (handle_setup0 (dev));
else if (intr == USB_INTR_DATA_TRANSFER) else if (intr == USB_INTR_DATA_TRANSFER)
return usb_handle_transfer (dev, dir, ep_num); 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; return USB_EVENT_OK;
} }
@@ -2106,10 +2169,10 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
data_p->len = buflen; data_p->len = buflen;
/* Restrict the data length to be the one host asks for */ /* Restrict the data length to be the one host asks for */
if (data_p->len > len_asked) if (data_p->len >= len_asked)
data_p->len = len_asked; data_p->len = len_asked;
/* ZLP is only required when host doesn't expect the end of packets. */
if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0) else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
data_p->require_zlp = 1; data_p->require_zlp = 1;
if (data_p->len < USB_MAX_PACKET_SIZE) if (data_p->len < USB_MAX_PACKET_SIZE)

View File

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

View File

@@ -64,6 +64,7 @@ enum {
/* Device reset and suspend. */ /* Device reset and suspend. */
USB_EVENT_DEVICE_RESET, USB_EVENT_DEVICE_RESET,
USB_EVENT_DEVICE_SUSPEND, USB_EVENT_DEVICE_SUSPEND,
USB_EVENT_DEVICE_WAKEUP,
/* Device Requests (Control WRITE Transfer): Standard */ /* Device Requests (Control WRITE Transfer): Standard */
USB_EVENT_SET_CONFIGURATION, USB_EVENT_SET_CONFIGURATION,
USB_EVENT_SET_INTERFACE, USB_EVENT_SET_INTERFACE,
@@ -83,12 +84,13 @@ enum {
}; };
enum DEVICE_STATE { enum DEVICE_STATE {
UNCONNECTED, USB_DEVICE_STATE_UNCONNECTED = 0, /* No USB */
ATTACHED, USB_DEVICE_STATE_ATTACHED = 1,
POWERED, USB_DEVICE_STATE_POWERED = 2,
SUSPENDED, USB_DEVICE_STATE_DEFAULT = 3,
ADDRESSED, USB_DEVICE_STATE_ADDRESSED = 4,
CONFIGURED 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); 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); void usb_lld_shutdown (void);
#if defined(MCU_KINETIS_L) #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_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_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_setup_endp (struct usb_dev *dev, int ep_num, int rx_en, int tx_en);
void usb_lld_stall (int ep_num); void usb_lld_stall (int ep_num);
#elif defined(GNU_LINUX_EMULATION) #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_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_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_tx (int ep_num);
void usb_lld_stall_rx (int ep_num); void usb_lld_stall_rx (int ep_num);
#else #else
#define INTR_REQ_USB 20
/* EP_TYPE[1:0] EndPoint TYPE */ /* EP_TYPE[1:0] EndPoint TYPE */
#define EP_BULK (0x0000) /* EndPoint BULK */ #define EP_BULK (0x0000) /* EndPoint BULK */
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */ #define EP_CONTROL (0x0200) /* EndPoint CONTROL */