Simpe C code physically breaks nucleo boards - stm32

Code below physically breaks nucleo boards. 2 so far.
ST links is unable to connect and boards are not detected.
first dead one was xncleo stm32f411re, another one is nucleo stm32f446re.
I'm a complete beginner and that is pretty much my first code.
and 2 boards dead;) The question is why it may happen? or can one reset the board harder that normal jumper reset
int main()
{
RCC->AHB1ENR = (1<<0);
GPIOA->MODER = (1<<5);
while(1)
{
GPIOA->ODR |= (0<<5);
}
}
This is similar to this question ->
https://electronics.stackexchange.com/questions/204996/stm32-st-link-cannot-connect-to-mcu-after-successful-programming
, answer to which helped me to restore the board, however answers to my problem in this thread are also very helpfull.

some pins used for debugging need to have some settings. if you change those settings the debugger cannot connect anymore. you need to set the debugger to connect under reset when the debug pins are in the initial corrct state. stm32 processors cannot be bricked this simple way.
so not listen to the advices that you need to use crappy STM libraries. just only set the pins you use, not the whole port.

Yes, your problem is with the line "RCC->AHB1ENR = (1<<0);". That enables power to GPIOA, but disables power to the other GPIOs (B,C,D,E, and H on the F411), which includes the SWD pins.

Edit:Reseting problem solved here: https://electronics.stackexchange.com/questions/204996/stm32-st-link-cannot-connect-to-mcu-after-successful-programming
the reason problem occured solved below
Ok, it doesn't physically break the board. Needed hard reset - shorting rst and sb11 pins on nucleo stm32f446re. didn't try on xnucleo yet.
User P__J__ got it right in the comment. I'll cite:
just do not assign to the moder. use |= or &= instead – P__J__
Done.
And the fixed code:
int main()
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
GPIOA->MODER |= GPIO_MODER_MODE5_0;
while(1)
{
GPIOA->ODR |= GPIO_ODR_OD5;
}
}

Related

STM32F105RB GPIO PB8 PB15 PB9 and PB3 Toggles together

please.
I am having weird behavior with STM32F105RB (64pins) board, the issue is on GPIO PB8, PB15, PB9 and PB3.
GPIO_InitTypeDef BOARDPINS;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
BOARDPINS.GPIO_Pin=(GPIO_Pin_9);
BOARDPINS.GPIO_Mode=GPIO_Mode_Out_PP;
BOARDPINS.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &BOARDPINS);
DISABLEJTAG();
The Problem:
Each time i configured one of these as OUTPUT PUSH PULL (PB8, PB15, PB9, PB3) and toggle a pin, they all act like there is a shot circuit. all these three pins will toggle together.
My Diagnosis:
I tested for continuity (shot circuit) among these pins by taking off power and physically test pair of these GPIOs. but no shot was detected.
I checked the datasheet and reference manual but did not see any special feature associated with these pins.
Every other pin with exception of these four toggles individually, no issue.
My based IDE is Truestudio 9.3.0, i tried using eclipse with arm plugins and also tried Arduiono 1.18.19. none got it solved.
Now, I am asking
What could be wrong?
Is there feature is need to disable?

STM32 F3 I2C on Port F SCL Push-Pull Failure

We're currently using STM32F373CC micros in several of our designs. Part of our standard design has an EEPROM connected via I2C. We have our own hardware layer that is tried and proven over the decades. However, it relies on the I2C port pins having pull-ups connected externally.
On some of our new designs we have designed out the pull-up on the SCL line and have set the port pin to Push-Pull mode. In theory, this should be no problem. However, what we've found is that the micro seems to be treating the port pin as open-drain regardless of the setting. For this particular design, we're using PF6 and PF7 as SCL and SDA respectively. With no pull-up connected, the SCL line is flat-lined. With internal pull-up enabled, the SCL line is pulsing, but the rise time is so long it's not working.
Nothing in the reference manual or the datasheet says anything about this issue. In the errata sheet we have (V4), there's quite a bit about the GPIO and I2C, but nothing that seems to relate to this.
For what it's worth, I'll copy and paste the relevant bit of the initialisation:
switch( kasPinMap[eSCL].lwI2CNum )
{
case 1: RCC_APB1ENR.I2C1EN = TRUE; nI2CEEpsRegisters = (void*)&I2C1_CR1; break;
case 2: RCC_APB1ENR.I2C2EN = TRUE; nI2CEEpsRegisters = (void*)&I2C2_CR1; break;
}
//configure the pins
DIO_vConfigure( kasPinMap[eSCL].ePort, kasPinMap[eSCL].lwBit, DIOkeM_Alternate, DIOkeD_PushPull, DIOkePU_None, DIOkeSP_Medium, kasPinMap[eSCL].lwAFN );
DIO_vConfigure( kasPinMap[eSDA].ePort, kasPinMap[eSDA].lwBit, DIOkeM_Alternate, DIOkeD_OpenDrain, DIOkePU_None, DIOkeSP_Medium, kasPinMap[eSDA].lwAFN );
//reset and enable the peripheral
nI2CEE_vReset();
In the debugger, GPIOF looks like this:
AFR values are set to 4.
The I2C registers look like this:
And the RCC registers look like this:
Our Technical Director mentioned that to comply with the I2C standard and allow for multi-master mode, both SCL and SDA should both be open-drain. However, all we have here is the F3 and the EEPROM.
Any thoughts on why we might not be getting the push-pull action out of the SCL line would be appreciated.

