Use chopstx
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 24 May 2013 06:51:10 +0000 (15:51 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 24 May 2013 06:55:40 +0000 (15:55 +0900)
14 files changed:
.gitmodules
chopstx [new submodule]
src/Makefile.in
src/adc.h
src/adc_stm32f103.c
src/aes-constant-ft.c
src/configure
src/main.c
src/neug.ld.in
src/random.c
src/stm32f103.h [new file with mode: 0644]
src/sys.c
src/sys.h
src/usb_stm32f103.c

index ad61fd3..2917670 100644 (file)
@@ -1,3 +1,6 @@
 [submodule "chibios"]
        path = chibios
        url = git@gitorious.org:gnuk/chibios.git
+[submodule "chopstx"]
+       path = chopstx
+       url = git@gitorious.org:chopstx/chopstx.git
diff --git a/chopstx b/chopstx
new file mode 160000 (submodule)
index 0000000..cf4a340
--- /dev/null
+++ b/chopstx
@@ -0,0 +1 @@
+Subproject commit cf4a340023cda2819d11d2911bbf983bb6be9240
index 6425ec3..52405a4 100644 (file)
 # Makefile for NeuG
 
-BOARD_DIR=@BOARD_DIR@
-
-##############################################################################
-# Build global options
-# NOTE: Can be overridden externally.
-#
-
-# Compiler options here.
-ifeq ($(USE_OPT),)
-  USE_OPT = -O3 -Os -ggdb -fomit-frame-pointer -falign-functions=16
-endif
-
-# C++ specific options here (added to USE_OPT).
-ifeq ($(USE_CPPOPT),)
-  USE_CPPOPT = -fno-rtti
-endif
-
-# Enable this if you want the linker to remove unused code and data
-ifeq ($(USE_LINK_GC),)
-  USE_LINK_GC = yes
-endif
-
-# If enabled, this option allows to compile the application in THUMB mode.
-ifeq ($(USE_THUMB),)
-  USE_THUMB = yes
-endif
-
-# Enable this if you want to see the full log while compiling.
-ifeq ($(USE_VERBOSE_COMPILE),)
-  USE_VERBOSE_COMPILE = no
-endif
-
-#
-# Build global options
-##############################################################################
-
-##############################################################################
-# Architecture or project specific options
-#
-
-# Enable this if you really want to use the STM FWLib.
-ifeq ($(USE_FWLIB),)
-  USE_FWLIB = no
-endif
-
-#
-# Architecture or project specific options
-##############################################################################
-
-##############################################################################
-# Project, sources and paths
-#
-
 # Define project name here
 PROJECT = neug
 
-# Imported source files
-CHIBIOS = ../chibios
-include $(CHIBIOS)/os/hal/platforms/STM32F1xx/platform.mk
-include $(CHIBIOS)/os/hal/hal.mk
-include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F1xx/port.mk
-include $(CHIBIOS)/os/kernel/kernel.mk
+CHOPSTX = ../chopstx
 
 # Define linker script file here
 LDSCRIPT= neug.ld
 
-# C sources that can be compiled in ARM or THUMB mode depending on the global
-# setting.
-CSRC = $(PORTSRC) \
-       $(KERNSRC) \
-       $(HALSRC) \
-       $(PLATFORMSRC) \
-       $(BOARDSRC) \
-       ../boards/common/board-common.c \
-       $(BOARD_DIR)/board.c \
-       sys.c aes-constant-ft.c main.c sha256.c usb_stm32f103.c \
-       random.c adc_stm32f103.c
-
-# List ASM source files here
-ASMSRC = $(PORTASM)
-
-INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
-         $(HALINC) $(PLATFORMINC) ../boards/common $(BOARD_DIR) \
-         $(CHIBIOS)/os/various
-
-#
-# Project, sources and paths
-##############################################################################
-
-##############################################################################
-# Compiler settings
-#
-
-MCU  = cortex-m3
+CSRC = sys.c aes-constant-ft.c \
+       main.c sha256.c random.c usb_stm32f103.c adc_stm32f103.c
 
-#TRGT = arm-elf-
-TRGT = arm-none-eabi-
-CC   = $(TRGT)gcc
-CPPC = $(TRGT)g++
-# Enable loading with g++ only if you need C++ runtime support.
-# NOTE: You can use C++ even without C++ support if you are careful. C++
-#       runtime support makes code size explode.
-LD   = $(TRGT)gcc
-#LD   = $(TRGT)g++
-CP   = $(TRGT)objcopy
-AS   = $(TRGT)gcc -x assembler-with-cpp
-OD   = $(TRGT)objdump
-HEX  = $(CP) -O ihex
-BIN  = $(CP) -O binary
+###################################
+CROSS = arm-none-eabi-
+CC   = $(CROSS)gcc
+LD   = $(CROSS)gcc
+OBJCOPY   = $(CROSS)objcopy
 
-# ARM-specific options here
-AOPT =
-
-# THUMB-specific options here
-TOPT = -mthumb -DTHUMB
-
-# Define C warning options here
+MCU   = cortex-m3
 CWARN = -Wall -Wextra -Wstrict-prototypes
+DEFS  = -DFREE_STANDING
+OPT   = -O3 -Os -g
+LIBS  =
 
-# Define C++ warning options here
-CPPWARN = -Wall -Wextra
-
-#
-# Compiler settings
-##############################################################################
-
-##############################################################################
-# Start of default section
-#
-
-# List all default C defines here, like -D_DEBUG=1
-DDEFS =
-
-# List all default ASM defines here, like -D_DEBUG=1
-DADEFS =
-
-# List all default directories to look for include files here
-DINCDIR =
-
-# List the default directory to look for the libraries here
-DLIBDIR =
-
-# List all default libraries here
-DLIBS =
-
-#
-# End of default section
-##############################################################################
-
-##############################################################################
-# Start of user section
-#
-
-# List all user C define here, like -D_DEBUG=1
-UDEFS =
-
-# Define ASM defines here
-UADEFS =
-
-# List all user directories here
-UINCDIR =
-
-# List the user directory to look for the libraries here
-ULIBDIR =
-
-# List all user libraries here
-ULIBS =
-
-#
-# End of user defines
-##############################################################################
+#######################
+include $(CHOPSTX)/rules.mk
 
-ifeq ($(USE_FWLIB),yes)
-  include $(CHIBIOS)/ext/stm32lib/stm32lib.mk
-  CSRC += $(STM32SRC)
-  INCDIR += $(STM32INC)
-  USE_OPT += -DUSE_STDPERIPH_DRIVER
-endif
+board.h:
+       @echo Please make a symbolic link \'board.h\' to a file in $(CHOPSTX)/board;
+       @exit 1
 
-include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk
-MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd
+sys.c: board.h
 
 distclean: clean
-       -rm -f Makefile neug.ld config.h usb-strings.c.inc usb-vid-pid-ver.c.inc
+       -rm -f neug.ld config.h board.h \
+              usb-strings.c.inc usb-vid-pid-ver.c.inc
index 366f22e..95f9c02 100644 (file)
--- a/src/adc.h
+++ b/src/adc.h
@@ -1,5 +1,7 @@
-#define ADC_DATA_AVAILABLE ((eventmask_t)1)
-extern Thread *rng_thread;
+extern chopstx_mutex_t adc_mtx;
+extern chopstx_cond_t adc_cond;
+extern int adc_waiting;
+extern int adc_data_available;
 
 void adc_init (void);
 void adc_start (void);
@@ -8,3 +10,4 @@ void adc_stop (void);
 #define ADC_SAMPLE_MODE 0
 #define ADC_CRC32_MODE       1
 void adc_start_conversion (int mode, uint32_t *p, int size);
+
index 8566968..c994494 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * adc_stm32f103.c - ADC driver for STM32F103
  *
- * Copyright (C) 2011, 2012 Free Software Initiative of Japan
+ * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
  * Author: NIIBE Yutaka <gniibe@fsij.org>
  *
  * This file is a part of NeuG, a True Random Number Generator
  *
  */
 
-#include "ch.h"
-#include "hal.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <chopstx.h>
+
 #include "neug.h"
+#include "stm32f103.h"
 #include "adc.h"
 
 #define NEUG_CRC32_COUNTS 4
 
 #define STM32_ADC_ADC1_DMA_PRIORITY         2
-#define STM32_ADC_ADC1_IRQ_PRIORITY         5
 
 #define ADC_SMPR1_SMP_VREF(n)   ((n) << 21)
 #define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18)
  */
 void adc_init (void)
 {
-  chSysLock ();
-  rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
+  RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
   ADC1->CR1 = 0;
   ADC1->CR2 = ADC_CR2_ADON;
   ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
@@ -129,21 +130,56 @@ void adc_init (void)
   while ((ADC2->CR2 & ADC_CR2_CAL) != 0)
     ;
   ADC2->CR2 = 0;
-  rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
-  chSysUnlock ();
+  RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
+
+  /* ... and DMA Initialize.  */
+  DMA1_Channel1->CCR = 0;
+  DMA1->IFCR = 0xffffffff;
+}
+
+extern uint8_t __process4_stack_base__, __process4_stack_size__;
+const uint32_t __stackaddr_adc = (uint32_t)&__process4_stack_base__;
+const size_t __stacksize_adc = (size_t)&__process4_stack_size__;
+#define PRIO_ADC 1
+
+static void adc_lld_serve_rx_interrupt (uint32_t flags);
+
+#define INTR_REQ_DMA1_Channel1 11
+static void *
+adc_intr_thread (void *arg)
+{
+  chopstix_intr_t interrupt;
+
+  (void)arg;
+  chopstx_intr_register (&interrupt, INTR_REQ_DMA1_Channel1);
+
+  while (1)
+    {
+      uint32_t flags;
+
+      chopstx_wait_intr (&interrupt);
+      flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause.  */
+      DMA1->IFCR = STM32_DMA_ISR_MASK; /* Clear interrupt of channel 1.  */
+      adc_lld_serve_rx_interrupt (flags);
+    }
+
+  return NULL;
 }
 
-static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags);
 
 void adc_start (void)
 {
-  dmaStreamAllocate (NEUG_DMA_CHANNEL, STM32_ADC_ADC1_IRQ_PRIORITY,
-                    adc_lld_serve_rx_interrupt, NULL);
-  dmaStreamSetPeripheral (NEUG_DMA_CHANNEL, &ADC1->DR);
+  chopstx_t thd;
+  chopstx_attr_t attr;
+
+  /* Allocate a DMA channel.  */
+  RCC->AHBENR |= RCC_AHBENR_DMA1EN;
+  DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
 
-  chSysLock ();
+  /**/
+  DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
 
-  rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
+  RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
 
   ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
               | ADC_CR1_SCAN);
