We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
I am writing an I2C master transmitter object. The problem I am having is that the IRQ Handler for I2C1 is not firing. According to the manual, it should fire after the start condition is sent and the status register is 0x08. When I step through the code with the debugger, the status code is 0x08. I am using an MCB1700 development board. Why is it not firing? Did I not configure something properly? For tests, All I am doing is toggling an LED on when the interrupt fires. Once I solve this problem, I will write the rest of the code.
#include <stdio.h> #include <LPC17XX.h> #include "GPIO1Output.h" GPIO1Output out(P1_28); __irq void I2C1_IRQHandler(void) { if (LPC_I2C1->I2STAT == 0x08) { out.Set(); } } int main(void) { // Initialize I2C. LPC_PINCON->PINSEL0 = 0x0F; LPC_PINCON->PINMODE_OD0 = 0x03; NVIC_EnableIRQ(I2C1_IRQn); LPC_I2C1->I2CONSET = 0x40; LPC_I2C1->I2CONSET = 0x20; int status = LPC_I2C1->I2STAT; }
Stepping through the startup file only just initializes the reset handler and the stack heap. Then it jumps into the infinate loop that is supposed to be the interrupt (the B instruction).
It appears as if the default ISR was called.
OK I figured it out. I am using C++ and this forum posting delivered the answer I was looking for. It talks about how the overloading of C++ functions could cause weak references to the intrrupt handlers.
electronics.stackexchange.com/.../bug-in-keil-arm-compiler-with-interrupt-handlers-and-c
All I have to do is put a wrapper around the interrupt functions and that fixes it.
extern "C" { ... Interrupt Functions. }
Is there a better way of doing this or do you always need the wrapper when using C++?
No, C++ does not cause weak references to interrupt handlers.
But C++ uses name mangling, which means the external name the linker sees contains extra characters encoding the returned data type, and the parameter list.
So a C++ file with a function void hello(void) will not let the linker see a function "hello". You don't need to use the braces to wrap. Standard C++ documentation tells you that you can specifiy directly for the function that it should use the C calling convention and have C bindings.
If I Recall/Remember Correctly, For Cortex-M3, or I should say NXP LPC17xx, There are two kind of Keil examples, 1. Older, not CMSIS style; it has two important source files; startup_LPC17xx.s, system_LPC17xx.c 2. Newer, CMSIS style; it has three important source files; startup_LPC17xx.s, system_LPC17xx.c, core_cm3.c Newer Keil MDK provides the CMSIS style source, startup_LPC17xx.s, system_LPC17xx.c, core_cm3.c. If you mix-up the [not CMSIS style source] with [CMSIS style source], you will have some problems to fix.
In your Difference Report->system_LPC17xx_c.htm
Left:
#define PLL0CFG_Val 0x0000000B
Right:
#define PLL0CFG_Val 0x00050063
As per your Difference Report, I believe that If you mix-up different versions of the [CMSIS style source], you will have some problems to fix.
There are also examples from NXP
I don't know, but I would not expect arbitrary files taken from NXP examples to "just work" with Keil examples - or vice-versa.