stm32f103c8 jump to application doesn't work - stm32

i write a programmer for boot stm32f103c8 by uart
when submit app.bin file via MCS bootloader(media uart) and in to stm32f103c8 give successful data and then run app.bin by jumpToApp() function. but jumpToApp() doesn't correctly work .
bootloader code (write to flash) :
#define APP1_START (0x08005000) //Origin + Bootloader size (20kB)
#define FLASH_BANK_SIZE (0XB000) //44kB
#define FLASH_PAGE_SIZE_USER (0x400) //1kB
unlockFlashAndEraseMemory();
for(iloop=0 ; iloop < 128; iloop+=4)
{
if(Buf[iloop]!=0x1a)
{
flashWord((Buf[iloop+3]<<24)|(Buf[iloop+2]<<16)|(Buf[iloop+1]<<8)|(Buf[iloop]));
}
}
bootloader code (jump to app function):
typedef struct
{
uint32_t stack_addr; // Stack Pointer
application_t* func_p; // Program Counter
} JumpStruct;
void jumpToApp(const uint32_t address)
{
//application_t jump_to_app;
const JumpStruct* vector_p = (JumpStruct*)address;
deinitEverything();
__set_MSP(*(volatile uint32_t*)vector_p->stack_addr);
vector_p->func_p();
}
app code:
MX_GPIO_Init();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5|GPIO_PIN_7, GPIO_PIN_SET);
while (1)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5|GPIO_PIN_7);
HAL_Delay(500);
}
app setting
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE
#define VECT_TAB_OFFSET 0x00000000U
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE
#define VECT_TAB_OFFSET 0x00005000U
#define FLASH_BASE 0x08005000
app.bin file correctly get and write on flash micro but But it doesn't run.
i use some code in this link and work keil ide

One possible problem is that in jumpToApp you set the stack pointer, and then call the reset handler as a function from C.
Calling a function from C almost always involves adjusting the stack pointer, which will make it incorrect. You need to atomically set the stack pointer and then jump to the function with no possibility of doing anything in between.
Do it from assembly with a function like this:
Header:
void __attribute__((noreturn)) jumpToApp(uint32_t vector);
Source:
jumpToApp:
ldr r1, [r0]
ldr r2, [r0, 4]
msr msp, r1
mov lr, r2
bx lr
I assume that your VECT_TAB_OFFSET setting causes the target application to set its own vector table into SCB-VTOR. If not then jumpToApp needs to do that too.

Related

The sample code does not work on STM32F103C6

experts.
I am new to STM32.
So I downloaded some sample code from github.
https://github.com/yohanes-erwin/stm32f103-keil
And I download the simple led blinking code of it to the STM32F103C6 developing board but it doesn't work at all.
The original program embedded on the chip had been erased successfully ( originally the led was always on and LCD screen shows some text, but now after I download the code, the led is off and screen off. So I think the downloading is successful.) but the code does not work.
When I download the original code to the chip, it works again. So I think the chip isn't broken.
I think it's because of compatibility of sample code and my chip. The sample code was written for STM32F103C8. But it was a very simple code. What is the reason?
Here is the code.
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
void delay(unsigned int nCount);
GPIO_InitTypeDef GPIO_InitStruct;
int main (void)
{
// Enable clock for GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// Configure PA4 as push-pull output
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
while (1)
{
/* Toggle LED on PA0 */
// Reset bit will turn on LED (because the logic is interved)
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
delay(1000);
// Set bit will turn off LED (because the logic is interved)
GPIO_SetBits(GPIOA, GPIO_Pin_4);
delay(1000);
}
}
// Delay function
void delay(unsigned int nCount)
{
unsigned int i, j;
for (i = 0; i < nCount; i++)
for (j = 0; j < 0x2AFF; j++);
}

ESP32 - Connection to MCP23009. Can't get the OUTPUT to HIGH even if the connections returns succesful ( 0 )

