update ChibiOS/RT and NeuG
This commit is contained in:
18
ChangeLog
18
ChangeLog
@@ -1,3 +1,21 @@
|
|||||||
|
2013-02-18 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* chibios: New submodule for ChibioS/RT 2.4.x.
|
||||||
|
* boards/*/*: Update for ChibiOS/RT 2.4.x.
|
||||||
|
|
||||||
|
* src/chconf.h, src/halconf.h, src/Makefile.in, src/gnuk.ld.in:
|
||||||
|
Update for ChibiOS/RT 2.4.x.
|
||||||
|
|
||||||
|
* src/main.c, src/openpgp.c, src/usb-icc.c: Follow the change of
|
||||||
|
ChibiOS/RT 2.4.x.
|
||||||
|
* boards/common/board-common.c: Rename from hwinit.c.
|
||||||
|
* src/usb_stm32f103.c: Rename from usb_lld.c.
|
||||||
|
|
||||||
|
* src/neug.h, src/neug.h: Update NeuG 0.05.
|
||||||
|
* src/adc_stm32f103.c, src/adc.h: New from NeuG 0.05.
|
||||||
|
|
||||||
|
* src/random.c: Follow the change of NeuG 0.05.
|
||||||
|
|
||||||
2013-02-15 Niibe Yutaka <gniibe@fsij.org>
|
2013-02-15 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* Version 1.0.2.
|
* Version 1.0.2.
|
||||||
|
|||||||
@@ -2,13 +2,11 @@
|
|||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
#include "../common/hwinit.c"
|
/*
|
||||||
|
* Board-specific initialization code.
|
||||||
void
|
*/
|
||||||
hwinit1 (void)
|
void boardInit(void)
|
||||||
{
|
{
|
||||||
hwinit1_common ();
|
|
||||||
|
|
||||||
#if defined(PINPAD_CIR_SUPPORT)
|
#if defined(PINPAD_CIR_SUPPORT)
|
||||||
/* PA0/TIM2_CH1 = 1 (pull up) */
|
/* PA0/TIM2_CH1 = 1 (pull up) */
|
||||||
/* PA1/TIM2_CH2 = 0 (pull down) */
|
/* PA1/TIM2_CH2 = 0 (pull down) */
|
||||||
|
|||||||
@@ -37,6 +37,14 @@
|
|||||||
#define GPIO_LED GPIOB_LED
|
#define GPIO_LED GPIOB_LED
|
||||||
#define IOPORT_LED GPIOB
|
#define IOPORT_LED GPIOB
|
||||||
|
|
||||||
|
/* NeuG settings for ADC2. */
|
||||||
|
#define NEUG_ADC_SETTING2_SMPR1 0
|
||||||
|
#define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) \
|
||||||
|
| ADC_SMPR2_SMP_AN9(ADC_SAMPLE_1P5)
|
||||||
|
#define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) \
|
||||||
|
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN9)
|
||||||
|
#define NEUG_ADC_SETTING2_NUM_CHANNELS 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Board identifier.
|
* Board identifier.
|
||||||
*/
|
*/
|
||||||
@@ -54,7 +62,6 @@
|
|||||||
* native STM32 HAL.
|
* native STM32 HAL.
|
||||||
*/
|
*/
|
||||||
#define STM32F10X_MD
|
#define STM32F10X_MD
|
||||||
#define CPU_WITH_NO_GPIOE 1
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IO pins assignments.
|
* IO pins assignments.
|
||||||
@@ -94,9 +101,10 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Port A setup.
|
* Port A setup.
|
||||||
* PA0 - input with pull-up (TIM2_CH1)
|
* PA0 - input with pull-up (TIM2_CH1): AN0 for NeuG
|
||||||
* PA1 - input with pull-down (TIM2_CH2)
|
* PA1 - input with pull-down (TIM2_CH2)
|
||||||
* PA2 - input with pull-up (TIM2_CH3)
|
* PA2 - input with pull-up (TIM2_CH3) connected to CIR module
|
||||||
|
* PA3 - input with pull-up: external pin available to user
|
||||||
* PA4 - Push pull output (SPI1_NSS)
|
* PA4 - Push pull output (SPI1_NSS)
|
||||||
* PA5 - Alternate Push pull output (SPI1_SCK)
|
* PA5 - Alternate Push pull output (SPI1_SCK)
|
||||||
* PA6 - Alternate Push pull output (SPI1_MISO)
|
* PA6 - Alternate Push pull output (SPI1_MISO)
|
||||||
@@ -111,6 +119,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Port B setup.
|
* Port B setup.
|
||||||
|
* PB1 - input with pull-up: AN9 for NeuG
|
||||||
* Everything input with pull-up except:
|
* Everything input with pull-up except:
|
||||||
* PB0 - Push pull output (LED 1:ON 0:OFF)
|
* PB0 - Push pull output (LED 1:ON 0:OFF)
|
||||||
*/
|
*/
|
||||||
@@ -144,4 +153,14 @@
|
|||||||
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
|
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
|
||||||
#define VAL_GPIOEODR 0xFFFFFFFF
|
#define VAL_GPIOEODR 0xFFFFFFFF
|
||||||
|
|
||||||
|
#if !defined(_FROM_ASM_)
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void boardInit(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _FROM_ASM_ */
|
||||||
|
|
||||||
#endif /* _BOARD_H_ */
|
#endif /* _BOARD_H_ */
|
||||||
|
|||||||
@@ -7,9 +7,8 @@
|
|||||||
#define STM32_PLLMUL_VALUE 6
|
#define STM32_PLLMUL_VALUE 6
|
||||||
#define STM32_HPRE STM32_HPRE_DIV1
|
#define STM32_HPRE STM32_HPRE_DIV1
|
||||||
#define STM32_PPRE1 STM32_PPRE1_DIV2
|
#define STM32_PPRE1 STM32_PPRE1_DIV2
|
||||||
#define STM32_PPRE2 STM32_PPRE2_DIV2
|
#define STM32_PPRE2 STM32_PPRE2_DIV1
|
||||||
#define STM32_ADCPRE STM32_ADCPRE_DIV4
|
#define STM32_ADCPRE STM32_ADCPRE_DIV6
|
||||||
#define STM32_USBPRE STM32_USBPRE_DIV1P5
|
#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK
|
||||||
#define STM32_MCO STM32_MCO_NOCLOCK
|
|
||||||
|
|
||||||
#include "mcuconf-common.h"
|
#include "mcuconf-common.h"
|
||||||
|
|||||||
@@ -24,36 +24,46 @@
|
|||||||
for full details of how and when the exception can be applied.
|
for full details of how and when the exception can be applied.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PAL setup.
|
||||||
|
* @details Digital I/O ports static configuration as defined in @p board.h.
|
||||||
|
* This variable is used by the HAL when initializing the PAL driver.
|
||||||
|
*/
|
||||||
|
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||||
|
const PALConfig pal_default_config =
|
||||||
|
{
|
||||||
|
{VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH},
|
||||||
|
{VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH},
|
||||||
|
{VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH},
|
||||||
|
{VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH},
|
||||||
|
{VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH},
|
||||||
|
#if defined(STM32F10X_HD)
|
||||||
|
{VAL_GPIOFODR, VAL_GPIOFCRL, VAL_GPIOFCRH},
|
||||||
|
{VAL_GPIOGODR, VAL_GPIOGCRL, VAL_GPIOGCRH},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Early initialization code.
|
* Early initialization code.
|
||||||
* This initialization is performed just after reset before BSS and DATA
|
* This initialization must be performed just after stack setup and before
|
||||||
* segments initialization.
|
* any other initialization.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
hwinit0 (void)
|
__early_init(void)
|
||||||
{
|
{
|
||||||
stm32_clock_init();
|
stm32_clock_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
const uint8_t *
|
||||||
* Late initialization code.
|
unique_device_id (void)
|
||||||
* This initialization is performed after BSS and DATA segments initialization
|
|
||||||
* and before invoking the main() function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Common code for hwinit1
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void hwinit1_common (void)
|
|
||||||
{
|
{
|
||||||
/*
|
/* STM32F103 has 96-bit unique device identifier */
|
||||||
* HAL initialization.
|
const uint8_t *addr = (const uint8_t *)0x1ffff7e8;
|
||||||
*/
|
|
||||||
halInit();
|
|
||||||
|
|
||||||
/*
|
return addr;
|
||||||
* ChibiOS/RT initialization.
|
|
||||||
*/
|
|
||||||
chSysInit();
|
|
||||||
}
|
}
|
||||||
@@ -38,6 +38,20 @@
|
|||||||
* 0...3 Lowest...Highest.
|
* 0...3 Lowest...Highest.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HAL driver system settings.
|
||||||
|
*/
|
||||||
|
#define STM32_NO_INIT FALSE
|
||||||
|
#define STM32_HSI_ENABLED TRUE
|
||||||
|
#define STM32_LSI_ENABLED FALSE
|
||||||
|
#define STM32_HSE_ENABLED TRUE
|
||||||
|
#define STM32_LSE_ENABLED FALSE
|
||||||
|
#define STM32_USB_CLOCK_REQUIRED TRUE
|
||||||
|
#define STM32_USBPRE STM32_USBPRE_DIV1P5
|
||||||
|
#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
|
||||||
|
#define STM32_PVD_ENABLE FALSE
|
||||||
|
#define STM32_PLS STM32_PLS_LEV0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC driver system settings.
|
* ADC driver system settings.
|
||||||
*/
|
*/
|
||||||
@@ -92,3 +106,11 @@
|
|||||||
#define STM32_SPI1_IRQ_PRIORITY 10
|
#define STM32_SPI1_IRQ_PRIORITY 10
|
||||||
#define STM32_SPI2_IRQ_PRIORITY 10
|
#define STM32_SPI2_IRQ_PRIORITY 10
|
||||||
#define STM32_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
#define STM32_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB driver system settings.
|
||||||
|
*/
|
||||||
|
#define STM32_USB_USE_USB1 TRUE
|
||||||
|
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
|
||||||
|
#define STM32_USB_USB1_HP_IRQ_PRIORITY 6
|
||||||
|
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ ifeq ($(USE_THUMB),)
|
|||||||
USE_THUMB = yes
|
USE_THUMB = yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Enable register caching optimization (read documentation).
|
# Enable this if you want to see the full log while compiling.
|
||||||
ifeq ($(USE_CURRP_CACHING),)
|
ifeq ($(USE_VERBOSE_COMPILE),)
|
||||||
USE_CURRP_CACHING = no
|
USE_VERBOSE_COMPILE = no
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -58,17 +58,17 @@ endif
|
|||||||
# Define project name here
|
# Define project name here
|
||||||
PROJECT = gnuk
|
PROJECT = gnuk
|
||||||
|
|
||||||
# Define linker script file here
|
|
||||||
LDSCRIPT= gnuk.ld
|
|
||||||
|
|
||||||
# Imported source files
|
# Imported source files
|
||||||
CHIBIOS = ../ChibiOS_2.0.8
|
CHIBIOS = ../chibios
|
||||||
include $(CHIBIOS)/os/hal/platforms/STM32/platform.mk
|
include $(CHIBIOS)/os/hal/platforms/STM32F1xx/platform.mk
|
||||||
include $(CHIBIOS)/os/hal/hal.mk
|
include $(CHIBIOS)/os/hal/hal.mk
|
||||||
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F10x/port.mk
|
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F1xx/port.mk
|
||||||
include $(CHIBIOS)/os/kernel/kernel.mk
|
include $(CHIBIOS)/os/kernel/kernel.mk
|
||||||
include crypt.mk
|
include crypt.mk
|
||||||
|
|
||||||
|
# Define linker script file here
|
||||||
|
LDSCRIPT= gnuk.ld
|
||||||
|
|
||||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||||
# setting.
|
# setting.
|
||||||
CSRC = $(PORTSRC) \
|
CSRC = $(PORTSRC) \
|
||||||
@@ -76,11 +76,12 @@ CSRC = $(PORTSRC) \
|
|||||||
$(HALSRC) \
|
$(HALSRC) \
|
||||||
$(PLATFORMSRC) \
|
$(PLATFORMSRC) \
|
||||||
$(BOARDSRC) \
|
$(BOARDSRC) \
|
||||||
|
../boards/common/board-common.c \
|
||||||
$(BOARD_DIR)/board.c \
|
$(BOARD_DIR)/board.c \
|
||||||
$(CHIBIOS)/os/various/evtimer.c \
|
$(CHIBIOS)/os/various/evtimer.c \
|
||||||
$(CHIBIOS)/os/various/syscalls.c \
|
$(CHIBIOS)/os/various/syscalls.c \
|
||||||
$(CRYPTSRC) \
|
$(CRYPTSRC) \
|
||||||
main.c usb_lld.c \
|
main.c usb_stm32f103.c adc_stm32f103.c \
|
||||||
usb_desc.c usb_ctrl.c \
|
usb_desc.c usb_ctrl.c \
|
||||||
usb-icc.c openpgp.c ac.c openpgp-do.c flash.c \
|
usb-icc.c openpgp.c ac.c openpgp-do.c flash.c \
|
||||||
random.c neug.c sys.c
|
random.c neug.c sys.c
|
||||||
@@ -98,8 +99,7 @@ CSRC += usb-msc.c
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# List ASM source files here
|
# List ASM source files here
|
||||||
ASMSRC = $(PORTASM) \
|
ASMSRC = $(PORTASM)
|
||||||
$(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F10x/vectors.s
|
|
||||||
|
|
||||||
INCDIR = $(CRYPTINCDIR) \
|
INCDIR = $(CRYPTINCDIR) \
|
||||||
$(PORTINC) $(KERNINC) $(TESTINC) \
|
$(PORTINC) $(KERNINC) $(TESTINC) \
|
||||||
@@ -152,7 +152,7 @@ CPPWARN = -Wall -Wextra
|
|||||||
#
|
#
|
||||||
|
|
||||||
# List all default C defines here, like -D_DEBUG=1
|
# List all default C defines here, like -D_DEBUG=1
|
||||||
DDEFS = -DCORTEX_USE_BASEPRI=TRUE
|
DDEFS =
|
||||||
|
|
||||||
# List all default ASM defines here, like -D_DEBUG=1
|
# List all default ASM defines here, like -D_DEBUG=1
|
||||||
DADEFS =
|
DADEFS =
|
||||||
@@ -193,7 +193,7 @@ ULIBS =
|
|||||||
# End of user defines
|
# End of user defines
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
include $(CHIBIOS)/os/ports/GCC/ARM/rules.mk
|
include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk
|
||||||
MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd
|
MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
|
|||||||
10
src/adc.h
Normal file
10
src/adc.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#define ADC_DATA_AVAILABLE ((eventmask_t)1)
|
||||||
|
extern Thread *rng_thread;
|
||||||
|
|
||||||
|
void adc_init (void);
|
||||||
|
void adc_start (void);
|
||||||
|
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);
|
||||||
288
src/adc_stm32f103.c
Normal file
288
src/adc_stm32f103.c
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
* adc_stm32f103.c - ADC driver for STM32F103
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011, 2012 Free Software Initiative of Japan
|
||||||
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
*
|
||||||
|
* This file is a part of NeuG, a True Random Number Generator
|
||||||
|
* implementation based on quantization error of ADC (for STM32F103).
|
||||||
|
*
|
||||||
|
* NeuG 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.
|
||||||
|
*
|
||||||
|
* NeuG 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
#include "neug.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)
|
||||||
|
|
||||||
|
#define ADC_SMPR1_SMP_AN10(n) ((n) << 0)
|
||||||
|
#define ADC_SMPR1_SMP_AN11(n) ((n) << 3)
|
||||||
|
|
||||||
|
#define ADC_SMPR2_SMP_AN0(n) ((n) << 0)
|
||||||
|
#define ADC_SMPR2_SMP_AN1(n) ((n) << 3)
|
||||||
|
#define ADC_SMPR2_SMP_AN2(n) ((n) << 6)
|
||||||
|
#define ADC_SMPR2_SMP_AN9(n) ((n) << 27)
|
||||||
|
|
||||||
|
#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
|
||||||
|
|
||||||
|
#define ADC_SQR3_SQ1_N(n) ((n) << 0)
|
||||||
|
#define ADC_SQR3_SQ2_N(n) ((n) << 5)
|
||||||
|
#define ADC_SQR3_SQ3_N(n) ((n) << 10)
|
||||||
|
#define ADC_SQR3_SQ4_N(n) ((n) << 15)
|
||||||
|
|
||||||
|
#define ADC_SAMPLE_1P5 0
|
||||||
|
|
||||||
|
#define ADC_CHANNEL_IN0 0
|
||||||
|
#define ADC_CHANNEL_IN1 1
|
||||||
|
#define ADC_CHANNEL_IN9 9
|
||||||
|
#define ADC_CHANNEL_IN2 2
|
||||||
|
#define ADC_CHANNEL_IN10 10
|
||||||
|
#define ADC_CHANNEL_IN11 11
|
||||||
|
#define ADC_CHANNEL_SENSOR 16
|
||||||
|
#define ADC_CHANNEL_VREFINT 17
|
||||||
|
|
||||||
|
#define DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
|
||||||
|
#define DELIBARATELY_DO_IT_WRONG_START_STOP
|
||||||
|
|
||||||
|
#ifdef DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
|
||||||
|
#define ADC_SAMPLE_VREF ADC_SAMPLE_1P5
|
||||||
|
#define ADC_SAMPLE_SENSOR ADC_SAMPLE_1P5
|
||||||
|
#else
|
||||||
|
#define ADC_SAMPLE_VREF ADC_SAMPLE_239P5
|
||||||
|
#define ADC_SAMPLE_SENSOR ADC_SAMPLE_239P5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1
|
||||||
|
#define NEUG_DMA_MODE_SAMPLE \
|
||||||
|
( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
|
||||||
|
| STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
|
||||||
|
| STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE \
|
||||||
|
| STM32_DMA_CR_TEIE)
|
||||||
|
|
||||||
|
#define NEUG_DMA_MODE_CRC32 \
|
||||||
|
( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
|
||||||
|
| STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
|
||||||
|
| STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE)
|
||||||
|
|
||||||
|
#define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \
|
||||||
|
| ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR)
|
||||||
|
#define NEUG_ADC_SETTING1_SMPR2 0
|
||||||
|
#define NEUG_ADC_SETTING1_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT) \
|
||||||
|
| ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR) \
|
||||||
|
| ADC_SQR3_SQ3_N(ADC_CHANNEL_SENSOR) \
|
||||||
|
| ADC_SQR3_SQ4_N(ADC_CHANNEL_VREFINT)
|
||||||
|
#define NEUG_ADC_SETTING1_NUM_CHANNELS 4
|
||||||
|
|
||||||
|
#if !defined(NEUG_ADC_SETTING2_SMPR1)
|
||||||
|
#define NEUG_ADC_SETTING2_SMPR1 0
|
||||||
|
#define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) \
|
||||||
|
| ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
|
||||||
|
#define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) \
|
||||||
|
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)
|
||||||
|
#define NEUG_ADC_SETTING2_NUM_CHANNELS 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do calibration for both of ADCs.
|
||||||
|
*/
|
||||||
|
void adc_init (void)
|
||||||
|
{
|
||||||
|
chSysLock ();
|
||||||
|
rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||||
|
ADC1->CR1 = 0;
|
||||||
|
ADC1->CR2 = ADC_CR2_ADON;
|
||||||
|
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
|
||||||
|
while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
|
||||||
|
;
|
||||||
|
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
|
||||||
|
while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
|
||||||
|
;
|
||||||
|
ADC1->CR2 = 0;
|
||||||
|
|
||||||
|
ADC2->CR1 = 0;
|
||||||
|
ADC2->CR2 = ADC_CR2_ADON;
|
||||||
|
ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
|
||||||
|
while ((ADC2->CR2 & ADC_CR2_RSTCAL) != 0)
|
||||||
|
;
|
||||||
|
ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
|
||||||
|
while ((ADC2->CR2 & ADC_CR2_CAL) != 0)
|
||||||
|
;
|
||||||
|
ADC2->CR2 = 0;
|
||||||
|
rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||||
|
chSysUnlock ();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
chSysLock ();
|
||||||
|
|
||||||
|
rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||||
|
|
||||||
|
ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
|
||||||
|
| ADC_CR1_SCAN);
|
||||||
|
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
|
||||||
|
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
|
||||||
|
ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1;
|
||||||
|
ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2;
|
||||||
|
ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS);
|
||||||
|
ADC1->SQR2 = 0;
|
||||||
|
ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3;
|
||||||
|
|
||||||
|
ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
|
||||||
|
| ADC_CR1_SCAN);
|
||||||
|
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
|
||||||
|
ADC2->SMPR1 = NEUG_ADC_SETTING2_SMPR1;
|
||||||
|
ADC2->SMPR2 = NEUG_ADC_SETTING2_SMPR2;
|
||||||
|
ADC2->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING2_NUM_CHANNELS);
|
||||||
|
ADC2->SQR2 = 0;
|
||||||
|
ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
|
||||||
|
|
||||||
|
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
|
||||||
|
ADC2->CR2 = 0;
|
||||||
|
ADC1->CR2 = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
chSysUnlock ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int adc_mode;
|
||||||
|
static uint32_t *adc_ptr;
|
||||||
|
static int adc_size;
|
||||||
|
|
||||||
|
static void adc_start_conversion_internal (void)
|
||||||
|
{
|
||||||
|
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
|
||||||
|
/* Power on */
|
||||||
|
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
|
||||||
|
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
|
||||||
|
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
|
||||||
|
/* Start conversion. tSTAB is 1uS, but we don't follow the spec. */
|
||||||
|
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
|
||||||
|
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
|
||||||
|
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
|
||||||
|
#else
|
||||||
|
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
|
||||||
|
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
|
||||||
|
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void adc_start_conversion (int mode, uint32_t *p, int size)
|
||||||
|
{
|
||||||
|
adc_mode = mode;
|
||||||
|
adc_ptr = p;
|
||||||
|
adc_size = 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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
adc_start_conversion_internal ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void adc_stop_conversion (void)
|
||||||
|
{
|
||||||
|
dmaStreamDisable (NEUG_DMA_CHANNEL);
|
||||||
|
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
|
||||||
|
ADC1->CR2 = 0;
|
||||||
|
ADC2->CR2 = 0;
|
||||||
|
#else
|
||||||
|
ADC2->CR2 &= ~ADC_CR2_CONT;
|
||||||
|
ADC1->CR2 &= ~ADC_CR2_CONT;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void adc_stop (void)
|
||||||
|
{
|
||||||
|
ADC1->CR1 = 0;
|
||||||
|
ADC1->CR2 = 0;
|
||||||
|
|
||||||
|
ADC2->CR1 = 0;
|
||||||
|
ADC2->CR2 = 0;
|
||||||
|
|
||||||
|
dmaStreamRelease (NEUG_DMA_CHANNEL);
|
||||||
|
rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
|
||||||
|
{
|
||||||
|
/* Should never happened. If any, it's coding error. */
|
||||||
|
/* Access an unmapped address space or alignment violation. */
|
||||||
|
adc_stop_conversion ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
|
||||||
|
{
|
||||||
|
adc_stop_conversion ();
|
||||||
|
|
||||||
|
if (adc_mode != ADC_SAMPLE_MODE)
|
||||||
|
{
|
||||||
|
adc_size -= 4;
|
||||||
|
*adc_ptr++ = CRC->DR;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
adc_start_conversion_internal ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adc_mode == ADC_SAMPLE_MODE || adc_size <= 0)
|
||||||
|
{
|
||||||
|
chSysLockFromIsr();
|
||||||
|
if (rng_thread)
|
||||||
|
chEvtSignalFlagsI (rng_thread, ADC_DATA_AVAILABLE);
|
||||||
|
chSysUnlockFromIsr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/chconf.h
22
src/chconf.h
@@ -3,10 +3,18 @@
|
|||||||
#ifndef _CHCONF_H_
|
#ifndef _CHCONF_H_
|
||||||
#define _CHCONF_H_
|
#define _CHCONF_H_
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#ifdef DFU_SUPPORT
|
||||||
|
#define CORTEX_VTOR_INIT (0x00003000+0x00001000)
|
||||||
|
#else
|
||||||
|
#define CORTEX_VTOR_INIT 0x00001000
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CH_FREQUENCY 1000
|
#define CH_FREQUENCY 1000
|
||||||
#define CH_TIME_QUANTUM 20
|
#define CH_TIME_QUANTUM 20
|
||||||
#define CH_USE_NESTED_LOCKS FALSE
|
#define CH_USE_NESTED_LOCKS FALSE
|
||||||
#define CH_MEMCORE_SIZE 0 /* Whole RAM */
|
#define CH_MEMCORE_SIZE 0 /* Whole RAM */
|
||||||
|
#define CH_NO_IDLE_THREAD FALSE
|
||||||
#define CH_OPTIMIZE_SPEED TRUE
|
#define CH_OPTIMIZE_SPEED TRUE
|
||||||
#define CH_USE_REGISTRY TRUE
|
#define CH_USE_REGISTRY TRUE
|
||||||
#define CH_USE_WAITEXIT TRUE
|
#define CH_USE_WAITEXIT TRUE
|
||||||
@@ -37,14 +45,16 @@
|
|||||||
#define CH_DBG_THREADS_PROFILING FALSE
|
#define CH_DBG_THREADS_PROFILING FALSE
|
||||||
|
|
||||||
#define THREAD_EXT_FIELDS \
|
#define THREAD_EXT_FIELDS \
|
||||||
struct { \
|
|
||||||
/* Add threads custom fields here.*/ \
|
/* Add threads custom fields here.*/ \
|
||||||
};
|
|
||||||
|
|
||||||
#define THREAD_EXT_INIT(tp) { \
|
#define THREAD_EXT_INIT(tp) { \
|
||||||
/* Add threads initialization code here.*/ \
|
/* Add threads initialization code here.*/ \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
|
||||||
|
/* System halt code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
#define THREAD_EXT_EXIT(tp) { \
|
#define THREAD_EXT_EXIT(tp) { \
|
||||||
/* Add threads finalization code here.*/ \
|
/* Add threads finalization code here.*/ \
|
||||||
}
|
}
|
||||||
@@ -53,4 +63,12 @@ struct { \
|
|||||||
/* Idle loop code here.*/ \
|
/* Idle loop code here.*/ \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SYSTEM_TICK_EVENT_HOOK() { \
|
||||||
|
/* System tick event code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SYSTEM_HALT_HOOK() { \
|
||||||
|
/* System halt code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _CHCONF_H_ */
|
#endif /* _CHCONF_H_ */
|
||||||
|
|||||||
100
src/gnuk.ld.in
100
src/gnuk.ld.in
@@ -29,12 +29,11 @@
|
|||||||
*/
|
*/
|
||||||
__main_stack_size__ = 0x0400;
|
__main_stack_size__ = 0x0400;
|
||||||
__process_stack_size__ = 0x0200;
|
__process_stack_size__ = 0x0200;
|
||||||
__stacks_total_size__ = __main_stack_size__ + __process_stack_size__;
|
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
flash0 : org = @ORIGIN@, len = 4k
|
flash0 : org = 0x08000000, len = 4k
|
||||||
flash : org = @ORIGIN@+0x1000, len = @FLASH_SIZE@k - 4k
|
flash : org = 0x08000000+0x1000, len = 128k - 4k
|
||||||
ram : org = 0x20000000, len = 20k
|
ram : org = 0x20000000, len = 20k
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,20 +55,43 @@ SECTIONS
|
|||||||
KEEP(*(.vectors))
|
KEEP(*(.vectors))
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
*(.sys.version)
|
*(.sys.version)
|
||||||
sys.o(.text)
|
*/sys.o(.text)
|
||||||
sys.o(.text.*)
|
*/sys.o(.text.*)
|
||||||
sys.o(.rodata)
|
*/sys.o(.rodata)
|
||||||
sys.o(.rodata.*)
|
*/sys.o(.rodata.*)
|
||||||
. = ALIGN(1024);
|
. = ALIGN(1024);
|
||||||
*(.sys.0)
|
*(.sys.0)
|
||||||
*(.sys.1)
|
*(.sys.1)
|
||||||
*(.sys.2)
|
*(.sys.2)
|
||||||
} > flash0
|
} > flash0
|
||||||
|
|
||||||
|
_text = .;
|
||||||
|
|
||||||
|
startup : ALIGN(16) SUBALIGN(16)
|
||||||
|
{
|
||||||
|
KEEP(*(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 : ALIGN(16) SUBALIGN(16)
|
||||||
{
|
{
|
||||||
_text = .;
|
*(.text.startup.*)
|
||||||
KEEP(*(vectors))
|
|
||||||
*(.text)
|
*(.text)
|
||||||
*(.text.*)
|
*(.text.*)
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
@@ -79,64 +101,70 @@ SECTIONS
|
|||||||
*(.gcc*)
|
*(.gcc*)
|
||||||
} > flash
|
} > flash
|
||||||
|
|
||||||
.ctors :
|
.ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash
|
||||||
{
|
|
||||||
PROVIDE(_ctors_start_ = .);
|
.ARM.exidx : {
|
||||||
KEEP(*(SORT(.ctors.*)))
|
PROVIDE(__exidx_start = .);
|
||||||
KEEP(*(.ctors))
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
PROVIDE(_ctors_end_ = .);
|
PROVIDE(__exidx_end = .);
|
||||||
} > flash
|
} > flash
|
||||||
|
|
||||||
.dtors :
|
.eh_frame_hdr : {*(.eh_frame_hdr)} > flash
|
||||||
{
|
|
||||||
PROVIDE(_dtors_start_ = .);
|
|
||||||
KEEP(*(SORT(.dtors.*)))
|
|
||||||
KEEP(*(.dtors))
|
|
||||||
PROVIDE(_dtors_end_ = .);
|
|
||||||
} > flash
|
|
||||||
|
|
||||||
.ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)}
|
.eh_frame : ONLY_IF_RO {*(.eh_frame)} > flash
|
||||||
|
|
||||||
__exidx_start = .;
|
.textalign : ONLY_IF_RO { . = ALIGN(8); } > flash
|
||||||
.ARM.exidx : {*(.ARM.exidx* .gnu.linkonce.armexidx.*)} > flash
|
|
||||||
__exidx_end = .;
|
|
||||||
|
|
||||||
.eh_frame_hdr : {*(.eh_frame_hdr)}
|
|
||||||
|
|
||||||
.eh_frame : ONLY_IF_RO {*(.eh_frame)}
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
_etext = .;
|
_etext = .;
|
||||||
_textdata = _etext;
|
_textdata = _etext;
|
||||||
|
|
||||||
|
.stacks :
|
||||||
|
{
|
||||||
|
. = 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 :
|
.data :
|
||||||
{
|
{
|
||||||
_data = .;
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_data = .);
|
||||||
*(.data)
|
*(.data)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
*(.data.*)
|
*(.data.*)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
*(.ramtext)
|
*(.ramtext)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_edata = .;
|
PROVIDE(_edata = .);
|
||||||
} > ram AT > flash
|
} > ram AT > flash
|
||||||
|
|
||||||
.bss :
|
.bss :
|
||||||
{
|
{
|
||||||
_bss_start = .;
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_bss_start = .);
|
||||||
*(.bss)
|
*(.bss)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
*(.bss.*)
|
*(.bss.*)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_bss_end = .;
|
PROVIDE(_bss_end = .);
|
||||||
} > ram
|
} > ram
|
||||||
|
|
||||||
PROVIDE(end = .);
|
PROVIDE(end = .);
|
||||||
_end = .;
|
_end = .;
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
|
|
||||||
_regnual_start = .;
|
_regnual_start = .;
|
||||||
|
/* It was __ram_start__ + 0x1a00 in 1.0.x */
|
||||||
|
|
||||||
@CERTDO_SUPPORT_START@
|
@CERTDO_SUPPORT_START@
|
||||||
.gnuk_ch_certificate :
|
.gnuk_ch_certificate :
|
||||||
@@ -166,4 +194,4 @@ SECTIONS
|
|||||||
}
|
}
|
||||||
|
|
||||||
__heap_base__ = _end;
|
__heap_base__ = _end;
|
||||||
__heap_end__ = __ram_end__ - __stacks_total_size__;
|
__heap_end__ = __ram_end__;
|
||||||
|
|||||||
@@ -5,13 +5,25 @@
|
|||||||
|
|
||||||
#include "mcuconf.h"
|
#include "mcuconf.h"
|
||||||
|
|
||||||
#define CH_HAL_USE_PAL TRUE
|
#define HAL_USE_PAL TRUE
|
||||||
#define CH_HAL_USE_ADC TRUE
|
#define HAL_USE_ADC FALSE
|
||||||
#define CH_HAL_USE_CAN FALSE
|
#define HAL_USE_CAN FALSE
|
||||||
#define CH_HAL_USE_MAC FALSE
|
#define HAL_USE_EXT FALSE
|
||||||
#define CH_HAL_USE_PWM FALSE
|
#define HAL_USE_GPT FALSE
|
||||||
#define CH_HAL_USE_SERIAL FALSE
|
#define HAL_USE_I2C FALSE
|
||||||
#define CH_HAL_USE_SPI FALSE
|
#define HAL_USE_ICU FALSE
|
||||||
#define CH_HAL_USE_MMC_SPI FALSE
|
#define HAL_USE_MAC FALSE
|
||||||
|
#define HAL_USE_MMC_SPI FALSE
|
||||||
|
#define HAL_USE_PWM FALSE
|
||||||
|
#define HAL_USE_RTC FALSE
|
||||||
|
#define HAL_USE_SDC FALSE
|
||||||
|
#define HAL_USE_SERIAL FALSE
|
||||||
|
#define HAL_USE_SERIAL_USB FALSE
|
||||||
|
#define HAL_USE_SPI FALSE
|
||||||
|
#define HAL_USE_UART FALSE
|
||||||
|
#define HAL_USE_USB FALSE
|
||||||
|
|
||||||
|
/* Define manually, as we implement ADC driver by ourselves. */
|
||||||
|
#define STM32_DMA_REQUIRED 1
|
||||||
|
|
||||||
#endif /* _HALCONF_H_ */
|
#endif /* _HALCONF_H_ */
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ void
|
|||||||
EP3_IN_Callback (void)
|
EP3_IN_Callback (void)
|
||||||
{
|
{
|
||||||
if (stdout_thread)
|
if (stdout_thread)
|
||||||
chEvtSignalI (stdout_thread, EV_TX_READY);
|
chEvtSignalFlagsI (stdout_thread, EV_TX_READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -316,7 +316,7 @@ static eventmask_t display_status_code (void)
|
|||||||
void
|
void
|
||||||
led_blink (int spec)
|
led_blink (int spec)
|
||||||
{
|
{
|
||||||
chEvtSignal (main_thread, spec);
|
chEvtSignalFlags (main_thread, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -463,7 +463,7 @@ void
|
|||||||
fatal (uint8_t code)
|
fatal (uint8_t code)
|
||||||
{
|
{
|
||||||
fatal_code = code;
|
fatal_code = code;
|
||||||
chEvtSignal (main_thread, LED_FATAL);
|
chEvtSignalFlags (main_thread, LED_FATAL);
|
||||||
_write ("fatal\r\n", 7);
|
_write ("fatal\r\n", 7);
|
||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|||||||
655
src/neug.c
655
src/neug.c
@@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* neug.c - random number generation (from NeuG/src/random.c)
|
* neug.c - random number generation (from NeuG/src/random.c)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Free Software Initiative of Japan
|
* Copyright (C) 2011, 2012 Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of NeuG, a Random Number Generator
|
* This file is a part of NeuG, a True Random Number Generator
|
||||||
* implementation (for STM32F103).
|
* implementation based on quantization error of ADC (for STM32F103).
|
||||||
*
|
*
|
||||||
* NeuG is free software: you can redistribute it and/or modify it
|
* NeuG is free software: you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by
|
* under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
|
* NeuG is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
* License for more details.
|
* License for more details.
|
||||||
@@ -22,221 +22,335 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h> /* for memcpy */
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
#include "sys.h"
|
||||||
|
#include "neug.h"
|
||||||
|
#include "adc.h"
|
||||||
|
#include "sha256.h"
|
||||||
|
|
||||||
static Thread *rng_thread;
|
Thread *rng_thread;
|
||||||
#define ADC_DATA_AVAILABLE ((eventmask_t)1)
|
#define ADC_DATA_AVAILABLE ((eventmask_t)1)
|
||||||
|
|
||||||
/* Total number of channels to be sampled by a single ADC operation.*/
|
static uint32_t adc_buf[SHA256_BLOCK_SIZE/sizeof (uint32_t)];
|
||||||
#define ADC_GRP1_NUM_CHANNELS 2
|
|
||||||
|
|
||||||
/* Depth of the conversion buffer, channels are sampled one time each.*/
|
static sha256_context sha256_ctx_data;
|
||||||
#define ADC_GRP1_BUF_DEPTH 4
|
static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC samples buffer.
|
* To be a full entropy source, the requirement is to have N samples
|
||||||
|
* for output of 256-bit, where:
|
||||||
|
*
|
||||||
|
* N = (256 * 2) / <min-entropy of a sample>
|
||||||
|
*
|
||||||
|
* For example, N should be more than 103 for min-entropy = 5.0.
|
||||||
|
*
|
||||||
|
* On the other hand, in the section 6.2 "Full Entropy Source
|
||||||
|
* Requirements", it says:
|
||||||
|
*
|
||||||
|
* At least twice the block size of the underlying cryptographic
|
||||||
|
* primitive shall be provided as input to the conditioning
|
||||||
|
* function to produce full entropy output.
|
||||||
|
*
|
||||||
|
* For us, cryptographic primitive is SHA-256 and its blocksize is
|
||||||
|
* 512-bit (64-byte), thus, N >= 128.
|
||||||
|
*
|
||||||
|
* We chose N=140. Note that we have "additional bits" of 16-byte for
|
||||||
|
* last block (feedback from previous output of SHA-256) to feed
|
||||||
|
* hash_df function of SHA-256, together with sample data of 140-byte.
|
||||||
|
*
|
||||||
|
* N=140 corresponds to min-entropy >= 3.68.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
static adcsample_t samp[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH];
|
#define NUM_NOISE_INPUTS 140
|
||||||
|
|
||||||
static void adccb (adcsample_t *buffer, size_t n);
|
#define EP_ROUND_0 0 /* initial-five-byte and 3-byte, then 56-byte-input */
|
||||||
|
#define EP_ROUND_1 1 /* 64-byte-input */
|
||||||
|
#define EP_ROUND_2 2 /* 17-byte-input */
|
||||||
|
#define EP_ROUND_RAW 3 /* 32-byte-input */
|
||||||
|
#define EP_ROUND_RAW_DATA 4 /* 32-byte-input */
|
||||||
|
|
||||||
|
#define EP_ROUND_0_INPUTS 56
|
||||||
|
#define EP_ROUND_1_INPUTS 64
|
||||||
|
#define EP_ROUND_2_INPUTS 17
|
||||||
|
#define EP_ROUND_RAW_INPUTS 32
|
||||||
|
#define EP_ROUND_RAW_DATA_INPUTS 32
|
||||||
|
|
||||||
|
static uint8_t ep_round;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC conversion group.
|
* Hash_df initial string:
|
||||||
* Mode: Linear buffer, 4 samples of 2 channels, SW triggered.
|
*
|
||||||
* Channels: Vref (1.5 cycles sample time, violating the spec.)
|
* 1, : counter = 1
|
||||||
* Sensor (1.5 cycles sample time, violating the spec.)
|
* 0, 0, 1, 0 : no_of_bits_returned (in big endian)
|
||||||
*/
|
*/
|
||||||
static const ADCConversionGroup adcgrpcfg = {
|
static void ep_fill_initial_string (void)
|
||||||
FALSE,
|
|
||||||
ADC_GRP1_NUM_CHANNELS,
|
|
||||||
0,
|
|
||||||
ADC_CR2_EXTSEL_SWSTART | ADC_CR2_TSVREFE | ADC_CR2_CONT,
|
|
||||||
ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_1P5) | ADC_SMPR1_SMP_VREF(ADC_SAMPLE_1P5),
|
|
||||||
0,
|
|
||||||
ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS),
|
|
||||||
0,
|
|
||||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR) | ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT)
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ADC end conversion callback.
|
|
||||||
*/
|
|
||||||
static void adccb (adcsample_t *buffer, size_t n)
|
|
||||||
{
|
{
|
||||||
ADCDriver *adcp = &ADCD1;
|
adc_buf[0] = 0x01000001; /* Regardless of endian */
|
||||||
|
adc_buf[1] = (CRC->DR & 0xffffff00);
|
||||||
|
}
|
||||||
|
|
||||||
(void) buffer; (void) n;
|
static void ep_init (int mode)
|
||||||
if (adcp->ad_state == ADC_COMPLETE)
|
{
|
||||||
chEvtSignalI (rng_thread, ADC_DATA_AVAILABLE);
|
chEvtClearFlags (ADC_DATA_AVAILABLE);
|
||||||
|
if (mode == NEUG_MODE_RAW)
|
||||||
|
{
|
||||||
|
ep_round = EP_ROUND_RAW;
|
||||||
|
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_RAW_INPUTS);
|
||||||
|
}
|
||||||
|
else if (mode == NEUG_MODE_RAW_DATA)
|
||||||
|
{
|
||||||
|
ep_round = EP_ROUND_RAW_DATA;
|
||||||
|
adc_start_conversion (ADC_SAMPLE_MODE, adc_buf, EP_ROUND_RAW_DATA_INPUTS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ep_round = EP_ROUND_0;
|
||||||
|
ep_fill_initial_string ();
|
||||||
|
adc_start_conversion (ADC_CRC32_MODE,
|
||||||
|
&adc_buf[2], EP_ROUND_0_INPUTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void noise_source_continuous_test (uint8_t noise);
|
||||||
|
|
||||||
|
static void ep_fill_wbuf (int i, int flip, int test)
|
||||||
|
{
|
||||||
|
uint32_t v = adc_buf[i];
|
||||||
|
|
||||||
|
if (test)
|
||||||
|
{
|
||||||
|
uint8_t b0, b1, b2, b3;
|
||||||
|
|
||||||
|
b3 = v >> 24;
|
||||||
|
b2 = v >> 16;
|
||||||
|
b1 = v >> 8;
|
||||||
|
b0 = v;
|
||||||
|
|
||||||
|
noise_source_continuous_test (b0);
|
||||||
|
noise_source_continuous_test (b1);
|
||||||
|
noise_source_continuous_test (b2);
|
||||||
|
noise_source_continuous_test (b3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flip)
|
||||||
|
v = __builtin_bswap32 (v);
|
||||||
|
|
||||||
|
sha256_ctx_data.wbuf[i] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here assumes little endian architecture. */
|
||||||
|
static int ep_process (int mode)
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
if (ep_round == EP_ROUND_RAW)
|
||||||
|
{
|
||||||
|
for (i = 0; i < EP_ROUND_RAW_INPUTS / 4; i++)
|
||||||
|
ep_fill_wbuf (i, 0, 1);
|
||||||
|
|
||||||
|
ep_init (mode);
|
||||||
|
return EP_ROUND_RAW_INPUTS / 4;
|
||||||
|
}
|
||||||
|
else if (ep_round == EP_ROUND_RAW_DATA)
|
||||||
|
{
|
||||||
|
for (i = 0; i < EP_ROUND_RAW_DATA_INPUTS / 4; i++)
|
||||||
|
ep_fill_wbuf (i, 0, 0);
|
||||||
|
|
||||||
|
ep_init (mode);
|
||||||
|
return EP_ROUND_RAW_DATA_INPUTS / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ep_round == EP_ROUND_0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 64 / 4; i++)
|
||||||
|
ep_fill_wbuf (i, 1, 1);
|
||||||
|
|
||||||
|
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_1_INPUTS);
|
||||||
|
sha256_start (&sha256_ctx_data);
|
||||||
|
sha256_process (&sha256_ctx_data);
|
||||||
|
ep_round++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (ep_round == EP_ROUND_1)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 64 / 4; i++)
|
||||||
|
ep_fill_wbuf (i, 1, 1);
|
||||||
|
|
||||||
|
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_2_INPUTS);
|
||||||
|
sha256_process (&sha256_ctx_data);
|
||||||
|
ep_round++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < (EP_ROUND_2_INPUTS + 3) / 4; i++)
|
||||||
|
ep_fill_wbuf (i, 0, 1);
|
||||||
|
|
||||||
|
n = SHA256_DIGEST_SIZE / 2;
|
||||||
|
ep_init (NEUG_MODE_CONDITIONED); /* The three-byte is used here. */
|
||||||
|
memcpy (((uint8_t *)sha256_ctx_data.wbuf)
|
||||||
|
+ ((NUM_NOISE_INPUTS+5)%SHA256_BLOCK_SIZE),
|
||||||
|
sha256_output, n); /* Don't use the last three-byte. */
|
||||||
|
sha256_ctx_data.total[0] = 5 + NUM_NOISE_INPUTS + n;
|
||||||
|
sha256_finish (&sha256_ctx_data, (uint8_t *)sha256_output);
|
||||||
|
return SHA256_DIGEST_SIZE / sizeof (uint32_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const uint32_t *ep_output (int mode)
|
||||||
|
{
|
||||||
|
if (mode)
|
||||||
|
return sha256_ctx_data.wbuf;
|
||||||
|
else
|
||||||
|
return sha256_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#define REPETITION_COUNT 1
|
||||||
* TinyMT routines.
|
#define ADAPTIVE_PROPORTION_64 2
|
||||||
*
|
#define ADAPTIVE_PROPORTION_4096 4
|
||||||
* See
|
|
||||||
* "Tiny Mersenne Twister (TinyMT): A small-sized variant of Mersenne Twister"
|
|
||||||
* by Mutsuo Saito and Makoto Matsumoto
|
|
||||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Use the first example of TinyMT */
|
uint8_t neug_err_state;
|
||||||
#define TMT_MAT1 0x8f7011ee
|
uint16_t neug_err_cnt;
|
||||||
#define TMT_MAT2 0xfc78ff1f
|
uint16_t neug_err_cnt_rc;
|
||||||
#define TMT_TMAT 0x3793fdff
|
uint16_t neug_err_cnt_p64;
|
||||||
|
uint16_t neug_err_cnt_p4k;
|
||||||
|
|
||||||
static uint32_t tmt[4];
|
uint16_t neug_rc_max;
|
||||||
|
uint16_t neug_p64_max;
|
||||||
|
uint16_t neug_p4k_max;
|
||||||
|
|
||||||
static void tmt_one_step (void);
|
#include "board.h"
|
||||||
|
|
||||||
#define TMT_INIT_MIN_LOOP 8
|
static void noise_source_cnt_max_reset (void)
|
||||||
#define TMT_INIT_PRE_LOOP 8
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TinyMT initialize function.
|
|
||||||
*/
|
|
||||||
static void tmt_init (uint32_t seed)
|
|
||||||
{
|
{
|
||||||
int i;
|
neug_err_cnt = neug_err_cnt_rc = neug_err_cnt_p64 = neug_err_cnt_p4k = 0;
|
||||||
|
neug_rc_max = neug_p64_max = neug_p4k_max = 0;
|
||||||
tmt[0] = seed;
|
|
||||||
tmt[1] = TMT_MAT1;
|
|
||||||
tmt[2] = TMT_MAT2;
|
|
||||||
tmt[3] = TMT_TMAT;
|
|
||||||
|
|
||||||
for (i = 1; i < TMT_INIT_MIN_LOOP; i++)
|
|
||||||
tmt[i & 3] ^= i + UINT32_C(1812433253) * (tmt[(i - 1) & 3]
|
|
||||||
^ (tmt[(i - 1) & 3] >> 30));
|
|
||||||
|
|
||||||
if ((tmt[0] & 0x7fffffff) == 0 && tmt[1] == 0 && tmt[2] == 0 && tmt[3] == 0)
|
|
||||||
{ /* Prevent all zero */
|
|
||||||
tmt[0] = 'T';
|
|
||||||
tmt[1] = 'I';
|
|
||||||
tmt[2] = 'N';
|
|
||||||
tmt[3] = 'Y';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < TMT_INIT_PRE_LOOP; i++)
|
static void noise_source_error_reset (void)
|
||||||
tmt_one_step ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TinyMT one step function, call this every time before tmt_value.
|
|
||||||
*/
|
|
||||||
static void tmt_one_step (void)
|
|
||||||
{
|
{
|
||||||
uint32_t x, y;
|
neug_err_state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
y = tmt[3];
|
static void noise_source_error (uint32_t err)
|
||||||
x = (tmt[0] & 0x7fffffff) ^ tmt[1] ^ tmt[2];
|
|
||||||
x ^= (x << 1);
|
|
||||||
y ^= (y >> 1) ^ x;
|
|
||||||
tmt[0] = tmt[1];
|
|
||||||
tmt[1] = tmt[2];
|
|
||||||
tmt[2] = x ^ (y << 10);
|
|
||||||
tmt[3] = y;
|
|
||||||
if ((y & 1))
|
|
||||||
{
|
{
|
||||||
tmt[1] ^= TMT_MAT1;
|
neug_err_state |= err;
|
||||||
tmt[2] ^= TMT_MAT2;
|
neug_err_cnt++;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if ((err & REPETITION_COUNT))
|
||||||
* @brief Get a random word (32-bit).
|
neug_err_cnt_rc++;
|
||||||
*/
|
if ((err & ADAPTIVE_PROPORTION_64))
|
||||||
static uint32_t tmt_value (void)
|
neug_err_cnt_p64++;
|
||||||
{
|
if ((err & ADAPTIVE_PROPORTION_4096))
|
||||||
uint32_t t0, t1;
|
neug_err_cnt_p4k++;
|
||||||
|
|
||||||
t0 = tmt[3];
|
|
||||||
t1 = tmt[0] + (tmt[2] >> 8);
|
|
||||||
t0 ^= t1;
|
|
||||||
if ((t1 & 1))
|
|
||||||
t0 ^= TMT_TMAT;
|
|
||||||
return t0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 8 parallel CRC-16 shift registers, with randomly rotated feedback */
|
|
||||||
#define EPOOL_SIZE 16
|
|
||||||
static uint8_t epool[EPOOL_SIZE]; /* Big-endian */
|
|
||||||
static uint8_t ep_count;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Magic number seven.
|
* For health tests, we assume that the device noise source has
|
||||||
|
* min-entropy >= 4.2. Observing raw data stream (before CRC-32) has
|
||||||
|
* more than 4.2 bit/byte entropy. When the data stream after CRC-32
|
||||||
|
* filter will be less than 4.2 bit/byte entropy, that must be
|
||||||
|
* something wrong. Note that even we observe < 4.2, we still have
|
||||||
|
* some margin, since we use NUM_NOISE_INPUTS=140.
|
||||||
*
|
*
|
||||||
* We did an experiment of measuring entropy of ADC output with MUST.
|
|
||||||
* The entropy of a byte by raw sampling of LSBs has more than 6.0 bit/byte.
|
|
||||||
* So, it is considered OK to get 4-byte from 7-byte (6x7 = 42 > 32).
|
|
||||||
*/
|
|
||||||
#define NUM_NOISE_INPUTS 7
|
|
||||||
|
|
||||||
#define SHIFT_RIGHT(f) ((f)>>1)
|
|
||||||
|
|
||||||
static void ep_add (uint8_t entropy_bits, uint8_t another_random_bit)
|
|
||||||
{
|
|
||||||
uint8_t v = epool[ep_count];
|
|
||||||
|
|
||||||
/* CRC-16-CCITT's Polynomial is: x^16 + x^12 + x^5 + 1 */
|
|
||||||
epool[(ep_count - 12)& 0x0f] ^= v;
|
|
||||||
epool[(ep_count - 5)& 0x0f] ^= v;
|
|
||||||
epool[ep_count] = SHIFT_RIGHT (v) ^ entropy_bits;
|
|
||||||
|
|
||||||
if ((v&1) || another_random_bit)
|
|
||||||
epool[ep_count] ^= 0xff;
|
|
||||||
|
|
||||||
ep_count = (ep_count + 1) & 0x0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FNV_INIT 2166136261U
|
|
||||||
#define FNV_PRIME 16777619
|
|
||||||
|
|
||||||
static uint32_t fnv32_hash (const uint8_t *buf, int len)
|
|
||||||
{
|
|
||||||
uint32_t v = FNV_INIT;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
v ^= buf[i];
|
|
||||||
v *= FNV_PRIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PROBABILITY_50_BY_TICK() ((SysTick->VAL & 0x02) != 0)
|
|
||||||
|
|
||||||
static uint32_t ep_output (void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint8_t buf[NUM_NOISE_INPUTS];
|
|
||||||
uint8_t *p = buf;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NUM_NOISE_INPUTS is seven.
|
|
||||||
*
|
|
||||||
* There are sixteen bytes in the CRC-16 buffer. We use seven
|
|
||||||
* outputs of CRC-16 buffer for final output. There are two parts;
|
|
||||||
* former 4 outputs which will be used directly, and latter 3
|
|
||||||
* outputs which will be used with feedback loop.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* At some probability, use latter 3 outputs of CRC-16 buffer */
|
/* Cuttoff = 9, when min-entropy = 4.2, W= 2^-30 */
|
||||||
for (i = NUM_NOISE_INPUTS - 1; i >= 4; i--)
|
/* ceiling of (1+30/4.2) */
|
||||||
if (PROBABILITY_50_BY_TICK ())
|
#define REPITITION_COUNT_TEST_CUTOFF 9
|
||||||
*p++ = epool[(ep_count+i) & 0x0f] ^ epool[(ep_count+i-4) & 0x0f];
|
|
||||||
|
|
||||||
/* Use former 4 outputs of CRC-16 buffer */
|
static uint8_t rct_a;
|
||||||
for (i = 3; i >= 0; i--)
|
static uint8_t rct_b;
|
||||||
*p++ = epool[(ep_count+i) & 0x0f];
|
|
||||||
|
|
||||||
return fnv32_hash (buf, p - buf);
|
static void repetition_count_test (uint8_t sample)
|
||||||
|
{
|
||||||
|
if (rct_a == sample)
|
||||||
|
{
|
||||||
|
rct_b++;
|
||||||
|
if (rct_b >= REPITITION_COUNT_TEST_CUTOFF)
|
||||||
|
noise_source_error (REPETITION_COUNT);
|
||||||
|
if (rct_b > neug_rc_max)
|
||||||
|
neug_rc_max = rct_b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rct_a = sample;
|
||||||
|
rct_b = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cuttoff = 18, when min-entropy = 4.2, W= 2^-30 */
|
||||||
|
/* With R, qbinom(1-2^-30,64,2^-4.2) */
|
||||||
|
#define ADAPTIVE_PROPORTION_64_TEST_CUTOFF 18
|
||||||
|
|
||||||
|
static uint8_t ap64t_a;
|
||||||
|
static uint8_t ap64t_b;
|
||||||
|
static uint8_t ap64t_s;
|
||||||
|
|
||||||
|
static void adaptive_proportion_64_test (uint8_t sample)
|
||||||
|
{
|
||||||
|
if (ap64t_s >= 64)
|
||||||
|
{
|
||||||
|
ap64t_a = sample;
|
||||||
|
ap64t_s = 0;
|
||||||
|
ap64t_b = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ap64t_s++;
|
||||||
|
if (ap64t_a == sample)
|
||||||
|
{
|
||||||
|
ap64t_b++;
|
||||||
|
if (ap64t_b > ADAPTIVE_PROPORTION_64_TEST_CUTOFF)
|
||||||
|
noise_source_error (ADAPTIVE_PROPORTION_64);
|
||||||
|
if (ap64t_b > neug_p64_max)
|
||||||
|
neug_p64_max = ap64t_b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cuttoff = 315, when min-entropy = 4.2, W= 2^-30 */
|
||||||
|
/* With R, qbinom(1-2^-30,4096,2^-4.2) */
|
||||||
|
#define ADAPTIVE_PROPORTION_4096_TEST_CUTOFF 315
|
||||||
|
|
||||||
|
static uint8_t ap4096t_a;
|
||||||
|
static uint16_t ap4096t_b;
|
||||||
|
static uint16_t ap4096t_s;
|
||||||
|
|
||||||
|
static void adaptive_proportion_4096_test (uint8_t sample)
|
||||||
|
{
|
||||||
|
if (ap4096t_s >= 4096)
|
||||||
|
{
|
||||||
|
ap4096t_a = sample;
|
||||||
|
ap4096t_s = 0;
|
||||||
|
ap4096t_b = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ap4096t_s++;
|
||||||
|
if (ap4096t_a == sample)
|
||||||
|
{
|
||||||
|
ap4096t_b++;
|
||||||
|
if (ap4096t_b > ADAPTIVE_PROPORTION_4096_TEST_CUTOFF)
|
||||||
|
noise_source_error (ADAPTIVE_PROPORTION_4096);
|
||||||
|
if (ap4096t_b > neug_p4k_max)
|
||||||
|
neug_p4k_max = ap4096t_b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void noise_source_continuous_test (uint8_t noise)
|
||||||
|
{
|
||||||
|
repetition_count_test (noise);
|
||||||
|
adaptive_proportion_64_test (noise);
|
||||||
|
adaptive_proportion_4096_test (noise);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ring buffer, filled by generator, consumed by neug_get routine.
|
* Ring buffer, filled by generator, consumed by neug_get routine.
|
||||||
*/
|
*/
|
||||||
@@ -286,55 +400,7 @@ static uint32_t rb_del (struct rng_rb *rb)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
uint8_t neug_mode;
|
||||||
* @brief Random number generation from ADC sampling.
|
|
||||||
* @param RB: Pointer to ring buffer structure
|
|
||||||
* @return -1 when failure, 0 otherwise.
|
|
||||||
* @note Called holding the mutex, with RB->full == 0.
|
|
||||||
* Keep generating until RB->full == 1.
|
|
||||||
*/
|
|
||||||
static int rng_gen (struct rng_rb *rb)
|
|
||||||
{
|
|
||||||
static uint8_t round = 0;
|
|
||||||
uint8_t b;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
chEvtWaitOne (ADC_DATA_AVAILABLE);
|
|
||||||
|
|
||||||
/* Got, ADC sampling data */
|
|
||||||
round++;
|
|
||||||
b = (((samp[0] & 0x01) << 0) | ((samp[1] & 0x01) << 1)
|
|
||||||
| ((samp[2] & 0x01) << 2) | ((samp[3] & 0x01) << 3)
|
|
||||||
| ((samp[4] & 0x01) << 4) | ((samp[5] & 0x01) << 5)
|
|
||||||
| ((samp[6] & 0x01) << 6) | ((samp[7] & 0x01) << 7));
|
|
||||||
|
|
||||||
adcStartConversion (&ADCD1, &adcgrpcfg, samp, ADC_GRP1_BUF_DEPTH, adccb);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Put a random byte to entropy pool.
|
|
||||||
*/
|
|
||||||
ep_add (b, PROBABILITY_50_BY_TICK ());
|
|
||||||
|
|
||||||
if ((round % NUM_NOISE_INPUTS) == 0)
|
|
||||||
{ /* We have enough entropy in the pool. */
|
|
||||||
uint32_t v = ep_output (); /* Get the random bits from the pool. */
|
|
||||||
|
|
||||||
/* Mix the random bits from the pool with the output of PRNG. */
|
|
||||||
tmt_one_step ();
|
|
||||||
v ^= tmt_value ();
|
|
||||||
|
|
||||||
/* We got the final random bits, add it to the ring buffer. */
|
|
||||||
rb_add (rb, v);
|
|
||||||
round = 0;
|
|
||||||
if (rb->full)
|
|
||||||
/* fully generated */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* success */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Random number generation thread.
|
* @brief Random number generation thread.
|
||||||
@@ -345,24 +411,56 @@ static msg_t rng (void *arg)
|
|||||||
|
|
||||||
rng_thread = chThdSelf ();
|
rng_thread = chThdSelf ();
|
||||||
|
|
||||||
adcStart (&ADCD1, NULL);
|
/* Enable ADCs */
|
||||||
adcStartConversion (&ADCD1, &adcgrpcfg, samp, ADC_GRP1_BUF_DEPTH, adccb);
|
adc_start ();
|
||||||
|
|
||||||
while (1)
|
ep_init (NEUG_MODE_CONDITIONED);
|
||||||
|
|
||||||
|
while (!chThdShouldTerminate ())
|
||||||
{
|
{
|
||||||
|
int n;
|
||||||
|
int mode = neug_mode;
|
||||||
|
|
||||||
|
chEvtWaitOne (ADC_DATA_AVAILABLE); /* Get ADC sampling. */
|
||||||
|
|
||||||
|
if ((n = ep_process (mode)))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const uint32_t *vp;
|
||||||
|
|
||||||
|
if (neug_err_state != 0
|
||||||
|
&& (mode == NEUG_MODE_CONDITIONED || mode == NEUG_MODE_RAW))
|
||||||
|
{
|
||||||
|
/* Don't use the result and do it again. */
|
||||||
|
noise_source_error_reset ();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
vp = ep_output (mode);
|
||||||
|
|
||||||
chMtxLock (&rb->m);
|
chMtxLock (&rb->m);
|
||||||
while (rb->full)
|
while (rb->full)
|
||||||
chCondWait (&rb->space_available);
|
chCondWait (&rb->space_available);
|
||||||
rng_gen (rb);
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
rb_add (rb, *vp++);
|
||||||
|
if (rb->full)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
chCondSignal (&rb->data_available);
|
chCondSignal (&rb->data_available);
|
||||||
chMtxUnlock ();
|
chMtxUnlock ();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adc_stop ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rng_rb the_ring_buffer;
|
static struct rng_rb the_ring_buffer;
|
||||||
static WORKING_AREA(wa_rng, 128);
|
static WORKING_AREA(wa_rng, 256);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize NeuG.
|
* @brief Initialize NeuG.
|
||||||
@@ -370,9 +468,21 @@ static WORKING_AREA(wa_rng, 128);
|
|||||||
void
|
void
|
||||||
neug_init (uint32_t *buf, uint8_t size)
|
neug_init (uint32_t *buf, uint8_t size)
|
||||||
{
|
{
|
||||||
|
const uint32_t *u = (const uint32_t *)unique_device_id ();
|
||||||
struct rng_rb *rb = &the_ring_buffer;
|
struct rng_rb *rb = &the_ring_buffer;
|
||||||
|
int i;
|
||||||
|
|
||||||
tmt_init (0);
|
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||||
|
CRC->CR = CRC_CR_RESET;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This initialization ensures that it generates different sequence
|
||||||
|
* even if all physical conditions are same.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
CRC->DR = *u++;
|
||||||
|
|
||||||
|
neug_mode = NEUG_MODE_CONDITIONED;
|
||||||
rb_init (rb, buf, size);
|
rb_init (rb, buf, size);
|
||||||
chThdCreateStatic (wa_rng, sizeof (wa_rng), NORMALPRIO, rng, rb);
|
chThdCreateStatic (wa_rng, sizeof (wa_rng), NORMALPRIO, rng, rb);
|
||||||
}
|
}
|
||||||
@@ -392,17 +502,6 @@ neug_flush (void)
|
|||||||
chMtxUnlock ();
|
chMtxUnlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @breif Set seed to PRNG
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
neug_prng_reseed (void)
|
|
||||||
{
|
|
||||||
uint32_t seed = ep_output ();
|
|
||||||
|
|
||||||
tmt_init (seed);
|
|
||||||
neug_flush ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wakes up RNG thread to generate random numbers.
|
* @brief Wakes up RNG thread to generate random numbers.
|
||||||
@@ -441,6 +540,45 @@ neug_get (int kick)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
neug_get_nonblock (uint32_t *p)
|
||||||
|
{
|
||||||
|
struct rng_rb *rb = &the_ring_buffer;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
chMtxLock (&rb->m);
|
||||||
|
if (rb->empty)
|
||||||
|
{
|
||||||
|
r = -1;
|
||||||
|
chCondSignal (&rb->space_available);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*p = rb_del (rb);
|
||||||
|
chMtxUnlock ();
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int neug_consume_random (void (*proc) (uint32_t, int))
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
struct rng_rb *rb = &the_ring_buffer;
|
||||||
|
|
||||||
|
chMtxLock (&rb->m);
|
||||||
|
while (!rb->empty)
|
||||||
|
{
|
||||||
|
uint32_t v;
|
||||||
|
|
||||||
|
v = rb_del (rb);
|
||||||
|
proc (v, i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
chCondSignal (&rb->space_available);
|
||||||
|
chMtxUnlock ();
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
neug_wait_full (void)
|
neug_wait_full (void)
|
||||||
{
|
{
|
||||||
@@ -451,3 +589,32 @@ neug_wait_full (void)
|
|||||||
chCondWait (&rb->data_available);
|
chCondWait (&rb->data_available);
|
||||||
chMtxUnlock ();
|
chMtxUnlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
neug_fini (void)
|
||||||
|
{
|
||||||
|
if (rng_thread)
|
||||||
|
{
|
||||||
|
chThdTerminate (rng_thread);
|
||||||
|
neug_get (1);
|
||||||
|
chThdWait (rng_thread);
|
||||||
|
rng_thread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
neug_mode_select (uint8_t mode)
|
||||||
|
{
|
||||||
|
if (neug_mode == mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
neug_wait_full ();
|
||||||
|
|
||||||
|
while (rng_thread->p_state != THD_STATE_WTCOND)
|
||||||
|
chThdSleep (MS2ST (1));
|
||||||
|
|
||||||
|
ep_init (mode);
|
||||||
|
noise_source_cnt_max_reset ();
|
||||||
|
neug_mode = mode;
|
||||||
|
neug_flush ();
|
||||||
|
}
|
||||||
|
|||||||
21
src/neug.h
21
src/neug.h
@@ -1,11 +1,28 @@
|
|||||||
#define NEUG_NO_KICK 0
|
#define NEUG_NO_KICK 0
|
||||||
#define NEUG_KICK_FILLING 1
|
#define NEUG_KICK_FILLING 1
|
||||||
|
|
||||||
#define NEUG_PRE_LOOP 16
|
#define NEUG_PRE_LOOP 32
|
||||||
|
|
||||||
|
#define NEUG_MODE_CONDITIONED 0
|
||||||
|
#define NEUG_MODE_RAW 1
|
||||||
|
#define NEUG_MODE_RAW_DATA 2
|
||||||
|
|
||||||
|
extern uint8_t neug_mode;
|
||||||
|
extern uint16_t neug_err_cnt;
|
||||||
|
extern uint16_t neug_err_cnt_rc;
|
||||||
|
extern uint16_t neug_err_cnt_p64;
|
||||||
|
extern uint16_t neug_err_cnt_p4k;
|
||||||
|
extern uint16_t neug_rc_max;
|
||||||
|
extern uint16_t neug_p64_max;
|
||||||
|
extern uint16_t neug_p4k_max;
|
||||||
|
|
||||||
void neug_init (uint32_t *buf, uint8_t size);
|
void neug_init (uint32_t *buf, uint8_t size);
|
||||||
void neug_prng_reseed (void);
|
|
||||||
uint32_t neug_get (int kick);
|
uint32_t neug_get (int kick);
|
||||||
|
int neug_get_nonblock (uint32_t *p);
|
||||||
void neug_kick_filling (void);
|
void neug_kick_filling (void);
|
||||||
void neug_flush (void);
|
void neug_flush (void);
|
||||||
void neug_wait_full (void);
|
void neug_wait_full (void);
|
||||||
|
void neug_fini (void);
|
||||||
|
void neug_mode_select (uint8_t mode);
|
||||||
|
|
||||||
|
int neug_consume_random (void (*proc) (uint32_t, int));
|
||||||
|
|||||||
@@ -1118,7 +1118,7 @@ GPGthread (void *arg)
|
|||||||
|
|
||||||
gpg_init ();
|
gpg_init ();
|
||||||
|
|
||||||
chEvtClear (ALL_EVENTS);
|
chEvtClearFlags (ALL_EVENTS);
|
||||||
|
|
||||||
while (!chThdShouldTerminate ())
|
while (!chThdShouldTerminate ())
|
||||||
{
|
{
|
||||||
@@ -1216,7 +1216,7 @@ GPGthread (void *arg)
|
|||||||
process_command_apdu ();
|
process_command_apdu ();
|
||||||
led_blink (LED_FINISH_COMMAND);
|
led_blink (LED_FINISH_COMMAND);
|
||||||
done:
|
done:
|
||||||
chEvtSignal (icc_thread, EV_EXEC_FINISHED);
|
chEvtSignalFlags (icc_thread, EV_EXEC_FINISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpg_fini ();
|
gpg_fini ();
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ random_init (void)
|
|||||||
|
|
||||||
for (i = 0; i < NEUG_PRE_LOOP; i++)
|
for (i = 0; i < NEUG_PRE_LOOP; i++)
|
||||||
(void)neug_get (NEUG_KICK_FILLING);
|
(void)neug_get (NEUG_KICK_FILLING);
|
||||||
|
|
||||||
neug_prng_reseed ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ static void notify_tx (struct ep_in *epi)
|
|||||||
struct ccid *c = (struct ccid *)epi->priv;
|
struct ccid *c = (struct ccid *)epi->priv;
|
||||||
|
|
||||||
/* The sequence of Bulk-IN transactions finished */
|
/* The sequence of Bulk-IN transactions finished */
|
||||||
chEvtSignalI (c->icc_thread, EV_TX_FINISHED);
|
chEvtSignalFlagsI (c->icc_thread, EV_TX_FINISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void no_buf (struct ep_in *epi, size_t len)
|
static void no_buf (struct ep_in *epi, size_t len)
|
||||||
@@ -405,7 +405,7 @@ static void notify_icc (struct ep_out *epo)
|
|||||||
struct ccid *c = (struct ccid *)epo->priv;
|
struct ccid *c = (struct ccid *)epo->priv;
|
||||||
|
|
||||||
c->err = epo->err;
|
c->err = epo->err;
|
||||||
chEvtSignalI (c->icc_thread, EV_RX_DATA_READY);
|
chEvtSignalFlagsI (c->icc_thread, EV_RX_DATA_READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int end_icc_rx (struct ep_out *epo, size_t orig_len)
|
static int end_icc_rx (struct ep_out *epo, size_t orig_len)
|
||||||
@@ -815,7 +815,7 @@ icc_power_off (struct ccid *c)
|
|||||||
if (c->application)
|
if (c->application)
|
||||||
{
|
{
|
||||||
chThdTerminate (c->application);
|
chThdTerminate (c->application);
|
||||||
chEvtSignal (c->application, EV_NOP);
|
chEvtSignalFlags (c->application, EV_NOP);
|
||||||
chThdWait (c->application);
|
chThdWait (c->application);
|
||||||
c->application = NULL;
|
c->application = NULL;
|
||||||
}
|
}
|
||||||
@@ -1140,7 +1140,7 @@ icc_handle_data (struct ccid *c)
|
|||||||
c->a->res_apdu_data_len = 0;
|
c->a->res_apdu_data_len = 0;
|
||||||
c->a->res_apdu_data = &icc_buffer[5];
|
c->a->res_apdu_data = &icc_buffer[5];
|
||||||
|
|
||||||
chEvtSignal (c->application, EV_CMD_AVAILABLE);
|
chEvtSignalFlags (c->application, EV_CMD_AVAILABLE);
|
||||||
next_state = ICC_STATE_EXECUTE;
|
next_state = ICC_STATE_EXECUTE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1199,7 +1199,7 @@ icc_handle_data (struct ccid *c)
|
|||||||
c->a->res_apdu_data_len = 0;
|
c->a->res_apdu_data_len = 0;
|
||||||
c->a->res_apdu_data = &c->p[5];
|
c->a->res_apdu_data = &c->p[5];
|
||||||
|
|
||||||
chEvtSignal (c->application, EV_VERIFY_CMD_AVAILABLE);
|
chEvtSignalFlags (c->application, EV_VERIFY_CMD_AVAILABLE);
|
||||||
next_state = ICC_STATE_EXECUTE;
|
next_state = ICC_STATE_EXECUTE;
|
||||||
}
|
}
|
||||||
else if (c->p[10-10] == 0x01) /* PIN Modification */
|
else if (c->p[10-10] == 0x01) /* PIN Modification */
|
||||||
@@ -1233,7 +1233,7 @@ icc_handle_data (struct ccid *c)
|
|||||||
c->a->res_apdu_data_len = 0;
|
c->a->res_apdu_data_len = 0;
|
||||||
c->a->res_apdu_data = &icc_buffer[5];
|
c->a->res_apdu_data = &icc_buffer[5];
|
||||||
|
|
||||||
chEvtSignal (c->application, EV_MODIFY_CMD_AVAILABLE);
|
chEvtSignalFlags (c->application, EV_MODIFY_CMD_AVAILABLE);
|
||||||
next_state = ICC_STATE_EXECUTE;
|
next_state = ICC_STATE_EXECUTE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1307,7 +1307,7 @@ USBthread (void *arg)
|
|||||||
ccid_init (c, epi, epo, a, chThdSelf ());
|
ccid_init (c, epi, epo, a, chThdSelf ());
|
||||||
apdu_init (a);
|
apdu_init (a);
|
||||||
|
|
||||||
chEvtClear (ALL_EVENTS);
|
chEvtClearFlags (ALL_EVENTS);
|
||||||
|
|
||||||
icc_prepare_receive (c);
|
icc_prepare_receive (c);
|
||||||
while (1)
|
while (1)
|
||||||
|
|||||||
Reference in New Issue
Block a user