14 Commits

Author SHA1 Message Date
NIIBE Yutaka
fffb8aa3b3 Version 1.11. 2018-10-02 09:58:45 +09:00
NIIBE Yutaka
0ed2e95ea2 Fix ackbtn clearing the edge detector. 2018-10-01 12:56:41 +09:00
NIIBE Yutaka
02aa678d4c Fix interrupt handling. 2018-10-01 10:10:09 +09:00
NIIBE Yutaka
d25cee5040 Version 1.10. 2018-09-29 11:03:32 +09:00
NIIBE Yutaka
e420168c82 doc: Update chopstx-api.texi. 2018-09-27 15:14:00 +09:00
NIIBE Yutaka
7dc67d2210 Minor change for ackbtn driver. 2018-09-27 12:53:43 +09:00
NIIBE Yutaka
49b0556a24 Add ack-botton driver. 2018-09-27 10:36:36 +09:00
NIIBE Yutaka
43bbdb44dc Fix examples. 2018-09-26 10:47:42 +09:00
NIIBE Yutaka
d4f4f80ad9 New API: chopstx_intr_done. 2018-09-26 10:18:23 +09:00
NIIBE Yutaka
7ad7527e81 Add defninitions of EXTI use for FST-01SZ. 2018-09-25 16:17:26 +09:00
NIIBE Yutaka
951afbad3a Consolidate definitions for STM32F103. 2018-09-21 14:47:16 +09:00
NIIBE Yutaka
2b717c91da Add FST-01SZ support. 2018-09-21 10:37:11 +09:00
NIIBE Yutaka
05732b445a Add MHZ for examples. 2018-08-23 14:36:22 +09:00
NIIBE Yutaka
1cbe0abdee usb: Fix for ZLP. 2018-08-20 12:43:35 +09:00
37 changed files with 463 additions and 141 deletions

View File

@@ -1,3 +1,75 @@
2018-10-02 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.11.
* doc/chopstx.texi (VERSION): 1.11.
2018-10-01 NIIBE Yutaka <gniibe@fsij.org>
* contrib/ackbtn-stm32f103.c (PINCFG_EDGE): New.
(ackbtn_init): Use PINCFG_EDGE bit.
(ackbtn_enable): Configure the edge detector here.
(ackbtn_disable): Disable the edge detector.
* chopstx.c (chopstx_poll): Don't clear ->ready here.
(chx_cond_hook): Set ->ready = 0 when condition does
not meet.
(chopstx_claim_irq): Make sure clearing the interrupt.
(chx_intr_hook): Add the case when ->ready == 1.
(chopstx_intr_done): Set ->ready = 0.
(chx_join_hook): Set ->ready = 0 when it is still alive.
2018-09-29 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.10.
* doc/chopstx.texi (VERSION): 1.10.
2018-09-27 NIIBE Yutaka <gniibe@fsij.org>
* contrib/ackbtn-stm32f103.c: New.
* rules.mk [USE_ACKBTN] (CSRC): Add ack-button support.
2018-09-26 NIIBE Yutaka <gniibe@fsij.org>
Fix for chopstx_intr_done. No spurious interrupts.
* contrib/adc-mkl27z.c (adc_wait_completion): Fix.
* contrib/adc-stm32f103.c (adc_wait_completion): Likewise.
* contrib/usart-stm32f103.c (usart_main): Likewise.
* example-cdc-gnu-linux/usb-cdc.c (tty_main): Likewise.
* example-cdc/usb-cdc.c (tty_main): Likewise.
* example-fraucheky/main.c (usb_main): Likewise.
* example-fs-bb48/touch.c (touch_get): Likewise.
* example-fs-bb48/usb-cdc.c (tty_main): Likewise.
* example-primer2/primer2-ts.c (adc3_conversion): Likewise.
* example-usb-serial/usb-cdc.c (cdc_main): Likewise.
2018-09-26 NIIBE Yutaka <gniibe@fsij.org>
* chopstx.h (chopstx_intr_done): New function.
* chopstx.c (chopstx_intr_done): New function.
(chopstx_poll): Don't call chx_clr_intr.
Ensure data memory barrier for interrupt handling.
* chopstx-cortex-m.c (chx_dmb): New static function.
* chopstx-gnu-linux.c (chx_dmb): Ditto.
2018-09-21 NIIBE Yutaka <gniibe@fsij.org>
* mcu/stm32.h (struct GPIO, struct FLASH): Moved from...
* mcu/clk_gpio_init-stm32.c: ... here.
(AFIO_MAPR_SWJ_CFG_JTAGDISABLE): Move to ...
* mcu/stm32f103.h: ... here.
* mcu/sys-stm32f103.c: Don't include "mcu/cortex-m.h".
* board/board-fst-01sz.h: New.
* mcu/sys-stm32f103.h (BOARD_ID_FST_01SZ): New.
* contrib/adc-stm32f103.c (get_adc_config): Add BOARD_ID_FST_01SZ.
2018-08-20 NIIBE Yutaka <gniibe@fsij.org>
* mcu/usb-stm32f103.c (usb_lld_ctrl_send): Fix for ZLP.
* mcu/usb-usbip.c (usb_lld_ctrl_send): Likewise.
* mcu/usb-mkl27z.c (usb_lld_ctrl_send): Likewise.
2018-05-09 NIIBE Yutaka <gniibe@fsij.org> 2018-05-09 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.9. * VERSION: 1.9.