I was trying to get an ESP32 working with I2C and because I had it around I took a MCP23009. Schmeantic is in the Image Image
My Code is the following :
#include <Wire.h> // specify use of Wire.h library.
#define MCPAddress 0x20 //I2C Address
#define IO_DIR_REG 0x00 // The Output Register
#define GPIO_REG 0x09 // The GPIO Register
#define IOCON 0x05 // Settings
#define SEQOP_REQ 0b00100000 // Disable address increment
#define I2C_SDA 21
#define I2C_SCL 22
int error;
void setup()
{
Serial.begin(115200);
delay(1000);
Serial.println("Starting Wire");
Wire.begin(I2C_SDA, I2C_SCL);
Wire.setClock(100000); //Frequenz
Wire.beginTransmission(MCPAddress); // Check if connection succesfull
error = Wire.endTransmission();
if(error == 0){
Serial.println("Success");
}else{
Serial.println("Failure: ");
Serial.print(error);
}
//Serial.println("Disable Auto-Address increment!");
//writeBlockData(IOCON,SEQOP_REQ); //Experimental, didn't make it work
Serial.println("Setting Outputs!");
writeBlockData(IO_DIR_REG,0x00);
Serial.println("Writing LOW!");
writeBlockData(GPIO_REG,0x00);
}
void loop()
{
Serial.println("Writing HIGH!");
writeBlockData(GPIO_REG,0b11111111);
delay(3000);
Serial.println("Writing LOW!");
writeBlockData(GPIO_REG,0b00000000);
delay(3000);
}
int writeBlockData(uint8_t cmd, uint8_t val)
{
Wire.beginTransmission(MCPAddress);
Wire.write(cmd);
Wire.write(val);
delay(10);
return Wire.endTransmission();
}
It's fairly simple and the connections works as I get only 0 when I read Wire.endTransmission() but the LEDs never turn High. No matter what I do. Here is the Datasheet from the MCP http://ww1.microchip.com/downloads/en/DeviceDoc/20002121C.pdf
If anybody sees my mistake I would really appreciate it ! I am fairly new to work with I2C so I dont really see it. Even working with a Arduino Library didnt work.
Thanks and greetings !
Well, I didn' read the whole datasheet. The MCP has open drain outputs so turning around the diodes and put the other end into Vdd fixed it.

Does HAL_NVIC_SetPendingIRQ call the ISR to execute?

I am really new to STM32 world so I came across this while reading:
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn);
This will cause the interrupt to fire, as it would be generated by the hardware. A distinctive feature
of Cortex-M processors it that it is possible to programmatically fire an interrupt inside the ISR
routine of another interrupt.
I got this from the book Mastering STM32 (by Carmine Noviello page 208). From this I have understood that If we set this pending bit even from the main function, then the interrupt is generated.
So to try this out, I have written this code:
while (1)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
for(int i = 0; i <10000000; i++);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
for(int i = 0; i <10000000; i++);
HAL_NVIC_SetPendingIRQ(EXTI0_IRQn);
}
}
along with this call back function
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_PIN){
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
}
I have programmed GPIO_PIN_0 as source of interrupt and when I press the push button connected to PA0 the Interrupt works perfectly i.e. ISR is executed. To my surprice HAL_NVIC_SetPendingIRQ function doesn't generate interrupt. I don't understand why?
More Info:
I am using STM32F411VET6 DISCO board
I am using STM32CubeIDE to program the board
Thank you #Tagli. I have found the function HAL_GPIO_EXTI_IRQHandler inside stm32f4xx_hal_gpio.c file. Defalult definition was like this:
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
I got why the GPIO was not being toggled. It was the same reason you have commented above.
I have modified to prove it.
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
HAL_GPIO_EXTI_Callback(GPIO_Pin);
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
Now the callback function is called when the HAL_NVIC_SetPendingIRQ(EXTI0_IRQn); is being called

STM32F103 | libopencm3 | GPIO toggle using interrupt issue

