36 Commits

Author SHA1 Message Date
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
57 changed files with 1030 additions and 598 deletions

127
ChangeLog
View File

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

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

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

View File

@@ -1 +1 @@
release/1.5
release/1.6

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
#define BOARD_NAME "Olimex STM32-H103"
#define BOARD_ID 0xf92bb594
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

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

View File

@@ -16,6 +16,7 @@
* GND BLACK --> 20 GND
*/
#define MCU_STM32F1 1
#define STM32F10X_MD /* Medium-density device */
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -79,7 +79,11 @@ chx_fatal (uint32_t err_code)
#include "chopstx-cortex-m.h"
#endif
/* RUNNING: the current thread. */
/* ALLOW_SLEEP for the idle thread. */
int chx_allow_sleep;
static struct chx_spinlock chx_enable_sleep_lock;
/* RUNNING: the current thread. */
struct chx_thread *running;
struct chx_queue {
@@ -382,6 +386,7 @@ chx_timer_expired (void)
{
uint32_t next_tick = tp->v;
tp->v = (uintptr_t)0;
chx_ready_enqueue (tp);
if (tp == running) /* tp->flag_sched_rr == 1 */
prio = MAX_PRIO;
@@ -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;
}

View File

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

View File

@@ -32,6 +32,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <chopstx.h>
#include <mcu/stm32.h>
#include <mcu/stm32f103.h>
#include "adc.h"

View File

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

View File

@@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename chopstx.info
@set VERSION 1.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
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -163,17 +163,19 @@ button (void *arg)
return NULL;
}
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#include "stack-def.h"
#define PRIO_LED 3
#define PRIO_BUTTON 2
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
#define STACK_ADDR_LED ((uint32_t)process1_base)
#define STACK_SIZE_LED (sizeof process1_base)
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__)
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__)
#define STACK_ADDR_BUTTON ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_BUTTON ((uint32_t)__process2_stack_size__)
#define STACK_ADDR_BUTTON ((uint32_t)process2_base)
#define STACK_SIZE_BUTTON (sizeof process2_base)
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
@@ -365,8 +367,6 @@ text_display (uint8_t kind)
}
static void setup_scr_sleepdeep (void);
int
main (int argc, const char *argv[])
{
@@ -378,6 +378,8 @@ main (int argc, const char *argv[])
(void)argc;
(void)argv;
chopstx_conf_idle (1);
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd1);
@@ -418,56 +420,6 @@ main (int argc, const char *argv[])
chopstx_join (button_thd, NULL);
chopstx_join (led_thd, NULL);
setup_scr_sleepdeep ();
for (;;)
asm volatile ("wfi" : : : "memory");
chopstx_conf_idle (4);
return 0;
}
struct SCB
{
volatile uint32_t CPUID;
volatile uint32_t ICSR;
volatile uint32_t VTOR;
volatile uint32_t AIRCR;
volatile uint32_t SCR;
volatile uint32_t CCR;
volatile uint8_t SHP[12];
volatile uint32_t SHCSR;
volatile uint32_t CFSR;
volatile uint32_t HFSR;
volatile uint32_t DFSR;
volatile uint32_t MMFAR;
volatile uint32_t BFAR;
volatile uint32_t AFSR;
volatile uint32_t PFR[2];
volatile uint32_t DFR;
volatile uint32_t ADR;
volatile uint32_t MMFR[4];
volatile uint32_t ISAR[5];
};
#define SCS_BASE (0xE000E000)
#define SCB_BASE (SCS_BASE + 0x0D00)
static struct SCB *const SCB = ((struct SCB *)SCB_BASE);
#define SCB_SCR_SLEEPDEEP (1 << 2)
struct PWR
{
volatile uint32_t CR;
volatile uint32_t CSR;
};
#define PWR_CR_PDDS 0x0002
#define PWR_CR_CWUF 0x0004
#define PWR_BASE (APBPERIPH_BASE + 0x00007000)
#define PWR ((struct PWR *) PWR_BASE)
static void setup_scr_sleepdeep (void)
{
PWR->CR |= PWR_CR_CWUF;
PWR->CR |= PWR_CR_PDDS;
SCB->SCR |= SCB_SCR_SLEEPDEEP;
}

View File