46
NEWS
View File

@@ -1,6 +1,42 @@
NEWS - Noteworthy changes NEWS - Noteworthy changes
* Major changes in Chopstx 1.11
Released 2018-10-02
** Support calling chopstx_poll with intr->ready==1
In version <= 1.10, it assumed that all events should be handled after
chopstx_poll, before calling chopstx_poll again. With having
chopstx_intr_done, it's OK now that chopstx_poll can be called again
not examining/handling all poll descriptors, but only parts of them.
** Acknowledge button change
In 1.10, the action was able to be "memorized" by the edge detector.
Now, the edge detector is disabled by ackbtn_disable, and it is
enabled by ackbtn_enable. So, the status is cleared correctly.
** New board support: FST-01SZ
It's still under development. Programming-wise, it will keep same.
* Major changes in Chopstx 1.10
Released 2018-09-29
** Function chopstx_intr_wait is not deprecated, now
Once, it was said that it's deprecated, but it's active again
to match the new function of chopstx_intr_done.
** API change: chopstx_poll, chopstx_intr_wait, chopstx_intr_done
To avoid spurious interrupt, we introduce new function
chopstx_intr_done, which should be called after interrupt handling.
** New driver: Acknowledge button for FST-01SZ
The use case is waiting user's acknowledge. We use EXTI interrupt
feature of STM32.
* Major changes in Chopstx 1.9 * Major changes in Chopstx 1.9
Released 2018-05-09 Released 2018-05-09
@@ -42,7 +78,7 @@ Timer expiration had a bug. When it is waken up, the wake up doesn't
handle as a timer expiration when there are multiple threads on same handle as a timer expiration when there are multiple threads on same
timing of expire. It confuses as if it were forced wakeup. timing of expire. It confuses as if it were forced wakeup.
** New driver: USART for STM32. ** New driver: USART for STM32
USART driver for STM32 is added. USART driver for STM32 is added.
@@ -377,11 +413,11 @@ Vectored Interrupt Controller (NVIC), in the ARM v7-M Architecture
Reference Manual. The subsection, B3.4.1, Theory of operation, Reference Manual. The subsection, B3.4.1, Theory of operation,
explains how it works. explains how it works.
** gpio_init change ** gpio_init change
Now, gpi_init support AFIO mapping and another GPIO (GPIO_OTHER) Now, gpi_init support AFIO mapping and another GPIO (GPIO_OTHER)
settings. settings.
Local Variables:
mode: outline # Local Variables:
End: # mode: outline
# End:

4
README
View File

@@ -1,6 +1,6 @@
Chopstx - Threads and only Threads Chopstx - Threads and only Threads
Version 1.9 Version 1.11
2018-05-09 2018-10-02
Niibe Yutaka Niibe Yutaka
Flying Stone Technology Flying Stone Technology

View File

@@ -1 +1 @@
release/1.9 release/1.11

View File

@@ -71,6 +71,7 @@
* Those will be removed soon, once such an driver will be improved * Those will be removed soon, once such an driver will be improved
* in new style. * in new style.
*/ */
#if defined(PINPAD_CIR_SUPPORT)
/* For pin-cir settings of Gnuk */ /* For pin-cir settings of Gnuk */
#define TIMx TIM2 #define TIMx TIM2
#define INTR_REQ_TIM TIM2_IRQ #define INTR_REQ_TIM TIM2_IRQ
@@ -83,3 +84,4 @@
#define ENABLE_RCC_APB1 #define ENABLE_RCC_APB1
#define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN #define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST #define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST
#endif

