2012-12-02 12:44 AM
I am writing some code to enable SPI to use the accelerometer. But when I enable the GPIOA clock in RCC_AHB1ENR it bricks the board and I have to use the BOOT pin to reset it. Here is the piece of code that makes it brick.
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOEEN; But when I change this line of code to: RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN; It does not brick the board anymore. I checked theRCC_AHB1ENR_GPIOAEN define and it has the value 0x00000001 which is the right mask. Why does it not like it when I enable the GPIOA clock? Here is the entire program that I have written so far.//Accelerometer
#include <
stdio.h
>
#include ''STM32F4xx.h''
#include ''LED.h''
#define CS_HIGH() GPIOE->BSRRL |= (1<<
3
)
#define CS_LOW() GPIOE->BSRRH |= (1<<
3
)
void SPI_init(void);
void acc_init(void);
unsigned char SPI_send(unsigned char data);
void acc_cmd(unsigned char cmd, unsigned char addr);
void acc_write(unsigned char data, unsigned char addr);
unsigned char acc_read(unsigned char addr);
unsigned char get_x_axis(void);
unsigned char get_y_axis(void);
unsigned char get_z_axis(void);
void delay(void);
int main(void)
{
LED_Init();
SPI_init();
while(1)
{
LED_On(1);
delay();
LED_Off(1);
delay();
}
}
unsigned char SPI_send(unsigned char data)
{
SPI1->DR = data;
while(SPI1->SR & SPI_SR_BSY);
return SPI1->DR;
}
void acc_write(unsigned char data, unsigned char addr)
{
}
unsigned char acc_read(unsigned char addr)
{
unsigned char data = 0;
return data;
}
void SPI_init(void)
{
/*********PINOUT*************
SCK = PA5
MOSI = PA7
MISO = PA6
CS = PE3
INT1 = PE0
INT2 = PE1
*****************************/
//Enable GPIO Clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOEEN;
//Enable pins as output or input
GPIOA->MODER |= GPIO_MODER_MODER5_1|GPIO_MODER_MODER7_1;
GPIOE->MODER |= GPIO_MODER_MODER3_0;
//GPIO pin speed
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5_0|GPIO_OSPEEDER_OSPEEDR6_0|GPIO_OSPEEDER_OSPEEDR7_0; //25Mhz gpio
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0_0|GPIO_OSPEEDER_OSPEEDR1_0|GPIO_OSPEEDER_OSPEEDR3_0; //25Mhz gpio
//Pull up configuration
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR6_0; //1 = pull down 0 = pull up default is pull up/down disabled
GPIOE->PUPDR |= GPIO_PUPDR_PUPDR0_0|GPIO_PUPDR_PUPDR1_0;
//Enable SPI Clock
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
//Enable Alternate Function on SPI pins and INT Pins
GPIOA->AFR[1] |= 0x55500000;
//Configure SPI for master mode and Fpclk/64
SPI1->CR1 |= SPI_CR1_SPE|SPI_CR1_MSTR|SPI_CR1_BR_0;
}
void delay(void)
{
unsigned long i = 0;
for(i=0; i<5000000; i++)
{
}
}
#gpioa-clock
2012-12-02 06:31 AM
I hate register level minutia, you can waste hours of time, as you're undoubtedly learning.
Some observations : You want to mask on values, ORing them on often results in getting more bits set than desired. With AFR[1], I think you're actually messing with PA[13,14,15], so much JTAG/SWD joy there as you break the debug interface. The debug interface runs some of your initial code as it wrestles control of the CPU, if you do a number of hazardous things the board with not respond.2012-12-02 09:29 AM
Your right! It was the GPIOA->AFR[1] line. I was changing pins 13,14,15. I changed it to
GPIOA->AFR[0] and it does not brick the board. Thanks for looking at the code to see the error.2012-12-02 01:00 PM
I'm also getting a MODF error (Mode fault error) when I put SPI1 in master mode. I read is was because of the NSS pin being pulled low?? But I set the pin as an output and pulled it high. I also made it an input and directly connected to VDD. But I still get the MODF error.
2012-12-02 01:11 PM
I forgot to put that pin in alternate function mode. Can't believe I missed that. I figured it out.