@@ -1,12 +1,6 @@
/*
* ST32F0 memory setup.
*/
__main_stack_size__ = 0x0100; /* Idle+Exception handlers */
__process0_stack_size__ = 0x0100; /* Main program */
__process1_stack_size__ = 0x0100; /* first thread program */
__process2_stack_size__ = 0x0100; /* second thread program */
__process3_stack_size__ = 0x0100; /* third thread program */
MEMORY
{
flash : org = 0x08000000, len = 16k
@@ -61,34 +55,15 @@ SECTIONS
_etext = .;
_textdata = _etext;
.process_stack :
.stacks (NOLOAD) :
{
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
*(.main_stack)
*(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
. = ALIGN(8);
__process3_stack_end__ = .;
__process2_stack_base__ = .;
. += __process2_stack_size__;
. = ALIGN(8);
__process2_stack_end__ = .;
__process1_stack_base__ = .;
. += __process1_stack_size__;
. = ALIGN(8);
__process1_stack_end__ = .;
__process0_stack_base__ = .;
. += __process0_stack_size__;
. = ALIGN(8);
__process0_stack_end__ = .;
} > ram
.main_stack :
{
. = ALIGN(8);
__main_stack_base__ = .;
. += __main_stack_size__;
. = ALIGN(8);
__main_stack_end__ = .;
} > ram
.data :

View File

@@ -166,14 +166,16 @@ button (void *arg)
#define PRIO_LED 3
#define PRIO_BUTTON 2
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
#define STACK_MAIN
#define STACK_PROCESS_1
#define STACK_PROCESS_2
#include "stack-def.h"
#define STACK_ADDR_LED ((uint32_t)__process1_stack_base__)
#define STACK_SIZE_LED ((uint32_t)__process1_stack_size__)
#define STACK_ADDR_LED ((uint32_t)process1_base)
#define STACK_SIZE_LED (sizeof process1_base)
#define STACK_ADDR_BUTTON ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_BUTTON ((uint32_t)__process2_stack_size__)
#define STACK_ADDR_BUTTON ((uint32_t)process2_base)
#define STACK_SIZE_BUTTON (sizeof process2_base)
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
@@ -355,8 +357,6 @@ text_display (uint8_t kind)
}
static void setup_scr_sleepdeep (void);
int
main (int argc, const char *argv[])
{
@@ -366,6 +366,8 @@ main (int argc, const char *argv[])
(void)argc;
(void)argv;
chopstx_conf_idle (1);
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd1);
@@ -406,56 +408,6 @@ main (int argc, const char *argv[])
chopstx_join (button_thd, NULL);
chopstx_join (led_thd, NULL);
setup_scr_sleepdeep ();
for (;;)
asm volatile ("wfi" : : : "memory");
chopstx_conf_idle (4);
return 0;
}
struct SCB
{
volatile uint32_t CPUID;
volatile uint32_t ICSR;
volatile uint32_t VTOR;
volatile uint32_t AIRCR;
volatile uint32_t SCR;
volatile uint32_t CCR;
volatile uint8_t SHP[12];
volatile uint32_t SHCSR;
volatile uint32_t CFSR;
volatile uint32_t HFSR;
volatile uint32_t DFSR;
volatile uint32_t MMFAR;
volatile uint32_t BFAR;
volatile uint32_t AFSR;
volatile uint32_t PFR[2];
volatile uint32_t DFR;
volatile uint32_t ADR;
volatile uint32_t MMFR[4];
volatile uint32_t ISAR[5];
};
#define SCS_BASE (0xE000E000)
#define SCB_BASE (SCS_BASE + 0x0D00)
static struct SCB *const SCB = ((struct SCB *)SCB_BASE);
#define SCB_SCR_SLEEPDEEP (1 << 2)
struct PWR
{
volatile uint32_t CR;
volatile uint32_t CSR;
};
#define PWR_CR_PDDS 0x0002
#define PWR_CR_CWUF 0x0004
#define PWR_BASE (APBPERIPH_BASE + 0x00007000)
#define PWR ((struct PWR *) PWR_BASE)
static void setup_scr_sleepdeep (void)
{
PWR->CR |= PWR_CR_CWUF;
PWR->CR |= PWR_CR_PDDS;
SCB->SCR |= SCB_SCR_SLEEPDEEP;
}

View File

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

View File

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

View File

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

View File

