35 Commits

Author SHA1 Message Date
NIIBE Yutaka
8dabbe6e1c Version 1.7. 2017-12-19 09:33:27 +09:00
NIIBE Yutaka
0a68140530 Prepare 1.7 release. 2017-12-18 14:45:41 +09:00
NIIBE Yutaka
ce3cd63144 USB-USART improvement: flush buffer, send_break, use callbacks. 2017-12-18 13:53:01 +09:00
NIIBE Yutaka
199db97025 USB-USART supports notification of serial error. 2017-12-18 11:11:25 +09:00
NIIBE Yutaka
1533284ace USB-USART config setup support. 2017-12-17 11:52:17 +09:00
NIIBE Yutaka
0e9737eb61 Fix priority setting of USART (serial needs tight timing). 2017-12-16 17:17:58 +09:00
NIIBE Yutaka
265fb971c0 Fix USART for overrun error. 2017-12-16 17:01:58 +09:00
NIIBE Yutaka
26d5bb0115 Remove debug output for USART example. 2017-12-16 16:20:12 +09:00
NIIBE Yutaka
bf1ac08e6c Fix usb-cdc.c in USART example. 2017-12-16 16:14:43 +09:00
NIIBE Yutaka
530ddcfeda Fix timer expiration. 2017-12-16 15:00:55 +09:00
NIIBE Yutaka
19b0590c1f USART fix handle_tx_ready, tweak priority of the sample. 2017-12-16 14:33:40 +09:00
NIIBE Yutaka
72210e4250 Fix USART README and Alternate input config. 2017-12-15 22:18:22 +09:00
NIIBE Yutaka
61892c85b0 Fix USART rb_read. 2017-12-15 21:48:54 +09:00
NIIBE Yutaka
75e6b06dd5 Fix USART driver. 2017-12-15 18:11:25 +09:00
NIIBE Yutaka
dd190c8207 Add link for example-usb-serial. 2017-12-15 17:07:50 +09:00
NIIBE Yutaka
22039ee717 Modify USB<->USART example. 2017-12-15 16:00:59 +09:00
NIIBE Yutaka
cb628fe317 Fix rough edges of USART driver. 2017-12-15 15:18:17 +09:00
NIIBE Yutaka
f3cc662548 Remove bb.c. 2017-12-15 15:08:39 +09:00
NIIBE Yutaka
b58dd05c9d USART access functions implemented. 2017-12-15 15:07:13 +09:00
NIIBE Yutaka
7b1c442d88 USART: Main implemented. 2017-12-15 13:51:55 +09:00
NIIBE Yutaka
b4b9aace03 Add ring buffer for USART. 2017-12-15 09:46:28 +09:00
NIIBE Yutaka
741aba1997 Add ChangeLog. 2017-12-14 20:41:54 +09:00
NIIBE Yutaka
022666402c Start writing USART driver of STM32. 2017-12-14 20:34:24 +09:00
NIIBE Yutaka
69677aecd4 Change ADC setting of ST Nucleo STM32F103. 2017-12-14 20:31:28 +09:00
NIIBE Yutaka
bc35bc81cf APB -> APB1. 2017-12-14 19:04:16 +09:00
NIIBE Yutaka
499e575528 Fix bb. 2017-12-14 19:04:01 +09:00
NIIBE Yutaka
9f9aeae4bf Add bb.c, bb.h. 2017-12-14 15:47:18 +09:00
NIIBE Yutaka
ecd90b1b99 Testing loopback from ttyACM0 <-> ttyACM1. 2017-12-14 15:46:38 +09:00
NIIBE Yutaka
39e53ae747 Rename serial->cdc for no confusion between USART. 2017-12-14 12:24:59 +09:00
NIIBE Yutaka
9b9d40c16b No line editing. 2017-12-14 12:10:27 +09:00
NIIBE Yutaka
1eff465303 Modification to support multiple serial lines. 2017-12-14 11:25:14 +09:00
NIIBE Yutaka
de895e6b65 Add another interface. 2017-12-14 10:55:55 +09:00
NIIBE Yutaka
d4cca9f0dc It's not TTY but USB to serial driver. 2017-12-14 10:19:01 +09:00
NIIBE Yutaka
de9eb6f1e7 Try to support multiple serial lines. 2017-12-14 10:16:53 +09:00
NIIBE Yutaka
2c14f21b20 Copied from example-cde (except README). 2017-12-14 09:34:16 +09:00
30 changed files with 2339 additions and 32 deletions

View File

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

View File