@@ -169,7 +205,10 @@ void adc_start (void)
   ADC1->CR2 = 0;
 #endif
 
-  chSysUnlock ();
+  chopstx_attr_init (&attr);
+  chopstx_attr_setschedparam (&attr, PRIO_ADC);
+  chopstx_attr_setstack (&attr, __stackaddr_adc, __stacksize_adc);
+  chopstx_create (&thd, &attr, adc_intr_thread, NULL);
 }
 
 static int adc_mode;
@@ -202,17 +241,17 @@ void adc_start_conversion (int mode, uint32_t *p, int size)
 
  if (mode == ADC_SAMPLE_MODE)
     {
-      dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, p);
-      dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, size / 4);
-      dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_SAMPLE);
-      dmaStreamEnable (NEUG_DMA_CHANNEL);
+      DMA1_Channel1->CMAR  = (uint32_t)p; /* SetMemory0 */
+      DMA1_Channel1->CNDTR  = (uint32_t)size / 4; /* size */
+      DMA1_Channel1->CCR  = (uint32_t)NEUG_DMA_MODE_SAMPLE; /*mode*/
+      DMA1_Channel1->CCR |= DMA_CCR1_EN;                   /* Enable */
     }
   else
     {
-      dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, &CRC->DR);
-      dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, NEUG_CRC32_COUNTS);
-      dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_CRC32);
-      dmaStreamEnable (NEUG_DMA_CHANNEL);
+      DMA1_Channel1->CMAR  = (uint32_t)&CRC->DR; /* SetMemory0 */
+      DMA1_Channel1->CNDTR  = (uint32_t)NEUG_CRC32_COUNTS; /* size */
+      DMA1_Channel1->CCR  = (uint32_t)NEUG_DMA_MODE_CRC32; /*mode*/
+      DMA1_Channel1->CCR |= DMA_CCR1_EN;                   /* Enable */
     }
 
  adc_start_conversion_internal ();
@@ -221,7 +260,8 @@ void adc_start_conversion (int mode, uint32_t *p, int size)
 
 static void adc_stop_conversion (void)
 {
-  dmaStreamDisable (NEUG_DMA_CHANNEL);
+  DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
+
 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
   ADC1->CR2 = 0;
   ADC2->CR2 = 0;
@@ -239,15 +279,14 @@ void adc_stop (void)
   ADC2->CR1 = 0;
   ADC2->CR2 = 0;
 
-  dmaStreamRelease (NEUG_DMA_CHANNEL);
-  rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
+  /* XXX: here to disable the associated IRQ vector; stop intr thread.  */
+  RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
+  RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
 }
 
 
-static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags)
+static void adc_lld_serve_rx_interrupt (uint32_t flags)
 {
-  (void)arg;
-
   if ((flags & STM32_DMA_ISR_TEIF) != 0)  /* DMA errors  */
     {
       /* Should never happened.  If any, it's coding error. */
@@ -267,21 +306,21 @@ static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags)
 
              if (adc_size > 0)
                {
-                 dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, &CRC->DR);
-                 dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, NEUG_CRC32_COUNTS);
-                 dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_CRC32);
-                 dmaStreamEnable (NEUG_DMA_CHANNEL);
-
+                 DMA1_Channel1->CMAR  = (uint32_t)&CRC->DR; /* SetMemory0 */
+                 DMA1_Channel1->CNDTR  = (uint32_t)NEUG_CRC32_COUNTS; /* size */
+                 DMA1_Channel1->CCR  = (uint32_t)NEUG_DMA_MODE_CRC32; /*mode*/
+                 DMA1_Channel1->CCR |= DMA_CCR1_EN;                /* Enable */
                  adc_start_conversion_internal ();
                }
            }
 
          if (adc_mode == ADC_SAMPLE_MODE || adc_size <= 0)
            {
-             chSysLockFromIsr();
-             if (rng_thread)
-               chEvtSignalFlagsI (rng_thread, ADC_DATA_AVAILABLE);
-             chSysUnlockFromIsr();
+             chopstx_mutex_lock (&adc_mtx);
+             adc_data_available++;
+             if (adc_waiting)
+               chopstx_cond_signal (&adc_cond);
+             chopstx_mutex_unlock (&adc_mtx);
            }
        }
     }
