STM32F103, непонятки с DMA
29.10.2014, 22:37
|
|
|
Гуру портала
Регистрация: 20.11.2004
Сообщений: 9,979
Сказал спасибо: 928
Сказали Спасибо 2,261 раз(а) в 1,557 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
Проверил одиночный выхлоп по твоему примеру - все в норме .
|
Код:
|
void _1wire_init (void)
{
uint16_t tim2_buff[8] = {10,20,30,40,50,60,70,80};
RCC-›AHBENR |=RCC_AHBENR_DMA1EN;
DMA1_Channel7 -›CPAR = (uint32_t)& (TIM2-›CCR4);
DMA1_Channel7 -›CMAR = (uint32_t)tim2_buff;
DMA1_Channel7 -›CNDTR =9;
DMA1_Channel7 -›CCR =
DMA_CCR7_MSIZE_0 |
DMA_CCR7_PSIZE_0 |
DMA_CCR7_MINC |
DMA_CCR7_DIR |
DMA_CCR7_EN ;
RCC-›APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC-›APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIOA-›CRL |= GPIO_CRL_MODE3;
GPIOA-›CRL &=~GPIO_CRL_CNF3;
GPIOA-›CRL |=GPIO_CRL_CNF3_1;
TIM2-›CR1 |= TIM_CR1_ARPE ;
TIM2-›PSC =72-1;
TIM2-›ARR= 87-1;
TIM2-›CCMR2 |=
TIM_CCMR2_OC4M_2 |
TIM_CCMR2_OC4M_1 |
TIM_CCMR2_OC4PE |
TIM_CCMR2_OC4FE
;
TIM2-›CCER |=
TIM_CCER_CC4E
;
TIM2-›DIER = TIM_DIER_CC4DE;
TIM2-›CR1 = TIM_CR1_CEN;
} |
__________________
Осторожно , злой кот
Последний раз редактировалось dosikus; 29.10.2014 в 22:52.
|
|
|
|
29.10.2014, 22:55
|
|
|
Заблокирован
Регистрация: 22.04.2014
Сообщений: 0
Сказал спасибо: 15
Сказали Спасибо 366 раз(а) в 284 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
Сообщение от eddy
|
|
Но аппаратный 1-wire очень хочется сделать.
|
Попробуй сначала на голом таймере без ДМА. Там одного прерывания достаточно. На СТМ8 потери на прерывания не превышают 5-7%.
|
|
|
|
30.10.2014, 10:43
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
dosikus, а почему "DMA1_Channel7 -›CNDTR =9;" ?
И почему DMA_CCR7_PSIZE_0?
И полярность инвертированная получилась.
Но таки все равно странно... У меня не работает.
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
|
|
|
|
30.10.2014, 11:07
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
Чертовщина какая-то! ЗАРАБОТАЛО!!!
|
Код:
|
uint16_t tim2_buff[8] = {10,20,30,40,50,60,70,80};
uint16_t tim2_inbuff[9];
void init_dmatimer(){ // tim2_ch4 - PA3, no remap
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO3);
rcc_periph_clock_enable(RCC_TIM2);
//nvic_enable_irq(NVIC_TIM2_IRQ);
timer_reset(TIM2);
// timers have frequency of 1MHz -- 1us for one step
// 36MHz of APB1
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
// 72MHz div 72 = 1MHz
timer_set_prescaler(TIM2, 71); // prescaler is (div - 1)
timer_continuous_mode(TIM2); // automatically reload
timer_enable_preload(TIM2); // force changing period
timer_set_period(TIM2, 86); // period is 87us
timer_enable_update_event(TIM2);
timer_set_oc_mode(TIM2, TIM_OC4, TIM_OCM_PWM1); // edge-aligned mode
timer_enable_oc_preload(TIM2, TIM_OC4);
timer_enable_oc_output(TIM2, TIM_OC4);
timer_enable_irq(TIM2, TIM_DIER_UDE | TIM_DIER_CC4DE | TIM_DIER_CC3DE);
// TIM2_CH4 - DMA1, channel 7
rcc_periph_clock_enable(RCC_DMA1);
dma_channel_reset(DMA1, DMA_CHANNEL7);
dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t) &(TIM_CCR4(TIM2)));
dma_set_read_from_memory(DMA1, DMA_CHANNEL7);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_16BIT);
dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL7);
dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL7);
dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t)tim2_buff);
nvic_enable_irq(NVIC_DMA1_CHANNEL7_IRQ); // enable dma1_channel7_isr
// capture: TIM2_CH3
timer_ic_set_input(TIM2, TIM_IC3, TIM_IC_IN_TI4);
timer_set_oc_polarity_high(TIM2, TIM_OC3);
timer_ic_enable(TIM2, TIM_IC3);
timer_enable_oc_output(TIM2, TIM_OC3);
// configure DMA1 Channel1 (ADC1)
dma_channel_reset(DMA1, DMA_CHANNEL1);
dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(TIM_CCR3(TIM2)));
dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) tim2_inbuff);
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8);
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL1);
dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL1);
dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);
}
void run_dmatimer(){
int i;
DMA1_IFCR = DMA_ISR_TEIF7|DMA_ISR_HTIF7|DMA_ISR_TCIF7|DMA_ISR_ GIF7 |
DMA_ISR_TEIF1|DMA_ISR_HTIF1|DMA_ISR_TCIF1|DMA_ISR_ GIF1; // clear flags
dma_set_number_of_data(DMA1, DMA_CHANNEL7, 8);
timer_set_dma_on_compare_event(TIM2);
timer_set_oc_polarity_low(TIM2, TIM_OC4);
timer_enable_oc_output(TIM2, TIM_OC4);
dma_enable_channel(DMA1, DMA_CHANNEL7);
timer_enable_counter(TIM2);
for(i = 0; i ‹ 9; i++) tim2_inbuff[i] = 0;
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 9);
dma_enable_channel(DMA1, DMA_CHANNEL1);
}
void dma1_channel7_isr(){
if(DMA1_ISR & DMA_ISR_TCIF7) {
DMA1_IFCR = DMA_IFCR_CTCIF7;
dma_disable_channel(DMA1, DMA_CHANNEL7);
}else if(DMA1_ISR & DMA_ISR_TEIF7){
DMA1_IFCR = DMA_IFCR_CTEIF7;
MSG("out transfer error\n");
}
}
void dma1_channel1_isr(){
int i;
if(DMA1_ISR & DMA_ISR_TCIF1) {
DMA1_IFCR = DMA_IFCR_CTCIF1;
dma_disable_channel(DMA1, DMA_CHANNEL1);
timer_disable_oc_output(TIM2, TIM_OC4);
timer_set_oc_polarity_high(TIM2, TIM_OC4);
timer_disable_counter(TIM2);
for(i = 1; i ‹ 9; i++){
print_int(tim2_inbuff[i], lastsendfun);
MSG(" ");
}
MSG("\n");
}else if(DMA1_ISR & DMA_ISR_TEIF1){
DMA1_IFCR = DMA_IFCR_CTEIF1;
MSG("in transfer error\n");
}
} |
Осталось только понять, какого хрена выход не устанавливается в единицу (timer_set_oc_polarity_high(TIM2, TIM_OC4) не отрабатывает почему-то)
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
|
|
|
|
30.10.2014, 11:12
|
|
|
Гуру портала
Регистрация: 20.11.2004
Сообщений: 9,979
Сказал спасибо: 928
Сказали Спасибо 2,261 раз(а) в 1,557 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
eddy, А ХЗ  )))))))) Поздно уже было .
Правильно конечно 8. А с 9 грузилось нечто в CCR4 большее ARR и ШИМ затыкался 
А DMA_CCR7_PSIZE_0, у меня массив uint16_t .
Полярность - лень было пуллапы лепить - у меня пашпул, отсюда иверсия.
Но это все не суть ...
__________________
Осторожно , злой кот
|
|
|
|
30.10.2014, 12:16
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
Все, заработало! Всем спасибо.
Желающие посмотреть результат могут заглядывать периодически сюда или сюда.
Пока что 1-wire не завел, но как только, так сразу сделаю коммит.
|
Код:
|
uint16_t tim2_buff[8] = {10,20,30,40,50,60,70,80};
uint16_t tim2_inbuff[8];
void init_dmatimer(){ // tim2_ch4 - PA3, no remap
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO3);
rcc_periph_clock_enable(RCC_TIM2);
timer_reset(TIM2);
// timers have frequency of 1MHz -- 1us for one step
// 36MHz of APB1
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
// 72MHz div 72 = 1MHz
timer_set_prescaler(TIM2, 71); // prescaler is (div - 1)
timer_continuous_mode(TIM2); // automatically reload
timer_enable_preload(TIM2); // force changing period
timer_set_period(TIM2, 86); // period is 87us
timer_enable_update_event(TIM2);
timer_set_oc_mode(TIM2, TIM_OC4, TIM_OCM_PWM1); // edge-aligned mode
timer_enable_oc_preload(TIM2, TIM_OC4);
timer_enable_oc_output(TIM2, TIM_OC4);
timer_enable_irq(TIM2, TIM_DIER_UDE | TIM_DIER_CC4DE | TIM_DIER_CC3DE);
timer_set_oc_polarity_low(TIM2, TIM_OC4);
// TIM2_CH4 - DMA1, channel 7
rcc_periph_clock_enable(RCC_DMA1);
dma_channel_reset(DMA1, DMA_CHANNEL7);
dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t) &(TIM_CCR4(TIM2)));
dma_set_read_from_memory(DMA1, DMA_CHANNEL7);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_16BIT);
dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL7);
dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL7);
dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t)tim2_buff);
nvic_enable_irq(NVIC_DMA1_CHANNEL7_IRQ); // enable dma1_channel7_isr
// capture: TIM2_CH3
timer_ic_set_input(TIM2, TIM_IC3, TIM_IC_IN_TI4);
timer_set_oc_polarity_high(TIM2, TIM_OC3);
timer_ic_enable(TIM2, TIM_IC3);
timer_enable_oc_output(TIM2, TIM_OC3);
// configure DMA1 Channel1 (ADC1)
dma_channel_reset(DMA1, DMA_CHANNEL1);
dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(TIM_CCR3(TIM2)));
dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) tim2_inbuff);
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8);
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL1);
dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL1);
dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);
}
void run_dmatimer(){
int i;
DMA1_IFCR = DMA_ISR_TEIF7|DMA_ISR_HTIF7|DMA_ISR_TCIF7|DMA_ISR_ GIF7 |
DMA_ISR_TEIF1|DMA_ISR_HTIF1|DMA_ISR_TCIF1|DMA_ISR_ GIF1; // clear flags
dma_set_number_of_data(DMA1, DMA_CHANNEL7, 8);
timer_set_dma_on_compare_event(TIM2);
timer_enable_oc_output(TIM2, TIM_OC4);
dma_enable_channel(DMA1, DMA_CHANNEL7);
timer_enable_counter(TIM2);
for(i = 0; i ‹ 8; i++) tim2_inbuff[i] = 0;
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8);
dma_enable_channel(DMA1, DMA_CHANNEL1);
}
void dma1_channel7_isr(){
if(DMA1_ISR & DMA_ISR_TCIF7) {
DMA1_IFCR = DMA_IFCR_CTCIF7;
dma_disable_channel(DMA1, DMA_CHANNEL7);
}else if(DMA1_ISR & DMA_ISR_TEIF7){
DMA1_IFCR = DMA_IFCR_CTEIF7;
MSG("out transfer error\n");
}
}
void dma1_channel1_isr(){
int i;
if(DMA1_ISR & DMA_ISR_TCIF1) {
DMA1_IFCR = DMA_IFCR_CTCIF1;
dma_disable_channel(DMA1, DMA_CHANNEL1);
timer_disable_counter(TIM2);
gpio_set(GPIOA, GPIO3);
for(i = 0; i ‹ 8; i++){
print_int(tim2_inbuff[i], lastsendfun);
MSG(" ");
}
MSG("\n");
}else if(DMA1_ISR & DMA_ISR_TEIF1){
DMA1_IFCR = DMA_IFCR_CTEIF1;
MSG("in transfer error\n");
}
} |
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
|
|
|
|
30.10.2014, 22:07
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
Ох и нелегкая же задача — с таймерами через DMA работать!
Переделал функции для работы с разным количеством данных (они помещаются в один и тот же буфер, предельное количество бит за одну посылку == 12  . Опять хрень какая-то! Такое впечатление, что DMA у меня где-то неправильно срабатывает: первая посылка вроде отрабатывает, а потом хрень какая-то; да и постоянно у таймера меняется уровень в выключенном состоянии (вообще беда с ним: счетчик отключаю, но таймер не позволяет явно ногу установить в 1; добавляю до выключения таймера установку пассивного уровня в 1, но срабатывает через раз).
Но добить надо будет обязательно.
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
|
|
|
|
31.10.2014, 07:32
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,026
Сказал спасибо: 60
Сказали Спасибо 3,941 раз(а) в 2,302 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
А не проще глянуть отладчиком?
Тем более если он поддерживается
Это только в первый раз сложно, а в дальнейшем такие проблемы будут решаться за десятки минут
|
|
|
|
31.10.2014, 09:16
|
|
|
Гуру портала
Регистрация: 20.11.2004
Сообщений: 9,979
Сказал спасибо: 928
Сказали Спасибо 2,261 раз(а) в 1,557 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
niXto, А у него только хардкор -дебуггер в консоли , надо наизусть помнить все адреса и регистры ...
__________________
Осторожно , злой кот
|
|
|
|
31.10.2014, 09:26
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
|
Re: STM32F103, непонятки с DMA
Сообщение от niXto
|
|
А не проще глянуть отладчиком?
|
Нет отладчика кроме printf ☺
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 02:36.
|
|