@@ -1,3 +1,27 @@
2017-12-19 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.7.
* doc/chopstx.texi (VERSION): 1.7.
2017-12-18 NIIBE Yutaka <gniibe@fsij.org>
* contrib/usart-stm32f103.c: New.
* example-usb-serial: New example.
2017-12-16 NIIBE Yutaka <gniibe@fsij.org>
* chopstx.c (chx_timer_expired): Bug fix of wake up.
(chx_mutex_unlock): Avoid non-deterministic thing.
2017-12-14 NIIBE Yutaka <gniibe@fsij.org>
* board/board-st-nucleo-f103.h: Update.
* mcu/sys-stm32f103.h (BOARD_ID_FST_01G): New.
* contrib/adc-stm32f103.c (get_adc_config): Add a case for
BOARD_ID_FST_01G and BOARD_ID_ST_NUCLEO_F103.
2017-11-24 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.6.

13
NEWS
View File

@@ -1,6 +1,19 @@
NEWS - Noteworthy changes
* Major changes in Chopstx 1.7
Released 2017-12-19
** Fix: timer wakeup
Timer expiration had a bug. When it is waken up, the wake up doesn't
handle as a timer expiration when there are multiple threads on same
timing of expire. It confuses as if it were forced wakeup.
** New driver: USART for STM32.
USART driver for STM32 is added.
* Major changes in Chopstx 1.6
Released 2017-11-24

9
README
View File

@@ -1,6 +1,6 @@
Chopstx - Threads and only Threads
Version 1.6
2017-11-24
Version 1.7
2017-12-19
Niibe Yutaka
Flying Stone Technology
@@ -17,6 +17,11 @@ stacks, Chopstx just offers a simple RT thread library.
With Chopstx, interrupt handling is also done by a thread. This
enables coherent code for ease of maintenance.
While threads are important, we don't need more threads than
necessary. Chopstx provides a feature of poll, so that we can
minimize use of threads.
Note that this library is _not_ related to the hand game:
https://en.wikipedia.org/wiki/Chopsticks_(hand_game)

View File

@@ -1 +1 @@
release/1.6
release/1.7

View File

@@ -31,11 +31,3 @@
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPCEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPCRST
/* NeuG settings for ADC2. */
#define NEUG_ADC_SETTING2_SMPR1 ADC_SMPR1_SMP_AN10(ADC_SAMPLE_1P5) \
| ADC_SMPR1_SMP_AN11(ADC_SAMPLE_1P5)
#define NEUG_ADC_SETTING2_SMPR2 0
#define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN10) \
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN11)
#define NEUG_ADC_SETTING2_NUM_CHANNELS 2

View File

@@ -26,21 +26,40 @@
#define GPIO_LED_BASE GPIOA_BASE
#define GPIO_LED_SET_TO_EMIT 5
#undef GPIO_USB_BASE /* No external DISCONNECT/RENUM circuit. */
#undef GPIO_OTHER_BASE
#define GPIO_OTHER_BASE GPIOB_BASE
/*
* Port A setup.
* PA0 - input with pull-up. AN0
* PA1 - input with pull-up. AN1
* PA5 - Push pull output 50MHz (LED 1:ON 0:OFF)
* PA0 - Input with pull-up USART2-CTS
* PA1 - Alternate function push pull output 2MHz USART2-RTS
* PA2 - Alternate function push pull output 2MHz USART2-TX
* PA3 - Input with pull-up USART2-RX
* PA4 - Alternate function push pull output 2MHz USART2-CK
* PA5 - Push pull output 2MHz (LED 1:ON 0:OFF)
* PA11 - Push Pull output 10MHz 0 default (until USB enabled) (USBDM)
* PA12 - Push Pull output 10MHz 0 default (until USB enabled) (USBDP)
* ------------------------ Default
* PAx - input with pull-up
*/
#define VAL_GPIO_LED_ODR 0xFFFFE7FF
#define VAL_GPIO_LED_CRL 0x88388888 /* PA7...PA0 */
#define VAL_GPIO_LED_CRL 0x882A8AA8 /* PA7...PA0 */
#define VAL_GPIO_LED_CRH 0x88811888 /* PA15...PA8 */
#define RCC_ENR_IOP_EN RCC_APB2ENR_IOPAEN
#define RCC_RSTR_IOP_RST RCC_APB2RSTR_IOPARST
/*
* Port B setup.
* PB0 - input with pull-up: AN8 for NeuG
* PB1 - input with pull-up: AN9 for NeuG
* PB10 - Alternate function push pull output 2MHz USART3-TX
* PB11 - Input with pull-up USART3-RX
* PB12 - Alternate function push pull output 2MHz USART3-CK
* PB13 - Input with pull-up USART3-CTS
* PB14 - Alternate function push pull output 2MHz USART3-RTS
* ------------------------ Default
* PBx - input with pull-up.
*/
#define VAL_GPIO_OTHER_ODR 0xFFFFFFFF
#define VAL_GPIO_OTHER_CRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIO_OTHER_CRH 0x8A8A8A88 /* PB15...PB8 */
#define RCC_ENR_IOP_EN (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN)
#define RCC_RSTR_IOP_RST (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST)