index 08dc9c9..21d1ba7 100644 (file)
@@ -1,7 +1,28 @@
 /*
- * Taken from polarssl aes.c
+ * aes-constant-ft.c - AES forward tables.
  *
- * Original copyright is below:
+ * We need something useful for the initial flash ROM page (4 Ki
+ * bytes), which cannot be modified after installation.  Even after
+ * upgrade of the firmware, it stays intact.
+ *
+ * We decide to put 3/4 of AES forward tables to fill 3 Ki bytes, as
+ * its useful and it won't change.
+ *
+ * The code was taken from aes.c of PolarSSL version 0.14, and then,
+ * modified to add section names.
+ *
+ * Since this is just a data, it wouldn't be copyright-able, but the
+ * original auther would claim so.  Thus, we put original copyright
+ * notice here.  It is highly likely that there will be no such a
+ * thing for copyright.  Nevertheless, we think that PolarSSL is good
+ * software to address here, and encourage people using it.
+ *
+ */
+
+#include <stdint.h>
+
+/*
+ * Original copyright notice is below:
  */
 
 /*
     V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
 
 #define V(a,b,c,d) 0x##a##b##c##d
-const unsigned long FT0[256] __attribute__((section(".sys.0"))) = { FT };
+const uint32_t FT0[256] __attribute__((section(".sys.0"))) = { FT };
 #undef V
 
 #define V(a,b,c,d) 0x##b##c##d##a
-const unsigned long FT1[256] __attribute__((section(".sys.1"))) = { FT };
+const uint32_t FT1[256] __attribute__((section(".sys.1"))) = { FT };
 #undef V
 
 #define V(a,b,c,d) 0x##c##d##a##b
-const unsigned long FT2[256] __attribute__((section(".sys.2"))) = { FT };
+const uint32_t FT2[256] __attribute__((section(".sys.2"))) = { FT };
+#undef V
+
+#ifdef ORIGINAL_IMPLEMENTATION 
+#define V(a,b,c,d) 0x##d##a##b##c
+const uint32_t FT3[256] = { FT };
 #undef V
+#endif
index 293ddbb..7e567db 100755 (executable)
@@ -22,7 +22,7 @@
 
 # Default settings
 help=no
-target=STBEE_MINI
+target=FST_01
 verbose=no
 vidpid=none
 with_dfu=default
@@ -65,12 +65,10 @@ Defaults for the options are specified in brackets.
 Configuration:
   -h, --help           display this help and exit      [no]
   --vidpid=VID:PID     specify vendor/product ID       [<NONE>]
-  --target=TARGET      specify target                  [STBEE_MINI]
+  --target=TARGET      specify target                  [FST_01]
                        supported targes are:
-                          OLIMEX_STM32_H103
-                          STBEE_MINI
-                          CQ_STARM
-                          STBEE
+                          FST_01
+                          STM8S_DISCOVERY
   --with-dfu           build image for DFU             [<target specific>]
 EOF
   exit 0
@@ -81,13 +79,13 @@ if test "$vidpid" = "none"; then
   exit 1
 fi
 
-BOARD_DIR=../boards/$target
-if test -d $BOARD_DIR; then
-  echo "Configured for target: $target"
-else
-  echo "Unsupported target \`$target'" >&2
-  exit 1
-fi
+BOARD_DIR=../boards/$target
+if test -d $BOARD_DIR; then
+  echo "Configured for target: $target"
+else
+  echo "Unsupported target \`$target'" >&2
+  exit 1
+fi
 
 # Flash page size in byte
 FLASH_PAGE_SIZE=1024
@@ -181,8 +179,6 @@ then
   exit 1
 fi
 
-sed -e "s%@BOARD_DIR@%$BOARD_DIR%" \
-       < Makefile.in > Makefile
 sed -e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
     -e "s/@MEMORY_SIZE@/$MEMORY_SIZE/" \
     -e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
index daab2a7..42009bc 100644 (file)
  *
  */
 
+
+#include <stdint.h>
+#include <string.h>
+#include <chopstx.h>
+
 #include "config.h"
-#include "ch.h"
-#include "hal.h"
-#include "board.h"
 #include "neug.h"
 #include "usb_lld.h"
 #include "sys.h"
+#include "stm32f103.h"
 #include "adc.h"
 
-/*
- * We are trying to avoid dependency to C library. 
- * GCC built-in function(s) are declared here.
- */
-extern void *memcpy(void *dest, const void *src, size_t n);
-extern void *memset (void *s, int c, size_t n);
+chopstx_mutex_t usb_mtx;
+chopstx_cond_t cnd_usb_connection;
+chopstx_cond_t cnd_usb_buffer_ready;
 
-static Thread *main_thread;
-
-\f
 #define ENDP0_RXADDR        (0x40)
 #define ENDP0_TXADDR        (0x80)
 #define ENDP1_TXADDR        (0xc0)
@@ -266,6 +263,7 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
        }
       else if (req_no == USB_NEUG_EXIT)
        {
+#if 0
          chSysLockFromIsr ();
          if (main_thread->p_state == THD_STATE_SUSPENDED
              || main_thread->p_state == THD_STATE_SLEEPING)
@@ -274,6 +272,7 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
              chSchReadyI (main_thread);
            }
          chSysUnlockFromIsr ();
+#endif
        }
     }
 }
@@ -330,17 +329,10 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value)
                connected = 0;
            }
 
+         chopstx_mutex_lock (&usb_mtx);
          if (connected != connected_saved)
-           {
-             chSysLockFromIsr ();
-             if (main_thread->p_state == THD_STATE_SUSPENDED
-                 || main_thread->p_state == THD_STATE_SLEEPING)
-               {
-                 main_thread->p_u.rdymsg = RDY_OK;
-                 chSchReadyI (main_thread);
-               }
-             chSysUnlockFromIsr ();
-           }
+           chopstx_cond_signal (&cnd_usb_connection);
+         chopstx_mutex_unlock (&usb_mtx);
 
          return USB_SUCCESS;
        }
@@ -592,6 +584,33 @@ int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
     }
 }
 
+#define INTR_REQ_USB 20
+#define PRIO_USB 2
+
+static void *
+usb_intr (void *arg)
+{
+  chopstix_intr_t interrupt;
+
+  (void)arg;
+  asm volatile ("cpsid   i" : : : "memory");
+  /* Disable because usb_lld_init assumes interrupt handler.  */
+  usb_lld_init (vcom_configuration_desc[7]);
+  chopstx_intr_register (&interrupt, INTR_REQ_USB);
+  /* Enable */
+  asm volatile ("cpsie   i" : : : "memory");
+
+  while (1)
+    {
+      chopstx_wait_intr (&interrupt);
+
+      /* Process interrupt. */
+      usb_interrupt_handler ();
+    }
+
+  return NULL;
+}
+
 
 static void fill_serial_no_by_unique_id (void)
 {
@@ -614,23 +633,12 @@ static void fill_serial_no_by_unique_id (void)
     }
 }
 \f
-CH_IRQ_HANDLER (Vector90)
-{
-  CH_IRQ_PROLOGUE();
-  usb_interrupt_handler ();
-  CH_IRQ_EPILOGUE();
-}
-
 void
 EP1_IN_Callback (void)
 {
-  chSysLockFromIsr ();
-  if (main_thread->p_state == THD_STATE_SUSPENDED)
-    {
-      main_thread->p_u.rdymsg = RDY_OK;
-      chSchReadyI (main_thread);
-    }
-  chSysUnlockFromIsr ();
+  chopstx_mutex_lock (&usb_mtx);
+  chopstx_cond_signal (&cnd_usb_buffer_ready);
+  chopstx_mutex_unlock (&usb_mtx);
 }
 
 void
@@ -644,44 +652,92 @@ EP3_OUT_Callback (void)
   usb_lld_rx_enable (ENDP3);
 }
 \f
-static WORKING_AREA(wa_led, 64);
+typedef uint32_t eventmask_t;
+#define ALL_EVENTS (~0)
+
+struct event_flag {
+  chopstx_mutex_t mutex;
+  chopstx_cond_t cond;
+  eventmask_t flag;
+};
+
+static void event_flag_init (struct event_flag *ev)
+{
+  ev->flag = 0;
+  chopstx_mutex_init (&ev->mutex);
+  chopstx_cond_init (&ev->cond);
+}
+
+
+static eventmask_t event_flag_waitone (struct event_flag *ev, eventmask_t m)
+{
+  int n;
+
+  chopstx_mutex_lock (&ev->mutex);
+  while (!(ev->flag & m))
+    chopstx_cond_wait (&ev->cond, &ev->mutex);
+
+  n = __builtin_ffs ((ev->flag & m));
+  ev->flag &= ~(1 << (n - 1));
+  chopstx_mutex_unlock (&ev->mutex);
+
+  return (1 << (n - 1));
+}
+
+static void event_flag_signal (struct event_flag *ev, eventmask_t m)
+{
+  chopstx_mutex_lock (&ev->mutex);
+  ev->flag |= m;
+  chopstx_cond_signal (&ev->cond);
+  chopstx_mutex_unlock (&ev->mutex);
+}
+
+extern uint8_t __process1_stack_base__, __process1_stack_size__;
+extern uint8_t __process3_stack_base__, __process3_stack_size__;
+
+const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__;
+const size_t __stacksize_led = (size_t)&__process1_stack_size__;
+const uint32_t __stackaddr_usb = (uint32_t)&__process3_stack_base__;
+const size_t __stacksize_usb = (size_t)&__process3_stack_size__;
+
+
+#define PRIO_LED 1
+struct event_flag led_event;
 
 #define LED_ONESHOT_SHORT      ((eventmask_t)1)
 #define LED_TWOSHOTS           ((eventmask_t)2)
 #define LED_ONESHOT_LONG       ((eventmask_t)4)
-static Thread *led_thread;
 
 /*
  * LED blinker: When notified, let LED emit for 100ms.
  */
