RM0091 interrupt priority > 4 - stm32f0

in RM0091 I found Table36 which defines priorities > 4 (I believe that for CortexM0 maximum interrupt priority = 3). Does anyone know what these numbers are?

You are correct that the priority of all interrupts on STM32F0xx is <= 3. (Note that this is for STM32F0xx, not all Cortex-M0).
The numbers in the column marked "Priority" are interrupt numbers adjusted so that the first interrupt with settable priority is zero. It isn't really a useful column, you can safely ignore it.
Note that ARM define a different interrupt numbering scheme, with zero set to the first interrupt which comes from a peripheral outside the processor core. This is used in all CMSIS headers (not just for STM32), for example "stm32f030x6.h":
/****** Cortex-M0 Processor Exceptions Numbers */
NonMaskableInt_IRQn = -14,
HardFault_IRQn = -13,
SVC_IRQn = -5,
PendSV_IRQn = -2,
SysTick_IRQn = -1,
/****** STM32F0 specific Interrupt Numbers */
WWDG_IRQn = 0,
RTC_IRQn = 2,
FLASH_IRQn = 3,
RCC_IRQn = 4,
EXTI0_1_IRQn = 5,
etc...
This enum is used in the various functions for enabling and disabling interrupts etc.
The only way that the interrupt numbers behave like a priority is if you set all the adjustable interrupt priorities to the same value. In that case only, the interrupts are handled in the order of their interrupt number, lowest first.

Related

ESP32 BLE - how to declare a characteristic value that is read only and ESP_GATT_RSP_BY_APP?

Following the declaration of the IDX_CHAR_VAL_A value attribute in the ESPIDF example here https://github.com/espressif/esp-idf/blob/master/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c#L189
If I change that declaration to allow read only and to use ESP_GATT_RSP_BY_APP instead of ESP_GATT_AUTO_RSP, is it ok to have the last three fields set to 0? My thinking is that the value buffer is not used anymore by the automatic value handling of the bluedroid stack, but couldn't find any mentioning or example in the ESP32 documentation.
That is, changing
[IDX_CHAR_VAL_A] =
{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_A,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},
to
[IDX_CHAR_VAL_A] =
{{ESP_GATT_RSP_BY_APP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_A,
ESP_GATT_PERM_READ,
0, 0, NULL}},

Variable runover when not reaching the limit yet