View File

@@ -287,7 +287,7 @@ chx_request_preemption (uint16_t prio)
*
* Returns:
* 1 on wakeup by others.
* 0 on normal wakeup.
* 0 on normal wakeup (timer expiration, lock aquirement).
* -1 on cancellation.
*/
static uintptr_t __attribute__ ((naked, noinline))

View File

@@ -403,6 +403,7 @@ chx_timer_expired (void)
tp = tp_next)
{
next_tick = tp->v;
tp->v = (uintptr_t)0;
tp_next = (struct chx_thread *)tp->next;
ll_dequeue ((struct chx_pq *)tp);
chx_ready_enqueue (tp);
@@ -575,6 +576,7 @@ chx_mutex_unlock (chopstx_mutex_t *mutex)
uint16_t newprio = running->prio_orig;
chopstx_mutex_t *m;
tp->v = (uintptr_t)0;
chx_ready_enqueue (tp);
/* Examine mutexes we hold, and determine new priority for running. */

View File

@@ -145,6 +145,7 @@ get_adc_config (uint32_t config[4])
config[2] = ADC_SQR1_NUM_CH(2);
switch (SYS_BOARD_ID)
{
case BOARD_ID_FST_01G:
case BOARD_ID_FST_01:
config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
@@ -170,13 +171,20 @@ get_adc_config (uint32_t config[4])
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN2);
break;
case BOARD_ID_ST_NUCLEO_F103:
config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN8(ADC_SAMPLE_1P5)
| ADC_SMPR2_SMP_AN9(ADC_SAMPLE_1P5);
config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN8)
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN9);
break;
case BOARD_ID_CQ_STARM:
case BOARD_ID_FST_01_00:
case BOARD_ID_MAPLE_MINI:
case BOARD_ID_STM32_PRIMER2:
case BOARD_ID_STM8S_DISCOVERY:
case BOARD_ID_ST_DONGLE:
case BOARD_ID_ST_NUCLEO_F103:
case BOARD_ID_NITROKEY_START:
default:
config[0] = 0;

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

