Main Site Documentation

Cerbuino Bee Native Code Timer using interupts


#1

The following code does not reach “return 6” and just seems to hang the Bee. Any thoughts? This code is compiled in Keil mu vision 4 (no errors) with defines copied from STM32F4xx discovery files. Is there a problem using this on the Microsoft 2010 Express system (i.e. is TIM2 used by that system?), or have I skrewed up the code somewhere? (Defines available if required).

// Free running clock at 2 microsecs, with pulse one microsec wide
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // enable the hardware clock to GPIOB
	
	RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable TIM2 clock on peripheral clock
	GPIOB->MODER = (1 << 26); // set pin 13 to be general purpose output
	// return 1;
NVIC->ISER[0] |= 1<< (TIM2_IRQn); // enable the TIM2 IRQ
// return 2; 
// TIM2->PSC = (0x0); // no prescaler, timer counts up in sync with the peripheral clock
	TIM2->PSC = 41999; // 2000 ticks per sec prescaler
TIM2->DIER |= TIM_DIER_UIE; // enable update interrupt
	// return 3; 
// TIM2->ARR = 99; // count to 0 (autoreload value 99) This counts 100 clicks
	TIM2->ARR = 1999; // use a longer count, 2000 (with prescaler set to 42000, gives 1 sec tick
// return 4; 
	TIM2->CR1 |= TIM_CR1_ARPE;  // autoreload on
// return 5; 
	
  TIM2->CR1 |= TIM_CR1_CEN; //  counter enabled
	return 6;
  TIM2->EGR |= (0x1); // trigger update event to reload timer registers
return 7;
	loops = 0;
	// while (1); // run forever
	while (loops<1000)
	{
		// do nothing
		loops++;
	}

	return loops;

}


#2

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

#3

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

#4

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

#5

Reproduced code :-

// Free running clock at 2 microsecs, with pulse one microsec wide
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // enable the hardware clock to GPIOB
	
	RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable TIM2 clock on peripheral clock
	GPIOB->MODER = (1 << 26); // set pin 13 to be general purpose output
	// return 1;
NVIC->ISER[0] |= 1<< (TIM2_IRQn); // enable the TIM2 IRQ
// return 2; 
// TIM2->PSC = (0x0); // no prescaler, timer counts up in sync with the peripheral clock
	TIM2->PSC = 41999; // 2000 ticks per sec prescaler
TIM2->DIER |= TIM_DIER_UIE; // enable update interrupt
	// return 3; 
// TIM2->ARR = 99; // count to 0 (autoreload value 99) This counts 100 clicks
	TIM2->ARR = 1999; // use a longer count, 2000 (with prescaler set to 42000, gives 1 sec tick
// return 4; 
	TIM2->CR1 |= TIM_CR1_ARPE;  // autoreload on
// return 5; 
	
  TIM2->CR1 |= TIM_CR1_CEN; //  counter enabled
	return 6;
  TIM2->EGR |= (0x1); // trigger update event to reload timer registers
return 7;
	loops = 0;
	// while (1); // run forever
	while (loops<1000)
	{
		// do nothing
		loops++;
	}

	return loops;

}


#6

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

#7

@ Ian - To apply syntax highlighting, select the code and press the binary button at the top of the editor, not the orange one below the editor. The button you must press looks disabled, but it is not.


#8

Thanks for the “101010” tip, but it hasn’t worked (as can be seen from previous replies) - it just acts like “submit”, sorry! Hope this is more readable.

Reproduced code :-

// Code for flashing LED
//… #include
#include <stm32f4xx.h>
#include <stdio.h>

//…#defines from stm32f4xx_discovery

typedef enum
{
GPIO_Speed_2MHz = 0x00,
GPIO_Speed_25MHz = 0x01,
GPIO_Speed_50MHz = 0x02,
GPIO_Speed_100MHz = 0x03
}GPIOSpeed_TypeDef;
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_2MHz) || ((SPEED) == GPIO_Speed_25MHz) ||
((SPEED) == GPIO_Speed_50MHz)|| ((SPEED) == GPIO_Speed_100MHz))

typedef enum
{
GPIO_Mode_IN = 0x00,
GPIO_Mode_OUT = 0x01,
GPIO_Mode_AF = 0x02,
GPIO_Mode_AN = 0x03
}GPIOMode_TypeDef;
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) ||
((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN))