So, I am trying to toggle a LED based on an interrupt from a button.
Ideally the when the button is pressed the LED should toggle i.e. switch on if its off and vice versa. But when I execute this code it toggles and returns to its original state.
Expected Result:
LED OFF » Button pressed » LED ON
Practical Result:
LED OFF » Button pressed » LED ON » LED OFF
I have added a delay for debouncing so bouncing is out of the picture. Also the GPIO's ODR is set in the ISR when the button is pressed so how is it getting cleared while exiting the ISR?
I would really appreciate your help! Thank you.
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/cm3/nvic.h>
#define LEDPIN (GPIO13)
static void exti_setup(void)
{
/* Enable GPIOA and AFIO clock. */
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_AFIO);
/* Enable EXTI0 interrupt. */
nvic_enable_irq(NVIC_EXTI15_10_IRQ);
/* Set GPIO12 (in GPIO port B) to input */
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT, GPIO12);
/* Configure the EXTI subsystem. */
exti_select_source(EXTI12,GPIOB);
exti_set_trigger(EXTI12, EXTI_TRIGGER_BOTH);
exti_enable_request(EXTI12);
}
static void gpio_setup(void)
{
/* Enable clock for GPIO port C */
rcc_periph_clock_enable(RCC_GPIOC);
/* Set LEDPIN (in GPIO port C) as opendrain output */
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, LEDPIN);
}
void delay(){
int i;
for (i = 0; i < 1000000; i++)
{
__asm__("nop");
}
}
void handler(){
delay();
gpio_toggle(GPIOC, GPIO13);
}
int main(void)
{
gpio_setup();
exti_setup();
while (1) {
__asm__("nop");
}
return 0;
}
void exti15_10_isr()
{
exti_reset_request(EXTI12);
handler();
}
Not open drain but push-pull
Butttons should not use EXTI as it makes debouncing more complicated, often floods the uC with interrupts, Use timer interrupt instead to read the key and debounce.
As #dev_eng rightly pointed out the issue was the interrupt being configured as both RISING/FALLING edge.
Configuring it with single EDGE that is either RISING or FALLING solved my problem.

How can you get Eclipse CDT to understand MSPGCC (MSP430) includes?

I'm using Eclipse and CDT to work with the mspgcc compiler, it compiles fine, but the code view highlights all my special function registers as unresolved.
I've made a C project where the compiler is "msp430-gcc -mmcu=msp430x2012", and that's set to look for includes in /usr/msp430/include/. I've set the linker to "msp430-gcc -mmcu=msp430x2012", and that's set to look fo libraries in /usr/msp430/lib/. I've set the assembler to "msp430-as". I've told eclipse it's making an elf and I've disabled automatic includes discovery to not find the i686 libraries on my linux box (stupid eclipse!).
Here's the code:
#include <msp430.h>
#include <signal.h> //for interrupts
#define RED 1
#define GREEN 64
#define S2VAL 8
void init(void);
int main(void) {
init(); //Setup Device
P1OUT = GREEN; //start with a green LED
_BIS_SR(LPM4_bits); //Go into Low power mode 4, main stops here
return(1); //never reached, surpresses compiler warning
}
interrupt (PORT1_VECTOR) S1ServiceRoutine(void) {
//we wake the MCU here
if (RED & P1IN) {
P1OUT = GREEN;
} else {
P1OUT = RED;
}
P1IFG = 0; //clear the interrupt flag or we immidiately go again
//we resume LPM4 here thanks to the RETI instruction
}
void init(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
/*Halt the watchdog timer
P1DIR = ~S2VAL; //Set LED pins as outputs and S2 as input
P1IES = S2VAL; //interrupt on High to Low
P1IE = S2VAL; //enable interrupt for S1 only
WRITE_SR(GIE); //enable maskable interrupts
}
All the variables defines in the mspgcc includes such as P1OUT and WDTCTL show up in the problems box as "not resolved", but remember it builds just fine. I've even tried explicitly including the header file for my chip (normally msp430-gcc does this via msp430.h and the -mmcu option).
I resolved this issue by explicitly including the msp430g2553.h file
#include <msp430g2553.h>
I resolved the issue by following the instructions here