@@ -0,0 +1,624 @@
/*
* usart-stm32.c - USART driver for STM32F103 (USART2 and USART3)
*
* Copyright (C) 2017 g10 Code GmbH
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Chopstx, a thread library for embedded.
*
* Chopstx is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chopstx is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* As additional permission under GNU GPL version 3 section 7, you may
* distribute non-source form of the Program without the copy of the
* GNU GPL normally required by section 4, provided you inform the
* receipents of GNU GPL by a written offer.
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <chopstx.h>
#include <mcu/stm32.h>
#include <contrib/usart.h>
struct USART {
volatile uint32_t SR;
volatile uint32_t DR;
volatile uint32_t BRR;
volatile uint32_t CR1;
volatile uint32_t CR2;
volatile uint32_t CR3;
volatile uint32_t GTPR;
};
#define USART2_BASE (APB1PERIPH_BASE + 0x4400)
#define USART3_BASE (APB1PERIPH_BASE + 0x4800)
static struct USART *const USART2 = (struct USART *)USART2_BASE;
static struct USART *const USART3 = (struct USART *)USART3_BASE;
#define USART_SR_CTS (1 << 9)
#define USART_SR_LBD (1 << 8)
#define USART_SR_TXE (1 << 7)
#define USART_SR_TC (1 << 6)
#define USART_SR_RXNE (1 << 5)
#define USART_SR_IDLE (1 << 4)
#define USART_SR_ORE (1 << 3)
#define USART_SR_NE (1 << 2)
#define USART_SR_FE (1 << 1)
#define USART_SR_PE (1 << 0)
#define USART_CR1_UE (1 << 13)
#define USART_CR1_M (1 << 12)
#define USART_CR1_WAKE (1 << 11)
#define USART_CR1_PCE (1 << 10)
#define USART_CR1_PS (1 << 9)
#define USART_CR1_PEIE (1 << 8)
#define USART_CR1_TXEIE (1 << 7)
#define USART_CR1_TCIE (1 << 6)
#define USART_CR1_RXNEIE (1 << 5)
#define USART_CR1_IDLEIE (1 << 4)
#define USART_CR1_TE (1 << 3)
#define USART_CR1_RE (1 << 2)
#define USART_CR1_RWU (1 << 1)
#define USART_CR1_SBK (1 << 0)
static struct USART *
get_usart_dev (uint8_t dev_no)
{
if (dev_no == 2)
return USART2;
else if (dev_no == 3)
return USART3;
return NULL;
}
/* We assume 36MHz f_PCLK */
struct brr_setting {
uint8_t baud_spec;
uint16_t brr_value;
};
#define NUM_BAUD (int)(sizeof (brr_table) / sizeof (struct brr_setting))
static const struct brr_setting brr_table[] = {
{ B600, (3750 << 4)},
{ B1200, (1875 << 4)},
{ B2400, ( 937 << 4)|8},
{ B9600, ( 234 << 4)|6},
{ B19200, ( 117 << 4)|3},
{ B57600, ( 39 << 4)|1},
{ B115200, ( 19 << 4)|8},
{ B230400, ( 9 << 4)|12},
{ B460800, ( 4 << 4)|14},
{ B921600, ( 2 << 4)|7},
};
static void *usart_main (void *arg);
static struct usart_stat usart2_stat;
static struct usart_stat usart3_stat;
int
usart_config (uint8_t dev_no, uint32_t config_bits)
{
struct USART *USARTx = get_usart_dev (dev_no);
uint8_t baud_spec = (config_bits & MASK_BAUD);
int i;
uint32_t cr1_config = (USART_CR1_UE | USART_CR1_RXNEIE
| USART_CR1_TE | USART_CR1_RE);
/* TXEIE will be enabled when putting char */
/* No CTSIE, PEIE, TCIE, IDLEIE, LBDIE */
if (USARTx == NULL)
return -1;
/* Disable USART before configure. */
USARTx->CR1 &= ~USART_CR1_UE;
if (((config_bits & MASK_CS) == CS7 && (config_bits & PARENB))
|| ((config_bits & MASK_CS) == CS8 && (config_bits & PARENB) == 0))
cr1_config &= ~USART_CR1_M;
else if ((config_bits & MASK_CS) == CS8)
cr1_config |= USART_CR1_M;
else
return -1;
if ((config_bits & PARENB) == 0)
cr1_config &= ~USART_CR1_PCE;
else
cr1_config |= USART_CR1_PCE;
if ((config_bits & PARODD) == 0)
cr1_config &= ~USART_CR1_PS;
else
cr1_config |= USART_CR1_PS;
if ((config_bits & MASK_STOP) == STOP0B5)
USARTx->CR2 = (0x1 << 12);
else if ((config_bits & MASK_STOP) == STOP1B)
USARTx->CR2 = (0x0 << 12);
else if ((config_bits & MASK_STOP) == STOP1B5)
USARTx->CR2 = (0x3 << 12);
else /* if ((config_bits & MASK_STOP) == STOP2B) */
USARTx->CR2 = (0x2 << 12);
for (i = 0; i < NUM_BAUD; i++)
if (brr_table[i].baud_spec == baud_spec)
break;
if (i >= NUM_BAUD)
return -1;
USARTx->BRR = brr_table[i].brr_value;
if ((config_bits & MASK_FLOW))
USARTx->CR3 = (1 << 9) | (1 << 8);
else
USARTx->CR3 = 0;
USARTx->CR1 = cr1_config;
return 0;
}
static int (*ss_notify_callback) (uint8_t dev_no, uint16_t notify_bits);
void
usart_init (uint16_t prio, uintptr_t stack_addr, size_t stack_size,
int (*cb) (uint8_t dev_no, uint16_t notify_bits))
{
ss_notify_callback = cb;
usart2_stat.dev_no = 2;
usart3_stat.dev_no = 3;
/* Enable USART2 and USART3 clocks, and strobe reset. */
RCC->APB1ENR |= ((1 << 18) | (1 << 17));
RCC->APB1RSTR = ((1 << 18) | (1 << 17));
RCC->APB1RSTR = 0;
usart_config (2, B115200 | CS8 | STOP1B);
usart_config (3, B115200 | CS8 | STOP1B);
chopstx_create (prio, stack_addr, stack_size, usart_main, NULL);
}
/*
* Ring buffer
*/
#define MAX_RB_BUF 1024
struct rb {
uint8_t *buf;
chopstx_mutex_t m;
chopstx_cond_t data_available;
chopstx_cond_t space_available;
uint32_t head :10;
uint32_t tail :10;
uint32_t size :10;
uint32_t full : 1;
uint32_t empty : 1;
};
/*
* Note: size = 1024 can still work, regardless of the limit of 10-bit.
*/
static void
rb_init (struct rb *rb, uint8_t *p, uint16_t size)
{
rb->buf = p;
rb->size = size;
chopstx_mutex_init (&rb->m);
chopstx_cond_init (&rb->data_available);
chopstx_cond_init (&rb->space_available);
rb->head = rb->tail = 0;
rb->full = 0;
rb->empty = 1;
}
static void
rb_add (struct rb *rb, uint8_t v)
{
rb->buf[rb->tail++] = v;
if (rb->tail == rb->size)
rb->tail = 0;
if (rb->tail == rb->head)
rb->full = 1;
rb->empty = 0;
}
static uint8_t
rb_del (struct rb *rb)
{
uint32_t v = rb->buf[rb->head++];
if (rb->head == rb->size)
rb->head = 0;
if (rb->head == rb->tail)
rb->empty = 1;
rb->full = 0;
return v;
}
/*
* Application: consumer
* Hardware: generator
*/
static int
rb_ll_put (struct rb *rb, uint8_t v)
{
int r;
chopstx_mutex_lock (&rb->m);
if (rb->full)
r = -1;
else
{
r = 0;
rb_add (rb, v);
chopstx_cond_signal (&rb->data_available);
}
chopstx_mutex_unlock (&rb->m);
return r;
}
/*
* Application: generator
* Hardware: consumer
*/
static int
rb_ll_get (struct rb *rb)
{
int r;
chopstx_mutex_lock (&rb->m);
if (rb->empty)
r = -1;
else
{
r = rb_del (rb);
chopstx_cond_signal (&rb->space_available);
}
chopstx_mutex_unlock (&rb->m);
return r;
}
static void
rb_ll_flush (struct rb *rb)
{
chopstx_mutex_lock (&rb->m);
while (!rb->empty)
rb_del (rb);
chopstx_cond_signal (&rb->space_available);
chopstx_mutex_unlock (&rb->m);
}
/*
* Application: consumer
* Hardware: generator
*/
static int
rb_read (struct rb *rb, uint8_t *buf, uint16_t buflen)
{
int i = 0;
chopstx_mutex_lock (&rb->m);
while (rb->empty)
chopstx_cond_wait (&rb->data_available, &rb->m);
while (i < buflen)
{
buf[i++] = rb_del (rb);
if (rb->empty)
break;
}
chopstx_cond_signal (&rb->space_available);
chopstx_mutex_unlock (&rb->m);
return i;
}
/*
* Application: generator
* Hardware: consumer
*/
static void
rb_write (struct rb *rb, uint8_t *buf, uint16_t buflen)
{
int i = 0;
chopstx_mutex_lock (&rb->m);
do
{
while (rb->full)
chopstx_cond_wait (&rb->space_available, &rb->m);
while (i < buflen)
{
rb_add (rb, buf[i++]);
if (rb->full)
{
chopstx_cond_signal (&rb->data_available);
break;
}
}
}
while (i < buflen);
if (i)
chopstx_cond_signal (&rb->data_available);
chopstx_mutex_unlock (&rb->m);
}
static int
rb_empty_check (void *arg)
{
struct rb *rb = arg;
return rb->empty == 0;
}
static void
rb_get_prepare_poll (struct rb *rb, chopstx_poll_cond_t *poll_desc)
{
poll_desc->type = CHOPSTX_POLL_COND;
poll_desc->ready = 0;
poll_desc->cond = &rb->data_available;
poll_desc->mutex = &rb->m;
poll_desc->check = rb_empty_check;
poll_desc->arg = rb;
}
#define INTR_REQ_USART2 38
#define INTR_REQ_USART3 39
static uint8_t buf_usart2_rb_a2h[256];
static uint8_t buf_usart2_rb_h2a[512];
static uint8_t buf_usart3_rb_a2h[256];
static uint8_t buf_usart3_rb_h2a[512];
static struct chx_intr usart2_intr;
static struct chx_intr usart3_intr;
static struct rb usart2_rb_a2h;
static struct rb usart2_rb_h2a;
static struct rb usart3_rb_a2h;
static struct rb usart3_rb_h2a;
static chopstx_poll_cond_t usart2_app_write_event;
static chopstx_poll_cond_t usart3_app_write_event;
static struct chx_poll_head *usart_poll[4];
/* Global variables so that it can be easier to debug. */
static int usart2_tx_ready;
static int usart3_tx_ready;
#define UART_STATE_BITMAP_RX_CARRIER (1 << 0)
#define UART_STATE_BITMAP_TX_CARRIER (1 << 1)
#define UART_STATE_BITMAP_BREAK (1 << 2)
#define UART_STATE_BITMAP_RINGSIGNAL (1 << 3)
#define UART_STATE_BITMAP_FRAMING (1 << 4)
#define UART_STATE_BITMAP_PARITY (1 << 5)
#define UART_STATE_BITMAP_OVERRUN (1 << 6)
static int
handle_intr (struct USART *USARTx, struct rb *rb2a, struct usart_stat *stat)
{
int tx_ready = 0;
uint32_t r = USARTx->SR;
int notify_bits = 0;
if ((r & USART_SR_TXE))
{
tx_ready = 1;
USARTx->CR1 &= ~USART_CR1_TXEIE;
}
if ((r & USART_SR_RXNE))
{
uint32_t data = USARTx->DR;
/* DR register should be accessed even if data is not used.
* Its read-access has side effect of clearing error flags.
*/
asm volatile ("" : : "r" (data) : "memory");
if ((r & USART_SR_NE))
stat->err_rx_noise++;
else if ((r & USART_SR_FE))
{
/* NOTE: Noway to distinguish framing error and break */
stat->rx_break++;
notify_bits |= UART_STATE_BITMAP_BREAK;
}
else if ((r & USART_SR_PE))
{
stat->err_rx_parity++;
notify_bits |= UART_STATE_BITMAP_PARITY;
}
else
{
if ((r & USART_SR_ORE))
{
stat->err_rx_overrun++;
notify_bits |= UART_STATE_BITMAP_OVERRUN;
}
/* XXX: if CS is 7-bit, mask it, or else parity bit in upper layer */
if (rb_ll_put (rb2a, (data & 0xff)) < 0)
stat->err_rx_overflow++;
else
stat->rx++;
}
}
else if ((r & USART_SR_ORE))
{ /* Clear ORE */
uint32_t data = USARTx->DR;
asm volatile ("" : : "r" (data) : "memory");
stat->err_rx_overrun++;
notify_bits |= UART_STATE_BITMAP_OVERRUN;
}
if (notify_bits)
{
if ((*ss_notify_callback) (stat->dev_no, notify_bits))
stat->err_notify_overflow++;
}
return tx_ready;
}
static int
handle_tx_ready (struct USART *USARTx, struct rb *rb2h,
struct usart_stat *stat)
{
int tx_ready = 1;
int c = rb_ll_get (rb2h);
if (c >= 0)
{
uint32_t r;
USARTx->DR = (c & 0xff);
stat->tx++;
r = USARTx->SR;
if ((r & USART_SR_TXE) == 0)
{
tx_ready = 0;
USARTx->CR1 |= USART_CR1_TXEIE;
}
}
return tx_ready;
}
static void *
usart_main (void *arg)
{
(void)arg;
usart2_tx_ready = 1;
usart3_tx_ready = 1;
chopstx_claim_irq (&usart2_intr, INTR_REQ_USART2);
chopstx_claim_irq (&usart3_intr, INTR_REQ_USART3);
rb_init (&usart2_rb_a2h, buf_usart2_rb_a2h, sizeof buf_usart2_rb_a2h);
rb_init (&usart2_rb_h2a, buf_usart2_rb_h2a, sizeof buf_usart2_rb_h2a);
rb_init (&usart3_rb_a2h, buf_usart3_rb_a2h, sizeof buf_usart3_rb_a2h);
rb_init (&usart3_rb_h2a, buf_usart3_rb_h2a, sizeof buf_usart3_rb_h2a);
rb_get_prepare_poll (&usart2_rb_a2h, &usart2_app_write_event);
rb_get_prepare_poll (&usart3_rb_a2h, &usart3_app_write_event);
while (1)
{
int n = 0;
usart_poll[n++] = (struct chx_poll_head *)&usart2_intr;
usart_poll[n++] = (struct chx_poll_head *)&usart3_intr;
if (usart2_tx_ready)
usart_poll[n++] = (struct chx_poll_head *)&usart2_app_write_event;
else
usart2_app_write_event.ready = 0;
if (usart3_tx_ready)
usart_poll[n++] = (struct chx_poll_head *)&usart3_app_write_event;
else
usart3_app_write_event.ready = 0;
chopstx_poll (NULL, n, usart_poll);
if (usart2_intr.ready)
usart2_tx_ready = handle_intr (USART2, &usart2_rb_h2a, &usart2_stat);
if (usart3_intr.ready)
usart3_tx_ready = handle_intr (USART3, &usart3_rb_h2a, &usart3_stat);
if (usart2_tx_ready && usart2_app_write_event.ready)
usart2_tx_ready = handle_tx_ready (USART2,
&usart2_rb_a2h, &usart2_stat);
if (usart3_tx_ready && usart3_app_write_event.ready)
usart3_tx_ready = handle_tx_ready (USART3,
&usart3_rb_a2h, &usart3_stat);
}
return NULL;
}
int
usart_read (uint8_t dev_no, char *buf, uint16_t buflen)
{
struct rb *rb;
if (dev_no == 2)
rb = &usart2_rb_h2a;
else if (dev_no == 3)
rb = &usart3_rb_h2a;
else
return -1;
if (buf == NULL && buflen == 0)
{
rb_ll_flush (rb);
return 0;
}
else
return rb_read (rb, (uint8_t *)buf, buflen);
}
int
usart_write (uint8_t dev_no, char *buf, uint16_t buflen)
{
struct rb *rb;
if (dev_no == 2)
rb = &usart2_rb_a2h;
else if (dev_no == 3)
rb = &usart3_rb_a2h;
else
return -1;
if (buf == NULL && buflen == 0)
rb_ll_flush (rb);
else
rb_write (rb, (uint8_t *)buf, buflen);
return 0;
}
const struct usart_stat *
usart_stat (uint8_t dev_no)
{
if (dev_no == 2)
return &usart2_stat;
else if (dev_no == 3)
return &usart3_stat;
else
return NULL;
}
int
usart_send_break (uint8_t dev_no)
{
struct USART *USARTx = get_usart_dev (dev_no);
if (USARTx == NULL)
return -1;
if ((USARTx->CR1 & 0x01))
return 1; /* Busy sending break, which was requested before. */
USARTx->CR1 |= 0x01;
return 0;
}