typedef enum
{
GPIO_OType_PP = 0x00,
GPIO_OType_OD = 0x01
}GPIOOType_TypeDef;
#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD))

typedef enum
{
GPIO_PuPd_NOPULL = 0x00,
GPIO_PuPd_UP = 0x01,
GPIO_PuPd_DOWN = 0x02
}GPIOPuPd_TypeDef;
#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) ||
((PUPD) == GPIO_PuPd_DOWN))

#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected /
#define GPIO_Pin_1 ((uint16_t)0x0002) /
Pin 1 selected /
#define GPIO_Pin_2 ((uint16_t)0x0004) /
Pin 2 selected /
#define GPIO_Pin_3 ((uint16_t)0x0008) /
Pin 3 selected /
#define GPIO_Pin_4 ((uint16_t)0x0010) /
Pin 4 selected /
#define GPIO_Pin_5 ((uint16_t)0x0020) /
Pin 5 selected /
#define GPIO_Pin_6 ((uint16_t)0x0040) /
Pin 6 selected /
#define GPIO_Pin_7 ((uint16_t)0x0080) /
Pin 7 selected /
#define GPIO_Pin_8 ((uint16_t)0x0100) /
Pin 8 selected /
#define GPIO_Pin_9 ((uint16_t)0x0200) /
Pin 9 selected /
#define GPIO_Pin_10 ((uint16_t)0x0400) /
Pin 10 selected /
#define GPIO_Pin_11 ((uint16_t)0x0800) /
Pin 11 selected /
#define GPIO_Pin_12 ((uint16_t)0x1000) /
Pin 12 selected /
#define GPIO_Pin_13 ((uint16_t)0x2000) /
Pin 13 selected /
#define GPIO_Pin_14 ((uint16_t)0x4000) /
Pin 14 selected /
#define GPIO_Pin_15 ((uint16_t)0x8000) /
Pin 15 selected /
#define GPIO_Pin_All ((uint16_t)0xFFFF) /
All pins selected */

#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00))
#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) ||
((PIN) == GPIO_Pin_1) ||
((PIN) == GPIO_Pin_2) ||
((PIN) == GPIO_Pin_3) ||
((PIN) == GPIO_Pin_4) ||
((PIN) == GPIO_Pin_5) ||
((PIN) == GPIO_Pin_6) ||
((PIN) == GPIO_Pin_7) ||
((PIN) == GPIO_Pin_8) ||
((PIN) == GPIO_Pin_9) ||
((PIN) == GPIO_Pin_10) ||
((PIN) == GPIO_Pin_11) ||
((PIN) == GPIO_Pin_12) ||
((PIN) == GPIO_Pin_13) ||
((PIN) == GPIO_Pin_14) ||
((PIN) == GPIO_Pin_15))

#define GPIO_PinSource0 ((uint8_t)0x00)
#define GPIO_PinSource1 ((uint8_t)0x01)
#define GPIO_PinSource2 ((uint8_t)0x02)
#define GPIO_PinSource3 ((uint8_t)0x03)
#define GPIO_PinSource4 ((uint8_t)0x04)
#define GPIO_PinSource5 ((uint8_t)0x05)
#define GPIO_PinSource6 ((uint8_t)0x06)
#define GPIO_PinSource7 ((uint8_t)0x07)
#define GPIO_PinSource8 ((uint8_t)0x08)
#define GPIO_PinSource9 ((uint8_t)0x09)
#define GPIO_PinSource10 ((uint8_t)0x0A)
#define GPIO_PinSource11 ((uint8_t)0x0B)
#define GPIO_PinSource12 ((uint8_t)0x0C)
#define GPIO_PinSource13 ((uint8_t)0x0D)
#define GPIO_PinSource14 ((uint8_t)0x0E)
#define GPIO_PinSource15 ((uint8_t)0x0F)