-static msg_t led_blinker (void *arg)
+static void *led_blinker (void *arg)
 {
   (void)arg;
 
-  led_thread = chThdSelf ();
   set_led (0);
 
   while (1)
     {
       eventmask_t m;
 
-      m = chEvtWaitOne (ALL_EVENTS);
+      m = event_flag_waitone (&led_event, ALL_EVENTS);
       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
        break;
 
       set_led (1);
       if (m == LED_ONESHOT_SHORT)
-       chThdSleepMilliseconds (100);
+       chopstx_usleep (100*1000);
       else if (m == LED_TWOSHOTS)
        {
-         chThdSleepMilliseconds (50);
+         chopstx_usleep (50*1000);
          set_led (0);
-         chThdSleepMilliseconds (50);
+         chopstx_usleep (50*1000);
          set_led (1);
-         chThdSleepMilliseconds (50);
+         chopstx_usleep (50*1000);
        }
       else
-       chThdSleepMilliseconds (250);
+       chopstx_usleep (250*1000);
       set_led (0);
     }
 
@@ -723,23 +779,32 @@ int
 main (int argc, char **argv)
 {
   uint32_t entry;
+  chopstx_t led_thread, thd;
+  chopstx_attr_t attr;
 
   (void)argc;
   (void)argv;
 
   fill_serial_no_by_unique_id ();
 
-  halInit ();
   adc_init ();
-  chSysInit ();
 
-  main_thread = chThdSelf ();
+  event_flag_init (&led_event);
 
-  chThdCreateStatic (wa_led, sizeof (wa_led), NORMALPRIO, led_blinker, NULL);
+  chopstx_attr_init (&attr);
+  chopstx_attr_setschedparam (&attr, PRIO_LED);
+  chopstx_attr_setstack (&attr, __stackaddr_led, __stacksize_led);
+  chopstx_create (&led_thread, &attr, led_blinker, NULL);
 
-  neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
+  chopstx_mutex_init (&usb_mtx);
+  chopstx_cond_init (&cnd_usb_connection);
+  chopstx_cond_init (&cnd_usb_buffer_ready);
 
-  usb_lld_init (vcom_configuration_desc[7]);
+  chopstx_attr_setschedparam (&attr, PRIO_USB);
+  chopstx_attr_setstack (&attr, __stackaddr_usb, __stacksize_usb);
+  chopstx_create (&thd, &attr, usb_intr, NULL);
+
+  neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
 
   while (1)
     {
@@ -758,8 +823,8 @@ main (int argc, char **argv)
          neug_flush ();
 
          if ((count & 0x0007) == 0)
-           chEvtSignalFlags (led_thread, LED_ONESHOT_SHORT);
-         chThdSleepMilliseconds (25);
+           event_flag_signal (&led_event, LED_ONESHOT_SHORT);
+         chopstx_usleep (25*1000);
          count++;
        }
 
@@ -770,8 +835,8 @@ main (int argc, char **argv)
            break;
 
          neug_flush ();
-         chEvtSignalFlags (led_thread, LED_TWOSHOTS);
-         chThdSleepMilliseconds (5000);
+         event_flag_signal (&led_event, LED_TWOSHOTS);
+         chopstx_usleep (5000*1000);
        }
 
       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
@@ -796,7 +861,7 @@ main (int argc, char **argv)
            break;
 
          if ((count & 0x03ff) == 0)
-           chEvtSignalFlags (led_thread, LED_ONESHOT_SHORT);
+           event_flag_signal (&led_event, LED_ONESHOT_SHORT);
 
          i = neug_consume_random (copy_to_tx);
 
@@ -811,25 +876,27 @@ main (int argc, char **argv)
          else
            last_was_fullsizepacket = 0;
 
-         chSysLock ();
+         chopstx_mutex_lock (&usb_mtx);
          if (connected == 0)
            {
-             chSysUnlock();
+             chopstx_mutex_unlock (&usb_mtx);
              goto waiting_connection;
            }
          else
            {
              usb_lld_tx_enable (ENDP1, i * 4);
-             chSchGoSleepS (THD_STATE_SUSPENDED);
+             chopstx_cond_wait (&cnd_usb_buffer_ready, &usb_mtx);
            }
-         chSysUnlock ();
+         chopstx_mutex_unlock (&usb_mtx);
 
          count++;
        }
     }
 
-  chEvtSignalFlags (led_thread, LED_ONESHOT_SHORT);
-  chThdWait (led_thread);
+  event_flag_signal (&led_event, LED_ONESHOT_SHORT);
+#if 0
+  chopstx_join (led_thread, NULL);
+#endif
 
   /*
    * We come here, because of FSIJ_DEVICE_NEUG_EXIT_REQUESTED.
@@ -839,15 +906,15 @@ main (int argc, char **argv)
   fsij_device_state = FSIJ_DEVICE_EXITED;
 
   while (fsij_device_state == FSIJ_DEVICE_EXITED)
-    chThdSleepMilliseconds (500);
+    chopstx_usleep (500*1000);
 
   flash_unlock ();             /* Flash unlock should be done here */
   set_led (1);
   usb_lld_shutdown ();
-  /* Disable SysTick */
-  SysTick->CTRL = 0;
-  /* Disable all interrupts */
-  port_disable ();
+#if 0
+  /* Finish kernel: stop scheduler, timer.  */
+  chx_fini ();
+#endif
   /* Set vector */
   SCB->VTOR = (uint32_t)&_regnual_start;
   entry = calculate_regnual_entry_address (&_regnual_start);
index d2ddc4f..6223752 100644 (file)
@@ -1,35 +1,12 @@
-/*
-    ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
-                 2011 Giovanni Di Sirio.
-
-    This file is part of ChibiOS/RT.
-
-    ChibiOS/RT 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.
-
-    ChibiOS/RT 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/>.
-
-                                      ---
-
-    A special exception to the GPL can be applied should you wish to distribute
-    a combined work that includes ChibiOS/RT, without being obliged to provide
-    the source code for any proprietary components. See the file exception.txt
-    for full details of how and when the exception can be applied.
-*/
-
 /*
  * ST32F103 memory setup.
  */