66
contrib/usart.h Normal file
View File

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

View File

@@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename chopstx.info
@set VERSION 1.6
@set VERSION 1.7
@settitle Chopstx Reference Manual
@c Unify some of the indices.
@syncodeindex tp fn
@@ -60,7 +60,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.
* Poll or Pole:: Poll or Pole.
* Note (Use of sleep mode):: Use it carefully.
* API:: API.
Appendix
@@ -90,11 +91,16 @@ Cortex-M3 and GNU/Linux emulation. Specifically, it is used for
STM32F030, MKL27Z, STM32F103 and as a command on GNU/Linux.
While most RTOSes come with many features, drivers, and stacks,
Chopstx just offers a RT thread library.
Chopstx just offers an RT thread library.
With Chopstx, interrupt handling is also done by a thread. This
enables coherent code for ease of maintenance.
While threads are important, we don't need more threads than
necessary. Chopstx provides a feature of poll, so that we can
minimize use of threads.
@node Threads and only Threads
@chapter Threads and only Threads
@@ -129,8 +135,17 @@ 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
@node Poll or Pole
@chapter Poll or Pole
Chopstx provides the @code{chopstx_poll} function to wait on multiple events.
Using @code{chopstx_poll}, we can write an application by event-driven
programming style, with minimum number of threads, avoiding
complicated dependency between threads.
@node Note (Use of sleep mode)
@chapter Note (Use of sleep mode)
Calling the chopstx_conf_idle function (> 0) to allow the idle thread
going to sleep. MCU will be in sleep mode when no threads are

