2017-03-10 06:46 AM
I'm trying to use timer2 ch2 for input capture, but I don't seem to get it to work.
I wonder what am I doing wrong?
I don't use CMSIS or any other libraries.
Here's my set-up:
nvic[NVIC_ICER_0] |= 0x10000000; // disable tim2 IRQ
nvic[NVIC_ICPR_0] |= 0x10000000; // clear tim2 pending tim2[TIM_DIER] &= 0xffffa0a0; // disable timer interrupts tim2[TIM_CCER] = 0x000000000; // disable channels /* switch timer2 ch2 for input capture on falling edge *//* put input capture routine to 'interrupt vector' */
dht_intvec = dht_irq_capt;/* T2 should be PA1 by default */
tim2[TIM_CCMR1] = (tim2[TIM_CCMR1] & 0x00000000) | 0x00000100; // CC2S=T2, OC1M = 000, IC2F = 000 tim2[TIM_CCER] = 0x00000030; // ch2 falling edge, capture enable /* pin PA1 = tmr2_ch2 *//* Input pull-up/down: min. 30kOhm, typ. 40kOhm, max. 50kOhm */
gpioa[GPIO_CRL] = (gpioa[GPIO_CRL] & 0xffffff0f) | 0x00000080; /* PA1 pull-up - line up to end the start pulse */ gpioa[GPIO_ODR] |= 0x00000002;/* enable interrupts */
tim2[TIM_SR] &= 0xffffe1a0; // clear flags tim2[TIM_DIER] = (tim2[TIM_DIER] & 0xffffa0a0) | 4; // CC2IE (enable capture 2 interrupt) nvic[NVIC_ICPR_0] |= 0x10000000; // clear tim2 pending nvic[NVIC_ISER_0] |= 0x10000000; // enable tim2 IRQ (28)The time base runs fine - I've checked by reading the CNT-register, and
output compare seems to work.
#timer2 #input-capture #stm32f1032017-03-10 01:32 PM
this is a terrible way to program the most important parts of you code..
and I think your problem will be in these lines;
tim2[TIM_DIER] &= 0xffffa0a0; // disable timer interrupts
gpioa[GPIO_CRL] = (gpioa[GPIO_CRL] & 0xffffff0f)
tim2[TIM_DIER] &= 0xffffa0a0; // disable timer interrupts
tim2[TIM_SR] &= 0xffffe1a0; // clear flags
tim2[TIM_DIER] = (tim2[TIM_DIER] & 0xffffa0a0)
the whole point of portability is to use the provided Constants,that's why we have CMSIS
My advice is don't hard code anything, otherwise you can't expect it to work anywhere else and it will be trouble to get working.
2017-03-10 03:54 PM
For someone who remembers 'CAN_MCR_INRQ' or 'CAN_BTR_LBKM'.
Especially when writing the code.
(Psst... '2 << 20 | 3 << 16 | 5 << 0'.) ;)
Those are actually hard to remember, when you deal with, say, 3 or 4 different devices:
Raspberry Pi, PowerPC, TI C6000-series DSP, ...
And I have come across several others with my ~20 years career with embedded programming.
At the moment I'm only dealing with STM32F103 and Raspberry Pi 2B.
And maybe Atmel atMega 169. All hobby-stuff.
If you are interested, Some time ago I wrote 'rpi_stub' - a bare metal GDB agent for Raspberry Pi 2B that uses
serial line:
https://github.com/turboscrew/rpi_stub
.That too without any libraries.
2017-03-10 04:16 PM
,
,
'the whole point of portability is to use the provided Constants' I thought the other way: constants being used for
achieving portability?
My point is rather, if there are some settings missing or in wrong order. Or if something else is clearly wrong.
I'd like to see a description about what should happen to the HW in correct initialization, not how to use a library
that I don't really have a clue of what it actually does, to achieve it.
I'd like to understand it, not just to get away with it.
Well, partly those weird constants came from misunderstanding of 'Reserved, must be kept at reset value'. :D
Should have realized that 'reset value' = 'zero', not the value it contained at reset.
(And I'm not the only one that has misunderstood that initially, I heard.)
Now I know that 'tim2[TIM_DIER] &,= 0xffffa0a0,' could have been written as 'tim2[TIM_DIER] = 0,'.
The first four 'f's come from writing 16-bit entity as 32-bit word. The a0a0-part comes from the fact that
bits 15, 13, 7 and 5 are 'Reserved, must be kept at reset value'.
The GPIO_CRL-setting if fine - that I know, and the e1a0-part of SR-value: bits 15, 14, 13, 8, 7 and 5
are 'Reserved, must be kept at reset value'. That could also be written as 'tim2[TIM_SR] = 0'.
(BTW some of what you picked were not whole logical lines.)
I think the comments help too:
,/* Input pull-up/down: min. 30kOhm, typ. 40kOhm, max. 50kOhm */
,
, , ,gpioa[GPIO_CRL] = (gpioa[GPIO_CRL] &, 0xffffff0f),
, , , , , , , , ,| 0x00000080,,tim2[TIM_DIER] = (tim2[TIM_DIER] &, 0xffffa0a0)
,
, , , , , ,| 4, // CC2IE (enable capture 2 interrupt)Like I mentioned, I don't use CMSIS or any other library - not even C standard library (except stdint.h).
This is a hobby/learning project. The professional stuff I do very differently.
I don't like to have textual definition for 'millions' of individual bits. I'll never remember them.
Web-programming comes to mind. You can't get even a small calculator program working without
downloading and installing tons of libraries first, some of which have version conflicts... :D
This close to HW isn't portable anyway. Even CMSIS has different code for different chips - ♯ ifdef'd in the files.
In most other contexts I would use named constants.
2017-03-10 04:27 PM
I used HAL for portability; eg.
CAN->MCR |= CAN_MCR_INRQ; // (1)
while ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) // (2) { // add time out here for a robust application } CAN->MCR &=~ CAN_MCR_SLEEP; // (3) CAN->BTR |= CAN_BTR_LBKM | 2 << 20 | 3 << 16 | 5 << 0; // (4) CAN->MCR &=~ CAN_MCR_INRQ; // (5) while ((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) // (6) { // add time out here for a robust application }this is much easier to read and bug free after you fix it.
2017-03-11 06:07 AM
Forget it. I found the problem.
It was kinda rude, to give someone the finger as the first answer.
2017-03-11 01:49 PM
huh ? are you referring to me ?
I was not rude, just pointing out how your coding style is inadequate for portability and debugging.
what was the fix ?
0xffffc1a0 not 0xffffe1a0 ?
ST processors have very good pin matching across many different processors, that's why it is imperative to use the portability constants.
We are all learning here, with some exceptions it seems.
2017-03-11 03:38 PM
>>
It was kinda rude, to give someone the finger as the first answer.
The question did lean towards 'what's wrong with my unique and unnecessarily awkward code', and doesn't look to be compilable by anyone else but yourself. When you do that you tend to limit the subset of people who might want to dig into it, and have to expect to rescue yourself when you inevitably fall over.
The use of 32-bit arrays and defines does seem awfully prone to causing issues. Using the C structs provided would seem to involve less work and less potential for issues, and makes the compiler do a lot of the work using code that has a thousand eyes on it.
I don't think any offence was meant, rather a 'what-the-heck are you doing, your head's going to hurt when you hit the pavement' kind of thing between colleagues.
2017-03-11 06:59 PM
Do you see my earlier response that's 'Currently being moderated.'?
Or is it visible only to me?
'...and doesn't look to be compilable by anyone else but yourself'
Well nobody's piece of code taken from the middle of everything else usually is,
except that I don't even use any libraries, so there are no library dependencies. ;)
In that sense it should be even more generally compilable than the ones that use
specific libraries... ;)
I have my reasons to do it that way this time.
Usually I'm writing more like this (also a hobby project):
https://github.com/turboscrew/rpi_stub
(Feel free if you have some use for it.)
At work a bit more 'high-level' way (when portability and maintainability by others is needed).
There are sometimes need to do things differently...
2017-03-12 05:16 AM
And the problem was a wrong index value of the TIM_CCMR1. I somehow missed the TIM_RCR
(that only exist in advanced timers).