#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) ||
((PINSOURCE) == GPIO_PinSource1) ||
((PINSOURCE) == GPIO_PinSource2) ||
((PINSOURCE) == GPIO_PinSource3) ||
((PINSOURCE) == GPIO_PinSource4) ||
((PINSOURCE) == GPIO_PinSource5) ||
((PINSOURCE) == GPIO_PinSource6) ||
((PINSOURCE) == GPIO_PinSource7) ||
((PINSOURCE) == GPIO_PinSource8) ||
((PINSOURCE) == GPIO_PinSource9) ||
((PINSOURCE) == GPIO_PinSource10) ||
((PINSOURCE) == GPIO_PinSource11) ||
((PINSOURCE) == GPIO_PinSource12) ||
((PINSOURCE) == GPIO_PinSource13) ||
((PINSOURCE) == GPIO_PinSource14) ||
((PINSOURCE) == GPIO_PinSource15))

#define RCC_AHB1Periph_GPIOB ((uint32_t)0x00000002)

#define RCC_APB2ENR_IOPAEN ((unsigned long)0x00000004)
#define RCC_APB2ENR_IOPCEN ((unsigned long)0x00000010)
#define TIM_CR1_CEN ((uint16_t)0x0001) /*!<Counter enable */

int RLP_freeclock(void* par0, int * par1, unsigned char * par2)
{
// the passed arguments /////
// keep these for passing params in and out later
unsigned char * ByteArray = par0;
unsigned int length = par1[0];
unsigned char value = par2[0];
//////////////////////////////

int index;
int loops;

// Blinking LED, using GPIO

 RCC->AHB1ENR |= RCC_AHB1Periph_GPIOB;
 GPIOB->MODER |= GPIO_Mode_OUT; 
 GPIOB->OSPEEDR |= GPIO_Speed_100MHz;
 GPIOB->PUPDR |= GPIO_PuPd_NOPULL;
 GPIOB->OTYPER |= GPIO_OType_PP;

// ignore this till next //*
// while (loops<120)
// {

			// GPIOB->BSRRL = GPIO_Pin_0;
			// for (index = 0; index < 1000000; index++);
			// GPIOB->BSRRH = GPIO_Pin_0;

// for (index = 0; index < 21000000; index++); // delay loop.

// GPIOB->ODR ^= 0x1; // Output Data Register @ bit 13, toggled.

// loops++;
// }
// End of Blinking LED (this all works)
//*

// Free running clock at 2 microsecs, with pulse one microsec wide
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // enable the hardware clock to GPIOB

RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable TIM2 clock on peripheral clock
GPIOB->MODER = (1 << 26); // set pin 13 to be general purpose output

// return 1;
NVIC->ISER[0] |= 1<< (TIM2_IRQn); // enable the TIM2 IRQ
// return 2;
// TIM2->PSC = (0x0); // no prescaler, timer counts up in sync with the peripheral clock
TIM2->PSC = 41999; // 2000 ticks per sec prescaler
TIM2->DIER |= TIM_DIER_UIE; // enable update interrupt
// return 3;
// TIM2->ARR = 99; // count to 0 (autoreload value 99) This counts 100 clicks
TIM2->ARR = 1999; // use a longer count, 2000 (with prescaler set to 42000, gives 1 sec tick
// return 4;
TIM2->CR1 |= TIM_CR1_ARPE; // autoreload on
// return 5;

TIM2->CR1 |= TIM_CR1_CEN; // counter enabled

return 6;
TIM2->EGR |= (0x1); // trigger update event to reload timer registers
return 7;
loops = 0;

while (loops<1000)
{
	// do nothing
	loops++;
}

return loops;
}
int main() // this not used in managed system, only calls to functions above
{
while(1);
}


#9

Thanks taylorza, I hadn’t even seen the 101010 button on the top of the editor window as it is a very pale green on my system - maybe the complete set of editor buttons could be coloured in red?


#10

One more try… sorry for all of this.

Reproduced code :-


// Code for flashing LED
//... #include .. 
 #include <stm32f4xx.h> 
 #include <stdio.h>

//...#defines from stm32f4xx_discovery

typedef enum
{ 
  GPIO_Speed_2MHz   = 0x00, 
  GPIO_Speed_25MHz  = 0x01, 
  GPIO_Speed_50MHz  = 0x02, 
  GPIO_Speed_100MHz = 0x03  
}GPIOSpeed_TypeDef;
 #define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_2MHz) || ((SPEED) == GPIO_Speed_25MHz) || \
                              ((SPEED) == GPIO_Speed_50MHz)||  ((SPEED) == GPIO_Speed_100MHz)) 

