Skip to content

Commit b2d34cb

Browse files
committed
Fixed DMA bugs
1 parent 7ec2336 commit b2d34cb

File tree

7 files changed

+115
-76
lines changed

7 files changed

+115
-76
lines changed

examples/adc_dma/adc_dma_main.c

+7-27
Original file line numberDiff line numberDiff line change
@@ -32,47 +32,27 @@ void OnReset(void) {
3232
RccInitForAdc();
3333

3434
// TODO: At the moment, only port A0 seems to be working.
35-
AdcInit(GPIOA, 0);
35+
AdcInit(GPIOA, 0, 0);
3636
DmaInit();
3737
AdcDmaOn(g_dma_buffer, DMA_BUFFER_SIZE);
38-
AdcOn();
38+
//AdcOn();
3939
while (1) {
4040
const int32_t adc_log_length = 256;
4141
char adc_log[adc_log_length];
4242
StrCpy(adc_log, adc_log_length, "DMA: ");
43-
StrCatInt32(adc_log, adc_log_length, g_error_count);
44-
StrCatStr(adc_log, adc_log_length, " errors,");
45-
StrCatInt32(adc_log, adc_log_length, g_half_count);
46-
StrCatStr(adc_log, adc_log_length, " half,");
47-
StrCatInt32(adc_log, adc_log_length, g_complete_count);
43+
StrCatInt32(adc_log, adc_log_length, g_error_count, 10);
44+
StrCatStr(adc_log, adc_log_length, " errors, ");
45+
StrCatInt32(adc_log, adc_log_length, g_half_count, 10);
46+
StrCatStr(adc_log, adc_log_length, " half, ");
47+
StrCatInt32(adc_log, adc_log_length, g_complete_count, 10);
4848
StrCatStr(adc_log, adc_log_length, " complete\n");
4949
DebugLog(adc_log);
5050
}
5151
AdcOff();
5252
}
5353