View File

@@ -71,7 +71,7 @@
* Those will be removed soon, once such an driver will be improved * Those will be removed soon, once such an driver will be improved
* in new style. * in new style.
*/ */
/* For pin-cir settings of Gnuk */ #if defined(PINPAD_CIR_SUPPORT)
#define TIMx TIM2 #define TIMx TIM2
#define INTR_REQ_TIM TIM2_IRQ #define INTR_REQ_TIM TIM2_IRQ
#define AFIO_EXTICR_INDEX 0 #define AFIO_EXTICR_INDEX 0
@@ -83,3 +83,4 @@
#define ENABLE_RCC_APB1 #define ENABLE_RCC_APB1
#define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN #define RCC_APBnENR_TIMxEN RCC_APB1ENR_TIM2EN
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST #define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM2RST
#endif

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

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

View File

@@ -44,7 +44,7 @@
#define VAL_GPIO_OTHER_CRH 0x88888888 /* PB15...PB8 */ #define VAL_GPIO_OTHER_CRH 0x88888888 /* PB15...PB8 */
/* For pin-cir settings of Gnuk */ #if defined(PINPAD_CIR_SUPPORT)
#define TIMx TIM3 #define TIMx TIM3
#define INTR_REQ_TIM TIM3_IRQ #define INTR_REQ_TIM TIM3_IRQ
#define AFIO_EXTICR_INDEX 1 #define AFIO_EXTICR_INDEX 1
@@ -58,3 +58,4 @@
#define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM3RST #define RCC_APBnRSTR_TIMxRST RCC_APB1RSTR_TIM3RST
#define AFIO_MAPR_SOMETHING AFIO_MAPR_TIM3_REMAP_PARTIALREMAP #define AFIO_MAPR_SOMETHING AFIO_MAPR_TIM3_REMAP_PARTIALREMAP
/* Remap (PB4, PB5) -> (TIM3_CH1, TIM3_CH2) */ /* Remap (PB4, PB5) -> (TIM3_CH1, TIM3_CH2) */
#endif

View File

