Compare commits
36 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e527b0532 | ||
|
|
817167dbcc | ||
|
|
63974743b4 | ||
|
|
14c4256337 | ||
|
|
8c4ea854cb | ||
|
|
a610821458 | ||
|
|
3071929c62 | ||
|
|
14cb38e56f | ||
|
|
a362f32cdd | ||
|
|
e684e853c8 | ||
|
|
2b98dc3de8 | ||
|
|
44054415c8 | ||
|
|
66b4eb3058 | ||
|
|
b72154f47b | ||
|
|
378201a1c7 | ||
|
|
1a7bd3e202 | ||
|
|
b34b9b6440 | ||
|
|
d745c9fdb9 | ||
|
|
3552fc5615 | ||
|
|
621dff7cb3 | ||
|
|
83643c53ca | ||
|
|
040f389449 | ||
|
|
44273a70fc | ||
|
|
7257f30636 | ||
|
|
941a8f6fbd | ||
|
|
13926ac05a | ||
|
|
bbe09de209 | ||
|
|
f161928b0b | ||
|
|
035057db24 | ||
|
|
5ac8a1f251 | ||
|
|
168af852a5 | ||
|
|
e398fc9689 | ||
|
|
5a08752b9c | ||
|
|
b572e3f8e0 | ||
|
|
55b011a721 | ||
|
|
c191d86bf2 |
127
ChangeLog
127
ChangeLog
@@ -1,3 +1,130 @@
|
||||
2017-11-24 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.6.
|
||||
* doc/chopstx.texi (VERSION): 1.6.
|
||||
* doc/chopstx-api.texi: Regenerated.
|
||||
|
||||
2017-11-21 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* example-fsm-55: Update using stack-def.h.
|
||||
|
||||
2017-11-20 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* example-led: Update using stack-def.h.
|
||||
|
||||
* chopstx-cortex-m.c [__ARM_ARCH_6M__] (chx_sched): Fix.
|
||||
|
||||
2017-11-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* example-fsm-55/hh.c (main): Just return.
|
||||
|
||||
2017-11-17 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* mcu/chx-stm32f103.c (configure_clock): Change prescaler on
|
||||
sleep.
|
||||
|
||||
* mcu/clk_gpio_init-stm32.c (clock_init): Don't turn on CRC
|
||||
module.
|
||||
|
||||
* mcu/clk_gpio_init-stm32.c (STM32_*): Move to...
|
||||
* mcu/stm32.h (STM32_*): ... this header file.
|
||||
|
||||
* mcu/stm32f103.h, mcu/clk_gpio_init-stm32.c (RCC): Move to...
|
||||
* mcu/stm32.h (RCC): ... this header file.
|
||||
|
||||
* example-fsm-55: Update for new sleep API.
|
||||
|
||||
* rules.mk (CSRC): Add mcu/chx-$(CHIP).c.
|
||||
|
||||
* chopstx-cortex-m.c (idle, chx_sleep_mode): Remove.
|
||||
(chx_sched, preempt): Call chx_idle.
|
||||
* mcu/chx-mkl27z.c, mcu/chx-stm32f0.c, mcu/chx-stm32f103.c: New.
|
||||
* mcu/stm32.h: New.
|
||||
|
||||
* chopstx-gnu-linux.c (chx_sleep_mode): Move to...
|
||||
* mcu/chx-gnu-linux.c: Here.
|
||||
|
||||
* mcu/stm32f103.h (DBGMCU): New.
|
||||
|
||||
* mcu/cortex-m.h: New.
|
||||
* mcu/sys-stm32f0.c, mcu/sys-stm32f103.c: Use mcu/cortex-m.h.
|
||||
|
||||
* chopstx.c (chopstx_conf_idle): Call chx_sleep_mode before
|
||||
changing chx_allow_sleep.
|
||||
|
||||
* board/board-blue-pill.h, board/board-cq-starm.h,
|
||||
board/board-fst-01-00.h, board/board-fst-01.h,
|
||||
board/board-fst-01g.h, board/board-maple-mini.h,
|
||||
board/board-nitrokey-start.h, board/board-olimex-stm32-h103.h,
|
||||
board/board-st-dongle.h, board/board-st-nucleo-f103.h,
|
||||
board/board-stbee-mini.h, board/board-stbee.h,
|
||||
board/board-stm32-primer2.h: Add MCU_STM32F1.
|
||||
|
||||
2017-11-16 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx.h (chopstx_poll): API change.
|
||||
* chopstx.c (chopstx_poll): Use const pointer.
|
||||
|
||||
* chopstx-cortex-m.c (idle): Support WFE.
|
||||
[!MCU_STM32F0] (chx_sleep_mode): Clock feed by HSI.
|
||||
|
||||
2017-11-15 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx.c (chopstx_conf_idle): Call chx_sleep_mode.
|
||||
* chopstx-cortex-m.c (chx_sleep_mode): New.
|
||||
* chopstx-gnu-linux.c (chx_sleep_mode): New.
|
||||
|
||||
2017-11-15 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* example-fsm-55/hh.c (main): Add call to chopstx_conf_idle.
|
||||
* example-fsm-55/Makefile (DEFS): Remove USE_WFI_FOR_IDLE.
|
||||
|
||||
* chopstx.c (chx_init): Initialize sleep lock.
|
||||
(chopstx_conf_idle): New.
|
||||
* chopstx-cortex-m.c (idle): Support sleep.
|
||||
|
||||
* mcu/usb-stm32f103.c (usb_lld_event_handler): Fix suspend/resume.
|
||||
|
||||
2017-11-14 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* usb_lld.h (DEVICE_STATE): Add prefix USB_DEVICE_STATE_.
|
||||
(USB_DEVICE_STATE_DEFAULT): New.
|
||||
|
||||
* mcu/usb-stm32f103.c (usb_lld_init): Suspend/resume init.
|
||||
(usb_lld_event_handler): Add suspend/resume support.
|
||||
|
||||
* example-cdc/usb-cdc.c: Follow the change of usb_lld.h.
|
||||
* example-cdc-gnu-linux/usb-cdc.c: Ditto.
|
||||
* example-fs-bb48/usb-cdc.c: Ditto.
|
||||
* example-fraucheky/main.c: Ditto.
|
||||
* example-fraucheky/Makefile (USE_SYS): Add for debug.
|
||||
|
||||
2017-11-13 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* mcu/usb-stm32f103.c (usb_lld_init): Set up interrupt on errors.
|
||||
|
||||
* usb_lld.h (USB_EVENT_DEVICE_WAKEUP): New.
|
||||
(INTR_REQ_USB): Define here.
|
||||
* mcu/usb-usbip.c, example-cdc/usb-cdc.c,
|
||||
example-fraucheky/main.c, example-fs-bb48/usb-cdc.c: Change
|
||||
for INTR_REQ_USB.
|
||||
|
||||
2017-11-10 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx-cortex-m.c (svc): Replace stack top to TP.
|
||||
(chx_sched): Return ->v correctly.
|
||||
|
||||
* chopstx.c (chx_timer_expired): Fix timeout.
|
||||
|
||||
2017-10-11 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* mcu/sys-stm32f103.h (nonreturn_handler0, nonreturn_handler1): New.
|
||||
|
||||
2017-10-10 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* mcu/usb-usbip.c (usbip_run_server): Shutdown support.
|
||||
(usb_lld_shutdown): Shutdown glace-fully.
|
||||
|
||||
2017-10-10 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.5.
|
||||
|
||||
30
NEWS
30
NEWS
@@ -1,6 +1,36 @@
|
||||
NEWS - Noteworthy changes
|
||||
|
||||
|
||||
* Major changes in Chopstx 1.6
|
||||
|
||||
Released 2017-11-24
|
||||
|
||||
** Fix cancellation
|
||||
In Chopstx 1.4 and 1.5, cancellation doesn't work for real MCU. This
|
||||
is due to the change of chx_sched interface, introduced for GNU/Linux
|
||||
emulation. This bug is fixed.
|
||||
|
||||
** New feature: sleep mode
|
||||
New function chopstx_conf_idle is added to support sleep. Note that
|
||||
use of sleep by this feature requires careful preparation. For
|
||||
example, enabling sleep, a board with no RESET pin cannot be debugged
|
||||
by JTAG/SWD. Setting of DBGMCU_CR (0xE0042004) is required beforehand
|
||||
(hardware default is zero).
|
||||
|
||||
** API change: chopstx_poll
|
||||
This is a kind of clarification. The third argument is now an array
|
||||
of constant pointers. We don't touch the array itself, just use it.
|
||||
This allows having the array in read-only memory and can contribute
|
||||
less use of RAM.
|
||||
|
||||
** USB API changes
|
||||
INTR_REQ_USB is now defined by usb_lld.h. Enumeration type of
|
||||
DEVICE_STATE now has USB_DEVICE_STATE_ prefix.
|
||||
|
||||
** USB driver change
|
||||
USB suspend and wakeup events are supported for STM32F103.
|
||||
|
||||
|
||||
* Major changes in Chopstx 1.5
|
||||
|
||||
Released 2017-10-10
|
||||
|
||||
10
README
10
README
@@ -1,6 +1,6 @@
|
||||
Chopstx - Threads and only Threads
|
||||
Version 1.5
|
||||
2017-10-10
|
||||
Version 1.6
|
||||
2017-11-24
|
||||
Niibe Yutaka
|
||||
Flying Stone Technology
|
||||
|
||||
@@ -17,12 +17,12 @@ stacks, Chopstx just offers a simple RT thread library.
|
||||
With Chopstx, interrupt handling is also done by a thread. This
|
||||
enables coherent code for ease of maintenance.
|
||||
|
||||
This library is _not_ related to the hand game:
|
||||
Note that this library is _not_ related to the hand game:
|
||||
|
||||
https://en.wikipedia.org/wiki/Chopsticks_(hand_game)
|
||||
|
||||
Thanks to Yao Wei and Enrico Zini for giving me the opportunity
|
||||
visiting the wiki page.
|
||||
Thanks to Yao Wei and Enrico Zini for giving me an opportunity
|
||||
visiting the wiki page above.
|
||||
|
||||
|
||||
License
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
/* echo -n "Blue Pill" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */
|
||||
#define BOARD_ID 0xa1099d43
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#define BOARD_NAME "CQ STARM"
|
||||
#define BOARD_ID 0xc5480875
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#define BOARD_NAME "FST-01-00"
|
||||
#define BOARD_ID 0x613870a9
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define BOARD_ID 0x696886af
|
||||
/* echo -n "FST-01" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define BOARD_ID 0x8801277f
|
||||
/* echo -n "FST-01G" | sha256sum | sed -e 's/^.*\(........\) -$/\1/' */
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#define BOARD_NAME "Maple Mini"
|
||||
#define BOARD_ID 0x7a445272
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#define BOARD_NAME "NITROKEY-START"
|
||||
#define BOARD_ID 0xad1e7ebd
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#define BOARD_NAME "Olimex STM32-H103"
|
||||
#define BOARD_ID 0xf92bb594
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/* echo -n "ST Dongle" | shasum -a 256 | sed -e 's/^.*\(........\) -$/\1/' */
|
||||
#define BOARD_ID 0x2cd4e471
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* GND BLACK --> 20 GND
|
||||
*/
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#define BOARD_NAME "STBee Mini"
|
||||
#define BOARD_ID 0x1f341961
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#define BOARD_NAME "STBee"
|
||||
#define BOARD_ID 0x945c37e8
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
/* High-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
#define STM32_PLLMUL_VALUE 6
|
||||
#define STM32_HSECLK 12000000
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#define BOARD_NAME "STM32 Primer2"
|
||||
#define BOARD_ID 0x21e5798d
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
/* High-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
#define STM32_PLLMUL_VALUE 6
|
||||
#define STM32_HSECLK 12000000
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#define BOARD_NAME "STM32F0 Discovery"
|
||||
#define BOARD_ID 0xde4b4bc1
|
||||
|
||||
#define MCU_STM32F0 1
|
||||
|
||||
/*
|
||||
* Running at 48MHz with HSI as clock source.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#define BOARD_NAME "STM8S Discovery"
|
||||
#define BOARD_ID 0x2f0976bb
|
||||
|
||||
#define MCU_STM32F1 1
|
||||
#define STM32F10X_MD /* Medium-density device */
|
||||
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
|
||||
@@ -229,18 +229,6 @@ chx_cpu_sched_unlock (void)
|
||||
}
|
||||
|
||||
|
||||
static void __attribute__((naked, used))
|
||||
idle (void)
|
||||
{
|
||||
#if defined(USE_WFI_FOR_IDLE)
|
||||
for (;;)
|
||||
asm volatile ("wfi" : : : "memory");
|
||||
#else
|
||||
for (;;);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
chx_handle_intr (void)
|
||||
{
|
||||
@@ -309,25 +297,24 @@ chx_sched (uint32_t yield)
|
||||
|
||||
#if defined(__ARM_ARCH_7M__)
|
||||
asm volatile (
|
||||
"svc #0\n\t"
|
||||
"bx lr"
|
||||
"svc #0"
|
||||
: "=r" (tp) : "0" (yield): "memory");
|
||||
#else
|
||||
register uint32_t arg_yield asm ("r1");
|
||||
|
||||
/* Build stack data as if it were an exception entry. */
|
||||
/*
|
||||
* r0: 0 scratch
|
||||
* r0: TP scratch
|
||||
* r1: 0 scratch
|
||||
* r2: 0 scratch
|
||||
* r3: 0 scratch
|
||||
* r12: 0 scratch
|
||||
* lr as-is
|
||||
* pc: return address (= lr)
|
||||
* pc: return address (= .L_CONTEXT_SWITCH_FINISH)
|
||||
* psr: INITIAL_XPSR scratch
|
||||
*/
|
||||
asm ("mov r1, lr\n\t"
|
||||
"mov r2, r1\n\t"
|
||||
"ldr r2, =.L_CONTEXT_SWITCH_FINISH\n\t"
|
||||
"mov r3, #128\n\t"
|
||||
"lsl r3, #17\n\t"
|
||||
"push {r1, r2, r3}\n\t"
|
||||
@@ -335,16 +322,16 @@ chx_sched (uint32_t yield)
|
||||
"mov r2, r1\n\t"
|
||||
"mov r3, r1\n\t"
|
||||
"push {r1, r2, r3}\n\t"
|
||||
"push {r1, r2}"
|
||||
: /* no output*/
|
||||
: /* no input */
|
||||
: "r1", "r2", "r3", "memory");
|
||||
|
||||
/* Save registers onto CHX_THREAD struct. */
|
||||
asm ("mov r1, r0\n\t"
|
||||
"mov r1, r0\n\t"
|
||||
"ldr r2, =running\n\t"
|
||||
"ldr r0, [r2]\n\t"
|
||||
"add r0, #20\n\t"
|
||||
"push {r0, r3}"
|
||||
: "=r" (tp), "=r" (arg_yield)
|
||||
: "0" (yield)
|
||||
: "r2", "r3", "memory");
|
||||
|
||||
/* Save registers onto CHX_THREAD struct. */
|
||||
asm ("add r0, #20\n\t"
|
||||
"stm r0!, {r4, r5, r6, r7}\n\t"
|
||||
"mov r2, r8\n\t"
|
||||
"mov r3, r9\n\t"
|
||||
@@ -353,8 +340,8 @@ chx_sched (uint32_t yield)
|
||||
"mov r6, sp\n\t"
|
||||
"stm r0!, {r2, r3, r4, r5, r6}\n\t"
|
||||
"sub r0, #56"
|
||||
: "=r" (tp), "=r" (arg_yield)
|
||||
: "0" (yield)
|
||||
: /* no output */
|
||||
: "r" (tp)
|
||||
: "r2", "r3", "r4", "r5", "r6", "r7", "memory");
|
||||
|
||||
if (arg_yield)
|
||||
@@ -383,7 +370,7 @@ chx_sched (uint32_t yield)
|
||||
/* Spawn an IDLE thread. */
|
||||
"ldr r1, =__main_stack_end__\n\t"
|
||||
"mov sp, r1\n\t"
|
||||
"ldr r0, =idle\n\t" /* PC = idle */
|
||||
"ldr r0, =chx_idle\n\t" /* PC = idle */
|
||||
/**/
|
||||
/* Unmask interrupts. */
|
||||
"cpsie i\n\t"
|
||||
@@ -391,11 +378,7 @@ chx_sched (uint32_t yield)
|
||||
|
||||
/* Normal context switch */
|
||||
"0:\n\t"
|
||||
"add r0, #16\n\t" /* ->V */
|
||||
"ldr r1, [r0]\n\t"
|
||||
"str r1, [sp]\n\t"
|
||||
/**/
|
||||
"add r0, #4\n\t"
|
||||
"add r0, #20\n\t"
|
||||
"ldm r0!, {r4, r5, r6, r7}\n\t"
|
||||
"ldm r0!, {r1, r2, r3}\n\t"
|
||||
"mov r8, r1\n\t"
|
||||
@@ -455,12 +438,17 @@ chx_sched (uint32_t yield)
|
||||
"mov r12, r0\n\t"
|
||||
"pop {r0, r1, r2, r3}\n\t"
|
||||
"add sp, #12\n\t"
|
||||
"pop {pc}"
|
||||
"pop {pc}\n\t"
|
||||
".L_CONTEXT_SWITCH_FINISH:"
|
||||
: "=r" (tp) /* Return value in R0 */
|
||||
: "0" (tp)
|
||||
: "memory");
|
||||
#endif
|
||||
|
||||
asm volatile ("bx lr"
|
||||
: "=r" (tp)
|
||||
: "0" (tp->v)
|
||||
: "memory");
|
||||
return (uintptr_t)tp;
|
||||
}
|
||||
|
||||
@@ -631,7 +619,7 @@ preempt (void)
|
||||
"mov r3, #0\n\t"
|
||||
"stm r0!, {r1, r2, r3}\n\t"
|
||||
"stm r0!, {r1, r2, r3}\n\t"
|
||||
"ldr r1, =idle\n\t" /* PC = idle */
|
||||
"ldr r1, =chx_idle\n\t" /* PC = idle */
|
||||
"mov r2, #0x010\n\t"
|
||||
"lsl r2, r2, #20\n\t" /* xPSR = T-flag set (Thumb) */
|
||||
"stm r0!, {r1, r2}\n\t"
|
||||
@@ -675,7 +663,8 @@ svc (void)
|
||||
"mov r5, r11\n\t"
|
||||
"mrs r6, PSP\n\t" /* r13(=SP) in user space. */
|
||||
"stm r1!, {r2, r3, r4, r5, r6}\n\t"
|
||||
"ldr r1, [r6]"
|
||||
"ldr r1, [r6]\n\t"
|
||||
"str r0, [r6]"
|
||||
: "=r" (tp), "=r" (orig_r0)
|
||||
: /* no input */
|
||||
: "r2", "r3", "r4", "r5", "r6", "memory");
|
||||
@@ -697,10 +686,6 @@ svc (void)
|
||||
}
|
||||
|
||||
asm volatile (
|
||||
"cbz r0, 0f\n\t"
|
||||
"ldr r1, [r0, #16]\n\t" /* ->V */
|
||||
"str r1, [sp]\n\t"
|
||||
"0:\n\t"
|
||||
"b .L_CONTEXT_SWITCH"
|
||||
: /* no output */ : "r" (tp) : "memory");
|
||||
}
|
||||
|
||||
45
chopstx.c
45
chopstx.c
@@ -79,7 +79,11 @@ chx_fatal (uint32_t err_code)
|
||||
#include "chopstx-cortex-m.h"
|
||||
#endif
|
||||
|
||||
/* RUNNING: the current thread. */
|
||||
/* ALLOW_SLEEP for the idle thread. */
|
||||
int chx_allow_sleep;
|
||||
static struct chx_spinlock chx_enable_sleep_lock;
|
||||
|
||||
/* RUNNING: the current thread. */
|
||||
struct chx_thread *running;
|
||||
|
||||
struct chx_queue {
|
||||
@@ -382,6 +386,7 @@ chx_timer_expired (void)
|
||||
{
|
||||
uint32_t next_tick = tp->v;
|
||||
|
||||
tp->v = (uintptr_t)0;
|
||||
chx_ready_enqueue (tp);
|
||||
if (tp == running) /* tp->flag_sched_rr == 1 */
|
||||
prio = MAX_PRIO;
|
||||
@@ -440,6 +445,7 @@ chx_init (struct chx_thread *tp)
|
||||
{
|
||||
chx_prio_init ();
|
||||
chx_init_arch (tp);
|
||||
chx_spin_init (&chx_enable_sleep_lock);
|
||||
|
||||
q_ready.q.next = q_ready.q.prev = (struct chx_pq *)&q_ready.q;
|
||||
chx_spin_init (&q_ready.lock);
|
||||
@@ -1316,7 +1322,7 @@ chx_proxy_init (struct chx_px *px, uint32_t *cp)
|
||||
* Returns number of active descriptors.
|
||||
*/
|
||||
int
|
||||
chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[])
|
||||
chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
|
||||
{
|
||||
uint32_t counter = 0;
|
||||
int i;
|
||||
@@ -1469,3 +1475,38 @@ chopstx_setpriority (chopstx_prio_t prio_new)
|
||||
|
||||
return prio_orig;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* chopstx_conf_idle - Configure IDLE thread
|
||||
* @enable_sleep: Enable sleep on idle or not
|
||||
*
|
||||
* If @enable_sleep is > 0, allow sleep for the idle thread.
|
||||
*
|
||||
* Behavior of @enable_sleep >= 1 depends on MCU.
|
||||
*
|
||||
* For STM32F0, 1 for Sleep (CPU clock OFF only), 2 for Stop (Wakeup
|
||||
* by EXTI, voltage regulator on), 3 for Stop (Wakeup by EXTI, voltage
|
||||
* regulator low-power), 4 for Standby (Wakeup by RESET, voltage
|
||||
* regulator off).
|
||||
*
|
||||
* For STM32F103, 1 for normal sleep, and 2 for sleep with lower 8MHz
|
||||
* clock.
|
||||
*
|
||||
* Return previous value of @enable_sleep.
|
||||
*/
|
||||
extern void chx_sleep_mode (int enable_sleep);
|
||||
|
||||
int
|
||||
chopstx_conf_idle (int enable_sleep)
|
||||
{
|
||||
int r;
|
||||
|
||||
chx_spin_lock (&chx_enable_sleep_lock);
|
||||
r = chx_allow_sleep;
|
||||
chx_sleep_mode (enable_sleep);
|
||||
chx_allow_sleep = enable_sleep;
|
||||
chx_spin_unlock (&chx_enable_sleep_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* chopstx.h - Threads and only threads.
|
||||
*
|
||||
* Copyright (C) 2013, 2016 Flying Stone Technology
|
||||
* Copyright (C) 2013, 2016, 2017 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Chopstx, a thread library for embedded.
|
||||
@@ -158,6 +158,9 @@ void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num);
|
||||
void chopstx_intr_wait (chopstx_intr_t *intr); /* DEPRECATED */
|
||||
|
||||
|
||||
int chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[]);
|
||||
int chopstx_poll (uint32_t *usec_p, int n,
|
||||
struct chx_poll_head *const pd_array[]);
|
||||
|
||||
int chopstx_conf_idle (int enable_sleep);
|
||||
|
||||
#define CHOPSTX_THREAD_SIZE 64
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <chopstx.h>
|
||||
#include <mcu/stm32.h>
|
||||
#include <mcu/stm32f103.h>
|
||||
#include "adc.h"
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ Returns old state which is 0 when it was enabled.
|
||||
|
||||
@subheading chopstx_poll
|
||||
@anchor{chopstx_poll}
|
||||
@deftypefun {int} {chopstx_poll} (uint32_t * @var{usec_p}, int @var{n}, struct chx_poll_head * [] @var{pd_array})
|
||||
@deftypefun {int} {chopstx_poll} (uint32_t * @var{usec_p}, int @var{n}, struct chx_poll_head *const [] @var{pd_array})
|
||||
@var{usec_p}: Pointer to usec for timeout. Forever if NULL.
|
||||
|
||||
@var{n}: Number of poll descriptors
|
||||
@@ -201,3 +201,23 @@ which starts its execution with priority of CHX_PRIO_MAIN_INIT, and
|
||||
let it change its priority after initialization of other threads.
|
||||
@end deftypefun
|
||||
|
||||
@subheading chx_sleep_mode
|
||||
@anchor{chx_sleep_mode}
|
||||
@deftypefun {extern void} {chx_sleep_mode} (int @var{enable_sleep})
|
||||
@var{enable_sleep}: Enable sleep on idle or not
|
||||
|
||||
If @var{enable_sleep} is > 0, allow sleep for the idle thread.
|
||||
|
||||
Behavior of @var{enable_sleep} >= 1 depends on MCU.
|
||||
|
||||
For STM32F0, 1 for Sleep (CPU clock OFF only), 2 for Stop (Wakeup
|
||||
by EXTI, voltage regulator on), 3 for Stop (Wakeup by EXTI, voltage
|
||||
regulator low-power), 4 for Standby (Wakeup by RESET, voltage
|
||||
regulator off).
|
||||
|
||||
For STM32F103, 1 for normal sleep, and 2 for sleep with lower 8MHz
|
||||
clock.
|
||||
|
||||
Return previous value of @var{enable_sleep}.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
@setfilename chopstx.info
|
||||
@set VERSION 1.5
|
||||
@set VERSION 1.6
|
||||
@settitle Chopstx Reference Manual
|
||||
@c Unify some of the indices.
|
||||
@syncodeindex tp fn
|
||||
@@ -11,7 +11,7 @@
|
||||
This manual is for Chopstx (version @value{VERSION}).
|
||||
|
||||
@noindent
|
||||
Copyright @copyright{} 2013, 2015, 2016 Flying Stone Technology @*
|
||||
Copyright @copyright{} 2013, 2015, 2016, 2017 Flying Stone Technology @*
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
@@ -59,6 +59,8 @@ section entitled ``Copying''.
|
||||
|
||||
@menu
|
||||
* Introduction:: What is Chopstx.
|
||||
* Threads and only Threads:: Threads and only Threads.
|
||||
* Note: Use of sleep mode:: Use it carefully.
|
||||
* API:: API.
|
||||
|
||||
Appendix
|
||||
@@ -83,9 +85,9 @@ Indexes
|
||||
@node Introduction
|
||||
@chapter Introduction
|
||||
|
||||
Chopstx is an RT thread library for ARM Cortex-M0, Cortex-M0plus and
|
||||
Cortex-M3. Specifically, it is used for STM32F030, MKL27Z and
|
||||
STM32F103.
|
||||
Chopstx is an RT thread library for ARM Cortex-M0, Cortex-M0plus,
|
||||
Cortex-M3 and GNU/Linux emulation. Specifically, it is used for
|
||||
STM32F030, MKL27Z, STM32F103 and as a command on GNU/Linux.
|
||||
|
||||
While most RTOSes come with many features, drivers, and stacks,
|
||||
Chopstx just offers a RT thread library.
|
||||
@@ -93,6 +95,52 @@ Chopstx just offers a RT thread library.
|
||||
With Chopstx, interrupt handling is also done by a thread. This
|
||||
enables coherent code for ease of maintenance.
|
||||
|
||||
@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 Note: Use of sleep mode
|
||||
@chapter Note: Use of sleep mode
|
||||
|
||||
Calling the chopstx_conf_idle function (> 0) to allow the idle thread
|
||||
going to sleep. MCU will be in sleep mode when no threads are
|
||||
running. By setting relevant bits of system registers, MCU will be
|
||||
able to be into stop or stand-by mode, which is MCU dependent.
|
||||
|
||||
If you use this sleep feature, please consider and implement your
|
||||
program carefully. Enabling sleep, it may result a bricked board; A
|
||||
board with no RESET pin cannot be debugged by JTAG/SWD.
|
||||
|
||||
|
||||
@node API
|
||||
@chapter API
|
||||
|
||||
35
entry.c
35
entry.c
@@ -205,23 +205,23 @@ handler vector_table[] __attribute__ ((section(".startup.vectors"))) = {
|
||||
preempt, /* PendSV */
|
||||
chx_timer_expired, /* SysTick */
|
||||
/* 0x40 */
|
||||
chx_handle_intr /* WWDG */, chx_handle_intr /* PVD */,
|
||||
chx_handle_intr /* TAMPER */, chx_handle_intr /* RTC */,
|
||||
chx_handle_intr /* FLASH */, chx_handle_intr /* RCC */,
|
||||
chx_handle_intr /* EXTI0 */, chx_handle_intr /* EXTI1 */,
|
||||
chx_handle_intr /* WWDG */, chx_handle_intr /* PVD */,
|
||||
chx_handle_intr /* TAMPER */, chx_handle_intr /* RTC */,
|
||||
chx_handle_intr /* FLASH */, chx_handle_intr /* RCC */,
|
||||
chx_handle_intr /* EXTI0 */, chx_handle_intr /* EXTI1 */,
|
||||
/* 0x60 */
|
||||
chx_handle_intr /* EXTI2 */, chx_handle_intr /* EXTI3 */,
|
||||
chx_handle_intr /* EXTI4 */, chx_handle_intr /* DMA1 CH1 */,
|
||||
chx_handle_intr /* DMA1 CH2 */, chx_handle_intr /* DMA1 CH3 */,
|
||||
chx_handle_intr /* DMA1 CH4 */, chx_handle_intr /* DMA1 CH5 */,
|
||||
chx_handle_intr /* EXTI2 */, chx_handle_intr /* EXTI3 */,
|
||||
chx_handle_intr /* EXTI4 */, chx_handle_intr /* DMA1 CH1 */,
|
||||
chx_handle_intr /* DMA1 CH2 */, chx_handle_intr /* DMA1 CH3 */,
|
||||
chx_handle_intr /* DMA1 CH4 */, chx_handle_intr /* DMA1 CH5 */,
|
||||
/* 0x80 */
|
||||
chx_handle_intr /* DMA1 CH6 */, chx_handle_intr /* DMA1 CH7 */,
|
||||
chx_handle_intr /* ADC1_2 */, chx_handle_intr /* USB HP */,
|
||||
chx_handle_intr /* DMA1 CH6 */, chx_handle_intr /* DMA1 CH7 */,
|
||||
chx_handle_intr /* ADC1_2 */, chx_handle_intr /* USB HP */,
|
||||
/* 0x90 */
|
||||
chx_handle_intr /* USB LP */, chx_handle_intr /* CAN */,
|
||||
/* ... and more. EXT9_5, TIMx, I2C, SPI, USART, EXT15_10 */
|
||||
chx_handle_intr, chx_handle_intr,
|
||||
/* 0xA0 */
|
||||
chx_handle_intr /* USB LP */, chx_handle_intr /* CAN RX1 */,
|
||||
chx_handle_intr /* CAN SCE */, chx_handle_intr /* EXT9_5 */,
|
||||
/* 0xa0 */
|
||||
/* ... and more. TIMx, I2C, SPI, USART... */
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
/* 0xc0 */
|
||||
@@ -229,15 +229,16 @@ handler vector_table[] __attribute__ ((section(".startup.vectors"))) = {
|
||||
/* STM32F0 doesn't have more. */
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
/* 0xe0 */
|
||||
chx_handle_intr /* EXT15_10 */, chx_handle_intr /* RTCAlarm */,
|
||||
chx_handle_intr /* USBWakeup */, chx_handle_intr,
|
||||
#endif
|
||||
#if !defined(STM32F10X_MD)
|
||||
/* High-density chips have more; RTCAlarm, USBWakeup, ... , DMA2_Channel4_5 */
|
||||
/* High-density chips have more; ... DMA2_Channel4_5 */
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
chx_handle_intr, chx_handle_intr, chx_handle_intr,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -244,7 +244,7 @@ usb_device_reset (struct usb_dev *dev)
|
||||
tty0.flag_connected = 0;
|
||||
tty0.flag_send_ready = 1;
|
||||
tty0.flag_input_avail = 0;
|
||||
tty0.device_state = ATTACHED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
|
||||
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -414,7 +414,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
vcom_setup_endpoints_for_interface (dev, i, 0);
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = CONFIGURED;
|
||||
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -427,7 +427,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
vcom_setup_endpoints_for_interface (dev, i, 1);
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = ADDRESSED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -629,8 +629,6 @@ usb_rx_ready (uint8_t ep_num, uint16_t len)
|
||||
|
||||
static void *tty_main (void *arg);
|
||||
|
||||
#include <signal.h>
|
||||
#define INTR_REQ_USB SIGUSR1
|
||||
#define PRIO_TTY 4
|
||||
|
||||
static char __process3_stack_base__[4096];
|
||||
@@ -647,7 +645,7 @@ tty_open (void)
|
||||
tty0.flag_connected = 0;
|
||||
tty0.flag_send_ready = 1;
|
||||
tty0.flag_input_avail = 0;
|
||||
tty0.device_state = UNCONNECTED;
|
||||
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
|
||||
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
|
||||
|
||||
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
|
||||
@@ -734,7 +732,7 @@ tty_main (void *arg)
|
||||
* OK.
|
||||
*/
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = ADDRESSED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
continue;
|
||||
@@ -790,7 +788,7 @@ tty_main (void *arg)
|
||||
}
|
||||
|
||||
chopstx_mutex_lock (&t->mtx);
|
||||
if (t->device_state == CONFIGURED && t->flag_connected
|
||||
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
|
||||
&& t->flag_send_ready)
|
||||
{
|
||||
uint8_t line[32];
|
||||
@@ -814,7 +812,7 @@ void
|
||||
tty_wait_configured (struct tty *t)
|
||||
{
|
||||
chopstx_mutex_lock (&t->mtx);
|
||||
while (t->device_state != CONFIGURED)
|
||||
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
|
||||
chopstx_cond_wait (&t->cnd, &t->mtx);
|
||||
chopstx_mutex_unlock (&t->mtx);
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ usb_device_reset (struct usb_dev *dev)
|
||||
tty0.flag_connected = 0;
|
||||
tty0.flag_send_ready = 1;
|
||||
tty0.flag_input_avail = 0;
|
||||
tty0.device_state = ATTACHED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
|
||||
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -417,7 +417,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
vcom_setup_endpoints_for_interface (i, 0);
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = CONFIGURED;
|
||||
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -430,7 +430,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
vcom_setup_endpoints_for_interface (i, 1);
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = ADDRESSED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -639,7 +639,6 @@ usb_rx_ready (uint8_t ep_num, uint16_t len)
|
||||
|
||||
static void *tty_main (void *arg);
|
||||
|
||||
#define INTR_REQ_USB 20
|
||||
#define PRIO_TTY 4
|
||||
|
||||
#define STACK_PROCESS_3
|
||||
@@ -657,7 +656,7 @@ tty_open (void)
|
||||
tty0.flag_connected = 0;
|
||||
tty0.flag_send_ready = 1;
|
||||
tty0.flag_input_avail = 0;
|
||||
tty0.device_state = UNCONNECTED;
|
||||
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
|
||||
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
|
||||
|
||||
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
|
||||
@@ -744,7 +743,7 @@ tty_main (void *arg)
|
||||
* OK.
|
||||
*/
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = ADDRESSED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
continue;
|
||||
@@ -800,7 +799,7 @@ tty_main (void *arg)
|
||||
}
|
||||
|
||||
chopstx_mutex_lock (&t->mtx);
|
||||
if (t->device_state == CONFIGURED && t->flag_connected
|
||||
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
|
||||
&& t->flag_send_ready)
|
||||
{
|
||||
uint8_t line[32];
|
||||
@@ -824,7 +823,7 @@ void
|
||||
tty_wait_configured (struct tty *t)
|
||||
{
|
||||
chopstx_mutex_lock (&t->mtx);
|
||||
while (t->device_state != CONFIGURED)
|
||||
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
|
||||
chopstx_cond_wait (&t->cnd, &t->mtx);
|
||||
chopstx_mutex_unlock (&t->mtx);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ LDSCRIPT=
|
||||
|
||||
CSRC = main.c
|
||||
CHIP=gnu-linux
|
||||
USE_SYS =
|
||||
USE_SYS = yes
|
||||
USE_USB = yes
|
||||
EMULATION=yes
|
||||
# USE_ADC = yes
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
static chopstx_mutex_t usb_mtx;
|
||||
static chopstx_cond_t usb_cnd;
|
||||
static uint32_t bDeviceState = UNCONNECTED; /* USB device status */
|
||||
static uint32_t bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
||||
|
||||
extern void EP6_IN_Callback (uint16_t len);
|
||||
extern void EP6_OUT_Callback (uint16_t len);
|
||||
@@ -47,7 +47,7 @@ usb_device_reset (struct usb_dev *dev)
|
||||
|
||||
/* Notify upper layer. */
|
||||
chopstx_mutex_lock (&usb_mtx);
|
||||
bDeviceState = ATTACHED;
|
||||
bDeviceState = USB_DEVICE_STATE_ATTACHED;
|
||||
chopstx_cond_signal (&usb_cnd);
|
||||
chopstx_mutex_unlock (&usb_mtx);
|
||||
}
|
||||
@@ -95,7 +95,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
setup_endpoints_for_interface (dev, i, 0);
|
||||
chopstx_mutex_lock (&usb_mtx);
|
||||
bDeviceState = CONFIGURED;
|
||||
bDeviceState = USB_DEVICE_STATE_CONFIGURED;
|
||||
chopstx_mutex_unlock (&usb_mtx);
|
||||
}
|
||||
else if (current_conf != dev->dev_req.value)
|
||||
@@ -107,7 +107,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
setup_endpoints_for_interface (dev, i, 1);
|
||||
chopstx_mutex_lock (&usb_mtx);
|
||||
bDeviceState = ADDRESSED;
|
||||
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
|
||||
chopstx_cond_signal (&usb_cnd);
|
||||
chopstx_mutex_unlock (&usb_mtx);
|
||||
}
|
||||
@@ -164,7 +164,6 @@ static void usb_tx_done (uint8_t ep_num, uint16_t len);
|
||||
static void usb_rx_ready (uint8_t ep_num, uint16_t len);
|
||||
|
||||
|
||||
#define INTR_REQ_USB SIGUSR1
|
||||
#define PRIO_USB 3
|
||||
|
||||
static void *
|
||||
@@ -207,7 +206,7 @@ usb_main (void *arg)
|
||||
|
||||
case USB_EVENT_DEVICE_ADDRESSED:
|
||||
chopstx_mutex_lock (&usb_mtx);
|
||||
bDeviceState = ADDRESSED;
|
||||
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
|
||||
chopstx_cond_signal (&usb_cnd);
|
||||
chopstx_mutex_unlock (&usb_mtx);
|
||||
continue;
|
||||
@@ -305,16 +304,16 @@ main (int argc, char **argv)
|
||||
chopstx_mutex_init (&usb_mtx);
|
||||
chopstx_cond_init (&usb_cnd);
|
||||
|
||||
bDeviceState = UNCONNECTED;
|
||||
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
||||
usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
|
||||
usb_main, NULL);
|
||||
while (bDeviceState != CONFIGURED)
|
||||
while (bDeviceState != USB_DEVICE_STATE_CONFIGURED)
|
||||
chopstx_usec_wait (250*1000);
|
||||
fraucheky_main ();
|
||||
chopstx_cancel (usb_thd);
|
||||
chopstx_join (usb_thd, NULL);
|
||||
usb_lld_shutdown ();
|
||||
bDeviceState = UNCONNECTED;
|
||||
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ usb_device_reset (struct usb_dev *dev)
|
||||
tty0.flag_connected = 0;
|
||||
tty0.flag_send_ready = 1;
|
||||
tty0.flag_input_avail = 0;
|
||||
tty0.device_state = ATTACHED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
|
||||
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -409,7 +409,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
vcom_setup_endpoints_for_interface (dev, i, 0);
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = CONFIGURED;
|
||||
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -422,7 +422,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
vcom_setup_endpoints_for_interface (dev, i, 1);
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = ADDRESSED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
}
|
||||
@@ -626,7 +626,6 @@ usb_rx_ready (uint8_t ep_num, uint16_t len)
|
||||
|
||||
static void *tty_main (void *arg);
|
||||
|
||||
#define INTR_REQ_USB 24
|
||||
#define PRIO_TTY 4
|
||||
|
||||
extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
|
||||
@@ -643,7 +642,7 @@ tty_open (void)
|
||||
tty0.flag_connected = 0;
|
||||
tty0.flag_send_ready = 1;
|
||||
tty0.flag_input_avail = 0;
|
||||
tty0.device_state = UNCONNECTED;
|
||||
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
|
||||
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
|
||||
|
||||
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
|
||||
@@ -733,7 +732,7 @@ tty_main (void *arg)
|
||||
* OK.
|
||||
*/
|
||||
chopstx_mutex_lock (&tty0.mtx);
|
||||
tty0.device_state = ADDRESSED;
|
||||
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
|
||||
chopstx_cond_signal (&tty0.cnd);
|
||||
chopstx_mutex_unlock (&tty0.mtx);
|
||||
continue;
|
||||
@@ -789,7 +788,7 @@ tty_main (void *arg)
|
||||
}
|
||||
|
||||
chopstx_mutex_lock (&t->mtx);
|
||||
if (t->device_state == CONFIGURED && t->flag_connected
|
||||
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
|
||||
&& t->flag_send_ready)
|
||||
{
|
||||
uint8_t line[32];
|
||||
@@ -813,7 +812,7 @@ void
|
||||
tty_wait_configured (struct tty *t)
|
||||
{
|
||||
chopstx_mutex_lock (&t->mtx);
|
||||
while (t->device_state != CONFIGURED)
|
||||
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
|
||||
chopstx_cond_wait (&t->cnd, &t->mtx);
|
||||
chopstx_mutex_unlock (&t->mtx);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ LDSCRIPT= hacker-emblem.ld
|
||||
|
||||
CSRC = reset.c hh.c
|
||||
|
||||
CHIP=stm32f0
|
||||
|
||||
# Hacker Emblem and "Happy Hacking!" demonstration
|
||||
# CSRC = reset.c hh.c
|
||||
|
||||
@@ -25,7 +27,7 @@ OBJCOPY = $(CROSS)objcopy
|
||||
MCU = cortex-m0 # -save-temps
|
||||
CWARN = -Wall -Wextra -Wstrict-prototypes
|
||||
DEFS = -DMAKE_ENTRY_PUBLIC \
|
||||
-DFREE_STANDING -DMHZ=48 -DUSE_WFI_FOR_IDLE
|
||||
-DFREE_STANDING -DMHZ=48
|
||||
OPT = -O3 -Os -g
|
||||
LIBS =
|
||||
|
||||
|
||||
@@ -163,17 +163,19 @@ button (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define STACK_MAIN
|
||||
#define STACK_PROCESS_1
|
||||
#define STACK_PROCESS_2
|
||||
#include "stack-def.h"
|
||||
|
||||
#define PRIO_LED 3
|
||||
#define PRIO_BUTTON 2
|
||||
|
||||
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
|
||||
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
|
||||
#define STACK_ADDR_LED ((uint32_t)process1_base)
|
||||
#define STACK_SIZE_LED (sizeof process1_base)
|
||||
|
||||
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__)
|
||||
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__)
|
||||
|
||||
#define STACK_ADDR_BUTTON ((uint32_t)__process2_stack_base__)
|
||||
#define STACK_SIZE_BUTTON ((uint32_t)__process2_stack_size__)
|
||||
#define STACK_ADDR_BUTTON ((uint32_t)process2_base)
|
||||
#define STACK_SIZE_BUTTON (sizeof process2_base)
|
||||
|
||||
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
|
||||
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
|
||||
@@ -365,8 +367,6 @@ text_display (uint8_t kind)
|
||||
}
|
||||
|
||||
|
||||
static void setup_scr_sleepdeep (void);
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
@@ -378,6 +378,8 @@ main (int argc, const char *argv[])
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
chopstx_conf_idle (1);
|
||||
|
||||
chopstx_mutex_init (&mtx);
|
||||
chopstx_cond_init (&cnd0);
|
||||
chopstx_cond_init (&cnd1);
|
||||
@@ -418,56 +420,6 @@ main (int argc, const char *argv[])
|
||||
chopstx_join (button_thd, NULL);
|
||||
chopstx_join (led_thd, NULL);
|
||||
|
||||
setup_scr_sleepdeep ();
|
||||
for (;;)
|
||||
asm volatile ("wfi" : : : "memory");
|
||||
|
||||
chopstx_conf_idle (4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct SCB
|
||||
{
|
||||
volatile uint32_t CPUID;
|
||||
volatile uint32_t ICSR;
|
||||
volatile uint32_t VTOR;
|
||||
volatile uint32_t AIRCR;
|
||||
volatile uint32_t SCR;
|
||||
volatile uint32_t CCR;
|
||||
volatile uint8_t SHP[12];
|
||||
volatile uint32_t SHCSR;
|
||||
volatile uint32_t CFSR;
|
||||
volatile uint32_t HFSR;
|
||||
volatile uint32_t DFSR;
|
||||
volatile uint32_t MMFAR;
|
||||
volatile uint32_t BFAR;
|
||||
volatile uint32_t AFSR;
|
||||
volatile uint32_t PFR[2];
|
||||
volatile uint32_t DFR;
|
||||
volatile uint32_t ADR;
|
||||
volatile uint32_t MMFR[4];
|
||||
volatile uint32_t ISAR[5];
|
||||
};
|
||||
|
||||
#define SCS_BASE (0xE000E000)
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
||||
static struct SCB *const SCB = ((struct SCB *)SCB_BASE);
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP (1 << 2)
|
||||
|
||||
struct PWR
|
||||
{
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CSR;
|
||||
};
|
||||
#define PWR_CR_PDDS 0x0002
|
||||
#define PWR_CR_CWUF 0x0004
|
||||
|
||||
#define PWR_BASE (APBPERIPH_BASE + 0x00007000)
|
||||
#define PWR ((struct PWR *) PWR_BASE)
|
||||
|
||||
static void setup_scr_sleepdeep (void)
|
||||
{
|
||||
PWR->CR |= PWR_CR_CWUF;
|
||||
PWR->CR |= PWR_CR_PDDS;
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/*
|
||||
* ST32F0 memory setup.
|
||||
*/
|
||||
__main_stack_size__ = 0x0100; /* Idle+Exception handlers */
|
||||
__process0_stack_size__ = 0x0100; /* Main program */
|
||||
__process1_stack_size__ = 0x0100; /* first thread program */
|
||||
__process2_stack_size__ = 0x0100; /* second thread program */
|
||||
__process3_stack_size__ = 0x0100; /* third thread program */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash : org = 0x08000000, len = 16k
|
||||
@@ -61,34 +55,15 @@ SECTIONS
|
||||
_etext = .;
|
||||
_textdata = _etext;
|
||||
|
||||
.process_stack :
|
||||
.stacks (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__process3_stack_base__ = .;
|
||||
. += __process3_stack_size__;
|
||||
*(.main_stack)
|
||||
*(.process_stack.0)
|
||||
*(.process_stack.1)
|
||||
*(.process_stack.2)
|
||||
*(.process_stack.3)
|
||||
. = ALIGN(8);
|
||||
__process3_stack_end__ = .;
|
||||
__process2_stack_base__ = .;
|
||||
. += __process2_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process2_stack_end__ = .;
|
||||
__process1_stack_base__ = .;
|
||||
. += __process1_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process1_stack_end__ = .;
|
||||
__process0_stack_base__ = .;
|
||||
. += __process0_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process0_stack_end__ = .;
|
||||
} > ram
|
||||
|
||||
.main_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__main_stack_base__ = .;
|
||||
. += __main_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__main_stack_end__ = .;
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
|
||||
@@ -166,14 +166,16 @@ button (void *arg)
|
||||
#define PRIO_LED 3
|
||||
#define PRIO_BUTTON 2
|
||||
|
||||
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
|
||||
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
|
||||
#define STACK_MAIN
|
||||
#define STACK_PROCESS_1
|
||||
#define STACK_PROCESS_2
|
||||
#include "stack-def.h"
|
||||
|
||||
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__)
|
||||
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__)
|
||||
#define STACK_ADDR_LED ((uint32_t)process1_base)
|
||||
#define STACK_SIZE_LED (sizeof process1_base)
|
||||
|
||||
#define STACK_ADDR_BUTTON ((uint32_t)__process2_stack_base__)
|
||||
#define STACK_SIZE_BUTTON ((uint32_t)__process2_stack_size__)
|
||||
#define STACK_ADDR_BUTTON ((uint32_t)process2_base)
|
||||
#define STACK_SIZE_BUTTON (sizeof process2_base)
|
||||
|
||||
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
|
||||
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
|
||||
@@ -355,8 +357,6 @@ text_display (uint8_t kind)
|
||||
}
|
||||
|
||||
|
||||
static void setup_scr_sleepdeep (void);
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
@@ -366,6 +366,8 @@ main (int argc, const char *argv[])
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
chopstx_conf_idle (1);
|
||||
|
||||
chopstx_mutex_init (&mtx);
|
||||
chopstx_cond_init (&cnd0);
|
||||
chopstx_cond_init (&cnd1);
|
||||
@@ -406,56 +408,6 @@ main (int argc, const char *argv[])
|
||||
chopstx_join (button_thd, NULL);
|
||||
chopstx_join (led_thd, NULL);
|
||||
|
||||
setup_scr_sleepdeep ();
|
||||
for (;;)
|
||||
asm volatile ("wfi" : : : "memory");
|
||||
|
||||
chopstx_conf_idle (4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct SCB
|
||||
{
|
||||
volatile uint32_t CPUID;
|
||||
volatile uint32_t ICSR;
|
||||
volatile uint32_t VTOR;
|
||||
volatile uint32_t AIRCR;
|
||||
volatile uint32_t SCR;
|
||||
volatile uint32_t CCR;
|
||||
volatile uint8_t SHP[12];
|
||||
volatile uint32_t SHCSR;
|
||||
volatile uint32_t CFSR;
|
||||
volatile uint32_t HFSR;
|
||||
volatile uint32_t DFSR;
|
||||
volatile uint32_t MMFAR;
|
||||
volatile uint32_t BFAR;
|
||||
volatile uint32_t AFSR;
|
||||
volatile uint32_t PFR[2];
|
||||
volatile uint32_t DFR;
|
||||
volatile uint32_t ADR;
|
||||
volatile uint32_t MMFR[4];
|
||||
volatile uint32_t ISAR[5];
|
||||
};
|
||||
|
||||
#define SCS_BASE (0xE000E000)
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
||||
static struct SCB *const SCB = ((struct SCB *)SCB_BASE);
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP (1 << 2)
|
||||
|
||||
struct PWR
|
||||
{
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CSR;
|
||||
};
|
||||
#define PWR_CR_PDDS 0x0002
|
||||
#define PWR_CR_CWUF 0x0004
|
||||
|
||||
#define PWR_BASE (APBPERIPH_BASE + 0x00007000)
|
||||
#define PWR ((struct PWR *) PWR_BASE)
|
||||
|
||||
static void setup_scr_sleepdeep (void)
|
||||
{
|
||||
PWR->CR |= PWR_CR_CWUF;
|
||||
PWR->CR |= PWR_CR_PDDS;
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP;
|
||||
}
|
||||
|
||||
@@ -86,12 +86,16 @@ led_enable_column (uint8_t col)
|
||||
}
|
||||
|
||||
|
||||
#define STACK_MAIN
|
||||
#define STACK_PROCESS_1
|
||||
#define STACK_PROCESS_2
|
||||
#define STACK_PROCESS_3
|
||||
#include "stack-def.h"
|
||||
|
||||
#define PRIO_LED 3
|
||||
|
||||
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
|
||||
|
||||
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__)
|
||||
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__)
|
||||
#define STACK_ADDR_LED ((uint32_t)process1_base)
|
||||
#define STACK_SIZE_LED (sizeof process1_base)
|
||||
|
||||
static void *
|
||||
led (void *arg)
|
||||
@@ -119,10 +123,9 @@ led (void *arg)
|
||||
|
||||
|
||||
#define PRIO_SPK 4
|
||||
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
|
||||
|
||||
#define STACK_ADDR_SPK ((uint32_t)__process2_stack_base__)
|
||||
#define STACK_SIZE_SPK ((uint32_t)__process2_stack_size__)
|
||||
#define STACK_ADDR_SPK ((uint32_t)process2_base)
|
||||
#define STACK_SIZE_SPK (sizeof process2_base)
|
||||
|
||||
static chopstx_mutex_t spk_mtx;
|
||||
static chopstx_cond_t spk_cnd;
|
||||
@@ -193,10 +196,9 @@ spk (void *arg)
|
||||
|
||||
|
||||
#define PRIO_MUSIC 2
|
||||
extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
|
||||
|
||||
#define STACK_ADDR_MUSIC ((uint32_t)__process3_stack_base__)
|
||||
#define STACK_SIZE_MUSIC ((uint32_t)__process3_stack_size__)
|
||||
#define STACK_ADDR_MUSIC ((uint32_t)process3_base)
|
||||
#define STACK_SIZE_MUSIC (sizeof process3_base)
|
||||
|
||||
#define C 0
|
||||
#define D 1
|
||||
|
||||
54
example-fsm-55/stack-def.h
Normal file
54
example-fsm-55/stack-def.h
Normal 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
|
||||
@@ -72,14 +72,17 @@ blk (void *arg)
|
||||
#define PRIO_BLK 2
|
||||
#endif
|
||||
|
||||
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
|
||||
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
|
||||
#define STACK_MAIN
|
||||
#define STACK_PROCESS_1
|
||||
#define STACK_PROCESS_2
|
||||
#include "stack-def.h"
|
||||
|
||||
#define STACK_ADDR_PWM ((uint32_t)__process1_stack_base__)
|
||||
#define STACK_SIZE_PWM ((uint32_t)__process1_stack_size__)
|
||||
|
||||
#define STACK_ADDR_BLK ((uint32_t)__process2_stack_base__)
|
||||
#define STACK_SIZE_BLK ((uint32_t)__process2_stack_size__)
|
||||
#define STACK_ADDR_PWM ((uint32_t)process1_base)
|
||||
#define STACK_SIZE_PWM (sizeof process1_base)
|
||||
|
||||
#define STACK_ADDR_BLK ((uint32_t)process2_base)
|
||||
#define STACK_SIZE_BLK (sizeof process2_base)
|
||||
|
||||
|
||||
int
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/*
|
||||
* ST32F0 memory setup.
|
||||
*/
|
||||
__main_stack_size__ = 0x0100; /* Idle+Exception handlers */
|
||||
__process0_stack_size__ = 0x0100; /* Main program */
|
||||
__process1_stack_size__ = 0x0100; /* first thread program */
|
||||
__process2_stack_size__ = 0x0100; /* second thread program */
|
||||
__process3_stack_size__ = 0x0100; /* third thread program */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash0 : org = 0x08000000, len = 4k
|
||||
@@ -87,34 +81,15 @@ SECTIONS
|
||||
KEEP(*(.bss.startup.*))
|
||||
} > ram
|
||||
|
||||
.process_stack :
|
||||
.stacks (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__process3_stack_base__ = .;
|
||||
. += __process3_stack_size__;
|
||||
*(.main_stack)
|
||||
*(.process_stack.0)
|
||||
*(.process_stack.1)
|
||||
*(.process_stack.2)
|
||||
*(.process_stack.3)
|
||||
. = ALIGN(8);
|
||||
__process3_stack_end__ = .;
|
||||
__process2_stack_base__ = .;
|
||||
. += __process2_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process2_stack_end__ = .;
|
||||
__process1_stack_base__ = .;
|
||||
. += __process1_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process1_stack_end__ = .;
|
||||
__process0_stack_base__ = .;
|
||||
. += __process0_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process0_stack_end__ = .;
|
||||
} > ram
|
||||
|
||||
.main_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__main_stack_base__ = .;
|
||||
. += __main_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__main_stack_end__ = .;
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/*
|
||||
* ST32F103 memory setup.
|
||||
*/
|
||||
__main_stack_size__ = 0x0100; /* Idle+Exception handlers */
|
||||
__process0_stack_size__ = 0x0100; /* Main program */
|
||||
__process1_stack_size__ = 0x0100; /* first thread program */
|
||||
__process2_stack_size__ = 0x0100; /* second thread program */
|
||||
__process3_stack_size__ = 0x0100; /* third thread program */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash0 : org = 0x08000000, len = 4k
|
||||
@@ -78,34 +72,14 @@ SECTIONS
|
||||
_etext = .;
|
||||
_textdata = _etext;
|
||||
|
||||
.process_stack :
|
||||
.stacks (NOLOAD) :
|
||||
{
|
||||
*(.main_stack)
|
||||
*(.process_stack.0)
|
||||
*(.process_stack.1)
|
||||
*(.process_stack.2)
|
||||
*(.process_stack.3)
|
||||
. = ALIGN(8);
|
||||
__process3_stack_base__ = .;
|
||||
. += __process3_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process3_stack_end__ = .;
|
||||
__process2_stack_base__ = .;
|
||||
. += __process2_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process2_stack_end__ = .;
|
||||
__process1_stack_base__ = .;
|
||||
. += __process1_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process1_stack_end__ = .;
|
||||
__process0_stack_base__ = .;
|
||||
. += __process0_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process0_stack_end__ = .;
|
||||
} > ram
|
||||
|
||||
.main_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__main_stack_base__ = .;
|
||||
. += __main_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__main_stack_end__ = .;
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
|
||||
53
example-led/stack-def.h
Normal file
53
example-led/stack-def.h
Normal 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
|
||||
5
mcu/chx-gnu-linux.c
Normal file
5
mcu/chx-gnu-linux.c
Normal file
@@ -0,0 +1,5 @@
|
||||
void
|
||||
chx_sleep_mode (int enable_sleep)
|
||||
{
|
||||
(void)enable_sleep;
|
||||
}
|
||||
23
mcu/chx-mkl27z.c
Normal file
23
mcu/chx-mkl27z.c
Normal 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
42
mcu/chx-stm32f0.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <stdint.h>
|
||||
#include <mcu/cortex-m.h>
|
||||
#define MCU_STM32F0
|
||||
#include <mcu/stm32.h>
|
||||
|
||||
extern int chx_allow_sleep;
|
||||
|
||||
void
|
||||
chx_sleep_mode (int how)
|
||||
{
|
||||
PWR->CR |= PWR_CR_CWUF;
|
||||
PWR->CR &= ~(PWR_CR_PDDS|PWR_CR_LPDS);
|
||||
|
||||
if (how == 0 || how == 1 /* Sleep only (not deepsleep) */)
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP;
|
||||
else
|
||||
{ /* Deepsleep */
|
||||
/* how == 2: deepsleep but regulator ON */
|
||||
if (how == 3)
|
||||
PWR->CR |= PWR_CR_LPDS; /* regulator low-power mode */
|
||||
else if (how == 4)
|
||||
PWR->CR |= PWR_CR_PDDS; /* Power down: All OFF */
|
||||
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP;
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((naked))
|
||||
chx_idle (void)
|
||||
{
|
||||
int sleep_enabled;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep));
|
||||
if (sleep_enabled)
|
||||
{
|
||||
asm volatile ("wfi" : : : "memory");
|
||||
/* NOTE: it never comes here. Don't add lines after this. */
|
||||
}
|
||||
}
|
||||
}
|
||||
88
mcu/chx-stm32f103.c
Normal file
88
mcu/chx-stm32f103.c
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <stdint.h>
|
||||
#include <mcu/stm32.h>
|
||||
#include <mcu/stm32f103.h>
|
||||
#include "board.h"
|
||||
|
||||
extern int chx_allow_sleep;
|
||||
|
||||
#define STM32_PLLSRC STM32_PLLSRC_HSE
|
||||
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
|
||||
|
||||
|
||||
static void
|
||||
configure_clock (int high)
|
||||
{
|
||||
uint32_t cfg_sw;
|
||||
uint32_t cfg;
|
||||
|
||||
if (high)
|
||||
{
|
||||
cfg = STM32_MCO_NOCLOCK | STM32_USBPRE_DIV1P5
|
||||
| STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC
|
||||
| STM32_ADCPRE_DIV6 | STM32_PPRE2_DIV1
|
||||
| STM32_PPRE1_DIV2 | STM32_HPRE_DIV1;
|
||||
|
||||
cfg_sw = RCC_CFGR_SW_PLL;
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg = STM32_MCO_NOCLOCK | STM32_USBPRE_DIV1P5
|
||||
| STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC
|
||||
| STM32_ADCPRE_DIV8 | STM32_PPRE2_DIV16
|
||||
| STM32_PPRE1_DIV16 | STM32_HPRE_DIV8;
|
||||
|
||||
cfg_sw = RCC_CFGR_SW_HSI;
|
||||
}
|
||||
|
||||
RCC->CFGR = cfg | cfg_sw;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != (cfg_sw << 2))
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* When HOW=0 or HOW=1, SYSCLK is PLL (72MHz).
|
||||
* When HOW=2, SYSCLK will be 1MHz with HSI (8MHz) on sleep.
|
||||
*
|
||||
* With lower clock, it can achieve lower power consumption.
|
||||
*
|
||||
* Implementation note: Deepsleep is only useful with RTC, Watch Dog,
|
||||
* or WKUP pin. We can't use deepsleep for USB, it never wakes up.
|
||||
*
|
||||
*/
|
||||
void
|
||||
chx_sleep_mode (int how)
|
||||
{
|
||||
if (how == 0 || how == 1)
|
||||
configure_clock (1);
|
||||
|
||||
/* how == 2: Defer setting to 8MHz clock to the idle function */
|
||||
}
|
||||
|
||||
void __attribute__((naked))
|
||||
chx_idle (void)
|
||||
{
|
||||
int sleep_enabled;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep));
|
||||
if (sleep_enabled)
|
||||
{
|
||||
asm volatile ("cpsid i" : : : "memory");
|
||||
if (sleep_enabled == 1)
|
||||
{
|
||||
/* Allow JTAG/SWD access on sleep. */
|
||||
DBGMCU->CR |= DBG_SLEEP;
|
||||
}
|
||||
else if (sleep_enabled == 2)
|
||||
{
|
||||
DBGMCU->CR &= ~DBG_SLEEP; /* Disable HCLK on sleep */
|
||||
configure_clock (0);
|
||||
}
|
||||
asm volatile ("cpsie i" : : : "memory");
|
||||
|
||||
asm volatile ("wfi" : : : "memory");
|
||||
/* NOTE: it never comes here. Don't add lines after this. */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,28 +26,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define STM32_SW_HSI (0 << 0)
|
||||
#define STM32_SW_PLL (2 << 0)
|
||||
#define STM32_PLLSRC_HSI (0 << 16)
|
||||
#define STM32_PLLSRC_HSE (1 << 16)
|
||||
|
||||
#define STM32_PLLXTPRE_DIV1 (0 << 17)
|
||||
#define STM32_PLLXTPRE_DIV2 (1 << 17)
|
||||
|
||||
#define STM32_HPRE_DIV1 (0 << 4)
|
||||
|
||||
#define STM32_PPRE1_DIV1 (0 << 8)
|
||||
#define STM32_PPRE1_DIV2 (4 << 8)
|
||||
|
||||
#define STM32_PPRE2_DIV1 (0 << 11)
|
||||
#define STM32_PPRE2_DIV2 (4 << 11)
|
||||
|
||||
#define STM32_ADCPRE_DIV4 (1 << 14)
|
||||
#define STM32_ADCPRE_DIV6 (2 << 14)
|
||||
|
||||
#define STM32_USBPRE_DIV1P5 (0 << 22)
|
||||
|
||||
#define STM32_MCO_NOCLOCK (0 << 24)
|
||||
#include <mcu/stm32.h>
|
||||
|
||||
#if defined(MCU_STM32F0)
|
||||
#define STM32_PPRE1 STM32_PPRE1_DIV1
|
||||
@@ -74,85 +53,6 @@
|
||||
#define STM32_HCLK (STM32_SYSCLK / 1)
|
||||
|
||||
|
||||
#define PERIPH_BASE 0x40000000
|
||||
#define APBPERIPH_BASE PERIPH_BASE
|
||||
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
|
||||
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
|
||||
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
|
||||
|
||||
struct RCC {
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CFGR;
|
||||
volatile uint32_t CIR;
|
||||
volatile uint32_t APB2RSTR;
|
||||
volatile uint32_t APB1RSTR;
|
||||
volatile uint32_t AHBENR;
|
||||
volatile uint32_t APB2ENR;
|
||||
volatile uint32_t APB1ENR;
|
||||
volatile uint32_t BDCR;
|
||||
volatile uint32_t CSR;
|
||||
#if defined(MCU_STM32F0)
|
||||
volatile uint32_t AHBRSTR;
|
||||
volatile uint32_t CFGR2;
|
||||
volatile uint32_t CFGR3;
|
||||
volatile uint32_t CR2;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
|
||||
static struct RCC *const RCC = (struct RCC *)RCC_BASE;
|
||||
|
||||
#define RCC_APB1ENR_USBEN 0x00800000
|
||||
#define RCC_APB1RSTR_USBRST 0x00800000
|
||||
|
||||
#define RCC_CR_HSION 0x00000001
|
||||
#define RCC_CR_HSIRDY 0x00000002
|
||||
#define RCC_CR_HSITRIM 0x000000F8
|
||||
#define RCC_CR_HSEON 0x00010000
|
||||
#define RCC_CR_HSERDY 0x00020000
|
||||
#define RCC_CR_PLLON 0x01000000
|
||||
#define RCC_CR_PLLRDY 0x02000000
|
||||
|
||||
#define RCC_CFGR_SWS 0x0000000C
|
||||
#define RCC_CFGR_SWS_HSI 0x00000000
|
||||
|
||||
#define RCC_AHBENR_CRCEN 0x0040
|
||||
|
||||
#if defined(MCU_STM32F0)
|
||||
#define RCC_AHBRSTR_IOPARST 0x00020000
|
||||
#define RCC_AHBRSTR_IOPBRST 0x00040000
|
||||
#define RCC_AHBRSTR_IOPCRST 0x00080000
|
||||
#define RCC_AHBRSTR_IOPDRST 0x00100000
|
||||
#define RCC_AHBRSTR_IOPFRST 0x00400000
|
||||
|
||||
#define RCC_AHBENR_IOPAEN 0x00020000
|
||||
#define RCC_AHBENR_IOPBEN 0x00040000
|
||||
#define RCC_AHBENR_IOPCEN 0x00080000
|
||||
#define RCC_AHBENR_IOPDEN 0x00100000
|
||||
#define RCC_AHBENR_IOPFEN 0x00400000
|
||||
|
||||
#define RCC_APB2RSTR_SYSCFGRST 0x00000001
|
||||
#define RCC_APB2ENR_SYSCFGEN 0x00000001
|
||||
#else
|
||||
#define RCC_APB2RSTR_AFIORST 0x00000001
|
||||
#define RCC_APB2RSTR_IOPARST 0x00000004
|
||||
#define RCC_APB2RSTR_IOPBRST 0x00000008
|
||||
#define RCC_APB2RSTR_IOPCRST 0x00000010
|
||||
#define RCC_APB2RSTR_IOPDRST 0x00000020
|
||||
#define RCC_APB2RSTR_IOPERST 0x00000040
|
||||
#define RCC_APB2RSTR_IOPFRST 0x00000080
|
||||
#define RCC_APB2RSTR_IOPGRST 0x00000100
|
||||
|
||||
#define RCC_APB2ENR_AFIOEN 0x00000001
|
||||
#define RCC_APB2ENR_IOPAEN 0x00000004
|
||||
#define RCC_APB2ENR_IOPBEN 0x00000008
|
||||
#define RCC_APB2ENR_IOPCEN 0x00000010
|
||||
#define RCC_APB2ENR_IOPDEN 0x00000020
|
||||
#define RCC_APB2ENR_IOPEEN 0x00000040
|
||||
#define RCC_APB2ENR_IOPFEN 0x00000080
|
||||
#define RCC_APB2ENR_IOPGEN 0x00000100
|
||||
#endif
|
||||
|
||||
#if defined(MCU_STM32F0)
|
||||
struct SYSCFG {
|
||||
volatile uint32_t CFGR1;
|
||||
@@ -218,9 +118,6 @@ clock_init (void)
|
||||
/* Flash setup */
|
||||
FLASH->ACR = STM32_FLASHBITS;
|
||||
|
||||
/* CRC */
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
|
||||
/* Switching on the configured clock source. */
|
||||
RCC->CFGR |= STM32_SW;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
|
||||
|
||||
29
mcu/cortex-m.h
Normal file
29
mcu/cortex-m.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* System Control Block */
|
||||
struct SCB
|
||||
{
|
||||
volatile uint32_t CPUID;
|
||||
volatile uint32_t ICSR;
|
||||
volatile uint32_t VTOR;
|
||||
volatile uint32_t AIRCR;
|
||||
volatile uint32_t SCR;
|
||||
volatile uint32_t CCR;
|
||||
volatile uint8_t SHP[12];
|
||||
volatile uint32_t SHCSR;
|
||||
volatile uint32_t CFSR;
|
||||
volatile uint32_t HFSR;
|
||||
volatile uint32_t DFSR;
|
||||
volatile uint32_t MMAR;
|
||||
volatile uint32_t BFAR;
|
||||
volatile uint32_t AFSR;
|
||||
volatile uint32_t PFR[2];
|
||||
volatile uint32_t DFR;
|
||||
volatile uint32_t AFR;
|
||||
volatile uint32_t MMFR[4];
|
||||
volatile uint32_t ISAR[5];
|
||||
};
|
||||
|
||||
#define SCS_BASE 0xE000E000
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
||||
static struct SCB *const SCB = (struct SCB *)SCB_BASE;
|
||||
#define SCB_SCR_SLEEPDEEP (1 << 2)
|
||||
#define SCB_AIRCR_SYSRESETREQ 0x04
|
||||
141
mcu/stm32.h
Normal file
141
mcu/stm32.h
Normal file
@@ -0,0 +1,141 @@
|
||||
#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_CFGR_SW_HSI (0 << 0)
|
||||
#define RCC_CFGR_SW_HSE (1 << 0)
|
||||
#define RCC_CFGR_SW_PLL (2 << 0)
|
||||
#define RCC_CFGR_SW_MASK (3 << 0)
|
||||
|
||||
#define RCC_AHBENR_DMA1EN 0x00000001
|
||||
#define RCC_AHBENR_CRCEN 0x00000040
|
||||
|
||||
#if defined(MCU_STM32F0)
|
||||
#define RCC_AHBRSTR_IOPARST 0x00020000
|
||||
#define RCC_AHBRSTR_IOPBRST 0x00040000
|
||||
#define RCC_AHBRSTR_IOPCRST 0x00080000
|
||||
#define RCC_AHBRSTR_IOPDRST 0x00100000
|
||||
#define RCC_AHBRSTR_IOPFRST 0x00400000
|
||||
|
||||
#define RCC_AHBENR_IOPAEN 0x00020000
|
||||
#define RCC_AHBENR_IOPBEN 0x00040000
|
||||
#define RCC_AHBENR_IOPCEN 0x00080000
|
||||
#define RCC_AHBENR_IOPDEN 0x00100000
|
||||
#define RCC_AHBENR_IOPFEN 0x00400000
|
||||
|
||||
#define RCC_APB2RSTR_SYSCFGRST 0x00000001
|
||||
#define RCC_APB2ENR_SYSCFGEN 0x00000001
|
||||
#else
|
||||
#define RCC_APB2ENR_ADC1EN 0x00000200
|
||||
#define RCC_APB2ENR_ADC2EN 0x00000400
|
||||
#define RCC_APB2ENR_TIM1EN 0x00000800
|
||||
#define RCC_APB1ENR_TIM2EN 0x00000001
|
||||
#define RCC_APB1ENR_TIM3EN 0x00000002
|
||||
#define RCC_APB1ENR_TIM4EN 0x00000004
|
||||
|
||||
#define RCC_APB2RSTR_ADC1RST 0x00000200
|
||||
#define RCC_APB2RSTR_ADC2RST 0x00000400
|
||||
#define RCC_APB2RSTR_TIM1RST 0x00000800
|
||||
#define RCC_APB1RSTR_TIM2RST 0x00000001
|
||||
#define RCC_APB1RSTR_TIM3RST 0x00000002
|
||||
#define RCC_APB1RSTR_TIM4RST 0x00000004
|
||||
|
||||
#define RCC_APB2RSTR_AFIORST 0x00000001
|
||||
#define RCC_APB2RSTR_IOPARST 0x00000004
|
||||
#define RCC_APB2RSTR_IOPBRST 0x00000008
|
||||
#define RCC_APB2RSTR_IOPCRST 0x00000010
|
||||
#define RCC_APB2RSTR_IOPDRST 0x00000020
|
||||
#define RCC_APB2RSTR_IOPERST 0x00000040
|
||||
#define RCC_APB2RSTR_IOPFRST 0x00000080
|
||||
#define RCC_APB2RSTR_IOPGRST 0x00000100
|
||||
|
||||
#define RCC_APB2ENR_AFIOEN 0x00000001
|
||||
#define RCC_APB2ENR_IOPAEN 0x00000004
|
||||
#define RCC_APB2ENR_IOPBEN 0x00000008
|
||||
#define RCC_APB2ENR_IOPCEN 0x00000010
|
||||
#define RCC_APB2ENR_IOPDEN 0x00000020
|
||||
#define RCC_APB2ENR_IOPEEN 0x00000040
|
||||
#define RCC_APB2ENR_IOPFEN 0x00000080
|
||||
#define RCC_APB2ENR_IOPGEN 0x00000100
|
||||
#endif
|
||||
|
||||
|
||||
/* Clock setting values.
|
||||
* Due to historical reason, it has the prefix of STM32_.
|
||||
*/
|
||||
#define STM32_SW_HSI (0 << 0)
|
||||
#define STM32_SW_HSE (1 << 0)
|
||||
#define STM32_SW_PLL (2 << 0)
|
||||
|
||||
#define STM32_PLLSRC_HSI (0 << 16)
|
||||
#define STM32_PLLSRC_HSE (1 << 16)
|
||||
|
||||
#define STM32_PLLXTPRE_DIV1 (0 << 17)
|
||||
#define STM32_PLLXTPRE_DIV2 (1 << 17)
|
||||
|
||||
#define STM32_HPRE_DIV1 (0 << 4)
|
||||
#define STM32_HPRE_DIV8 (10 << 4)
|
||||
#define STM32_HPRE_DIV16 (11 << 4)
|
||||
|
||||
#define STM32_PPRE1_DIV1 (0 << 8)
|
||||
#define STM32_PPRE1_DIV2 (4 << 8)
|
||||
#define STM32_PPRE1_DIV16 (7 << 8)
|
||||
|
||||
#define STM32_PPRE2_DIV1 (0 << 11)
|
||||
#define STM32_PPRE2_DIV2 (4 << 11)
|
||||
#define STM32_PPRE2_DIV16 (7 << 11)
|
||||
|
||||
#define STM32_ADCPRE_DIV4 (1 << 14)
|
||||
#define STM32_ADCPRE_DIV6 (2 << 14)
|
||||
#define STM32_ADCPRE_DIV8 (3 << 14)
|
||||
|
||||
#define STM32_USBPRE_DIV1P5 (0 << 22)
|
||||
|
||||
#define STM32_MCO_NOCLOCK (0 << 24)
|
||||
|
||||
struct PWR
|
||||
{
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CSR;
|
||||
};
|
||||
static struct PWR *const PWR = ((struct PWR *)0x40007000);
|
||||
#define PWR_CR_LPDS 0x0001 /* Low-power deepsleep */
|
||||
#define PWR_CR_PDDS 0x0002 /* Power down deepsleep */
|
||||
#define PWR_CR_CWUF 0x0004 /* Clear wakeup flag */
|
||||
@@ -1,41 +1,3 @@
|
||||
#define PERIPH_BASE 0x40000000
|
||||
#define APB1PERIPH_BASE PERIPH_BASE
|
||||
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
|
||||
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
|
||||
|
||||
struct RCC {
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CFGR;
|
||||
volatile uint32_t CIR;
|
||||
volatile uint32_t APB2RSTR;
|
||||
volatile uint32_t APB1RSTR;
|
||||
volatile uint32_t AHBENR;
|
||||
volatile uint32_t APB2ENR;
|
||||
volatile uint32_t APB1ENR;
|
||||
volatile uint32_t BDCR;
|
||||
volatile uint32_t CSR;
|
||||
};
|
||||
|
||||
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
|
||||
static struct RCC *const RCC = (struct RCC *)RCC_BASE;
|
||||
|
||||
#define RCC_AHBENR_DMA1EN 0x00000001
|
||||
#define RCC_AHBENR_CRCEN 0x00000040
|
||||
|
||||
#define RCC_APB2ENR_ADC1EN 0x00000200
|
||||
#define RCC_APB2ENR_ADC2EN 0x00000400
|
||||
#define RCC_APB2ENR_TIM1EN 0x00000800
|
||||
#define RCC_APB1ENR_TIM2EN 0x00000001
|
||||
#define RCC_APB1ENR_TIM3EN 0x00000002
|
||||
#define RCC_APB1ENR_TIM4EN 0x00000004
|
||||
|
||||
#define RCC_APB2RSTR_ADC1RST 0x00000200
|
||||
#define RCC_APB2RSTR_ADC2RST 0x00000400
|
||||
#define RCC_APB2RSTR_TIM1RST 0x00000800
|
||||
#define RCC_APB1RSTR_TIM2RST 0x00000001
|
||||
#define RCC_APB1RSTR_TIM3RST 0x00000002
|
||||
#define RCC_APB1RSTR_TIM4RST 0x00000004
|
||||
|
||||
#define CRC_CR_RESET 0x00000001
|
||||
|
||||
struct CRC {
|
||||
@@ -182,36 +144,6 @@ static struct DMA *const DMA1 = (struct DMA *)DMA1_BASE;
|
||||
static struct DMA_Channel *const DMA1_Channel1 =
|
||||
(struct DMA_Channel *)DMA1_Channel1_BASE;
|
||||
|
||||
/* System Control Block */
|
||||
struct SCB
|
||||
{
|
||||
volatile uint32_t CPUID;
|
||||
volatile uint32_t ICSR;
|
||||
volatile uint32_t VTOR;
|
||||
volatile uint32_t AIRCR;
|
||||
volatile uint32_t SCR;
|
||||
volatile uint32_t CCR;
|
||||
volatile uint8_t SHP[12];
|
||||
volatile uint32_t SHCSR;
|
||||
volatile uint32_t CFSR;
|
||||
volatile uint32_t HFSR;
|
||||
volatile uint32_t DFSR;
|
||||
volatile uint32_t MMFAR;
|
||||
volatile uint32_t BFAR;
|
||||
volatile uint32_t AFSR;
|
||||
volatile uint32_t PFR[2];
|
||||
volatile uint32_t DFR;
|
||||
volatile uint32_t ADR;
|
||||
volatile uint32_t MMFR[4];
|
||||
volatile uint32_t ISAR[5];
|
||||
uint32_t RESERVED0[5];
|
||||
volatile uint32_t CPACR;
|
||||
};
|
||||
|
||||
#define SCS_BASE 0xE000E000
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
||||
static struct SCB *const SCB = (struct SCB *)SCB_BASE;
|
||||
|
||||
/* Timer */
|
||||
struct TIM
|
||||
{
|
||||
@@ -698,3 +630,12 @@ static struct AFIO *const AFIO = (struct AFIO *)AFIO_BASE;
|
||||
|
||||
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
|
||||
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
|
||||
|
||||
|
||||
struct DBGMCU {
|
||||
volatile uint32_t CR;
|
||||
};
|
||||
|
||||
#define DBGMCU_BASE 0xE0042004
|
||||
#define DBG_SLEEP 1
|
||||
static struct DBGMCU *const DBGMCU = (struct DBGMCU *)DBGMCU_BASE;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* sys.c - system routines for the initial page for STM32F030 / STM32F103.
|
||||
* sys-stm32f0.c - system routines for the initial page for STM32F030.
|
||||
*
|
||||
* Copyright (C) 2013, 2014, 2015, 2016 Flying Stone Technology
|
||||
* Copyright (C) 2013, 2014, 2015, 2016, 2017
|
||||
* Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* Copying and distribution of this file, with or without modification,
|
||||
@@ -18,6 +19,7 @@
|
||||
#include "board.h"
|
||||
|
||||
#define STM32F0_USE_VECTOR_ON_RAM
|
||||
#include "mcu/cortex-m.h"
|
||||
#include "mcu/clk_gpio_init-stm32.c"
|
||||
|
||||
|
||||
@@ -298,38 +300,11 @@ flash_erase_all_and_exec (void (*entry)(void))
|
||||
for (;;);
|
||||
}
|
||||
|
||||
struct SCB
|
||||
{
|
||||
volatile uint32_t CPUID;
|
||||
volatile uint32_t ICSR;
|
||||
volatile uint32_t VTOR;
|
||||
volatile uint32_t AIRCR;
|
||||
volatile uint32_t SCR;
|
||||
volatile uint32_t CCR;
|
||||
volatile uint8_t SHP[12];
|
||||
volatile uint32_t SHCSR;
|
||||
volatile uint32_t CFSR;
|
||||
volatile uint32_t HFSR;
|
||||
volatile uint32_t DFSR;
|
||||
volatile uint32_t MMFAR;
|
||||
volatile uint32_t BFAR;
|
||||
volatile uint32_t AFSR;
|
||||
volatile uint32_t PFR[2];
|
||||
volatile uint32_t DFR;
|
||||
volatile uint32_t ADR;
|
||||
volatile uint32_t MMFR[4];
|
||||
volatile uint32_t ISAR[5];
|
||||
};
|
||||
|
||||
#define SCS_BASE (0xE000E000)
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
||||
static struct SCB *const SCB = (struct SCB *)SCB_BASE;
|
||||
|
||||
#define SYSRESETREQ 0x04
|
||||
static void
|
||||
nvic_system_reset (void)
|
||||
{
|
||||
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ);
|
||||
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
|
||||
asm volatile ("dsb");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* sys.c - system routines for the initial page for STM32F103.
|
||||
* sys-stm32f103.c - system routines for the initial page for STM32F103.
|
||||
*
|
||||
* Copyright (C) 2013, 2014, 2015, 2016 Flying Stone Technology
|
||||
* Copyright (C) 2013, 2014, 2015, 2016, 2017
|
||||
* Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* Copying and distribution of this file, with or without modification,
|
||||
@@ -17,6 +18,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "board.h"
|
||||
|
||||
#include "mcu/cortex-m.h"
|
||||
#include "mcu/clk_gpio_init-stm32.c"
|
||||
|
||||
|
||||
@@ -299,38 +301,10 @@ flash_erase_all_and_exec (void (*entry)(void))
|
||||
for (;;);
|
||||
}
|
||||
|
||||
struct SCB
|
||||
{
|
||||
volatile uint32_t CPUID;
|
||||
volatile uint32_t ICSR;
|
||||
volatile uint32_t VTOR;
|
||||
volatile uint32_t AIRCR;
|
||||
volatile uint32_t SCR;
|
||||
volatile uint32_t CCR;
|
||||
volatile uint8_t SHP[12];
|
||||
volatile uint32_t SHCSR;
|
||||
volatile uint32_t CFSR;
|
||||
volatile uint32_t HFSR;
|
||||
volatile uint32_t DFSR;
|
||||
volatile uint32_t MMFAR;
|
||||
volatile uint32_t BFAR;
|
||||
volatile uint32_t AFSR;
|
||||
volatile uint32_t PFR[2];
|
||||
volatile uint32_t DFR;
|
||||
volatile uint32_t ADR;
|
||||
volatile uint32_t MMFR[4];
|
||||
volatile uint32_t ISAR[5];
|
||||
};
|
||||
|
||||
#define SCS_BASE (0xE000E000)
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
||||
static struct SCB *const SCB = (struct SCB *)SCB_BASE;
|
||||
|
||||
#define SYSRESETREQ 0x04
|
||||
static void
|
||||
nvic_system_reset (void)
|
||||
{
|
||||
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ);
|
||||
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
|
||||
asm volatile ("dsb");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ extern const uint8_t sys_board_name[];
|
||||
#endif
|
||||
|
||||
typedef void (*handler)(void);
|
||||
typedef void (*nonreturn_handler0)(void)__attribute__((noreturn));
|
||||
typedef void (*nonreturn_handler1)(void *)__attribute__((noreturn));
|
||||
extern handler vector[16];
|
||||
|
||||
static inline const uint8_t *
|
||||
@@ -90,10 +92,9 @@ flash_protect (void)
|
||||
static inline void __attribute__((noreturn))
|
||||
flash_erase_all_and_exec (void (*entry)(void))
|
||||
{
|
||||
void (*func) (void (*)(void)) = (void (*)(void (*)(void)))vector[9];
|
||||
nonreturn_handler1 func = (nonreturn_handler1) vector[9] ;
|
||||
|
||||
(*func) (entry);
|
||||
for (;;);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -111,7 +112,9 @@ usb_lld_sys_shutdown (void)
|
||||
static inline void __attribute__((noreturn))
|
||||
nvic_system_reset (void)
|
||||
{
|
||||
(*vector[12]) ();
|
||||
nonreturn_handler0 func = (nonreturn_handler0)vector[12];
|
||||
|
||||
(func) ();
|
||||
}
|
||||
|
||||
#ifdef REQUIRE_CLOCK_GPIO_SETTING_IN_SYS
|
||||
|
||||
@@ -41,6 +41,7 @@ struct endpoint_ctl {
|
||||
};
|
||||
static struct endpoint_ctl ep[16];
|
||||
|
||||
#if 0
|
||||
struct USB_CONF {
|
||||
const uint8_t PERID; /* Peripheral ID register */
|
||||
uint8_t rsvd0[3]; /* */
|
||||
@@ -51,6 +52,7 @@ struct USB_CONF {
|
||||
volatile uint8_t ADDINFO; /* Peripheral Additional Info register */
|
||||
};
|
||||
static struct USB_CONF *const USB_CONF = (struct USB_CONF *)0x40072000;
|
||||
#endif
|
||||
|
||||
struct USB_CTRL0 {
|
||||
volatile uint8_t OTGCTL; /* OTG Control register */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* usb-stm32f103.c - USB driver for STM32F103
|
||||
*
|
||||
* Copyright (C) 2016 Flying Stone Technology
|
||||
* Copyright (C) 2016, 2017 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Chopstx, a thread library for embedded.
|
||||
@@ -339,7 +339,22 @@ void usb_lld_init (struct usb_dev *dev, uint8_t feature)
|
||||
|
||||
/* Clear Interrupt Status Register, and enable interrupt for USB */
|
||||
st103_set_istr (0);
|
||||
st103_set_cntr (CNTR_CTRM | CNTR_RESETM);
|
||||
st103_set_cntr (CNTR_CTRM | CNTR_OVRM | CNTR_ERRM
|
||||
| CNTR_WKUPM | CNTR_SUSPM | CNTR_RESETM);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Since stop mode makes PLL, HSI & HES oscillators stop, USB clock is
|
||||
* not supplied in stop mode. Thus, USB wakeup can't occur.
|
||||
*
|
||||
* So, only sleep mode can be supported with USB, which doesn't
|
||||
* require use of EXTI.
|
||||
*/
|
||||
#include "mcu/stm32f103.h"
|
||||
/* Setting of EXTI wakeup event to break stop mode. */
|
||||
EXTI->EMR |= (1 << 18); /* Event mask cleared */
|
||||
EXTI->RTSR |= (1 << 18); /* Rising trigger selection */
|
||||
#endif
|
||||
}
|
||||
|
||||
void usb_lld_prepare_shutdown (void)
|
||||
@@ -367,6 +382,19 @@ usb_lld_event_handler (struct usb_dev *dev)
|
||||
st103_set_istr (CLR_RESET);
|
||||
return USB_MAKE_EV (USB_EVENT_DEVICE_RESET);
|
||||
}
|
||||
else if ((istr_value & ISTR_WKUP))
|
||||
{
|
||||
*CNTR &= ~CNTR_FSUSP;
|
||||
st103_set_istr (CLR_WKUP);
|
||||
return USB_MAKE_EV (USB_EVENT_DEVICE_WAKEUP);
|
||||
}
|
||||
else if ((istr_value & ISTR_SUSP))
|
||||
{
|
||||
*CNTR |= CNTR_FSUSP;
|
||||
st103_set_istr (CLR_SUSP);
|
||||
*CNTR |= CNTR_LPMODE;
|
||||
return USB_MAKE_EV (USB_EVENT_DEVICE_SUSPEND);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((istr_value & ISTR_OVR))
|
||||
|
||||
@@ -187,6 +187,7 @@ enum {
|
||||
USB_INTR_DATA_TRANSFER,
|
||||
USB_INTR_RESET,
|
||||
USB_INTR_SUSPEND,
|
||||
USB_INTR_SHUTDOWN
|
||||
};
|
||||
|
||||
struct usb_controller {
|
||||
@@ -457,6 +458,7 @@ usbip_handle_data_urb (struct urb *urb)
|
||||
}
|
||||
|
||||
static int fd;
|
||||
static int shutdown_notify_fd;
|
||||
static pthread_mutex_t fd_mutex;
|
||||
|
||||
static void unlink_urb (struct urb *urb);
|
||||
@@ -801,7 +803,8 @@ usbip_process_cmd (void)
|
||||
|
||||
if (recv (fd, (char *)&msg, sizeof (msg), 0) != sizeof (msg))
|
||||
{
|
||||
perror ("msg recv");
|
||||
if (errno)
|
||||
perror ("msg recv");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1039,6 +1042,9 @@ usbip_run_server (void *arg)
|
||||
const int one = 1;
|
||||
struct pollfd pollfds[16];
|
||||
int i;
|
||||
int r = 0;
|
||||
|
||||
(void)arg;
|
||||
|
||||
pthread_mutex_init (&usbc.mutex, NULL);
|
||||
pthread_cond_init (&usbc.cond, NULL);
|
||||
@@ -1046,7 +1052,6 @@ usbip_run_server (void *arg)
|
||||
pthread_mutex_init (&fd_mutex, NULL);
|
||||
pthread_mutex_init (&urb_mutex, NULL);
|
||||
|
||||
(void)arg;
|
||||
if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
perror ("socket");
|
||||
@@ -1075,9 +1080,7 @@ usbip_run_server (void *arg)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* FIXME: We don't use this pollstruct as EP0 is handled
|
||||
synchronously. */
|
||||
pollfds[1].fd = usbc_ep0.eventfd;
|
||||
pollfds[1].fd = shutdown_notify_fd;
|
||||
pollfds[1].events = POLLIN;
|
||||
pollfds[1].revents = 0;
|
||||
|
||||
@@ -1097,14 +1100,15 @@ usbip_run_server (void *arg)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Since EP0 is handled synchronously, we don't poll on
|
||||
* usbc_ep0.eventfd. We poll on socket and shutdown request.
|
||||
*/
|
||||
pollfds[0].fd = fd;
|
||||
pollfds[0].events = POLLIN;
|
||||
pollfds[0].revents = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int r;
|
||||
|
||||
for (i = 1; i < 8; i++)
|
||||
{
|
||||
if (usbc_ep_in[i].urb)
|
||||
@@ -1124,7 +1128,7 @@ usbip_run_server (void *arg)
|
||||
if (poll (pollfds, 16, -1) < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
goto again;
|
||||
continue;
|
||||
|
||||
perror ("poll");
|
||||
exit (1);
|
||||
@@ -1146,6 +1150,20 @@ usbip_run_server (void *arg)
|
||||
goto again;
|
||||
}
|
||||
|
||||
if ((pollfds[1].revents & POLLNVAL)
|
||||
|| (pollfds[1].revents & POLLERR))
|
||||
{
|
||||
fprintf (stderr, "Error on USBIP client socket: %d\n",
|
||||
pollfds[1].revents);
|
||||
exit (1);
|
||||
}
|
||||
if ((pollfds[1].revents & POLLIN))
|
||||
{
|
||||
/* Shutdown request */
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; i++)
|
||||
{
|
||||
if ((pollfds[i*2].revents & POLLNVAL)
|
||||
@@ -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 (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;
|
||||
}
|
||||
|
||||
@@ -1408,9 +1458,8 @@ read_data_transaction (struct usb_control *usbc_p,
|
||||
return count;
|
||||
}
|
||||
|
||||
void chx_handle_intr (uint32_t irq_num);
|
||||
extern void chx_handle_intr (uint32_t irq_num);
|
||||
|
||||
#define INTR_REQ_USB SIGUSR1
|
||||
|
||||
static void
|
||||
usb_intr (int signum, siginfo_t *siginfo, void *arg)
|
||||
@@ -1445,6 +1494,13 @@ usb_lld_init (struct usb_dev *dev, uint8_t feature)
|
||||
|
||||
pthread_sigmask (SIG_BLOCK, &sigset, NULL);
|
||||
|
||||
shutdown_notify_fd = eventfd (0, EFD_CLOEXEC);
|
||||
if (shutdown_notify_fd < 0)
|
||||
{
|
||||
perror ("eventfd");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
pthread_mutex_init (&usbc_ep0.mutex, NULL);
|
||||
usbc_ep0.urb = NULL;
|
||||
usbc_ep0.eventfd = eventfd (0, EFD_CLOEXEC);
|
||||
@@ -1506,12 +1562,14 @@ usb_lld_prepare_shutdown (void)
|
||||
void
|
||||
usb_lld_shutdown (void)
|
||||
{
|
||||
const uint64_t l = 1;
|
||||
|
||||
/*
|
||||
* Stop USBIP server thread.
|
||||
* Tell USBIP server thread about shutdown.
|
||||
*/
|
||||
pthread_cancel (tid_usbip);
|
||||
write (shutdown_notify_fd, &l, sizeof (l));
|
||||
pthread_join (tid_usbip, NULL);
|
||||
/* FIXME: Cancel all URB in the list here. */
|
||||
notify_device (USB_INTR_SHUTDOWN, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1550,6 +1608,11 @@ usb_lld_event_handler (struct usb_dev *dev)
|
||||
return USB_MAKE_EV (handle_setup0 (dev));
|
||||
else if (intr == USB_INTR_DATA_TRANSFER)
|
||||
return usb_handle_transfer (dev, dir, ep_num);
|
||||
else if (intr == USB_INTR_SHUTDOWN)
|
||||
{
|
||||
if ((debug & DEBUG_USB))
|
||||
puts ("USB shutdown");
|
||||
}
|
||||
|
||||
return USB_EVENT_OK;
|
||||
}
|
||||
|
||||
6
rules.mk
6
rules.mk
@@ -6,6 +6,12 @@ ifneq ($(USE_EVENTFLAG),)
|
||||
CSRC += $(CHOPSTX)/eventflag.c
|
||||
endif
|
||||
|
||||
ifeq ($(EMULATION),)
|
||||
CSRC += $(CHOPSTX)/mcu/chx-$(CHIP).c
|
||||
else
|
||||
CSRC += $(CHOPSTX)/mcu/chx-gnu-linux.c
|
||||
endif
|
||||
|
||||
ifneq ($(USE_SYS),)
|
||||
CSRC += $(CHOPSTX)/mcu/sys-$(CHIP).c
|
||||
endif
|
||||
|
||||
18
usb_lld.h
18
usb_lld.h
@@ -64,6 +64,7 @@ enum {
|
||||
/* Device reset and suspend. */
|
||||
USB_EVENT_DEVICE_RESET,
|
||||
USB_EVENT_DEVICE_SUSPEND,
|
||||
USB_EVENT_DEVICE_WAKEUP,
|
||||
/* Device Requests (Control WRITE Transfer): Standard */
|
||||
USB_EVENT_SET_CONFIGURATION,
|
||||
USB_EVENT_SET_INTERFACE,
|
||||
@@ -83,12 +84,13 @@ enum {
|
||||
};
|
||||
|
||||
enum DEVICE_STATE {
|
||||
UNCONNECTED,
|
||||
ATTACHED,
|
||||
POWERED,
|
||||
SUSPENDED,
|
||||
ADDRESSED,
|
||||
CONFIGURED
|
||||
USB_DEVICE_STATE_UNCONNECTED = 0, /* No USB */
|
||||
USB_DEVICE_STATE_ATTACHED = 1,
|
||||
USB_DEVICE_STATE_POWERED = 2,
|
||||
USB_DEVICE_STATE_DEFAULT = 3,
|
||||
USB_DEVICE_STATE_ADDRESSED = 4,
|
||||
USB_DEVICE_STATE_CONFIGURED = 5,
|
||||
USB_DEVICE_STATE_SUSPEND = 128 /* Or-ed to other states */
|
||||
};
|
||||
|
||||
void usb_lld_init (struct usb_dev *dev, uint8_t feature);
|
||||
@@ -135,12 +137,15 @@ void usb_lld_prepare_shutdown (void);
|
||||
void usb_lld_shutdown (void);
|
||||
|
||||
#if defined(MCU_KINETIS_L)
|
||||
#define INTR_REQ_USB 24
|
||||
void usb_lld_tx_enable_buf (int ep_num, const void *buf, size_t len);
|
||||
void usb_lld_rx_enable_buf (int ep_num, void *buf, size_t len);
|
||||
|
||||
void usb_lld_setup_endp (struct usb_dev *dev, int ep_num, int rx_en, int tx_en);
|
||||
void usb_lld_stall (int ep_num);
|
||||
#elif defined(GNU_LINUX_EMULATION)
|
||||
#include <signal.h>
|
||||
#define INTR_REQ_USB SIGUSR1
|
||||
void usb_lld_tx_enable_buf (int ep_num, const void *buf, size_t len);
|
||||
void usb_lld_rx_enable_buf (int ep_num, void *buf, size_t len);
|
||||
|
||||
@@ -148,6 +153,7 @@ void usb_lld_setup_endp (struct usb_dev *dev, int ep_num, int rx_en, int tx_en);
|
||||
void usb_lld_stall_tx (int ep_num);
|
||||
void usb_lld_stall_rx (int ep_num);
|
||||
#else
|
||||
#define INTR_REQ_USB 20
|
||||
/* EP_TYPE[1:0] EndPoint TYPE */
|
||||
#define EP_BULK (0x0000) /* EndPoint BULK */
|
||||
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
|
||||
|
||||
Reference in New Issue
Block a user