View File

@@ -7,7 +7,7 @@
static uint8_t main_finished;
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)

View File

@@ -7,7 +7,7 @@
static uint8_t main_finished;
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)

View File

@@ -6,7 +6,7 @@
#include "board.h"
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)

View File

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

View File

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

View File

@@ -0,0 +1,37 @@
# Makefile for example application of Chopstx
PROJECT = sample
CHOPSTX = ..
LDSCRIPT= sample.ld
CSRC = sample.c usb-cdc.c
CHIP=stm32f103
USE_SYS = yes
USE_USB = yes
USE_USART = yes
###################################
CROSS = arm-none-eabi-
CC = $(CROSS)gcc
LD = $(CROSS)gcc
OBJCOPY = $(CROSS)objcopy
MCU = cortex-m3
CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DUSE_SYS3 -DFREE_STANDING
OPT = -O3 -Os -g
LIBS =
####################
include ../rules.mk
board.h:
@echo Please make a symbolic link \'board.h\' to a file in ../board;
@exit 1
sys.c: board.h
distclean: clean
rm -f board.h

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

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

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

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

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

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

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

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

View File

@@ -0,0 +1,127 @@
/*
* ST32F103 memory setup.
*/
MEMORY
{
flash0 : org = 0x08000000, len = 4k
flash : org = 0x08000000+0x1000, len = 60k
ram : org = 0x20000000, len = 20k
}
__ram_start__ = ORIGIN(ram);
__ram_size__ = 20k;
__ram_end__ = __ram_start__ + __ram_size__;
SECTIONS
{
. = 0;
.sys : ALIGN(4) SUBALIGN(4)
{
_sys = .;
KEEP(*(.vectors))
. = ALIGN(16);
KEEP(*(.sys.version))
KEEP(*(.sys.board_id))
KEEP(*(.sys.board_name))
build/sys-*.o(.text)
build/sys-*.o(.text.*)
build/sys-*.o(.rodata)
build/sys-*.o(.rodata.*)
. = ALIGN(1024);
*(.sys.0)
*(.sys.1)
*(.sys.2)
} > flash0
_text = .;
.startup : ALIGN(128) SUBALIGN(128)
{
KEEP(*(.startup.vectors))
. = ALIGN (16);
} > flash =0xffffffff
.text : ALIGN(16) SUBALIGN(16)
{
*(.text.startup.*)
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
*(.glue_7t)
*(.glue_7)
*(.gcc*)
. = ALIGN(8);
} > flash
.ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash
.ARM.exidx : {
PROVIDE(__exidx_start = .);
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
PROVIDE(__exidx_end = .);
} > flash
.eh_frame_hdr : {*(.eh_frame_hdr)} > flash
.eh_frame : ONLY_IF_RO {*(.eh_frame)} > flash
.textalign : ONLY_IF_RO { . = ALIGN(8); } > flash
_etext = .;
_textdata = _etext;
.process_stack (NOLOAD) :
{
. = ALIGN(8);
*(.process_stack.6)
*(.process_stack.5)
*(.process_stack.4)
*(.process_stack.3)
*(.process_stack.2)
*(.process_stack.1)
*(.process_stack.0)
. = ALIGN(8);
} > ram
.main_stack (NOLOAD) :
{
. = ALIGN(8);
*(.main_stack)
. = ALIGN(8);
} > ram
.data :
{
. = ALIGN(4);
PROVIDE(_data = .);
*(.data)
. = ALIGN(4);
*(.data.*)
. = ALIGN(4);
*(.ramtext)
. = ALIGN(4);
PROVIDE(_edata = .);
} > ram AT > flash
.bss :
{
. = ALIGN(4);
PROVIDE(_bss_start = .);
*(.bss)
. = ALIGN(4);
*(.bss.*)
. = ALIGN(4);
*(COMMON)
. = ALIGN(4);
PROVIDE(_bss_end = .);
} > ram
PROVIDE(end = .);
_end = .;
}
__heap_base__ = _end;
__heap_end__ = __ram_end__;