54-
// If you have a function named OnAdcInterrupt() in your program, this will be
55-
// called once an ADC value is available, if you've set up the system as shown
56-
// in the OnReset() function above.
57-
void OnAdcInterrupt() {
58-
// We're expecting an EOC signal to be marked in the status register.
59-
if (!(ADC1->SR & ADC_SR_EOC)) {
60-
DebugLog("ADC Interrupt called outside of an End Of Conversion event.\n");
61-
return;
62-
}
63-
// Read the value from the data register and output it to the debug log.
64-
const int32_t adc_value = ADC1->DR;
65-
const int32_t adc_log_length = 256;
66-
char adc_log[adc_log_length];
67-
StrCpy(adc_log, adc_log_length, "ADC: ");
68-
StrCatInt32(adc_log, adc_log_length, adc_value);
69-
StrCatStr(adc_log, adc_log_length, "\n");
70-
DebugLog(adc_log);
71-
}
72-
7354
void OnDma1Channel1Interrupt() {
7455
if (DMA1->ISR & DMA_ISR_TEIF1) {
75-
//DebugLog("DMA Error\n");
7656
++g_error_count;
7757
DMA1->IFCR |= DMA_IFCR_CTEIF1;
7858
return;

examples/adc_interrupt/adc_interrupt_main.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void OnReset(void) {
2323
RccInitForAdc();
2424

2525
// TODO: At the moment, only port A0 seems to be working.
26-
AdcInit(GPIOA, 0);
26+
AdcInit(GPIOA, 0, 1);
2727
while (1) {
2828
// Calls to AdcOn() cause the interrupt to be called back once
2929
// a value is available.
@@ -46,7 +46,7 @@ void OnAdcInterrupt() {
4646
const int32_t adc_log_length = 256;
4747
char adc_log[adc_log_length];
4848
StrCpy(adc_log, adc_log_length, "ADC: ");
49-
StrCatInt32(adc_log, adc_log_length, adc_value);
49+
StrCatInt32(adc_log, adc_log_length, adc_value, 10);
5050
StrCatStr(adc_log, adc_log_length, "\n");
5151
DebugLog(adc_log);
5252
}

include/adc.h

+41-18
Original file line numberDiff line numberDiff line change
@@ -40,38 +40,61 @@ static inline void EnableNvic(int irq) {
4040

4141
// Sets up the clock control system for ADC access.
4242
static inline void RccInitForAdc(void) {
43-
// RCC->CFGR = PLL_HSE | PLL_9 | SYS_HSI | APB1_DIV2;
44-
RCC->CFGR = RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL_9 | RCC_CFGR_SW_HSI | RCC_CFGR_PPRE1_DIV_2;
45-
RCC->CR = RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_PLLON;
43+
RCC->CFGR =
44+
RCC_CFGR_PLLSRC_HSE |
45+
RCC_CFGR_PLLMUL_9 |
46+
RCC_CFGR_SW_HSI |
47+
RCC_CFGR_PPRE1_DIV_2;
48+
RCC->CR =
49+
RCC_CR_HSION |
50+
RCC_CR_HSEON |
51+
RCC_CR_PLLON;
4652
while (!(RCC->CR & RCC_CR_PLLRDY)) {
4753
}
4854

4955
// Configure flash to work with the new speed, with prefetching enabled
5056
// and a two-clock wait for access.
5157
*FLASH_ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_2;
5258

53-
//RCC->CFGR = PLL_HSE | PLL_9 | SYS_PLL | ADC_DIV6 | APB1_DIV2;
54-
RCC->CFGR = RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL_9 | RCC_CFGR_SW_PLL | RCC_CFGR_ADCPRE_DIV_6 | RCC_CFGR_HPRE_DIV_2;
55-
56-
RCC->APB2ENR |= RCC_GPIOA_ENABLE;
57-
RCC->APB2ENR |= RCC_GPIOB_ENABLE;
58-
RCC->APB2ENR |= RCC_GPIOC_ENABLE;
59-
RCC->APB2ENR |= RCC_ADC1_ENABLE;
60-
RCC->APB2ENR |= RCC_ADC2_ENABLE;
61-
RCC->APB2ENR |= RCC_UART1_ENABLE;
62-
RCC->APB1ENR |= RCC_TIMER2_ENABLE;
59+
RCC->CFGR =
60+
RCC_CFGR_PLLSRC_HSE |
61+
RCC_CFGR_PLLMUL_9 |
62+
RCC_CFGR_SW_PLL |
63+
RCC_CFGR_ADCPRE_DIV_8 |
64+
RCC_CFGR_HPRE_DIV_2;
65+
66+
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
67+
68+
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
69+
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
70+
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
71+
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
72+
RCC->APB2ENR |= RCC_APB2ENR_ADC2EN;
73+
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
6374
}
6475

6576
// This needs to be called before the ADC can be accessed.
66-
static inline void AdcInit(GPIO_t* gpio, int port) {
67-
EnableNvic(ADC_IRQ_NUMBER);
77+
static inline void AdcInit(GPIO_t* gpio, int port, int do_interrupt) {
78+
if (do_interrupt) {
79+
EnableNvic(ADC_IRQ_NUMBER);
80+
}
81+
if (do_interrupt) {
82+
// Trigger an interrupt at the end of a conversion.
83+
ADC1->CR1 |= ADC_CR1_EOCIE;
84+
} else {
85+
ADC1->CR2 |= ADC_CR2_CONT;
86+
ADC1->CR2 |= ADC_CR2_DMA;
87+
ADC1->CR2 |= ADC_CR2_SWSTART | ADC_CR2_EXTTRIG;
88+
}
89+
6890
ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_TSVREFE;
6991
BusyWaitMicroseconds(30 * 1000);
7092
ADC1->CR2 |= ADC_CR2_CAL;
7193
while (ADC1->CR2 & ADC_CR2_CAL) {
7294
}
73-
// Trigger an interrupt at the end of a conversion.
74-
//ADC1->CR1 |= ADC_CR1_EOCIE;
95+
96+
ADC1->CR2 |= ADC_CR2_ADON;
97+
7598
SetGpioMode(gpio, port, GPIO_MODE_INPUT_ANALOG);
7699
}
77100

@@ -91,11 +114,11 @@ static inline void AdcDmaOn(void* dma_buffer, int dma_buffer_count) {
91114
DMA_CCR_TEIE |
92115
DMA_CCR_DIR_FROM_PERIPHERAL |
93116
DMA_CCR_CIRC |
117+
DMA_CCR_MINC |
94118
DMA_CCR_PSIZE_16 |
95119
DMA_CCR_MSIZE_16 |
96120
DMA_CCR_PL_LOW;
97121
DMA1->CCR1 |= DMA_CCR_EN;
98-
ADC1->CR2 |= ADC_CR2_DMA;
99122
}
100123

101124
static inline void AdcOn(void) {

include/debug_log.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,21 @@ static inline void DebugLogInt32(int32_t i) {
3737
char number_string[kFastToBufferSize];
3838
number_string[0] = 'b';
3939
number_string[1] = 0;
40-
FastInt32ToBufferLeft(i, number_string);
40+
FastInt32ToBufferLeft(i, number_string, 10);
4141
DebugLog(number_string);
4242
}
4343

4444
// Writes out an unsigned 32-bit number to the debug console.
4545
static inline void DebugLogUInt32(uint32_t i) {
4646
char number_string[kFastToBufferSize];
47-
FastUInt32ToBufferLeft(i, number_string);
47+
FastUInt32ToBufferLeft(i, number_string, 10);
48+
DebugLog(number_string);
49+
}
50+
51+
// Writes out an unsigned 32-bit number to the debug console as hex.
52+
static inline void DebugLogHex(uint32_t i) {
53+
char number_string[kFastToBufferSize];
54+
FastUInt32ToBufferLeft(i, number_string, 16);
4855
DebugLog(number_string);
4956
}
5057

include/led.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ limitations under the License.
2323
// This needs to be called before the LED can be accessed.
2424
static inline void LedInit() {
2525
// Enable GPIOC.
26-
RCC->APB2ENR |= RCC_GPIOC_ENABLE;
26+
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
2727

2828
// Set up speed and configuration.
2929
const int shift = (LED_PORT - 8) * 4;

include/stm32_specifics.h

+45-16
Original file line numberDiff line numberDiff line change
@@ -145,22 +145,6 @@ typedef struct {
145145
#define DMA1 ((DMA_t*)DMA1_BASE)
146146
#define DMA2 ((DMA_t*)DMA2_BASE)
147147

148-
// Register access values.
149-
#define RCC_GPIOA_ENABLE (0x4)
150-
#define RCC_GPIOB_ENABLE (0x8)
151-
#define RCC_GPIOC_ENABLE (0x10)
152-
#define RCC_ADC1_ENABLE (0x200)
153-
#define RCC_ADC2_ENABLE (0x400)
154-
#define RCC_TIMER1_ENABLE (0x800)
155-
#define RCC_UART1_ENABLE (0x4000)
156-
157-
#define RCC_TIMER2_ENABLE (0x1)
158-
#define RCC_TIMER3_ENABLE (0x2)
159-
#define RCC_TIMER4_ENABLE (0x4)
160-
#define RCC_UART2_ENABLE (0x20000)
161-
#define RCC_UART3_ENABLE (0x40000)
162-
#define RCC_USB_ENABLE (0x800000)
163-
164148
// GPIO settings.
165149
#define GPIO_MODE_OUT_2 (0x2)
166150
#define GPIO_CONF_GP_UD (0x0)
@@ -282,6 +266,51 @@ typedef struct {
282266
#define RCC_AHBENR_FSMCEN (1 << 8)
283267
#define RCC_AHBENR_SDIOEN (1 << 10)
284268

269+
// Reset and Clock Control APB1 Peripheral Clock Enable Register flag values.
270+
#define RCC_APB1ENR_TIM2EN (1 << 0)
271+
#define RCC_APB1ENR_TIM3EN (1 << 1)
272+
#define RCC_APB1ENR_TIM4EN (1 << 2)
273+
#define RCC_APB1ENR_TIM5EN (1 << 3)
274+
#define RCC_APB1ENR_TIM6EN (1 << 4)
275+
#define RCC_APB1ENR_TIM7EN (1 << 5)
276+
#define RCC_APB1ENR_TIM12EN (1 << 6)
277+
#define RCC_APB1ENR_TIM13EN (1 << 7)
278+
#define RCC_APB1ENR_TIM14EN (1 << 8)
279+
#define RCC_APB1ENR_WWDGEN (1 << 11)
280+
#define RCC_APB1ENR_SPI2EN (1 << 14)
281+
#define RCC_APB1ENR_SPI3EN (1 << 15)
282+
#define RCC_APB1ENR_USART2EN (1 << 17)
283+
#define RCC_APB1ENR_USART3EN (1 << 18)
284+
#define RCC_APB1ENR_USART4EN (1 << 19)
285+
#define RCC_APB1ENR_USART5EN (1 << 20)
286+
#define RCC_APB1ENR_I2C1EN (1 << 21)
287+
#define RCC_APB1ENR_I2C2EN (1 << 22)
288+
#define RCC_APB1ENR_USBEN (1 << 23)
289+
#define RCC_APB1ENR_CANEN (1 << 25)
290+
#define RCC_APB1ENR_BKPEN (1 << 27)
291+
#define RCC_APB1ENR_PWREN (1 << 28)
292+
#define RCC_APB1ENR_DACEN (1 << 29)
293+
294+
// Reset and Clock Control APB2 Peripheral Clock Enable Register flag values.
295+
#define RCC_APB2ENR_AFIOEN (1 << 0)
296+
#define RCC_APB2ENR_IOPAEN (1 << 2)
297+
#define RCC_APB2ENR_IOPBEN (1 << 3)
298+
#define RCC_APB2ENR_IOPCEN (1 << 4)
299+
#define RCC_APB2ENR_IOPDEN (1 << 5)
300+
#define RCC_APB2ENR_IOPEEN (1 << 6)
301+
#define RCC_APB2ENR_IOPFEN (1 << 7)
302+
#define RCC_APB2ENR_IOPGEN (1 << 8)
303+
#define RCC_APB2ENR_ADC1EN (1 << 9)
304+
#define RCC_APB2ENR_ADC2EN (1 << 10)
305+
#define RCC_APB2ENR_TIM1EN (1 << 11)
306+
#define RCC_APB2ENR_SPI1EN (1 << 12)
307+
#define RCC_APB2ENR_TIM8EN (1 << 13)
308+
#define RCC_APB2ENR_USART1EN (1 << 14)
309+
#define RCC_APB2ENR_ADC3EN (1 << 15)
310+
#define RCC_APB2ENR_TIM91EN (1 << 19)
311+
#define RCC_APB2ENR_TIM10EN (1 << 20)
312+
#define RCC_APB2ENR_TIM11EN (1 << 21)
313+
285314
// DMA Configuration Register flag values.
286315
#define DMA_CCR_EN (1 << 0)
287316
#define DMA_CCR_TCIE (1 << 1)

include/strings.h

+10-10
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,28 @@ static inline char* ReverseStringInPlace(char* start, char* end) {
3030
}
3131

3232
// Populates the provided buffer with an ASCII representation of the number.
33-
static inline char* FastUInt32ToBufferLeft(uint32_t i, char* buffer) {
33+
static inline char* FastUInt32ToBufferLeft(uint32_t i, char* buffer, int base) {
3434
char* start = buffer;
3535
do {
36-
*buffer++ = ((i % 10) + '0');
37-
i /= 10;
36+
*buffer++ = ((i % base) + '0');
37+
i /= base;
3838
} while (i > 0);
3939
*buffer = 0;
4040
ReverseStringInPlace(start, buffer);
4141
return buffer;
4242
}
4343

4444
// All input buffers to the number conversion functions must be this long.
45-
static const int kFastToBufferSize = 32;
45+
static const int kFastToBufferSize = 48;
4646

4747
// Populates the provided buffer with an ASCII representation of the number.
48-
static inline char* FastInt32ToBufferLeft(int32_t i, char* buffer) {
48+
static inline char* FastInt32ToBufferLeft(int32_t i, char* buffer, int base) {
4949
uint32_t u = i;
5050
if (i < 0) {
5151
*buffer++ = '-';
5252
u = -u;
5353
}
54-
return FastUInt32ToBufferLeft(u, buffer);
54+
return FastUInt32ToBufferLeft(u, buffer, base);
5555
}
5656

5757
// Appends a string to a string, in-place. You need to pass in the maximum string
@@ -72,16 +72,16 @@ static inline char* StrCatStr(char* main, int main_max_length, char* to_append)
7272
}
7373

7474
// Converts a number to a string and appends it to another.
75-
static inline char* StrCatInt32(char* main, int main_max_length, int32_t number) {
75+
static inline char* StrCatInt32(char* main, int main_max_length, int32_t number, int base) {
7676
char number_string[kFastToBufferSize];
77-
FastInt32ToBufferLeft(number, number_string);
77+
FastInt32ToBufferLeft(number, number_string, base);
7878
StrCatStr(main, main_max_length, number_string);
7979
}
8080

8181
// Converts a number to a string and appends it to another.
82-
static inline char* StrCatUInt32(char* main, int main_max_length, uint32_t number) {
82+
static inline char* StrCatUInt32(char* main, int main_max_length, uint32_t number, int base) {
8383
char number_string[kFastToBufferSize];
84-
FastUInt32ToBufferLeft(number, number_string);
84+
FastUInt32ToBufferLeft(number, number_string, base);
8585
StrCatStr(main, main_max_length, number_string);
8686
}
8787

0 commit comments

Comments
 (0)