STM32 Register Value Doesn't Change

Problem Definition
Board: STM32F407
Hello all,
I am trying to change any register value. But it doesn't change. For example if we look GPIOB port's MODER register it has default "0x0000 0280" value for port B. This means that MODER registers 7 and 9 have a value of 1, other MODER registers have a value of 0. I am trying to change 1 to 0 for MODER 7 register. I am sharing the simple one-line I did below.
GPIOB ->MODER &= ~(1 << 7);
DEBUG PROCESS
I am debugging the code. And register value doesn't change. I tried for some another register to see whether it is done or not. Bu it didn't.
What can I do, what is my fault.
Thank in advance
You need to enable the GPIOB clock in one of the RCC regesters first.
If the clock is disabled the digital part of the peripheral is disabled too.
I faced the same issue. And the solution is you forgot to enable the clock of the peripheral.
RCC->AxBxENR |= (1<<BITPOSITION);

LGT8F328P-SSOP20 arduino clone and SPI

LGT8F328P clone I Would like to use the SPI interface.
as indicated on the datasheet:
It has everything necessary but I don't know how to configure <SPI.h>.
and how to make it works for example with W5500?
I found out the problem, using LGT8F328P-SSOP20 there are two pins identical!
the MOSI on 11 and SS on 10.
in this way I cannot communicate with SPI protocol.
This may help you:
https://github.com/dbuezas/lgt8fx/issues/54
Somebody else got SPI working on the SSOP20 package by overriding the default pin IO direction of PB0
For W5500 chip, you can using ethernet2 library. Edit the ethernet2.h file for replacing w5500_cspin to 9.
EthernetClass() { _dhcp = NULL; w5500_cspin = 9; } //default 10
void init(uint8_t _cspin = 9) { w5500_cspin = _cspin; }
This is specially for LGT8F328P-SSOP20

Clearing pending EXTI interrupt in stm32f103

I'm trying to toggle an LED at PC13 by toggling PC14, the problem is that the interrupt handler is kept being called without toggling PC14 and the the pending interrupt is not cleared using EXTI->PR register, nor cleared manually using the debugger. I tried also clearing it in NVIC->ICPR, I'm not sure why there are two registers for clearing the same interrupt.
here is my code
and you can find the header in
https://github.com/AymenSekhri/tinyHAL-STM32f103/tree/master/STM32F103-HAL/tinyHAL
/*
* Description:
* Toggle LED at C13 whenever C14 goes from HIGH to LOW.
*
*/
#include "tinyHAL/stm32f103_hal.h"
int main(){
//Enable AFIO clock from RCC
enablePeripheralClock(Peripheral_AFIO);
//Enable and configure C13 & C14
enablePeripheralClock(Peripheral_GPIOC);
configureGPIO(Peripheral_GPIOC, 13, GPIO_MODE_OUT_50MHZ, GPIO_CONF_OUT_PUSHPULL);
configureGPIO(Peripheral_GPIOC, 14, GPIO_MODE_IN, GPIO_CONF_IN_PUSHUP_PULLDOWN);
//Link EXTI14 to C14
AFIO->EXTICR[3] = (AFIO->EXTICR[3] & ~(0xF<<8)) | 2;
//Configure inturrput at EXTI14 falling edge
EXTI->FTSR |= 1<<14;
//Unmask interrupt 40 (EXTI10-15)
EXTI->IMR |= 1<<14;
//Set Priority to interrupt 40 (EXTI10-15)
NVIC->IP[40] |= 0x10;
//Enable interrupt 40 (EXTI10-15)
NVIC->ISER[40>>5] |= (1 << (40&0x1F));
while(1);
}
void EXTI15_10_IRQHandler(void){
toggleGPIOBit(Peripheral_GPIOC, 13);
if (EXTI->PR & (1 << 14)){
EXTI->PR |= (1 << 14);
}
//NVIC->ICPR[40>>5] |= (1 << (40&0x1F));
__COMPILER_BARRIER();
}
The best solution to get rid of the electronic noise at the pin that (over-)triggers your EXTI is to improve the hardware - but this is the software board, not the electronic one.
If you had a TIM channel connected to that pin, I would recommend to use it to filter the signal coming in. But I think that PC14 doesn't have a timer.
The second-best solution (and this is where workarounds have already started!) is to use a timer (the TIM, not its channel), either to establish a periodic time base to sample the pin (by DMA or by an ISR, and feed samples into a software-based filtering...) - or to deactivate the EXTI interrupt in the EXTI ISR, start the timer and re-activate the EXTI interrupt when the timer expired.
Both of these µC-based approaches are clumsy and clearly inferior to developing a good hardware. This doesn't say that with a "good" hardware you shouldn't add some debouncing or noise protection inside your software!
As #P__J__ suggest add some denouncing logic. There are two methods for de-bouncing like suing RC filter and using software de-bouncing logic.
Due to noise on the pins ISR is getting executed continously.
You can check one more thing.
Try pulling UP/Down the pin and observe the behaviour. ISR should not get executed if logic level doesn't change on Pin.
Maybe It's because of TAMPER/RTC second output redirected to PC13. I also faced the same problem before when using PC13 as EXTI. Set BKP_RTCCR->ASOE to 1 to force it as alarm output that will never triggered because i dont't set any rtc alarm.