-__main_stack_size__     = 0x0400;
-__process_stack_size__  = 0x0400;
+__main_stack_size__     = 0x0100;      /* Exception handlers     */
+__process0_stack_size__  = 0x0400;     /* main */
+__process1_stack_size__  = 0x0100;     /* led */
+__process2_stack_size__  = 0x0200;     /* rng */
+__process3_stack_size__  = 0x0100;     /* intr: usb */
+__process4_stack_size__  = 0x0100;     /* intr: adc dma */
 
 MEMORY
 {
@@ -56,10 +33,10 @@ SECTIONS
         KEEP(*(.vectors))
        . = ALIGN(16);
        *(.sys.version)
-       */sys.o(.text)
-       */sys.o(.text.*)
-        */sys.o(.rodata)
-       */sys.o(.rodata.*)
+       build/sys.o(.text)
+       build/sys.o(.text.*)
+        build/sys.o(.rodata)
+       build/sys.o(.rodata.*)
        . = ALIGN(1024);
        *(.sys.0)
        *(.sys.1)
@@ -68,28 +45,12 @@ SECTIONS
 
     _text = .;
 
-    startup : ALIGN(16) SUBALIGN(16)
+    .startup : ALIGN(128) SUBALIGN(128)
     {
-        KEEP(*(vectors))
+        KEEP(*(.startup.vectors))
         . = ALIGN (16);
     } > flash =0xffffffff
 
-    constructors : ALIGN(4) SUBALIGN(4)
-    {
-        PROVIDE(__init_array_start = .);
-        KEEP(*(SORT(.init_array.*)))
-        KEEP(*(.init_array))
-        PROVIDE(__init_array_end = .);
-    } > flash
-
-    destructors : ALIGN(4) SUBALIGN(4)
-    {
-        PROVIDE(__fini_array_start = .);
-        KEEP(*(.fini_array))
-        KEEP(*(SORT(.fini_array.*)))
-        PROVIDE(__fini_array_end = .);
-    } > flash
-
     .text : ALIGN(16) SUBALIGN(16)
     {
         *(.text.startup.*)
@@ -121,17 +82,32 @@ SECTIONS
 
     .stacks :
     {
+        . = ALIGN(8);
+        __process4_stack_base__ = .;
+        . += __process4_stack_size__;
+        . = ALIGN(8);
+        __process4_stack_end__ = .;
+        __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__ = .;
         . = ALIGN(8);
         __main_stack_base__ = .;
         . += __main_stack_size__;
         . = ALIGN(8);
         __main_stack_end__ = .;
-        __process_stack_base__ = .;
-        __main_thread_stack_base__ = .;
-        . += __process_stack_size__;
-        . = ALIGN(8);
-        __process_stack_end__ = .;
-        __main_thread_stack_end__ = .;
     } > ram
 
     .data :
index e426da5..f2d6075 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * random.c - random number generation
  *
- * Copyright (C) 2011, 2012 Free Software Initiative of Japan
+ * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
  * Author: NIIBE Yutaka <gniibe@fsij.org>
  *
  * This file is a part of NeuG, a True Random Number Generator
  *
  */
 
-#include <string.h>            /* for memcpy */
+#include <stdint.h>
+#include <string.h>
+#include <chopstx.h>
+
 #include "config.h"
 
-#include "ch.h"
-#include "hal.h"
 #include "sys.h"
 #include "neug.h"
+#include "stm32f103.h"
 #include "adc.h"
 #include "sha256.h"
 
-Thread *rng_thread;
-#define ADC_DATA_AVAILABLE ((eventmask_t)1)
+chopstx_mutex_t adc_mtx;
+chopstx_cond_t adc_cond;
+int adc_waiting;
+int adc_data_available;
 
 static uint32_t adc_buf[SHA256_BLOCK_SIZE/sizeof (uint32_t)];
 
@@ -95,7 +99,8 @@ static void ep_fill_initial_string (void)
 
 static void ep_init (int mode)
 {
-  chEvtClearFlags (ADC_DATA_AVAILABLE);
+  adc_data_available = 0;
+
   if (mode == NEUG_MODE_RAW)
     {
       ep_round = EP_ROUND_RAW;
@@ -356,9 +361,9 @@ static void noise_source_continuous_test (uint8_t noise)
  */
 struct rng_rb {
   uint32_t *buf;
-  Mutex m;
-  CondVar data_available;
-  CondVar space_available;
+  chopstx_mutex_t m;
+  chopstx_cond_t data_available;
+  chopstx_cond_t space_available;
   uint8_t head, tail;
   uint8_t size;
   unsigned int full :1;
@@ -369,9 +374,9 @@ static void rb_init (struct rng_rb *rb, uint32_t *p, uint8_t size)
 {
   rb->buf = p;
   rb->size = size;
-  chMtxInit (&rb->m);
-  chCondInit (&rb->data_available);
-  chCondInit (&rb->space_available);
+  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;
@@ -401,27 +406,41 @@ static uint32_t rb_del (struct rng_rb *rb)
 }
 
 uint8_t neug_mode;
+static int rng_should_terminate;
+static chopstx_t rng_thread;
+
 
 /**
  * @brief Random number generation thread.
  */
-static msg_t rng (void *arg)
+static void *
+rng (void *arg)
 {
   struct rng_rb *rb = (struct rng_rb *)arg;
 
-  rng_thread = chThdSelf ();
+  rng_should_terminate = 0;
+  chopstx_mutex_init (&adc_mtx);
+  chopstx_cond_init (&adc_cond);
 
   /* Enable ADCs */
   adc_start ();
 
   ep_init (NEUG_MODE_CONDITIONED);
 
-  while (!chThdShouldTerminate ())
+  while (!rng_should_terminate)
     {
       int n;
       int mode = neug_mode;
 
-      chEvtWaitOne (ADC_DATA_AVAILABLE); /* Get ADC sampling.  */
+      chopstx_mutex_lock (&adc_mtx);
+      if (!adc_data_available)
+       {
+         adc_waiting = 1;
+         chopstx_cond_wait (&adc_cond, &adc_mtx);
+         adc_waiting = 0;
+       }
+      adc_data_available = 0;
+      chopstx_mutex_unlock (&adc_mtx);
 
       if ((n = ep_process (mode)))
        {
@@ -438,9 +457,9 @@ static msg_t rng (void *arg)
 
          vp = ep_output (mode);
 
-         chMtxLock (&rb->m);
+         chopstx_mutex_lock (&rb->m);
          while (rb->full)
-           chCondWait (&rb->space_available);
+           chopstx_cond_wait (&rb->space_available, &rb->m);
 
          for (i = 0; i < n; i++)
            {
@@ -449,18 +468,22 @@ static msg_t rng (void *arg)
                break;
            }
 
-         chCondSignal (&rb->data_available);
-         chMtxUnlock ();
+         chopstx_cond_signal (&rb->data_available);
+         chopstx_mutex_unlock (&rb->m);
        }
     }
 
   adc_stop ();
 
-  return 0;
+  return NULL;
 }
 
 static struct rng_rb the_ring_buffer;
-static WORKING_AREA(wa_rng, 256);
+
+extern uint8_t __process2_stack_base__, __process2_stack_size__;
+const uint32_t __stackaddr_rng = (uint32_t)&__process2_stack_base__;
+const size_t __stacksize_rng = (size_t)&__process2_stack_size__;
+#define PRIO_RNG 3
 
 /**
  * @brief Initialize NeuG.
@@ -468,6 +491,7 @@ static WORKING_AREA(wa_rng, 256);
 void
 neug_init (uint32_t *buf, uint8_t size)
 {
+  chopstx_attr_t attr;
   const uint32_t *u = (const uint32_t *)unique_device_id ();
   struct rng_rb *rb = &the_ring_buffer;
   int i;
@@ -484,7 +508,11 @@ neug_init (uint32_t *buf, uint8_t size)
 
   neug_mode = NEUG_MODE_CONDITIONED;
   rb_init (rb, buf, size);
-  chThdCreateStatic (wa_rng, sizeof (wa_rng), NORMALPRIO, rng, rb);
+
+  chopstx_attr_init (&attr);
+  chopstx_attr_setschedparam (&attr, PRIO_RNG);
+  chopstx_attr_setstack (&attr, __stackaddr_rng, __stacksize_rng);
+  chopstx_create (&rng_thread, &attr, rng, rb);
 }
 
 /**
@@ -495,11 +523,11 @@ neug_flush (void)
 {
   struct rng_rb *rb = &the_ring_buffer;
 
-  chMtxLock (&rb->m);
+  chopstx_mutex_lock (&rb->m);
   while (!rb->empty)
     (void)rb_del (rb);
-  chCondSignal (&rb->space_available);
-  chMtxUnlock ();
+  chopstx_cond_signal (&rb->space_available);
+  chopstx_mutex_unlock (&rb->m);
 }
 
 
@@ -511,10 +539,10 @@ neug_kick_filling (void)
 {
   struct rng_rb *rb = &the_ring_buffer;
 
-  chMtxLock (&rb->m);
+  chopstx_mutex_lock (&rb->m);
   if (!rb->full)
-    chCondSignal (&rb->space_available);
-  chMtxUnlock ();
+    chopstx_cond_signal (&rb->space_available);
+  chopstx_mutex_unlock (&rb->m);
 }
 
 /**
@@ -529,13 +557,13 @@ neug_get (int kick)
   struct rng_rb *rb = &the_ring_buffer;
   uint32_t v;
 
-  chMtxLock (&rb->m);
+  chopstx_mutex_lock (&rb->m);
   while (rb->empty)
-    chCondWait (&rb->data_available);
+    chopstx_cond_wait (&rb->data_available, &rb->m);
   v = rb_del (rb);
   if (kick)
-    chCondSignal (&rb->space_available);
-  chMtxUnlock ();
+    chopstx_cond_signal (&rb->space_available);
+  chopstx_mutex_unlock (&rb->m);
 
   return v;
 }
@@ -546,15 +574,15 @@ neug_get_nonblock (uint32_t *p)
   struct rng_rb *rb = &the_ring_buffer;
   int r = 0;
 
-  chMtxLock (&rb->m);
+  chopstx_mutex_lock (&rb->m);
   if (rb->empty)
     {
       r = -1;
-      chCondSignal (&rb->space_available);
+      chopstx_cond_signal (&rb->space_available);
     }
   else
     *p = rb_del (rb);
-  chMtxUnlock ();
+  chopstx_mutex_unlock (&rb->m);
 
   return r;
 }
@@ -564,7 +592,7 @@ int neug_consume_random (void (*proc) (uint32_t, int))
   int i = 0;
   struct rng_rb *rb = &the_ring_buffer;
 
-  chMtxLock (&rb->m);
+  chopstx_mutex_lock (&rb->m);
   while (!rb->empty)
     {
       uint32_t v;
@@ -573,8 +601,8 @@ int neug_consume_random (void (*proc) (uint32_t, int))
       proc (v, i);
       i++;
     }
-  chCondSignal (&rb->space_available);
-  chMtxUnlock ();
+  chopstx_cond_signal (&rb->space_available);
+  chopstx_mutex_unlock (&rb->m);
 
   return i;
 }
@@ -584,22 +612,20 @@ neug_wait_full (void)
 {
   struct rng_rb *rb = &the_ring_buffer;
 
-  chMtxLock (&rb->m);
+  chopstx_mutex_lock (&rb->m);
   while (!rb->full)
-    chCondWait (&rb->data_available);
-  chMtxUnlock ();
+    chopstx_cond_wait (&rb->data_available, &rb->m);
+  chopstx_mutex_unlock (&rb->m);
 }
 
 void
 neug_fini (void)
 {
-  if (rng_thread)
-    {
-      chThdTerminate (rng_thread);
-      neug_get (1);
-      chThdWait (rng_thread);
-      rng_thread = NULL;
-    }
+  rng_should_terminate = 1;
+  neug_get (1);
+#if 0
+  chopstx_join (rng_thread, NULL);
+#endif
 }
 
 void
@@ -610,8 +636,14 @@ neug_mode_select (uint8_t mode)
 
   neug_wait_full ();
 
-  while (rng_thread->p_state != THD_STATE_WTCOND)
-    chThdSleep (MS2ST (1));
+  chopstx_mutex_lock (&adc_mtx);
+  while (adc_waiting == 0)
+    {
+      chopstx_mutex_unlock (&adc_mtx);
+      chopstx_usleep (1000);
+      chopstx_mutex_lock (&adc_mtx);
+    }
+  chopstx_mutex_unlock (&adc_mtx);
 
   ep_init (mode);
   noise_source_cnt_max_reset ();
diff --git a/src/stm32f103.h b/src/stm32f103.h
new file mode 100644 (file)
index 0000000..02f6adc
--- /dev/null
@@ -0,0 +1,201 @@
+#define PERIPH_BASE    0x40000000
+#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 *const)RCC_BASE);
+
+#define RCC_AHBENR_DMA1EN       0x00000001
+#define RCC_AHBENR_CRCEN        0x00000040
+
+#define RCC_APB2ENR_ADC1EN      0x00000200
+#define RCC_APB2ENR_ADC2EN      0x00000400
+
+#define  CRC_CR_RESET                        0x00000001
+
+struct CRC {
+  volatile uint32_t DR;
+  volatile uint8_t  IDR;
+  uint8_t   RESERVED0;
+  uint16_t  RESERVED1;
+  volatile uint32_t CR;
+};
+
+#define CRC_BASE              (AHBPERIPH_BASE + 0x3000)
+static struct CRC *const CRC = ((struct CRC *const)CRC_BASE);
+
+
+struct ADC {
+  volatile uint32_t SR;
+  volatile uint32_t CR1;
+  volatile uint32_t CR2;
+  volatile uint32_t SMPR1;
+  volatile uint32_t SMPR2;
+  volatile uint32_t JOFR1;
+  volatile uint32_t JOFR2;
+  volatile uint32_t JOFR3;
+  volatile uint32_t JOFR4;
+  volatile uint32_t HTR;
+  volatile uint32_t LTR;
+  volatile uint32_t SQR1;
+  volatile uint32_t SQR2;
+  volatile uint32_t SQR3;
+  volatile uint32_t JSQR;
+  volatile uint32_t JDR1;
+  volatile uint32_t JDR2;
+  volatile uint32_t JDR3;
+  volatile uint32_t JDR4;
+  volatile uint32_t DR;
+};
+
+#define ADC1_BASE             (APB2PERIPH_BASE + 0x2400)
+#define ADC2_BASE             (APB2PERIPH_BASE + 0x2800)
+
+static struct ADC *const ADC1 = (struct ADC *const)ADC1_BASE;
+static struct ADC *const ADC2 = (struct ADC *const)ADC2_BASE;
+
+#define  ADC_CR1_DUALMOD_0       0x00010000
+#define  ADC_CR1_DUALMOD_1       0x00020000
+#define  ADC_CR1_DUALMOD_2       0x00040000
+#define  ADC_CR1_DUALMOD_3       0x00080000
+
+#define  ADC_CR1_SCAN            0x00000100
+
+#define  ADC_CR2_ADON            0x00000001
+#define  ADC_CR2_CONT            0x00000002
+#define  ADC_CR2_CAL             0x00000004
+#define  ADC_CR2_RSTCAL          0x00000008
+#define  ADC_CR2_DMA             0x00000100
+#define  ADC_CR2_ALIGN           0x00000800
+#define  ADC_CR2_EXTSEL          0x000E0000
+#define  ADC_CR2_EXTSEL_0        0x00020000
+#define  ADC_CR2_EXTSEL_1        0x00040000
+#define  ADC_CR2_EXTSEL_2        0x00080000
+#define  ADC_CR2_EXTTRIG         0x00100000
+#define  ADC_CR2_SWSTART         0x00400000
+#define  ADC_CR2_TSVREFE         0x00800000
+
+struct DMA_Channel {
+  volatile uint32_t CCR;
+  volatile uint32_t CNDTR;
+  volatile uint32_t CPAR;
+  volatile uint32_t CMAR;
+};
+
+struct DMA {
+  volatile uint32_t ISR;
+  volatile uint32_t IFCR;
+};
+
+#define STM32_DMA_CR_MINC           DMA_CCR1_MINC
+#define STM32_DMA_CR_MSIZE_WORD     DMA_CCR1_MSIZE_1
+#define STM32_DMA_CR_PSIZE_WORD     DMA_CCR1_PSIZE_1
+#define STM32_DMA_CR_TCIE           DMA_CCR1_TCIE
+#define STM32_DMA_CR_TEIE           DMA_CCR1_TEIE
+#define STM32_DMA_CR_HTIE           DMA_CCR1_HTIE
+#define STM32_DMA_ISR_TEIF          DMA_ISR_TEIF1
+#define STM32_DMA_ISR_HTIF          DMA_ISR_HTIF1
+#define STM32_DMA_ISR_TCIF          DMA_ISR_TCIF1
+
+#define STM32_DMA_ISR_MASK          0x0F
+#define STM32_DMA_CCR_RESET_VALUE   0x00000000
+#define STM32_DMA_CR_PL_MASK        DMA_CCR1_PL
+#define STM32_DMA_CR_PL(n)          ((n) << 12)
+
+#define  DMA_CCR1_EN                         0x00000001
+#define  DMA_CCR1_TCIE                       0x00000002
+#define  DMA_CCR1_HTIE                       0x00000004
+#define  DMA_CCR1_TEIE                       0x00000008
+#define  DMA_CCR1_DIR                        0x00000010
+#define  DMA_CCR1_CIRC                       0x00000020
+#define  DMA_CCR1_PINC                       0x00000040
+#define  DMA_CCR1_MINC                       0x00000080
+#define  DMA_CCR1_PSIZE                      0x00000300
+#define  DMA_CCR1_PSIZE_0                    0x00000100
+#define  DMA_CCR1_PSIZE_1                    0x00000200
+#define  DMA_CCR1_MSIZE                      0x00000C00
+#define  DMA_CCR1_MSIZE_0                    0x00000400
+#define  DMA_CCR1_MSIZE_1                    0x00000800
+#define  DMA_CCR1_PL                         0x00003000
+#define  DMA_CCR1_PL_0                       0x00001000
+#define  DMA_CCR1_PL_1                       0x00002000
+#define  DMA_CCR1_MEM2MEM                    0x00004000
+
+#define  DMA_ISR_GIF1                        0x00000001
+#define  DMA_ISR_TCIF1                       0x00000002
+#define  DMA_ISR_HTIF1                       0x00000004
+#define  DMA_ISR_TEIF1                       0x00000008
+#define  DMA_ISR_GIF2                        0x00000010
+#define  DMA_ISR_TCIF2                       0x00000020
+#define  DMA_ISR_HTIF2                       0x00000040
+#define  DMA_ISR_TEIF2                       0x00000080
+#define  DMA_ISR_GIF3                        0x00000100
+#define  DMA_ISR_TCIF3                       0x00000200
+#define  DMA_ISR_HTIF3                       0x00000400
+#define  DMA_ISR_TEIF3                       0x00000800
+#define  DMA_ISR_GIF4                        0x00001000
+#define  DMA_ISR_TCIF4                       0x00002000
+#define  DMA_ISR_HTIF4                       0x00004000
+#define  DMA_ISR_TEIF4                       0x00008000
+#define  DMA_ISR_GIF5                        0x00010000
+#define  DMA_ISR_TCIF5                       0x00020000
+#define  DMA_ISR_HTIF5                       0x00040000
+#define  DMA_ISR_TEIF5                       0x00080000
+#define  DMA_ISR_GIF6                        0x00100000
+#define  DMA_ISR_TCIF6                       0x00200000
+#define  DMA_ISR_HTIF6                       0x00400000
+#define  DMA_ISR_TEIF6                       0x00800000
+#define  DMA_ISR_GIF7                        0x01000000
+#define  DMA_ISR_TCIF7                       0x02000000
+#define  DMA_ISR_HTIF7                       0x04000000
+#define  DMA_ISR_TEIF7                       0x08000000
+
+#define DMA1_BASE             (AHBPERIPH_BASE + 0x0000)
+static struct DMA *const DMA1 = (struct DMA *const)DMA1_BASE;
+
+#define DMA1_Channel1_BASE    (AHBPERIPH_BASE + 0x0008)
+static struct DMA_Channel *const DMA1_Channel1 =
+  (struct DMA_Channel *const)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 *const)SCB_BASE;
index 0dd410f..af594b0 100644 (file)
--- a/src/sys.c
+++ b/src/sys.c
 /*
- * sys.c - system services at the first flash ROM blocks
+ * sys.c - system routines for the initial page for STM32F103.
  *
- * Copyright (C) 2012 Free Software Initiative of Japan
+ * Copyright (C) 2013 Flying Stone Technology
  * Author: NIIBE Yutaka <gniibe@fsij.org>
  *
- * This file is a part of Gnuk, a GnuPG USB Token implementation.
- *
- * Gnuk 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.
- *
- * Gnuk 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/>.
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.  This file is offered as-is,
+ * without any warranty.
  *
+ * When the flash ROM is protected, we cannot modify the initial page.
+ * We put some system routines (which is useful for any program) here.
  */
 
-#include "config.h"
-#include "ch.h"
-#include "hal.h"
+#include <stdint.h>
+#include <stdlib.h>
 #include "board.h"
-#include "usb_lld.h"
 
-extern uint8_t __flash_start__, __flash_end__;
 
+#define CORTEX_PRIORITY_BITS    4
+#define CORTEX_PRIORITY_MASK(n)  ((n) << (8 - CORTEX_PRIORITY_BITS))
+#define USB_LP_CAN1_RX0_IRQn    20
+#define STM32_USB_IRQ_PRIORITY     11
+
+#define FLASH_PAGE_SIZE 1024
+
+
+
+#define STM32_SW_PLL           (2 << 0)
+#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_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)
+
+#define STM32_SW               STM32_SW_PLL
+#define STM32_PLLSRC           STM32_PLLSRC_HSE
+#define STM32_HPRE             STM32_HPRE_DIV1
+#define STM32_PPRE1            STM32_PPRE1_DIV2
+#define STM32_PPRE2            STM32_PPRE2_DIV1
+#define STM32_ADCPRE           STM32_ADCPRE_DIV6
+#define STM32_MCOSEL           STM32_MCO_NOCLOCK
+#define STM32_USBPRE            STM32_USBPRE_DIV1P5
+
+#define STM32_PLLCLKIN         (STM32_HSECLK / 1)
+#define STM32_PLLMUL           ((STM32_PLLMUL_VALUE - 2) << 18)
+#define STM32_PLLCLKOUT                (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
+#define STM32_SYSCLK           STM32_PLLCLKOUT
+#define STM32_HCLK             (STM32_SYSCLK / 1)
+
+#define STM32_FLASHBITS                0x00000012
+
+struct NVIC {
+  uint32_t ISER[8];
+  uint32_t unused1[24];
+  uint32_t ICER[8];
+  uint32_t unused2[24];
+  uint32_t ISPR[8];
+  uint32_t unused3[24];
+  uint32_t ICPR[8];
+  uint32_t unused4[24];
+  uint32_t IABR[8];
+  uint32_t unused5[56];
+  uint32_t IPR[60];
+};
+
+static struct NVIC *const NVICBase = ((struct NVIC *const)0xE000E100);
+#define NVIC_ISER(n)   (NVICBase->ISER[n >> 5])
+#define NVIC_ICPR(n)   (NVICBase->ICPR[n >> 5])
+#define NVIC_IPR(n)    (NVICBase->IPR[n >> 2])
+
+static void
+nvic_enable_vector (uint32_t n, uint32_t prio)
+{
+  unsigned int sh = (n & 3) << 3;
+
+  NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh)) | (prio << sh);
+  NVIC_ICPR (n) = 1 << (n & 0x1F);
+  NVIC_ISER (n) = 1 << (n & 0x1F);
+}
+
+
+#define PERIPH_BASE    0x40000000
+#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 *const)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
+
+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 *const) FLASH_R_BASE);
+
+static void
+clock_init (void)
+{
+  /* HSI setup */
+  RCC->CR |= RCC_CR_HSION;
+  while (!(RCC->CR & RCC_CR_HSIRDY))
+    ;
+  RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION;
+  RCC->CFGR = 0;
+  while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
+    ;
+
+  /* HSE setup */
+  RCC->CR |= RCC_CR_HSEON;
+  while (!(RCC->CR & RCC_CR_HSERDY))
+    ;
+
+  /* PLL setup */
+  RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
+  RCC->CR   |= RCC_CR_PLLON;
+  while (!(RCC->CR & RCC_CR_PLLRDY))
+    ;
+
+  /* Clock settings */
+  RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE
+    | STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
+
+  /* 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))
+    ;
+}
+
+#define RCC_APB2ENR_IOPAEN     0x00000004
+#define RCC_APB2RSTR_IOPARST   0x00000004
+#define RCC_APB2ENR_IOPBEN     0x00000008
+#define RCC_APB2RSTR_IOPBRST   0x00000008
+#define RCC_APB2ENR_IOPCEN     0x00000010
+#define RCC_APB2RSTR_IOPCRST   0x00000010
+#define RCC_APB2ENR_IOPDEN     0x00000020
+#define RCC_APB2RSTR_IOPDRST   0x00000020
+
+
+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)
+
+static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE);
+static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
+
+static void
+gpio_init (void)
+{
+  /* Enable GPIO clock. */
+  RCC->APB2ENR |= RCC_APB2ENR_IOP_EN;
+  RCC->APB2RSTR = RCC_APB2RSTR_IOP_RST;
+  RCC->APB2RSTR = 0;
+
+  GPIO_USB->ODR = VAL_GPIO_ODR;
+  GPIO_USB->CRH = VAL_GPIO_CRH;
+  GPIO_USB->CRL = VAL_GPIO_CRL;
+
+#if GPIO_USB_BASE != GPIO_LED_BASE
+  GPIO_LED->ODR = VAL_GPIO_LED_ODR;
+  GPIO_LED->CRH = VAL_GPIO_LED_CRH;
+  GPIO_LED->CRL = VAL_GPIO_LED_CRL;
+#endif
+}
 
 static void
 usb_cable_config (int enable)
 {
-#if defined(SET_USB_CONDITION)
-  if (SET_USB_CONDITION (enable))
-    palSetPad (IOPORT_USB, GPIO_USB);
+#if defined(GPIO_USB_SET_TO_ENABLE)
+  if (enable)
+    GPIO_USB->BSRR = (1 << GPIO_USB_SET_TO_ENABLE);
   else
-    palClearPad (IOPORT_USB, GPIO_USB);
+    GPIO_USB->BRR = (1 << GPIO_USB_SET_TO_ENABLE);
+#elif defined(GPIO_USB_CLEAR_TO_ENABLE)
+  if (enable)
+    GPIO_USB->BRR = (1 << GPIO_USB_CLEAR_TO_ENABLE);
+  else
+    GPIO_USB->BSRR = (1 << GPIO_USB_CLEAR_TO_ENABLE);
 #else
   (void)enable;
 #endif
 }
 
-static void
+void
 set_led (int on)
 {
-  if (SET_LED_CONDITION (on))
-    palSetPad (IOPORT_LED, GPIO_LED);
+#if defined(GPIO_LED_CLEAR_TO_EMIT)
+  if (on)
+    GPIO_LED->BRR = (1 << GPIO_LED_CLEAR_TO_EMIT);
+  else
+    GPIO_LED->BSRR = (1 << GPIO_LED_CLEAR_TO_EMIT);
+#else
+  if (on)
+    GPIO_LED->BSRR = (1 << GPIO_LED_SET_TO_EMIT);
   else
-    palClearPad (IOPORT_LED, GPIO_LED);
+    GPIO_LED->BRR = (1 << GPIO_LED_SET_TO_EMIT);
+#endif
 }
 
+static void wait (int count)
+{
+  int i;
+
+  for (i = 0; i < count; i++)
+    asm volatile ("" : : "r" (i) : "memory");
+}
+
+#define USB_IRQ 20
+#define USB_IRQ_PRIORITY ((11) << 4)
+
+static void
+usb_lld_sys_shutdown (void)
+{
+  RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
+  RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
+  usb_cable_config (0);
+}
+
+static void
+usb_lld_sys_init (void)
+{
+  if ((RCC->APB1ENR & RCC_APB1ENR_USBEN)
+      && (RCC->APB1RSTR & RCC_APB1RSTR_USBRST) == 0)
+    /* Make sure the device is disconnected, even after core reset.  */
+    {
+      usb_lld_sys_shutdown ();
+      /* Disconnect requires SE0 (>= 2.5uS).  */
+      wait (300);
+    }
+
+  usb_cable_config (1);
+  RCC->APB1ENR |= RCC_APB1ENR_USBEN;
+  nvic_enable_vector (USB_LP_CAN1_RX0_IRQn,
+                     CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
+  /*
+   * Note that we also have other IRQ(s):
+   *   USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous)
+   *   USBWakeUp_IRQn (suspend/resume)
+   */
+  RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
+  RCC->APB1RSTR = 0;
+}
 
 #define FLASH_KEY1               0x45670123UL
 #define FLASH_KEY2               0xCDEF89ABUL
 
-static void
+enum flash_status
+{
+  FLASH_BUSY = 1,
+  FLASH_ERROR_PG,
+  FLASH_ERROR_WRP,
+  FLASH_COMPLETE,
+  FLASH_TIMEOUT
+};
+
+static void __attribute__ ((used))
 flash_unlock (void)
 {
   FLASH->KEYR = FLASH_KEY1;
@@ -64,6 +335,27 @@ flash_unlock (void)
 }
 
 
+#define intr_disable()  asm volatile ("cpsid   i" : : : "memory")
+
+#define intr_enable()  asm volatile ("msr     BASEPRI, %0\n\t"          \
+                                    "cpsie   i" : : "r" (0) : "memory")
+
+#define FLASH_SR_BSY           0x01
+#define FLASH_SR_PGERR         0x04
+#define FLASH_SR_WRPRTERR      0x10
+#define FLASH_SR_EOP           0x20
+
+#define FLASH_CR_PG    0x0001
+#define FLASH_CR_PER   0x0002
+#define FLASH_CR_MER   0x0004
+#define FLASH_CR_OPTPG 0x0010
+#define FLASH_CR_OPTER 0x0020
+#define FLASH_CR_STRT  0x0040
+#define FLASH_CR_LOCK  0x0080
+#define FLASH_CR_OPTWRE        0x0200
+#define FLASH_CR_ERRIE 0x0400
+#define FLASH_CR_EOPIE 0x1000
+
 static int
 flash_wait_for_last_operation (uint32_t timeout)
 {
@@ -90,7 +382,7 @@ flash_program_halfword (uint32_t addr, uint16_t data)
 
   status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT);
 
-  port_disable ();
+  intr_disable ();
   if (status == 0)
     {
       FLASH->CR |= FLASH_CR_PG;
@@ -100,7 +392,7 @@ flash_program_halfword (uint32_t addr, uint16_t data)
       status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT);
       FLASH->CR &= ~FLASH_CR_PG;
     }