typedef enum
{ 
  GPIO_Mode_IN   = 0x00, 
  GPIO_Mode_OUT  = 0x01, 
  GPIO_Mode_AF   = 0x02, 
  GPIO_Mode_AN   = 0x03  
}GPIOMode_TypeDef;
 #define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN)  || ((MODE) == GPIO_Mode_OUT) || \
                            ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN))

typedef enum
{ 
  GPIO_OType_PP = 0x00,
  GPIO_OType_OD = 0x01
}GPIOOType_TypeDef;
 #define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD))

typedef enum
{ 
  GPIO_PuPd_NOPULL = 0x00,
  GPIO_PuPd_UP     = 0x01,
  GPIO_PuPd_DOWN   = 0x02
}GPIOPuPd_TypeDef;
 #define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \
                            ((PUPD) == GPIO_PuPd_DOWN))

 #define GPIO_Pin_0                 ((uint16_t)0x0001)  /* Pin 0 selected */
 #define GPIO_Pin_1                 ((uint16_t)0x0002)  /* Pin 1 selected */
 #define GPIO_Pin_2                 ((uint16_t)0x0004)  /* Pin 2 selected */
 #define GPIO_Pin_3                 ((uint16_t)0x0008)  /* Pin 3 selected */
 #define GPIO_Pin_4                 ((uint16_t)0x0010)  /* Pin 4 selected */
 #define GPIO_Pin_5                 ((uint16_t)0x0020)  /* Pin 5 selected */
 #define GPIO_Pin_6                 ((uint16_t)0x0040)  /* Pin 6 selected */
 #define GPIO_Pin_7                 ((uint16_t)0x0080)  /* Pin 7 selected */
 #define GPIO_Pin_8                 ((uint16_t)0x0100)  /* Pin 8 selected */
 #define GPIO_Pin_9                 ((uint16_t)0x0200)  /* Pin 9 selected */
 #define GPIO_Pin_10                ((uint16_t)0x0400)  /* Pin 10 selected */
 #define GPIO_Pin_11                ((uint16_t)0x0800)  /* Pin 11 selected */
 #define GPIO_Pin_12                ((uint16_t)0x1000)  /* Pin 12 selected */
 #define GPIO_Pin_13                ((uint16_t)0x2000)  /* Pin 13 selected */
 #define GPIO_Pin_14                ((uint16_t)0x4000)  /* Pin 14 selected */
 #define GPIO_Pin_15                ((uint16_t)0x8000)  /* Pin 15 selected */
 #define GPIO_Pin_All               ((uint16_t)0xFFFF)  /* All pins selected */

 #define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00))
 #define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \
                              ((PIN) == GPIO_Pin_1) || \
                              ((PIN) == GPIO_Pin_2) || \
                              ((PIN) == GPIO_Pin_3) || \
                              ((PIN) == GPIO_Pin_4) || \
                              ((PIN) == GPIO_Pin_5) || \
                              ((PIN) == GPIO_Pin_6) || \
                              ((PIN) == GPIO_Pin_7) || \
                              ((PIN) == GPIO_Pin_8) || \
                              ((PIN) == GPIO_Pin_9) || \
                              ((PIN) == GPIO_Pin_10) || \
                              ((PIN) == GPIO_Pin_11) || \
                              ((PIN) == GPIO_Pin_12) || \
                              ((PIN) == GPIO_Pin_13) || \
                              ((PIN) == GPIO_Pin_14) || \
                              ((PIN) == GPIO_Pin_15))

 #define GPIO_PinSource0            ((uint8_t)0x00)
 #define GPIO_PinSource1            ((uint8_t)0x01)
 #define GPIO_PinSource2            ((uint8_t)0x02)
 #define GPIO_PinSource3            ((uint8_t)0x03)
 #define GPIO_PinSource4            ((uint8_t)0x04)
 #define GPIO_PinSource5            ((uint8_t)0x05)
 #define GPIO_PinSource6            ((uint8_t)0x06)
 #define GPIO_PinSource7            ((uint8_t)0x07)
 #define GPIO_PinSource8            ((uint8_t)0x08)
 #define GPIO_PinSource9            ((uint8_t)0x09)
 #define GPIO_PinSource10           ((uint8_t)0x0A)
 #define GPIO_PinSource11           ((uint8_t)0x0B)
 #define GPIO_PinSource12           ((uint8_t)0x0C)
 #define GPIO_PinSource13           ((uint8_t)0x0D)
 #define GPIO_PinSource14           ((uint8_t)0x0E)
 #define GPIO_PinSource15           ((uint8_t)0x0F)

 #define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \
                                       ((PINSOURCE) == GPIO_PinSource1) || \
                                       ((PINSOURCE) == GPIO_PinSource2) || \
                                       ((PINSOURCE) == GPIO_PinSource3) || \
                                       ((PINSOURCE) == GPIO_PinSource4) || \
                                       ((PINSOURCE) == GPIO_PinSource5) || \
                                       ((PINSOURCE) == GPIO_PinSource6) || \
                                       ((PINSOURCE) == GPIO_PinSource7) || \
                                       ((PINSOURCE) == GPIO_PinSource8) || \
                                       ((PINSOURCE) == GPIO_PinSource9) || \
                                       ((PINSOURCE) == GPIO_PinSource10) || \
                                       ((PINSOURCE) == GPIO_PinSource11) || \
                                       ((PINSOURCE) == GPIO_PinSource12) || \
                                       ((PINSOURCE) == GPIO_PinSource13) || \
                                       ((PINSOURCE) == GPIO_PinSource14) || \
                                       ((PINSOURCE) == GPIO_PinSource15))
																			 
 #define RCC_AHB1Periph_GPIOB             ((uint32_t)0x00000002)

 #define RCC_APB2ENR_IOPAEN    ((unsigned long)0x00000004) 
 #define RCC_APB2ENR_IOPCEN    ((unsigned long)0x00000010) 
 #define  TIM_CR1_CEN          ((uint16_t)0x0001)            /*!<Counter enable */