@@ -1,12 +1,6 @@
/*
* ST32F0 memory setup.
*/
__main_stack_size__ = 0x0100; /* Idle+Exception handlers */
__process0_stack_size__ = 0x0100; /* Main program */
__process1_stack_size__ = 0x0100; /* first thread program */
__process2_stack_size__ = 0x0100; /* second thread program */
__process3_stack_size__ = 0x0100; /* third thread program */
MEMORY
{
flash0 : org = 0x08000000, len = 4k
@@ -87,34 +81,15 @@ SECTIONS
KEEP(*(.bss.startup.*))
} > ram
.process_stack :
.stacks (NOLOAD) :
{
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
*(.main_stack)
*(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
. = ALIGN(8);
__process3_stack_end__ = .;
__process2_stack_base__ = .;
. += __process2_stack_size__;
. = ALIGN(8);
__process2_stack_end__ = .;
__process1_stack_base__ = .;
. += __process1_stack_size__;
. = ALIGN(8);
__process1_stack_end__ = .;
__process0_stack_base__ = .;
. += __process0_stack_size__;
. = ALIGN(8);
__process0_stack_end__ = .;
} > ram
.main_stack :
{
. = ALIGN(8);
__main_stack_base__ = .;
. += __main_stack_size__;
. = ALIGN(8);
__main_stack_end__ = .;
} > ram
.data :

View File

@@ -1,12 +1,6 @@
/*
* ST32F103 memory setup.
*/
__main_stack_size__ = 0x0100; /* Idle+Exception handlers */
__process0_stack_size__ = 0x0100; /* Main program */
__process1_stack_size__ = 0x0100; /* first thread program */
__process2_stack_size__ = 0x0100; /* second thread program */
__process3_stack_size__ = 0x0100; /* third thread program */
MEMORY
{
flash0 : org = 0x08000000, len = 4k
@@ -78,34 +72,14 @@ SECTIONS
_etext = .;
_textdata = _etext;
.process_stack :
.stacks (NOLOAD) :
{
*(.main_stack)
*(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
. = ALIGN(8);
__process3_stack_base__ = .;
. += __process3_stack_size__;
. = ALIGN(8);
__process3_stack_end__ = .;
__process2_stack_base__ = .;
. += __process2_stack_size__;
. = ALIGN(8);
__process2_stack_end__ = .;
__process1_stack_base__ = .;
. += __process1_stack_size__;
. = ALIGN(8);
__process1_stack_end__ = .;
__process0_stack_base__ = .;
. += __process0_stack_size__;
. = ALIGN(8);
__process0_stack_end__ = .;
} > ram
.main_stack :
{
. = ALIGN(8);
__main_stack_base__ = .;
. += __main_stack_size__;
. = ALIGN(8);
__main_stack_end__ = .;
} > ram
.data :

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

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

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

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

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

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

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

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

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

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

View File

@@ -26,28 +26,7 @@
*
*/
#define STM32_SW_HSI (0 << 0)
#define STM32_SW_PLL (2 << 0)
#define STM32_PLLSRC_HSI (0 << 16)
#define STM32_PLLSRC_HSE (1 << 16)
#define STM32_PLLXTPRE_DIV1 (0 << 17)
#define STM32_PLLXTPRE_DIV2 (1 << 17)
#define STM32_HPRE_DIV1 (0 << 4)
#define STM32_PPRE1_DIV1 (0 << 8)
#define STM32_PPRE1_DIV2 (4 << 8)
#define STM32_PPRE2_DIV1 (0 << 11)
#define STM32_PPRE2_DIV2 (4 << 11)
#define STM32_ADCPRE_DIV4 (1 << 14)
#define STM32_ADCPRE_DIV6 (2 << 14)
#define STM32_USBPRE_DIV1P5 (0 << 22)
#define STM32_MCO_NOCLOCK (0 << 24)
#include <mcu/stm32.h>
#if defined(MCU_STM32F0)
#define STM32_PPRE1 STM32_PPRE1_DIV1
@@ -74,85 +53,6 @@
#define STM32_HCLK (STM32_SYSCLK / 1)
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct RCC {
volatile uint32_t CR;
volatile uint32_t CFGR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
#if defined(MCU_STM32F0)
volatile uint32_t AHBRSTR;
volatile uint32_t CFGR2;
volatile uint32_t CFGR3;
volatile uint32_t CR2;
#endif
};
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
static struct RCC *const RCC = (struct RCC *)RCC_BASE;
#define RCC_APB1ENR_USBEN 0x00800000
#define RCC_APB1RSTR_USBRST 0x00800000
#define RCC_CR_HSION 0x00000001
#define RCC_CR_HSIRDY 0x00000002
#define RCC_CR_HSITRIM 0x000000F8
#define RCC_CR_HSEON 0x00010000
#define RCC_CR_HSERDY 0x00020000
#define RCC_CR_PLLON 0x01000000
#define RCC_CR_PLLRDY 0x02000000
#define RCC_CFGR_SWS 0x0000000C
#define RCC_CFGR_SWS_HSI 0x00000000
#define RCC_AHBENR_CRCEN 0x0040
#if defined(MCU_STM32F0)
#define RCC_AHBRSTR_IOPARST 0x00020000
#define RCC_AHBRSTR_IOPBRST 0x00040000
#define RCC_AHBRSTR_IOPCRST 0x00080000
#define RCC_AHBRSTR_IOPDRST 0x00100000
#define RCC_AHBRSTR_IOPFRST 0x00400000
#define RCC_AHBENR_IOPAEN 0x00020000
#define RCC_AHBENR_IOPBEN 0x00040000
#define RCC_AHBENR_IOPCEN 0x00080000
#define RCC_AHBENR_IOPDEN 0x00100000
#define RCC_AHBENR_IOPFEN 0x00400000
#define RCC_APB2RSTR_SYSCFGRST 0x00000001
#define RCC_APB2ENR_SYSCFGEN 0x00000001
#else
#define RCC_APB2RSTR_AFIORST 0x00000001
#define RCC_APB2RSTR_IOPARST 0x00000004
#define RCC_APB2RSTR_IOPBRST 0x00000008
#define RCC_APB2RSTR_IOPCRST 0x00000010
#define RCC_APB2RSTR_IOPDRST 0x00000020
#define RCC_APB2RSTR_IOPERST 0x00000040
#define RCC_APB2RSTR_IOPFRST 0x00000080
#define RCC_APB2RSTR_IOPGRST 0x00000100
#define RCC_APB2ENR_AFIOEN 0x00000001
#define RCC_APB2ENR_IOPAEN 0x00000004
#define RCC_APB2ENR_IOPBEN 0x00000008
#define RCC_APB2ENR_IOPCEN 0x00000010
#define RCC_APB2ENR_IOPDEN 0x00000020
#define RCC_APB2ENR_IOPEEN 0x00000040
#define RCC_APB2ENR_IOPFEN 0x00000080
#define RCC_APB2ENR_IOPGEN 0x00000100
#endif
#if defined(MCU_STM32F0)
struct SYSCFG {
volatile uint32_t CFGR1;
@@ -218,9 +118,6 @@ clock_init (void)
/* Flash setup */
FLASH->ACR = STM32_FLASHBITS;
/* CRC */
RCC->AHBENR |= RCC_AHBENR_CRCEN;
/* Switching on the configured clock source. */
RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))

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

@@ -0,0 +1,29 @@
/* System Control Block */
struct SCB
{
volatile uint32_t CPUID;
volatile uint32_t ICSR;
volatile uint32_t VTOR;
volatile uint32_t AIRCR;
volatile uint32_t SCR;
volatile uint32_t CCR;
volatile uint8_t SHP[12];
volatile uint32_t SHCSR;
volatile uint32_t CFSR;
volatile uint32_t HFSR;
volatile uint32_t DFSR;
volatile uint32_t MMAR;
volatile uint32_t BFAR;
volatile uint32_t AFSR;
volatile uint32_t PFR[2];
volatile uint32_t DFR;
volatile uint32_t AFR;
volatile uint32_t MMFR[4];
volatile uint32_t ISAR[5];
};
#define SCS_BASE 0xE000E000
#define SCB_BASE (SCS_BASE + 0x0D00)
static struct SCB *const SCB = (struct SCB *)SCB_BASE;
#define SCB_SCR_SLEEPDEEP (1 << 2)
#define SCB_AIRCR_SYSRESETREQ 0x04

141
mcu/stm32.h Normal file
View File

@@ -0,0 +1,141 @@
#define PERIPH_BASE 0x40000000
#define 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 */

View File

@@ -1,41 +1,3 @@
#define PERIPH_BASE 0x40000000
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
struct RCC {
volatile uint32_t CR;
volatile uint32_t CFGR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
};
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
static struct RCC *const RCC = (struct RCC *)RCC_BASE;
#define RCC_AHBENR_DMA1EN 0x00000001
#define RCC_AHBENR_CRCEN 0x00000040
#define RCC_APB2ENR_ADC1EN 0x00000200
#define RCC_APB2ENR_ADC2EN 0x00000400
#define RCC_APB2ENR_TIM1EN 0x00000800
#define RCC_APB1ENR_TIM2EN 0x00000001
#define RCC_APB1ENR_TIM3EN 0x00000002
#define RCC_APB1ENR_TIM4EN 0x00000004
#define RCC_APB2RSTR_ADC1RST 0x00000200
#define RCC_APB2RSTR_ADC2RST 0x00000400
#define RCC_APB2RSTR_TIM1RST 0x00000800
#define RCC_APB1RSTR_TIM2RST 0x00000001
#define RCC_APB1RSTR_TIM3RST 0x00000002
#define RCC_APB1RSTR_TIM4RST 0x00000004
#define CRC_CR_RESET 0x00000001
struct CRC {
@@ -182,36 +144,6 @@ static struct DMA *const DMA1 = (struct DMA *)DMA1_BASE;
static struct DMA_Channel *const DMA1_Channel1 =
(struct DMA_Channel *)DMA1_Channel1_BASE;
/* System Control Block */
struct SCB
{
volatile uint32_t CPUID;
volatile uint32_t ICSR;
volatile uint32_t VTOR;
volatile uint32_t AIRCR;
volatile uint32_t SCR;
volatile uint32_t CCR;
volatile uint8_t SHP[12];
volatile uint32_t SHCSR;
volatile uint32_t CFSR;
volatile uint32_t HFSR;
volatile uint32_t DFSR;
volatile uint32_t MMFAR;
volatile uint32_t BFAR;
volatile uint32_t AFSR;
volatile uint32_t PFR[2];
volatile uint32_t DFR;
volatile uint32_t ADR;
volatile uint32_t MMFR[4];
volatile uint32_t ISAR[5];
uint32_t RESERVED0[5];
volatile uint32_t CPACR;
};
#define SCS_BASE 0xE000E000
#define SCB_BASE (SCS_BASE + 0x0D00)
static struct SCB *const SCB = (struct SCB *)SCB_BASE;
/* Timer */
struct TIM
{
@@ -698,3 +630,12 @@ static struct AFIO *const AFIO = (struct AFIO *)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
struct DBGMCU {
volatile uint32_t CR;
};
#define DBGMCU_BASE 0xE0042004
#define DBG_SLEEP 1
static struct DBGMCU *const DBGMCU = (struct DBGMCU *)DBGMCU_BASE;

View File

@@ -1,7 +1,8 @@
/*
* sys.c - system routines for the initial page for STM32F030 / STM32F103.
* sys-stm32f0.c - system routines for the initial page for STM32F030.
*
* Copyright (C) 2013, 2014, 2015, 2016 Flying Stone Technology
* Copyright (C) 2013, 2014, 2015, 2016, 2017
* Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* Copying and distribution of this file, with or without modification,
@@ -18,6 +19,7 @@
#include "board.h"
#define STM32F0_USE_VECTOR_ON_RAM
#include "mcu/cortex-m.h"
#include "mcu/clk_gpio_init-stm32.c"
@@ -298,38 +300,11 @@ flash_erase_all_and_exec (void (*entry)(void))
for (;;);
}
struct SCB
{
volatile uint32_t CPUID;
volatile uint32_t ICSR;
volatile uint32_t VTOR;
volatile uint32_t AIRCR;
volatile uint32_t SCR;
volatile uint32_t CCR;
volatile uint8_t SHP[12];
volatile uint32_t SHCSR;
volatile uint32_t CFSR;
volatile uint32_t HFSR;
volatile uint32_t DFSR;
volatile uint32_t MMFAR;
volatile uint32_t BFAR;
volatile uint32_t AFSR;
volatile uint32_t PFR[2];
volatile uint32_t DFR;
volatile uint32_t ADR;
volatile uint32_t MMFR[4];
volatile uint32_t ISAR[5];
};
#define SCS_BASE (0xE000E000)
#define SCB_BASE (SCS_BASE + 0x0D00)
static struct SCB *const SCB = (struct SCB *)SCB_BASE;
#define SYSRESETREQ 0x04
static void
nvic_system_reset (void)
{
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ);
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
asm volatile ("dsb");
for (;;);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,6 +6,12 @@ ifneq ($(USE_EVENTFLAG),)
CSRC += $(CHOPSTX)/eventflag.c
endif
ifeq ($(EMULATION),)
CSRC += $(CHOPSTX)/mcu/chx-$(CHIP).c
else
CSRC += $(CHOPSTX)/mcu/chx-gnu-linux.c
endif
ifneq ($(USE_SYS),)
CSRC += $(CHOPSTX)/mcu/sys-$(CHIP).c
endif

View File

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