-  port_enable ();
+  intr_enable ();
 
   return status;
 }
@@ -112,7 +404,7 @@ flash_erase_page (uint32_t addr)
 
   status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
 
-  port_disable ();
+  intr_disable ();
   if (status == 0)
     {
       FLASH->CR |= FLASH_CR_PER;
@@ -122,7 +414,7 @@ flash_erase_page (uint32_t addr)
       status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
       FLASH->CR &= ~FLASH_CR_PER;
     }
-  port_enable ();
+  intr_enable ();
 
   return status;
 }
@@ -139,6 +431,8 @@ flash_check_blank (const uint8_t *p_start, size_t size)
   return 1;
 }
 
+extern uint8_t __flash_start__, __flash_end__;
+
 static int
 flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
 {
@@ -175,7 +469,7 @@ flash_protect (void)
 
   status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
 
-  port_disable ();
+  intr_disable ();
   if (status == 0)
     {
       FLASH->OPTKEYR = FLASH_KEY1;
@@ -187,7 +481,7 @@ flash_protect (void)
       status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
       FLASH->CR &= ~FLASH_CR_OPTER;
     }
-  port_enable ();
+  intr_enable ();
 
   if (status != 0)
     return 0;
@@ -196,7 +490,6 @@ flash_protect (void)
   return (option_bytes_value & 0xff) == 0xff ? 1 : 0;
 }
 