int RLP_freeclock(void* par0, int * par1, unsigned char * par2)
{
		// the passed arguments	 /////
	// keep these for passing params in and out later
	unsigned char * ByteArray = par0;
	unsigned int length = par1[0];
	unsigned char value = par2[0];
	//////////////////////////////

int index;
int loops;

	// Blinking LED, using GPIO

	 RCC->AHB1ENR |= RCC_AHB1Periph_GPIOB;
	 GPIOB->MODER |= GPIO_Mode_OUT; 
	 GPIOB->OSPEEDR |= GPIO_Speed_100MHz;
	 GPIOB->PUPDR |= GPIO_PuPd_NOPULL;
	 GPIOB->OTYPER |= GPIO_OType_PP;

// ignore this till next //*
//		while (loops<120)
//		{
						
				// GPIOB->BSRRL = GPIO_Pin_0;
				// for (index = 0; index < 1000000; index++);
				// GPIOB->BSRRH = GPIO_Pin_0;
			
//				for (index = 0; index < 21000000; index++); // delay loop.
			
//				GPIOB->ODR ^= 0x1; // Output Data Register @ bit 13, toggled.
			
//			loops++;
//		}
		// End of Blinking LED (this all works)
//*		

// Free running clock at 2 microsecs, with pulse one microsec wide
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // enable the hardware clock to GPIOB

	RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable TIM2 clock on peripheral clock
	GPIOB->MODER = (1 << 26); // set pin 13 to be general purpose output
// return 1;
	NVIC->ISER[0] |= 1<< (TIM2_IRQn); // enable the TIM2 IRQ
// return 2;
// TIM2->PSC = (0x0); // no prescaler, timer counts up in sync with the peripheral clock
	TIM2->PSC = 41999; // 2000 ticks per sec prescaler
	TIM2->DIER |= TIM_DIER_UIE; // enable update interrupt
// return 3;
// TIM2->ARR = 99; // count to 0 (autoreload value 99) This counts 100 clicks
	TIM2->ARR = 1999; // use a longer count, 2000 (with prescaler set to 42000, gives 1 sec tick
// return 4;
	TIM2->CR1 |= TIM_CR1_ARPE; // autoreload on
// return 5;

	TIM2->CR1 |= TIM_CR1_CEN; // counter enabled
return 6;
	TIM2->EGR |= (0x1); // trigger update event to reload timer registers
return 7;
	loops = 0;

	while (loops<1000)
	{
		// do nothing
		loops++;
	}

return loops;
}
int main()  // this not used in managed system, only calls to functions above
{
	while(1);
}

