port to chopstx
This commit is contained in:
@@ -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
|
||||
@@ -22,15 +22,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#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)
|
||||
@@ -82,6 +84,7 @@
|
||||
#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_MINC \
|
||||
| STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE)
|
||||
|
||||
#define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \
|
||||
@@ -108,8 +111,10 @@
|
||||
*/
|
||||
void adc_init (void)
|
||||
{
|
||||
chSysLock ();
|
||||
rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||
RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
||||
RCC->APB2RSTR = (RCC_APB2RSTR_ADC1RST | RCC_APB2RSTR_ADC2RST);
|
||||
RCC->APB2RSTR = 0;
|
||||
|
||||
ADC1->CR1 = 0;
|
||||
ADC1->CR2 = ADC_CR2_ADON;
|
||||
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
|
||||
@@ -129,21 +134,48 @@ 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);
|
||||
}
|
||||
|
||||
static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags);
|
||||
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 3
|
||||
|
||||
static void adc_lld_serve_rx_interrupt (uint32_t flags);
|
||||
|
||||
#define INTR_REQ_DMA1_Channel1 11
|
||||
static void *
|
||||
adc_intr_thread (void *arg)
|
||||
{
|
||||
chopstx_intr_t interrupt;
|
||||
|
||||
(void)arg;
|
||||
chopstx_claim_irq (&interrupt, INTR_REQ_DMA1_Channel1);
|
||||
|
||||
while (1)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
chopstx_intr_wait (&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 chopstx_t adc_thd;
|
||||
|
||||
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);
|
||||
/* Use DMA channel 1. */
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
|
||||
DMA1->IFCR = 0xffffffff;
|
||||
|
||||
chSysLock ();
|
||||
|
||||
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,12 +201,14 @@ void adc_start (void)
|
||||
ADC1->CR2 = 0;
|
||||
#endif
|
||||
|
||||
chSysUnlock ();
|
||||
adc_thd = chopstx_create (PRIO_ADC, __stackaddr_adc, __stacksize_adc,
|
||||
adc_intr_thread, NULL);
|
||||
}
|
||||
|
||||
static int adc_mode;
|
||||
static uint32_t *adc_ptr;
|
||||
static int adc_size;
|
||||
static uint32_t adc_buf[64];
|
||||
|
||||
static void adc_start_conversion_internal (void)
|
||||
{
|
||||
@@ -202,17 +236,19 @@ 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->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
|
||||
DMA1_Channel1->CMAR = (uint32_t)p; /* SetMemory0 */
|
||||
DMA1_Channel1->CNDTR = (uint32_t)size / 4; /* counter */
|
||||
DMA1_Channel1->CCR = 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->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
|
||||
DMA1_Channel1->CMAR = (uint32_t)adc_buf; /* SetMemory0 */
|
||||
DMA1_Channel1->CNDTR = size; /* counter */
|
||||
DMA1_Channel1->CCR = NEUG_DMA_MODE_CRC32; /*mode*/
|
||||
DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
|
||||
}
|
||||
|
||||
adc_start_conversion_internal ();
|
||||
@@ -221,7 +257,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 +276,16 @@ void adc_stop (void)
|
||||
ADC2->CR1 = 0;
|
||||
ADC2->CR2 = 0;
|
||||
|
||||
dmaStreamRelease (NEUG_DMA_CHANNEL);
|
||||
rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
|
||||
RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
||||
|
||||
chopstx_cancel (adc_thd);
|
||||
chopstx_join (adc_thd, NULL);
|
||||
}
|
||||
|
||||
|
||||
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. */
|
||||
@@ -262,27 +300,23 @@ static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags)
|
||||
|
||||
if (adc_mode != ADC_SAMPLE_MODE)
|
||||
{
|
||||
adc_size -= 4;
|
||||
*adc_ptr++ = CRC->DR;
|
||||
int i;
|
||||
|
||||
if (adc_size > 0)
|
||||
for (i = 0; i < adc_size;)
|
||||
{
|
||||
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 ();
|
||||
CRC->DR = adc_buf[i++];
|
||||
CRC->DR = adc_buf[i++];
|
||||
CRC->DR = adc_buf[i++];
|
||||
CRC->DR = adc_buf[i++];
|
||||
*adc_ptr++ = CRC->DR;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user