-
 static void __attribute__((naked))
 flash_erase_all_and_exec (void (*entry)(void))
 {
@@ -219,39 +512,32 @@ flash_erase_all_and_exec (void (*entry)(void))
   for (;;);
 }
 
-static void
-nvic_enable_vector (uint32_t n, uint32_t prio)
+struct SCB
 {
-  unsigned int sh = (n & 3) << 3;
-
-  NVIC_IPR (n >> 2) = (NVIC_IPR(n >> 2) & ~(0xFF << sh)) | (prio << sh);
-  NVIC_ICPR (n >> 5) = 1 << (n & 0x1F);
-  NVIC_ISER (n >> 5) = 1 << (n & 0x1F);
-}
-
-static void
-usb_lld_sys_init (void)
-{
-  RCC->APB1ENR |= RCC_APB1ENR_USBEN;
-  nvic_enable_vector (USB_LP_CAN1_RX0_IRQn,
-                     CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
-  /*
-   * Note that we also have other IRQ(s):
-   *   USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous)
-   *   USBWakeUp_IRQn (suspend/resume)
-   */
-  RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
-  RCC->APB1RSTR = 0;
-
-  usb_cable_config (1);
-}
+  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];
+};
 
-static void
-usb_lld_sys_shutdown (void)
-{
-  RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
-  usb_cable_config (0);
-}
+#define SCS_BASE       (0xE000E000)
+#define SCB_BASE       (SCS_BASE +  0x0D00)
+static struct SCB *const SCB = ((struct SCB *const) SCB_BASE);
 
 #define SYSRESETREQ 0x04
 static void