My variable had a Runover even before it reached its range.
Currently, I am working with timer 2 with a frequency of 90MHz. When I retrieved the current time by __HAL_TIM_GET_COUNTER() and printed it by printf("receive_time: %lu\n", (unsigned long)receive_time), the maximum the receive_time get is 16 bits although I declared it as 32 bits. I observed the printed value and it never exceeded 2^16 -1.
I also tried to print with printf("%" PRIu32 "\n",a); but it also returned the same.
I had another 32-bit variable send_time which is used later to subtract with receive_time. However, it gave me something in the order of 2*10^9 (2147482170 for example) besides some common values.
I want to ask what happen and if I do something wrong. If everything is correct, is there any way to handle the rollover besides having 2 timers starting at different times?
The code is here:
Radio::radio.tx_buf[0] = seq++; /* set payload */
printf("send a ready message\r\n");
Radio::Send(1, 0, 0, 0); /* begin transmission */
send_time = __HAL_TIM_GET_COUNTER(&htim2);
.
.
.
if (Radio::radio.rx_buf[0] == 100)
{
receive_time = __HAL_TIM_GET_COUNTER(&htim2);
printf("receive_time: %lu\n", (unsigned long)receive_time);
printf("send_time: %lu\n", (unsigned long)send_time);
time_difference = (receive_time - send_time)/2;
printf("time_difference: %lu\n", (unsigned long)time_difference);
uint32_t distance = time_difference * 10 / 3;
printf("Distance: %lu\n", (unsigned long)distance);
}```
Thank you in advanced,
Huy Nguyen.

STM32F4 Encoder count is changing when it should not

I am currently using the STM32F4 with the STM32F429ZI Nucleo-144 Board. I am looking to use this microcontroller to evaluate the position of a rotary encoder via a quadrature encoder interface. Looking at the documentation, this is done with the timers. I have the A/B encoder outputs hooked up to PA6 and PC7 on the micro, but I have noticed that the counts appear to be drifting.
During the debugging, I noticed that if I disconnect one of the encoder outputs to the microcontroller and I move the motor, the counts still increment/decrement even though only one of the encoder lines are connected. Since I am counting on both the TI1 and TI2 edges, this should not be happening. If I am reading the below diagram correctly, since one of my lines is held high using the internal pull-up, clock pulses on the other input should be going up/down/up/down and really just cycling between two different counts. However, if I am rotating the encoder, the counts keep incrementing or decrementing depending on the direction.
Why is the encoder count changing with only one encoder input connected? I also have the scope trace attached to prove that only one count is is active, as well as the code.
EDIT: I have also tried changing the polarity from BOTH EDGE to RISING EDGE, with no perceived benefit.
#include "stm32f4xx_hal.h"
#include "encoder_test.h"
GPIO_InitTypeDef GPIO_InitStruct;
TIM_HandleTypeDef Timer_InitStruct;
TIM_Encoder_InitTypeDef Encoder_InitStruct;
void EncoderTest_Init()
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_TIM3_CLK_ENABLE();
/**TIM3 GPIO Configuration
PA6 ------> TIM3_CH1
PC7 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
Timer_InitStruct.Instance = TIM3;
Timer_InitStruct.Init.Period = 0xFFFF;
Timer_InitStruct.Init.CounterMode = TIM_COUNTERMODE_UP;
Timer_InitStruct.Init.Prescaler = 1;
Timer_InitStruct.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
Encoder_InitStruct.EncoderMode = TIM_ENCODERMODE_TI12;
Encoder_InitStruct.IC1Filter = 0x00;
Encoder_InitStruct.IC1Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
Encoder_InitStruct.IC1Prescaler = TIM_ICPSC_DIV1;
Encoder_InitStruct.IC1Selection = TIM_ICSELECTION_DIRECTTI;
Encoder_InitStruct.IC2Filter = 0x00;
Encoder_InitStruct.IC2Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
Encoder_InitStruct.IC2Prescaler = TIM_ICPSC_DIV1;
Encoder_InitStruct.IC2Selection = TIM_ICSELECTION_DIRECTTI;
if (HAL_TIM_Encoder_Init(&Timer_InitStruct, &Encoder_InitStruct) != HAL_OK)
{
while (1);
}
if (HAL_TIM_Encoder_Start_IT(&Timer_InitStruct, TIM_CHANNEL_1) != HAL_OK)
{
while (1);
}
}
void TIM3_IRQHandler()
{
HAL_TIM_IRQHandler(&Timer_InitStruct);
}
Upon further investigation, it appears that the issue is due to the prescaler. The prescaler does not work in encoder mode when you provide even values. Since prescaler is the entered value + 1, using the STM32F4 HAL, the entered prescaler must be even.
I found confirmation that I am not the only person with this issue at this forum post. There is some discussion at the post that prescalers may not be compatible with encoder mode, but this has not yet been confirmed. I have sent an email to ST to get to the bottom of it. It is safe to enter a prescaler value of 0 if it is not supported.
Here is the working code below:
#include "stm32f4xx_hal.h"
#include "encoder_test.h"
GPIO_InitTypeDef GPIO_InitStruct;
TIM_HandleTypeDef Timer3_InitStruct;
TIM_Encoder_InitTypeDef EncoderTim3_InitStruct;
void EncoderTest_Init_Tim3()
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_TIM3_CLK_ENABLE();
/**TIM3 GPIO Configuration
PA6 ------> TIM3_CH1
PC7 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
Timer3_InitStruct.Instance = TIM3;
Timer3_InitStruct.Init.Period = 0xFFFF;
Timer3_InitStruct.Init.CounterMode = TIM_COUNTERMODE_UP;
Timer3_InitStruct.Init.Prescaler = 10;
Timer3_InitStruct.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
EncoderTim3_InitStruct.EncoderMode = TIM_ENCODERMODE_TI12;
EncoderTim3_InitStruct.IC1Filter = 0x00;
EncoderTim3_InitStruct.IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING;
EncoderTim3_InitStruct.IC1Prescaler = TIM_ICPSC_DIV4;
EncoderTim3_InitStruct.IC1Selection = TIM_ICSELECTION_DIRECTTI;
EncoderTim3_InitStruct.IC2Filter = 0x00;
EncoderTim3_InitStruct.IC2Polarity = TIM_INPUTCHANNELPOLARITY_RISING;
EncoderTim3_InitStruct.IC2Prescaler = TIM_ICPSC_DIV4;
EncoderTim3_InitStruct.IC2Selection = TIM_ICSELECTION_DIRECTTI;
if (HAL_TIM_Encoder_Init(&Timer3_InitStruct, &EncoderTim3_InitStruct) != HAL_OK)
{
while (1);
}
if (HAL_TIM_Encoder_Start_IT(&Timer3_InitStruct, TIM_CHANNEL_1) != HAL_OK)
{
while (1);
}
}
void TIM3_IRQHandler()
{
HAL_TIM_IRQHandler(&Timer3_InitStruct);
}
EDIT:
After speaking with ST tech support, the encoder interface was not intended to be used with a prescaler value, even OR odd. I have pasted their response below, but even with using a prescaler value that appears to work, it seems possible that the encoder counts drift over time.
Another solution is to use no prescalers, but instead extend the 16 bit value into the 32 bit space using the approach suggested here. I have reprinted the approach here in case the link goes dead:
From user goosen.kobus.001 on 11/19/2013 on ST's forum:
In my experience using an overflow interrupt to scale up an encoder is not reliable, especially when you have high resolution encoders: it happens from time to time that the encoder value will change sign in the instant you enter the interrupt, causing the system to increment the upper word when it should have decremented etc. This is especially true if the encoder is supposed to be stalled at 0, like a servo motor commanded to go to encoder position 0.
The best approach I have found is to do it manually. this is my procedure:
Ensure that the control loop that reads the encoder value is run often, (i.e. that if your encoder is rotating at full speed, the encoder value is still read at least 10-20 times between overflows. For my servo motor application a 1ms loop interval was sufficient.
keep track of the last read encoder value.
divide the current and last encoder value into quadrants (the most significant 2 bits). i.e. pos_now &= 0xC000; pos_last &= 0xC000;
check to see if the encoder has moved from quadrant 0 to quadrant 3 or 3 to 0 in the last step:
4.1 if(pos_now == 0 && pos_last == 0xC000) upper_word++;
4.2 if(pos_now == 0xC000 && pos_last == 0) upper_word--;
this is why I say the encoder read loop needs to be run often; you need to be sure that the value is read often enough that it is impossible to go from quadrant 0->1->2->3 in between reads.
It should also be possible to put this logic in another timer interrupt that runs at say 10kHz. that way you have an encoder value which is always up to date.
ST RESPONSE:
Hi,
I have got the feedback from the design and the architect of the timers.
The encoder interface has been designed to work without prescaler in order to not downgrade the resolution of the encoder.
As you observed, they have confirmed that it cannot work with even prescaler value but only the odd ones.
We have a sub-counter for the prescaler which is mono-directional, so not affected by the counter direction and incremented on every rising edge of the timer clock (without the prescaler).
The counter direction is updated on every rising edge of the timer clock (without the prescaler) but the counter is incremented only while the sub-counter of the prescaler reach the programmed value and according to the value in the direction bit.
So, in one case, the behavior is the same as without prescaler, because the counter is updated with a different direction (every odd clock cycles number), but in the other case, the direction is always the same when the counter is updated and the encoder interface doesn't work correctly.
So you can use the prescaler but with an odd value.
The recommended use case is without prescaler.
Best regards
ST MCU Tech Support

OpenCL passing multiple arrays of different sizes to kernel

I want to pass two arrays of different sizes to the kernel, how can I set the cl_ndrange?
With only one array of size NUM_VALUES, the range can be easily set as
cl_ndrange range = { // 6
1, // The number of dimensions to use.
{0, 0, 0}, // The offset in each dimension. To specify
// that all the data is processed, this is 0
// in the test case. // 7
{NUM_VALUES, 0, 0}, // The global range—this is how many items
// IN TOTAL in each dimension you want to
// process.
{NULL, 0, 0} // The local size of each workgroup. This
// determines the number of work items per
// workgroup. It indirectly affects the
// number of workgroups, since the global
// size / local size yields the number of
// workgroups. In this test case, there are
// NUM_VALUE / wgs workgroups.
};
But I don't know what to do for two arrays with different sizes. In my case, one array is actually used as input for calculation, while another is used to for lookups.
Thanks in advance.

FSM data structure design

I want to write an FSM which starts with an idle state and moves from one state to another based on some event. I am not familiar with coding of FSM and google didn't help.
Appreciate if someone could post the C data structure that could be used for the same.
Thanks,
syuga2012
We've implemented finite state machine for Telcos in the past and always used an array of structures, pre-populated like:
/* States */
#define ST_ANY 0
#define ST_START 1
: : : : :
/* Events */
#define EV_INIT 0
#define EV_ERROR 1
: : : : :
/* Rule functions */
int initialize(void) {
/* Initialize FSM here */
return ST_INIT_DONE
}
: : : : :
/* Structures for transition rules */
typedef struct {
int state;
int event;
(int)(*fn)();
} rule;
rule ruleset[] = {
{ST_START, EV_INIT, initialize},
: : : : :
{ST_ANY, EV_ERROR, error},
{ST_ANY, EV_ANY, fatal_fsm_error}
};
I may have the function pointer fn declared wrong since this is from memory. Basically the state machine searched the array for a relevant state and event and called the function which did what had to be done then returned the new state.
The specific states were put first and the ST_ANY entries last since priority of the rules depended on their position in the array. The first rule that was found was the one used.
In addition, I remember we had an array of indexes to the first rule for each state to speed up the searches (all rules with the same starting state were grouped).
Also keep in mind that this was pure C - there may well be a better way to do it with C++.
A finite state machine consists of a finite number discrete of states (I know pedantic, but still), which can generally be represented as integer values. In c or c++ using an enumeration is very common.
The machine responds to a finite number of inputs which can often be represented with another integer valued variable. In more complicated cases you can use a structure to represent the input state.
Each combination of internal state and external input will cause the machine to:
possibly transition to another state
possibly generate some output
A simple case in c might look like this
enum state_val {
IDLE_STATE,
SOME_STATE,
...
STOP_STATE
}
//...
state_val state = IDLE_STATE
while (state != STOP_STATE){
int input = GetInput();
switch (state) {
case IDLE_STATE:
switch (input) {
case 0:
case 3: // note the fall-though here to handle multiple states
write(input); // no change of state
break;
case 1:
state = SOME_STATE;
break
case 2:
// ...
};
break;
case SOME_STATE:
switch (input) {
case 7:
// ...
};
break;
//...
};
};
// handle final output, clean up, whatever
though this is hard to read and more easily split into multiple function by something like:
while (state != STOP_STATE){
int input = GetInput();
switch (state) {
case IDLE_STATE:
state = DoIdleState(input);
break;
// ..
};
};
with the complexities of each state held in it's own function.
As m3rLinEz says, you can hold transitions in an array for quick indexing. You can also hold function pointer in an array to efficiently handle the action phase. This is especially useful for automatic generation of large and complex state machines.
The answers here seem really complex (but accurate, nonetheless.) So here are my thoughts.
First, I like dmckee's (operational) definition of an FSM and how they apply to programming.
A finite state machine consists of a
finite number discrete of states (I
know pedantic, but still), which can
generally be represented as integer
values. In c or c++ using an
enumeration is very common.
The machine responds to a finite
number of inputs which can often be
represented with another integer
valued variable. In more complicated
cases you can use a structure to
represent the input state.
Each combination of internal state and
external input will cause the machine
to:
possibly transition to another state
possibly generate some output
So you have a program. It has states, and there is a finite number of them. ("the light bulb is bright" or "the light bulb is dim" or "the light bulb is off." 3 states. finite.) Your program can only be in one state at a time.
So, say you want your program to change states. Usually, you'll want something to happen to trigger a state change. In this example, how about we take user input to determine the state - say, a key press.
You might want logic like this. When the user presses a key:
If the bulb is "off" then make the bulb "dim".
If the bulb is "dim", make the bulb "bright".
If the bulb is "bright", make the bulb "off".
Obviously, instead of "changing a bulb", you might be "changing the text color" or whatever it is you program needs to do. Before you start, you'll want to define your states.
So looking at some pseudoish C code:
/* We have 3 states. We can use constants to represent those states */
#define BULB_OFF 0
#define BULB_DIM 1
#define BULB_BRIGHT 2
/* And now we set the default state */
int currentState = BULB_OFF;
/* now we want to wait for the user's input. While we're waiting, we are "idle" */
while(1) {
waitForUserKeystroke(); /* Waiting for something to happen... */
/* Okay, the user has pressed a key. Now for our state machine */
switch(currentState) {
case BULB_OFF:
currentState = BULB_DIM;
break;
case BULB_DIM:
currentState = BULB_BRIGHT;
doCoolBulbStuff();
break;
case BULB_BRIGHT:
currentState = BULB_OFF;
break;
}
}
And, voila. A simple program which changes the state.
This code executes only a small part of the switch statement - depending on the current state. Then it updates that state. That's how FSMs work.
Now here are some things you can do:
Obviously, this program just changes the currentState variable. You'll want your code to do something more interesting on a state change. The doCoolBulbStuff() function might, i dunno, actually put a picture of a lightbulb on a screen. Or something.
This code only looks for a keypress. But your FSM (and thus your switch statement) can choose state based on what the user inputted (eg, "O" means "go to off" rather than just going to whatever is next in the sequence.)
Part of your question asked for a data structure.
One person suggested using an enum to keep track of states. This is a good alternative to the #defines that I used in my example. People have also been suggesting arrays - and these arrays keep track of the transitions between states. This is also a fine structure to use.
Given the above, well, you could use any sort of structure (something tree-like, an array, anything) to keep track of the individual states and define what to do in each state (hence some of the suggestions to use "function pointers" - have a state map to a function pointer which indicates what to do at that state.)
Hope that helps!
See Wikipedia for the formal definition. You need to decide on your set of states S, your input alphabet Σ and your transition function δ. The simplest representation is to have S be the set of integers 0, 1, 2, ..., N-1, where N is the number of states, and for Σ be the set of integers 0, 1, 2, ..., M-1, where M is the number of inputs, and then δ is just a big N by M matrix. Finally, you can store the set of accepting states by storing an array of N bits, where the ith bit is 1 if the ith state is an accepting state, or 0 if it is not an accepting state.
For example, here is the FSM in Figure 3 of the Wikipedia article:
#define NSTATES 2
#define NINPUTS 2
const int transition_function[NSTATES][NINPUTS] = {{1, 0}, {0, 1}};
const int is_accepting_state[NSTATES] = {1, 0};
int main(void)
{
int current_state = 0; // initial state
while(has_more_input())
{
// advance to next state based on input
int input = get_next_input();
current_state = transition_function[current_state][input];
}
int accepted = is_accepting_state[current_state];
// do stuff
}
You can basically use "if" conditional and a variable to store the current state of FSM.
For example (just a concept):
int state = 0;
while((ch = getch()) != 'q'){
if(state == 0)
if(ch == '0')
state = 1;
else if(ch == '1')
state = 0;
else if(state == 1)
if(ch == '0')
state = 2;
else if(ch == '1')
state = 0;
else if(state == 2)
{
printf("detected two 0s\n");
break;
}
}
For more sophisticated implementation, you may consider store state transition in two dimension array:
int t[][] = {{1,0},{2,0},{2,2}};
int state = 0;
while((ch = getch()) != 'q'){
state = t[state][ch - '0'];
if(state == 2){
...
}
}
A few guys from AT&T, now at Google, wrote one of the best FSM libraries available for general use. Check it out here, it's called OpenFST.
It's fast, efficient, and they created a very clear set of operations you can perform on the FSMs to do things like minimize them or determinize them to make them even more useful for real world problems.
if by FSM you mean finite state machine,
and you like it simple, use enums to name your states
and switch betweem them.
Otherwise use functors. you can look the
fancy definition up in the stl or boost docs.
They are more or less objects, that have a
method e.g. called run(), that executes
everything that should be done in that state,
with the advantage that each state has it's own
scope.

Resources