#11

And here is the missing interrupt handler…

void TIM2_IRQHandler(void) 
{
	// This is the Interrupt Handler code (replaces the standard code of the same name
  // flash on update event
  if (TIM2->SR & TIM_SR_UIF) GPIOB->ODR ^= (0x01);
   
  TIM2->SR = 0x0; // reset the status register
}


#12

As a further request… does anyone have some native code interrupt-driven timer that I can try please? This is for the Cerbuino Bee.

My requirement is to produce a clock at 1MHz with a small amount of processing at each tick. I can see how to do this, and it must be in native code to get the speed.

As I cannot get even an interrupt-driven ‘Blinky’ to work at the moment, I am getting desperate!

Any help appreciated…!


#13

It looks like you are on the right track, not sure why it would not work for you.


#14

What part of your code doesn’t work? The original post had returns in them you said were never getting reached. But that code has been modified substantially in your next post.

Also: I’m not really sure why you’re not just using a debugger, stepping through code, and checking to see where things break?

If you set a breakpoint in the ISR, does it fire?


#15

@ Ian - I have not tried this from RLP on the Cerberus devices, but if I remember correctly (I will double check tonight) the STM32 firmware actually cascades the timers on the device to get greater range on the timer counter. It might be that when you configure your timer you are interfering with the NETMF internals.

Like I say, I need to double check, but I seem to remember seeing this when I was browsing the code a few months ago, I work mostly with the Hydra so I am not that familiar with the Cerb firmware.


#16

Thanks guys, I have tried moving the code by adding in some random initialisation at the start, but it still fails in the same place ( by not processing the return). So this may suggest that the Native code (which is virtually undebuggable as the break points do not return to the Managed code) may be interacting with the management routine which should be waiting patiently in the background for a return from the native code.

I don’t know what the timers are set for in the managed code (NETMF), and I may be interfering with them.

This stuff runs on the STM Discovery boards, and is a modified (shortened) version of that code using the Keil muvision compiler.

I have cut down the code to that which is shown so as to avoid causing further confusion.

It would be good to have a simle interrupt driven timer so that I can see what works. any suggestions?


#17

I didn’t realize you were trying to run that code inside of RLP/Interops – I thought you were just debugging a stand-alone native project.

The STM32F4 port, by default, uses Timer 2 as the 32-bit timer and Timer 3 as the 16-bit timer. You won’t be able to use them.


#18

Thanks Jay, that sounds reasonable enough.

I tried using TIM6 and have the same problem; any further thoughts?


#19

When I can’t get something working like that, I start with the simplest possible project and slowly build things up.

Therefore, I’d recommend that you do this:
[ul]Start with a blank C++ project in MDK. No RLP/interop crap; just a regular old MDK project.
Declare an ISR function
In the main() function, configure the timer and then sit in a while(1) loop forever.
Set a breakpoint in the ISR and see if it ever fires.[/ul]

If you can get that working, and then it stops working when you put it into an RLP/interop library, then you know something in the porting kit is screwing things up. Try a different timer and repeat from the beginning.

If you can’t get that working, you can post your code here and we can have a look at it.


#20

Thanks Jay, just a little background… I started working on the Cerbuino Bee because I wanted a good development environment in which to build software for eventual use on the Cerb40.

However, The main development is stalled as I have reduced the code down to isolate the problem. I agree that the best way forward is to develop a very simple program to demonstrate the timer. Currently I am using Keil muvision to compile the native code in C/C++, and then NETMF on the Bee via Microsoft Visual C# 2010 Development System.

Although all of this is tricky to master, it is good enough for development, and can be handed over to others when completed. You suggested using a basic MDK project, and I ask which system you had in mind?

I am a little reluctant to introduce yet another variation in to the overall project, having started with a STM Discovery environment, and Raspberry Pi (only to find that neither the provided Linux environment, nor RTOS could provide a suitable solution at the time), so here I am, and just seem to be stuck at the moment.

I would be pleased to hear further from you.