@@ -299,6 +585,8 @@ handler vector[] __attribute__ ((section(".vectors"))) = {
   usb_lld_sys_init,
   usb_lld_sys_shutdown,
   nvic_system_reset,
+  clock_init,
+  gpio_init,
   (handler)&FT0,
   (handler)&FT1,
   (handler)&FT2,
@@ -307,6 +595,6 @@ handler vector[] __attribute__ ((section(".vectors"))) = {
 const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
   3*2+2,            /* bLength */
   0x03,                     /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE*/
-  /* sys version: "1.0" */
-  '1', 0, '.', 0, '0', 0,
+  /* sys version: "2.0" */
+  '2', 0, '.', 0, '0', 0,
 };
index 3884c95..1f5b602 100644 (file)
--- a/src/sys.h
+++ b/src/sys.h
@@ -1,7 +1,7 @@
 extern const uint8_t sys_version[8];
 
 typedef void (*handler)(void);
-extern handler vector[14];
+extern handler vector[18];
 
 static inline const uint8_t *
 unique_device_id (void)
index 74f5acf..887d69f 100644 (file)
@@ -1,5 +1,12 @@
 #ifdef FREE_STANDING
-#include "types.h"
+#include <stdint.h>
+#include <stdlib.h>
+#define TRUE  1
+#define FALSE 0
+
+#define NULL  0
+
+#define     __IO    volatile
 #else
 #include "ch.h"
 #include "hal.h"