View File

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

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

File diff suppressed because it is too large Load Diff

View File

@@ -62,7 +62,7 @@ struct SYSCFG {
};
#define SYSCFG_CFGR1_MEM_MODE 0x03
#define SYSCFG_BASE (APBPERIPH_BASE + 0x00010000)
#define SYSCFG_BASE (APB1PERIPH_BASE + 0x00010000)
static struct SYSCFG *const SYSCFG = (struct SYSCFG *)SYSCFG_BASE;
#endif

View File

@@ -1,5 +1,5 @@
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)

View File

@@ -1,6 +1,7 @@
#define BOARD_ID_CQ_STARM 0xc5480875
#define BOARD_ID_FST_01_00 0x613870a9
#define BOARD_ID_FST_01 0x696886af
#define BOARD_ID_FST_01G 0x8801277f
#define BOARD_ID_MAPLE_MINI 0x7a445272
#define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594
#define BOARD_ID_STBEE_MINI 0x1f341961

View File

@@ -25,6 +25,9 @@ endif
ifneq ($(USE_ADC),)
CSRC += $(CHOPSTX)/contrib/adc-$(CHIP).c
endif
ifneq ($(USE_USART),)
CSRC += $(CHOPSTX)/contrib/usart-$(CHIP).c
endif
INCDIR += $(CHOPSTX)