I'm trying to interface a 4-wire resistive touchscreen to a STM32F429 Discovery board but I can't figure out how it works. I want the MCU to detect a touch so I configured the 4 pins like this:
X+ --> input w/pullup connected to EXTI external interrupt
X- --> input floating (tristated)
Y+ --> input floating (tristated)
Y- --> output to GND
in this configuration I should be able to detect a touch and trigger an interrupt on the EXTI line so I can enter a ISR and sample the x and y values with the ADC. But when I connect the X- pin the X+ pin goes to near GND. It seems like current flows between X+ and X- (so the X- is not tristated?).
Here's the code I use to configure the GPIO pins:
GPIO_InitTypeDef gpio;
gpio.Pin = GPIO_PIN_2 | GPIO_PIN_1;
gpio.Mode = GPIO_MODE_INPUT;
gpio.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &gpio);
gpio.Pin = GPIO_PIN_0;
gpio.Mode = GPIO_MODE_INPUT;
gpio.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &gpio);
gpio.Pin = GPIO_PIN_5;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOA, &gpio);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
/* initialization using registers, works the same as above */
// /* Xr and Yu open (input floating) */
// GPIOA->MODER &= ~(GPIO_MODER_MODE2 | GPIO_MODER_MODE1);
// GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPD2 | GPIO_PUPDR_PUPD1);
//
// /* Xl input with pull-up */
// GPIOA->MODER &= ~GPIO_MODER_MODE0;
// GPIOA->PUPDR |= GPIO_PUPDR_PUPD0_0;
//
// /* Yd to GND (output set to 0) */
// GPIOA->MODER |= GPIO_MODER_MODE5_0;
// GPIOA->ODR &= ~GPIO_ODR_OD5;
I can't understand what I am doing wrong or how to configure the tristated pins correctly so they don't pull down the X+ pin.
Between selecting the touch event and reading the touch position, you must reconfigure the pins. The following is from an NXP application note (AN10675), but applies to any microcontroller and can be adapted to STM32:
The outputs are set to provide a voltage source for the analogue measurement of the effective voltage divider formed by the touch position:
On the STM32 it is of course important not to use the GPIO configuration lock feature on these pins as you need three different configurations to read a single touch position event.
Related
I have a MSP chip and a LCD screen - throughout my code I output messages to my LCD screen. 80% of the time it works but if I do a power cycle the screen will get stuck on "UART Baud: 9600". I am not sure if there is something I am missing in the initialisation of the LCD Screen:
P3SEL = 0x30; // P3.4,5 = USCI_A0 TXD/RXD
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide)
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS_3+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE;
Digole_setLCDColRow(20,4);
Digole_disableCursor();
__delay_cycles(1000);
Digole_clearScreen();
__delay_cycles(1000);
Digole_setPrintPos(0,0,0);
Digole_printStr("PFA Error Messages");
__delay_cycles(1000);
Any help would be appreciated...
I am using IAR embedded workbench, code is in C, MSP chip, Digole 2004A display using the RXD/TXD mode.
I would like to configure tim3 ch1 ch2 as encoder mode, I have the same code on tim2( it's also general purpose timer) and it's working good.
Maybe there's another bits should I set but I cant find them.
I was trying to configure this timer to work without any outputs, just generate interrupt after set period of time but it's not working as well.
//TIM2 CH1 PA0 CH2 PA1 AF1
//TIM3 CH1 PE2 CH2 PE3 AF2
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN ;
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN;
GPIOA->MODER |= GPIO_MODER_MODER0_1 | GPIO_MODER_MODER1_1;
GPIOE->MODER |= GPIO_MODER_MODER2_1 | GPIO_MODER_MODER3_1;
GPIOA->AFR[0] |= 0X00000011;
GPIOE->AFR[0] |= 0X00002200;
TIM2->SMCR = TIM_SMCR_SMS_0;
TIM2->CCMR1 = TIM_CCMR1_CC1S_0|TIM_CCMR1_CC2S_0;
TIM2->ARR = 24;
TIM2->DIER = TIM_DIER_UIE;
TIM2->CR1= TIM_CR1_CEN;
TIM3->SMCR = TIM_SMCR_SMS_0 ;
TIM3->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
TIM3->ARR = 24;
TIM3->DIER = TIM_DIER_UIE;
TIM3->CR1= TIM_CR1_CEN ;
enter image description here
Set SMCR to 0
Your code sets both timers to encoder mode 1, see the description of the SMCR register in the reference manual.
0001: Encoder mode 1 - Counter counts up/down on TI1FP1 edge depending on TI2FP2 level.
In this mode, the timer counter is incremented or decremented by the signals on then CH1 and CH2 input, instead of the internal clock. There must be some other component on the board, or line noise when they are unconnected, that managed to trigger TIM2 a few times.
PE2 is connected to an output of another IC
Check the schematics in the board user manual. PE2 is connected to the DRDY output of the onboard accelerometer.
You can use the CubeMX tool to find available pins for TIM3. Select your board in the Board Selector screen, it will show that PE2 and PE3 are already connected to something.
Set TIM3 combined channels to encoder mode, it will assign some free pins to the timer. You can then hold down CTRL and click on the pin to see alternatives (they will blink in blue), and you can drag the pin assignments with the mouse.
Ok, I find a solution :)
If I assign TIM3 CH1 to PB4 and CH2 to PB5 it's work good, but I don't understand why, can someone explain it ?
I have to wire a code for STM32F4 discovery and pcf8574 with I2C.
I can't use any library function. I try something I didn't do it. I did write after init code.
My init code
RCC->APB1ENR|=RCC_APB1ENR_I2C1EN ; // enable APB1 peripheral clock for I2C1
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOBEN; // enable clock for SCL and SDA pins
//SCL on PB6 and SDA on PB7
GPIOB->MODER|=GPIO_MODER_MODER6; // set pin to alternate function
GPIOB->MODER|=GPIO_MODER_MODER7; // set pin to alternate function
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR6; //set GPIO speed
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR7; //set GPIO speed
GPIOB-> OTYPER |= GPIO_OTYPER_OT_6; // set output to open drain --> the line has to be only pulled low, not driven high
GPIOB-> OTYPER |= GPIO_OTYPER_OT_7; // set output to open drain --> the line has to be only pulled low, not driven high
GPIOB-> PUPDR |=GPIO_PUPDR_PUPDR6_0; // enable pull up resistors
GPIOB-> PUPDR |=GPIO_PUPDR_PUPDR7_0; // enable pull up resistors
GPIOB-> AFR[1] = 0x44000000; // Connect I2C1 pins to AF (af4)
// configure I2C1
I2C1-> CR2 = 8; // set peripheral clock to 8mhz
I2C1-> CR2 = 40; // 100khz i2c clock
I2C1-> CR2 |= ~(I2C_CR1_SMBUS); // I2C mode
I2C1-> OAR2 = 0x00; // address not important
I2C1-> CR2 |= 1; // i2c enable;
I2C1-> CR2 |= ~(I2C_CR1_SMBUS); // I2C mode
This line does something different that you think. If the idea was to clear that bit it shuold be
I2C1-> CR2 &= ~(I2C_CR1_SMBUS); // I2C mode
Otherwise you set all the bits in the CR2 register except I2C_CR1_SMBUS which is left unchanged.
Another problem is that you try to set CR2 using CR1 bit definitions.
Same is with the enable bit - wrong register.
I2C should be reset before first use on many STM32 micros.
Hi I am having the same problem with setting an STM32F4 DISCO board to go
I noticed that you are setting
I2C1-> CR2 = 8; // set peripheral clock to 8mhz
I2C1-> CR2 = 40; // 100khz i2c clock
you are writing twice to the same register.
For the I2C clock you need to set I2C1->CCR to the calculated value
I hope this helps
Recently I've been trying to get the I2C bus working on the STM32F030F4P6 MCU, but with little luck.
I'm using an STM32F0 module and have found plenty of resources for the STM32F1 module I2C initialization, but nothing specific about the STM32F0 initialization/transfer process.
Here's my initialization code:
void i2c_init(uint8_t ownAddress)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// Enable GPIOA clocks
RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
// Configure I2C1 clock and GPIO
GPIO_StructInit(&GPIO_InitStructure);
/* I2C1 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* I2C1 SDA and SCL configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* I2C1 Reset */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
/* Configure I2C1 */
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
//I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = ownAddress;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
//I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
In order to test to see if my setup was correct I designed some I2C transmission code that would transfer data in a never ending loop. Here's the code for that:
while(1)
{
I2C_SlaveAddressConfig(I2C1, RegName);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_NumberOfBytesConfig(I2C1, 8);
I2C_SendData(I2C1,0b00000000);
I2C_GenerateSTOP(I2C1, ENABLE);
}
Where:
RegName = 0x75
SDA = GPIO_PIN_10 on GPIOA
SCL = GPIO_PIN_9 on GPIOA
I2C = I2C1
ownAdrress = 0x68
When I scope the I2C lines after I start this code I get a floating voltage around 160mV. When I step through the code every one of the I2C function calls happen and complete, so that's why I was thinking that it had something more so to do with my initialization of the pins themselves.
My problem is very similar to this thread, but was never answered:
https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F0%20I2C%20code%20doesn%27t%20work&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=1342
Edit 1: Here's my latest code; still not working (Edit 2: Updated to what I currently have; moved things into more correct locations):
void i2c_init(uint8_t ownAddress)
{
/* TypeDefs for GPIOA and I2C1 */
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/* Enable GPIOA clocks and I2C1 clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Configure I2C1 clock and GPIO */
GPIO_StructInit(&GPIO_InitStructure);
/* I2C1 SDA and SCL configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //UP
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
/* GPIO AF Configuration -> GPIO_AF_1: USART2, CEC, Tim3, USART1, USART2,EVENTOUT, I2C1, I2C2, TIM15 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* I2C1 Reset */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
//I2C_DeInit(I2C1);
/* Configure I2C1 */
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1 = ownAddress;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
//I2C_AcknowledgeConfig(I2C1, ENABLE);
}
As you can see I added the two lines GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); and GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); where I found that GPIO_AF_1 had the alternate function of I2C1 from the STM32F0 Standard Peripheral bibliotheek.
Any other ideas? I've been playing around with the clocks to see if that changed anything and have been adding snippets of other people's code just to see if that has any effect on the output of my device.
Edit 3: I have tried pulling both the SDA and SCL lines up to VCC with a 1kohm resistor as instructed by this guide: https://electronics.stackexchange.com/questions/57121/i2c-pullup-resistor-calculations
->(3.3V-0.4)/3mA ~= 1kohm
Edit 4: After going through my code line by line I tried outputting various flag bit registers. Specifically these registers: isr = I2C1->ISR;, cr1 = I2C1->CR1;, and cr2 = I2C1->CR2;
The flag I get after initiating the I2C transfer handling with I2C_TransferHandling(I2C1, 0x02, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); was 0x8001 which can be deciphered down to two errors:
#define I2C_ISR_BUSY ((uint32_t)0x00008000) /*!< Bus busy */
and
#define I2C_ISR_TXE ((uint32_t)0x00000001) /*!< Transmit data register empty */
I've found some work arounds at this link here (remove the space after https: to go to the link -> stack overflow won't let me post more than 1 link for some reason): https: //my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FSTM32L151RB%20I2C%20Busy%20flag%20always%20set&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=690 that I'm looking to implement and will report back as soon as I try them out.
I have I2C working as master and slave on the F0. The main issue I can see with your code is that in master mode you absolutely must set the I2C_Timing initialisation structure member. See RM0091 for sample values that correspond to the frequency you want to generate on SCL. In slave mode the clock is recovered from the master so the timing member doesn't appear to be used.
As the others have said, external pullups to Vcc on SCL and SDA are not optional and must be present once per bus not per peripheral as you incorrectly stated in a comment. You were right to use the calculator to choose suitable values because the internal pullups in the STM32 at about 30-50K are far too weak for use as I2C pullups.
The problem is that you don't configure proper AF (Alternate Function) source for I2C pins. After reset registers that configure AF are all 0, and I2C's function is 1, so your I2C peripheral is in fact disconnected from the GPIOs.
Technically it makes no difference when you configure that, but it's best to do that before GPIO configuration to minimize any unwanted transitions on the pins.
Edit: You MUST have the pullups on the I2C pins - without them you have "low" level there, and I2C peripheral detects that as bus error, which obviously prevents it from working properly. Either connect external resistors, or at least enable internal pullups instead of "no pullups/no pulldowns" configuration.
Moreover - it's just not possible for an "open drain" pin to work properly without pullup.
The Core of Cortex M0 is different then Core of Cortex M3, STM32f030f4 has AHB and APB1 (bridged) only. The C code of STM32f1xx never be run under STM32f0xx.
Use STM32F0xx_Snippets_Package for solve your key problems.
I just noticed this too:
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
So you have disabled the clock after you enabled it. I don't see where you have re-enabled it later.
I notice that you are mapping the pins to AF_1 and that is for the UART function.
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
You need to map them to AF_4 to use the I2C function.
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_4);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_4);
I'm trying to configure SPI to work with a ST7565 GLCD library which is given here. For now, I'm trying to use SPI1 to achieve this. When the init function -which is given below- is called in main(), it causes the program to loop in assert_failed function.
void init_SPI1(void){
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
// enable clock for used IO pins
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* configure pins used by SPI1
* PA5 = SCK
* PA6 = MISO
* PA7 = MOSI
*/
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// connect SPI1 pins to SPI alternate function
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
// enable clock for used IO pins
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
/* Configure the chip select pin
in this case we will use PE7 */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high
// enable peripheral clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/* configure SPI1 in Mode 0
* CPOL = 0 --> clock is low when idle
* CPHA = 0 --> data is sampled at the first edge
*/
SPI_InitStruct.SPI_Direction = SPI_Direction_1Line_Tx; // set to full duplex mode, seperate MOSI and MISO lines
SPI_InitStruct.SPI_Mode = SPI_Mode_Master; // transmit in master mode, NSS pin has to be always high
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; // clock is low when idle
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; // data sampled at first edge
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; // set the NSS management to internal and pull internal NSS high
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // SPI frequency is APB2 frequency / 4
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
SPI_Init(SPI1, &SPI_InitStruct);
SPI_Cmd(SPI1, ENABLE); // enable SPI1
}
I've noticed that program goes in infinite loop inside assert_failed function when it reaches SPI_Init() line:
SPI_Init(SPI1, &SPI_InitStruct);
The assert_failed function ( Default in Firmware Library) is below:
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
I don't know what does it supposed to mean that it loops in assert_failed function. Is it a problem to do with the SPI configuration. I need guidance to understand the problem and generate a solution. Any help will be greately appreciated. Thanks in advance.
EDIT: I've checked inside of the SPI_Init function in stm32f4xx_spi.c
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
{
uint16_t tmpreg = 0;
/* check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
/* Check the SPI parameters */
assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));
assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
Since the library is locked, I cant get to type anything inside to debug in Live Watch. (I'm using IAR EWARM)
It loops in assert() because the assert failed, so the loop is there to stop further execution.
Just step up on your stack so that you can see which assert in the peripheral library it was that failed. The library does pretty extensive validation of its parameters, so probably something is wrong in one of your calls.
UPDATE It seems you never initialize the CRCPolynomial field, but it's asserted upon. I suggest adding a call to SPI_StructInit() to make sure your init struct is sanely initialized, before you start setting it up according to your application's wishes.