@@ -2,7 +2,7 @@
* chopstx-cortex-m.c - Threads and only threads: Arch specific code * chopstx-cortex-m.c - Threads and only threads: Arch specific code
* for Cortex-M0/M3 * for Cortex-M0/M3
* *
* Copyright (C) 2013, 2014, 2015, 2016, 2017 * Copyright (C) 2013, 2014, 2015, 2016, 2017, 2018
* Flying Stone Technology * Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
@@ -28,6 +28,13 @@
* *
*/ */
/* Data Memory Barrier. */
static void
chx_dmb (void)
{
asm volatile ("dmb" : : : "memory");
}
/* Saved registers on the stack. */ /* Saved registers on the stack. */
struct chx_stack_regs { struct chx_stack_regs {
uint32_t reg[8]; /* r0, r1, r2, r3, r12, lr, pc, xpsr */ uint32_t reg[8]; /* r0, r1, r2, r3, r12, lr, pc, xpsr */

View File

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

View File

@@ -1,7 +1,7 @@
/* /*
* chopstx.c - Threads and only threads. * chopstx.c - Threads and only threads.
* *
* Copyright (C) 2013, 2014, 2015, 2016, 2017 * Copyright (C) 2013, 2014, 2015, 2016, 2017, 2018
* Flying Stone Technology * Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
@@ -969,6 +969,7 @@ chx_cond_hook (struct chx_px *px, struct chx_poll_head *pd)
{ /* Condition doesn't met. { /* Condition doesn't met.
* Register the proxy to wait for the condition. * Register the proxy to wait for the condition.
*/ */
pc->ready = 0;
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
chx_spin_lock (&pc->cond->lock); chx_spin_lock (&pc->cond->lock);
ll_prio_enqueue ((struct chx_pq *)px, &pc->cond->q); ll_prio_enqueue ((struct chx_pq *)px, &pc->cond->q);
@@ -998,6 +999,7 @@ chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num)
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
chx_spin_lock (&q_intr.lock); chx_spin_lock (&q_intr.lock);
chx_disable_intr (irq_num); chx_disable_intr (irq_num);
chx_clr_intr (irq_num);
chx_set_intr_prio (irq_num); chx_set_intr_prio (irq_num);
chx_spin_unlock (&q_intr.lock); chx_spin_unlock (&q_intr.lock);
chx_cpu_sched_unlock (); chx_cpu_sched_unlock ();
@@ -1012,10 +1014,19 @@ chx_intr_hook (struct chx_px *px, struct chx_poll_head *pd)
chopstx_testcancel (); chopstx_testcancel ();
chx_cpu_sched_lock (); chx_cpu_sched_lock ();
px->v = intr->irq_num; px->v = intr->irq_num;
chx_spin_lock (&q_intr.lock); if (intr->ready)
ll_prio_enqueue ((struct chx_pq *)px, &q_intr.q); {
chx_enable_intr (intr->irq_num); chx_spin_lock (&px->lock);
chx_spin_unlock (&q_intr.lock); (*px->counter_p)++;
chx_spin_unlock (&px->lock);
}
else
{
chx_spin_lock (&q_intr.lock);
ll_prio_enqueue ((struct chx_pq *)px, &q_intr.q);
chx_enable_intr (intr->irq_num);
chx_spin_unlock (&q_intr.lock);
}
chx_cpu_sched_unlock (); chx_cpu_sched_unlock ();
} }
@@ -1034,6 +1045,26 @@ chopstx_intr_wait (chopstx_intr_t *intr)
} }
/**
* chopstx_intr_done - Finish an IRQ handling
* @intr: Pointer to INTR structure
*
* Finish for the interrupt @intr occurred.
*
*/
void
chopstx_intr_done (chopstx_intr_t *intr)
{
chx_dmb ();
if (intr->ready)
{
chx_clr_intr (intr->irq_num);
intr->ready = 0;
}
}
/** /**
* chopstx_cleanup_push - Register a clean-up * chopstx_cleanup_push - Register a clean-up
* @clp: Pointer to clean-up structure * @clp: Pointer to clean-up structure
@@ -1198,6 +1229,7 @@ chx_join_hook (struct chx_px *px, struct chx_poll_head *pd)
{ /* Not yet exited. { /* Not yet exited.
* Register the proxy to wait for TP's exit. * Register the proxy to wait for TP's exit.
*/ */
pj->ready = 0;
px->v = (uintptr_t)tp; px->v = (uintptr_t)tp;
chx_spin_lock (&q_join.lock); chx_spin_lock (&q_join.lock);
ll_prio_enqueue ((struct chx_pq *)px, &q_join.q); ll_prio_enqueue ((struct chx_pq *)px, &q_join.q);
@@ -1332,6 +1364,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
struct chx_poll_head *pd; struct chx_poll_head *pd;
int r = 0; int r = 0;
chx_dmb ();
chopstx_testcancel (); chopstx_testcancel ();
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
@@ -1340,7 +1373,6 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
pd = pd_array[i]; pd = pd_array[i];
pd->ready = 0;
px[i].ready_p = &pd->ready; px[i].ready_p = &pd->ready;
if (pd->type == CHOPSTX_POLL_COND) if (pd->type == CHOPSTX_POLL_COND)
chx_cond_hook (&px[i], pd); chx_cond_hook (&px[i], pd);
@@ -1384,6 +1416,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
while (r == 0); while (r == 0);
} }
chx_dmb ();
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
pd = pd_array[i]; pd = pd_array[i];
@@ -1404,9 +1437,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *const pd_array[])
{ {
struct chx_intr *intr = (struct chx_intr *)pd; struct chx_intr *intr = (struct chx_intr *)pd;
if (intr->ready) if (intr->ready == 0)
chx_clr_intr (intr->irq_num);
else
{ {
chx_spin_lock (&q_intr.lock); chx_spin_lock (&q_intr.lock);
ll_dequeue ((struct chx_pq *)&px[i]); ll_dequeue ((struct chx_pq *)&px[i]);

View File

@@ -155,7 +155,8 @@ typedef struct chx_intr chopstx_intr_t;
void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num); void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num);
void chopstx_intr_wait (chopstx_intr_t *intr); /* DEPRECATED */ void chopstx_intr_wait (chopstx_intr_t *intr);
void chopstx_intr_done (chopstx_intr_t *intr);
int chopstx_poll (uint32_t *usec_p, int n, int chopstx_poll (uint32_t *usec_p, int n,

View File

@@ -0,0 +1,96 @@
/*
* ackbtn-stm32f103.c - Acknowledge button support for STM32F103
*
* Copyright (C) 2018 g10 Code GmbH
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Chopstx, a thread library for embedded.
*
* Chopstx is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chopstx is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* As additional permission under GNU GPL version 3 section 7, you may
* distribute non-source form of the Program without the copy of the
* GNU GPL normally required by section 4, provided you inform the
* receipents of GNU GPL by a written offer.
*
*/
#include <stdint.h>
#include <string.h>
#include <chopstx.h>
#include <mcu/stm32f103.h>
#include "board.h"
#include "sys.h"
static uint32_t pin_config;
#define PINCFG_EDGE 0x80000000
#define PINCFG_EDGE_RISING PINCFG_EDGE
void
ackbtn_init (chopstx_intr_t *intr)
{
uint8_t irq_num;
uint32_t afio_exticr_index;
uint32_t afio_exticr_extiX_pY;
switch (SYS_BOARD_ID)
{
case BOARD_ID_FST_01SZ:
default:
/* PA3 is connected to a hall sensor DRV5032FA */
afio_exticr_index = 0;
afio_exticr_extiX_pY = AFIO_EXTICR1_EXTI3_PA;
irq_num = EXTI3_IRQ;
pin_config = 0x0008; /* EXTI_PR_PR3 == EXTI_IMR_MR3 == EXTI_RTSR_TR3 */
pin_config |= PINCFG_EDGE_RISING;
break;
}
/* Configure EXTI line */
if (afio_exticr_extiX_pY)
AFIO->EXTICR[afio_exticr_index] |= afio_exticr_extiX_pY;
/* Interrupt is masked, now */
EXTI->IMR &= ~(pin_config & ~PINCFG_EDGE);
chopstx_claim_irq (intr, irq_num);
}
void
ackbtn_enable (void)
{
/* Clear pending interrupt */
EXTI->PR |= (pin_config & ~PINCFG_EDGE);
/* Enable interrupt, clearing the mask */
EXTI->IMR |= (pin_config & ~PINCFG_EDGE);
/* Configure which edge is detected */
if ((pin_config & PINCFG_EDGE))
EXTI->RTSR |= (pin_config & ~PINCFG_EDGE);
else
EXTI->FTSR |= (pin_config & ~PINCFG_EDGE);
}
void
ackbtn_disable (void)
{
/* Disable interrupt having the mask */
EXTI->IMR &= ~(pin_config & ~PINCFG_EDGE);
/* Clear pending interrupt */
/* Disable edge detection */
EXTI->RTSR &= ~(pin_config & ~PINCFG_EDGE);
EXTI->FTSR &= ~(pin_config & ~PINCFG_EDGE);
}

3
contrib/ackbtn.h Normal file
View File

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

View File

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

View File

@@ -192,6 +192,7 @@ get_adc_config (uint32_t config[4])
case BOARD_ID_STM8S_DISCOVERY: case BOARD_ID_STM8S_DISCOVERY:
case BOARD_ID_ST_DONGLE: case BOARD_ID_ST_DONGLE:
case BOARD_ID_NITROKEY_START: case BOARD_ID_NITROKEY_START:
case BOARD_ID_FST_01SZ:
default: default:
config[0] = 0; config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
@@ -315,11 +316,10 @@ int
adc_wait_completion (void) adc_wait_completion (void)
{ {
uint32_t flags; uint32_t flags;
struct chx_poll_head *pd_array[1] = { (struct chx_poll_head *)&adc_intr };
while (1) while (1)
{ {
chopstx_poll (NULL, 1, pd_array); chopstx_intr_wait (&adc_intr);
flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */ flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */
/* /*
* Clear interrupt cause of channel 1. * Clear interrupt cause of channel 1.
@@ -328,6 +328,7 @@ adc_wait_completion (void)
* and TEIF. * and TEIF.
*/ */
DMA1->IFCR = (flags & ~1); DMA1->IFCR = (flags & ~1);
chopstx_intr_done (&adc_intr);
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */ if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
{ {

View File

@@ -541,10 +541,16 @@ usart_main (void *arg)
chopstx_poll (NULL, n, usart_poll); chopstx_poll (NULL, n, usart_poll);
if (usart2_intr.ready) if (usart2_intr.ready)
usart2_tx_ready = handle_intr (USART2, &usart2_rb_h2a, &usart2_stat); {
usart2_tx_ready = handle_intr (USART2, &usart2_rb_h2a, &usart2_stat);
chopstx_intr_done (&usart2_intr);
}
if (usart3_intr.ready) if (usart3_intr.ready)
usart3_tx_ready = handle_intr (USART3, &usart3_rb_h2a, &usart3_stat); {
usart3_tx_ready = handle_intr (USART3, &usart3_rb_h2a, &usart3_stat);
chopstx_intr_done (&usart3_intr);
}
if (usart2_tx_ready && usart2_app_write_event.ready) if (usart2_tx_ready && usart2_app_write_event.ready)
usart2_tx_ready = handle_tx_ready (USART2, usart2_tx_ready = handle_tx_ready (USART2,

View File

@@ -107,6 +107,14 @@ Claim interrupt @var{intr} with @var{irq_num}
Wait for the interrupt @var{intr} to be occured. Wait for the interrupt @var{intr} to be occured.
@end deftypefun @end deftypefun
@subheading chopstx_intr_done
@anchor{chopstx_intr_done}
@deftypefun {void} {chopstx_intr_done} (chopstx_intr_t * @var{intr})
@var{intr}: Pointer to INTR structure
Finish for the interrupt @var{intr} occurred.
@end deftypefun
@subheading chopstx_cleanup_push @subheading chopstx_cleanup_push
@anchor{chopstx_cleanup_push} @anchor{chopstx_cleanup_push}
@deftypefun {void} {chopstx_cleanup_push} (struct chx_cleanup * @var{clp}) @deftypefun {void} {chopstx_cleanup_push} (struct chx_cleanup * @var{clp})

View File

@@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*- \input texinfo @c -*-texinfo-*-
@c %**start of header @c %**start of header
@setfilename chopstx.info @setfilename chopstx.info
@set VERSION 1.9 @set VERSION 1.11
@settitle Chopstx Reference Manual @settitle Chopstx Reference Manual
@c Unify some of the indices. @c Unify some of the indices.
@syncodeindex tp fn @syncodeindex tp fn

View File

@@ -708,6 +708,7 @@ tty_main (void *arg)
* *
*/ */
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&usb_intr);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)

View File

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

View File

@@ -719,6 +719,7 @@ tty_main (void *arg)
* *
*/ */
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&usb_intr);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)

View File

@@ -185,6 +185,7 @@ usb_main (void *arg)
event_handle: event_handle:
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&interrupt);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)

View File

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

View File

@@ -708,6 +708,7 @@ tty_main (void *arg)
* *
*/ */
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&usb_intr);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)

View File

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

View File

@@ -20,7 +20,7 @@ OBJCOPY = $(CROSS)objcopy
MCU = cortex-m3 MCU = cortex-m3
CWARN = -Wall -Wextra -Wstrict-prototypes CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DUSE_SYS3 -DFREE_STANDING DEFS = -DUSE_SYS3 -DFREE_STANDING -DMHZ=72
OPT = -O3 -Os -g OPT = -O3 -Os -g
LIBS = LIBS =

View File

@@ -770,6 +770,7 @@ cdc_main (void *arg)
* *
*/ */
e = usb_lld_event_handler (&dev); e = usb_lld_event_handler (&dev);
chopstx_intr_done (&usb_intr);
ep_num = USB_EVENT_ENDP (e); ep_num = USB_EVENT_ENDP (e);
if (ep_num != 0) if (ep_num != 0)

View File

@@ -1,7 +1,7 @@
/* /*
* clk_gpio_init-stm32.c - Clock and GPIO initialization for STM32. * clk_gpio_init-stm32.c - Clock and GPIO initialization for STM32.
* *
* Copyright (C) 2015 Flying Stone Technology * Copyright (C) 2015, 2018 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Chopstx, a thread library for embedded. * This file is a part of Chopstx, a thread library for embedded.
@@ -26,7 +26,11 @@
* *
*/ */
#if defined(MCU_STM32F0)
#include <mcu/stm32.h> #include <mcu/stm32.h>
#else
#include <mcu/stm32f103.h>
#endif
#if defined(MCU_STM32F0) #if defined(MCU_STM32F0)
#define STM32_PPRE1 STM32_PPRE1_DIV1 #define STM32_PPRE1 STM32_PPRE1_DIV1
@@ -57,34 +61,6 @@
#define STM32_HCLK (STM32_SYSCLK / 1) #define STM32_HCLK (STM32_SYSCLK / 1)
#if defined(MCU_STM32F0)
struct SYSCFG {
volatile uint32_t CFGR1;
uint32_t dummy0;
volatile uint32_t EXTICR[4];
volatile uint32_t CFGR2;
};
#define SYSCFG_CFGR1_MEM_MODE 0x03
#define SYSCFG_BASE (APB1PERIPH_BASE + 0x00010000)
static struct SYSCFG *const SYSCFG = (struct SYSCFG *)SYSCFG_BASE;
#endif
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = (struct FLASH *)FLASH_R_BASE;
static void __attribute__((used)) static void __attribute__((used))
clock_init (void) clock_init (void)
{ {
@@ -140,75 +116,6 @@ clock_init (void)
} }
#if defined(MCU_STM32F0)
struct GPIO {
volatile uint32_t MODER;
volatile uint16_t OTYPER;
uint16_t dummy0;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint16_t IDR;
uint16_t dummy1;
volatile uint16_t ODR;
uint16_t dummy2;
volatile uint16_t BSRR;
uint16_t dummy3;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint16_t BRR;
uint16_t dummy4;
};
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (AHB2PERIPH_BASE + 0x0400)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (AHB2PERIPH_BASE + 0x0800)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (AHB2PERIPH_BASE + 0x0C00)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
#else
struct AFIO
{
volatile uint32_t EVCR;
volatile uint32_t MAPR;
volatile uint32_t EXTICR[4];
uint32_t RESERVED0;
volatile uint32_t MAPR2;
};
#define AFIO_BASE 0x40010000
static struct AFIO *const AFIO = (struct AFIO *)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE 0x02000000
struct GPIO {
volatile uint32_t CRL;
volatile uint32_t CRH;
volatile uint32_t IDR;
volatile uint32_t ODR;
volatile uint32_t BSRR;
volatile uint32_t BRR;
volatile uint32_t LCKR;
};
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define GPIOE ((struct GPIO *) GPIOE_BASE)
#endif
static struct GPIO *const GPIO_LED = (struct GPIO *)GPIO_LED_BASE; static struct GPIO *const GPIO_LED = (struct GPIO *)GPIO_LED_BASE;
#ifdef GPIO_USB_BASE #ifdef GPIO_USB_BASE
static struct GPIO *const GPIO_USB = (struct GPIO *)GPIO_USB_BASE; static struct GPIO *const GPIO_USB = (struct GPIO *)GPIO_USB_BASE;
@@ -248,7 +155,7 @@ gpio_init (void)
AFIO->MAPR |= AFIO_MAPR_SOMETHING; AFIO->MAPR |= AFIO_MAPR_SOMETHING;
#endif #endif
/* LED is mandatory. If it's on an independent port, we configure it. */ /* LED is mandatory. We configure it always. */
GPIO_LED->ODR = VAL_GPIO_LED_ODR; GPIO_LED->ODR = VAL_GPIO_LED_ODR;
GPIO_LED->CRH = VAL_GPIO_LED_CRH; GPIO_LED->CRH = VAL_GPIO_LED_CRH;
GPIO_LED->CRL = VAL_GPIO_LED_CRL; GPIO_LED->CRL = VAL_GPIO_LED_CRL;

View File

@@ -140,3 +140,85 @@ static struct PWR *const PWR = ((struct PWR *)0x40007000);
#define PWR_CR_LPDS 0x0001 /* Low-power deepsleep */ #define PWR_CR_LPDS 0x0001 /* Low-power deepsleep */
#define PWR_CR_PDDS 0x0002 /* Power down deepsleep */ #define PWR_CR_PDDS 0x0002 /* Power down deepsleep */
#define PWR_CR_CWUF 0x0004 /* Clear wakeup flag */ #define PWR_CR_CWUF 0x0004 /* Clear wakeup flag */
#if defined(MCU_STM32F0)
struct GPIO {
volatile uint32_t MODER;
volatile uint16_t OTYPER;
uint16_t dummy0;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint16_t IDR;
uint16_t dummy1;
volatile uint16_t ODR;
uint16_t dummy2;
volatile uint16_t BSRR;
uint16_t dummy3;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint16_t BRR;
uint16_t dummy4;
};
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x0000)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (AHB2PERIPH_BASE + 0x0400)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (AHB2PERIPH_BASE + 0x0800)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (AHB2PERIPH_BASE + 0x0C00)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
#else
struct GPIO {
volatile uint32_t CRL;
volatile uint32_t CRH;
volatile uint32_t IDR;
volatile uint32_t ODR;
volatile uint32_t BSRR;
volatile uint32_t BRR;
volatile uint32_t LCKR;
};
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define GPIOE ((struct GPIO *) GPIOE_BASE)
#endif
#if defined(MCU_STM32F0)
struct SYSCFG {
volatile uint32_t CFGR1;
uint32_t dummy0;
volatile uint32_t EXTICR[4];
volatile uint32_t CFGR2;
};
#define SYSCFG_CFGR1_MEM_MODE 0x03
#define SYSCFG_BASE (APB1PERIPH_BASE + 0x00010000)
static struct SYSCFG *const SYSCFG = (struct SYSCFG *)SYSCFG_BASE;
#endif
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = (struct FLASH *)FLASH_R_BASE;

View File

@@ -574,6 +574,8 @@ static struct EXTI *const EXTI = (struct EXTI *)EXTI_BASE;
#define EXTI0_IRQ 6 #define EXTI0_IRQ 6
#define EXTI1_IRQ 7 #define EXTI1_IRQ 7
#define EXTI2_IRQ 8 #define EXTI2_IRQ 8
#define EXTI3_IRQ 9
#define EXTI4_IRQ 10
#define EXTI9_5_IRQ 23 #define EXTI9_5_IRQ 23
#define TIM2_IRQ 28 #define TIM2_IRQ 28
#define TIM3_IRQ 29 #define TIM3_IRQ 29
@@ -633,6 +635,7 @@ static struct AFIO *const AFIO = (struct AFIO *)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800 #define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000 #define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE 0x02000000
struct DBGMCU { struct DBGMCU {

View File

@@ -18,7 +18,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "board.h" #include "board.h"
#include "mcu/cortex-m.h"
#include "mcu/clk_gpio_init-stm32.c" #include "mcu/clk_gpio_init-stm32.c"

View File

@@ -2,6 +2,7 @@
#define BOARD_ID_FST_01_00 0x613870a9 #define BOARD_ID_FST_01_00 0x613870a9
#define BOARD_ID_FST_01 0x696886af #define BOARD_ID_FST_01 0x696886af
#define BOARD_ID_FST_01G 0x8801277f #define BOARD_ID_FST_01G 0x8801277f
#define BOARD_ID_FST_01SZ 0x7e6fb084
#define BOARD_ID_MAPLE_MINI 0x7a445272 #define BOARD_ID_MAPLE_MINI 0x7a445272
#define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594 #define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594
#define BOARD_ID_STBEE_MINI 0x1f341961 #define BOARD_ID_STBEE_MINI 0x1f341961

View File

@@ -950,11 +950,11 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
data_p->len = buflen; data_p->len = buflen;
/* Restrict the data length to be the one host asks for */ /* Restrict the data length to be the one host asks for */
if (data_p->len > len_asked) if (data_p->len >= len_asked)
data_p->len = len_asked; data_p->len = len_asked;
/* ZLP is only required when host doesn't expect the end of packets. */
data_p->require_zlp = (data_p->len != 0 else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
&& (data_p->len % USB_MAX_PACKET_SIZE) == 0); data_p->require_zlp = 1;
if (data_p->len < USB_MAX_PACKET_SIZE) if (data_p->len < USB_MAX_PACKET_SIZE)
{ {

View File

@@ -1105,10 +1105,10 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
data_p->len = buflen; data_p->len = buflen;
/* Restrict the data length to be the one host asks for */ /* Restrict the data length to be the one host asks for */
if (data_p->len > len_asked) if (data_p->len >= len_asked)
data_p->len = len_asked; data_p->len = len_asked;
/* ZLP is only required when host doesn't expect the end of packets. */
if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0) else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
data_p->require_zlp = 1; data_p->require_zlp = 1;
if (data_p->len < USB_MAX_PACKET_SIZE) if (data_p->len < USB_MAX_PACKET_SIZE)

View File

@@ -2169,10 +2169,10 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
data_p->len = buflen; data_p->len = buflen;
/* Restrict the data length to be the one host asks for */ /* Restrict the data length to be the one host asks for */
if (data_p->len > len_asked) if (data_p->len >= len_asked)
data_p->len = len_asked; data_p->len = len_asked;
/* ZLP is only required when host doesn't expect the end of packets. */
if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0) else if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
data_p->require_zlp = 1; data_p->require_zlp = 1;
if (data_p->len < USB_MAX_PACKET_SIZE) if (data_p->len < USB_MAX_PACKET_SIZE)

View File

@@ -28,6 +28,9 @@ endif
ifneq ($(USE_USART),) ifneq ($(USE_USART),)
CSRC += $(CHOPSTX)/contrib/usart-$(CHIP).c CSRC += $(CHOPSTX)/contrib/usart-$(CHIP).c
endif endif
ifneq ($(USE_ACKBTN),)
CSRC += $(CHOPSTX)/contrib/ackbtn-$(CHIP).c
endif
INCDIR += $(CHOPSTX) INCDIR += $(CHOPSTX)