I've been trying to get the SPI1 on the stm32f103c8 (blue pill board) working correctly for some time now. As I'm just starting to learn ARM I am simply trying to shift data to a 74hc595 shift register and latch it to light up a byte of LEDs. I am not reading back any data so I only have MOSI, SCK and SS lines.

At first I wasn't getting anything out but reading some online examples I could fix these first problems to get the comms going (needed to set correctly GPIOA pins and set software SS).

The main problem right now is that if I don't include pullup resistors on all lines (MOSI, SCK and SS) the microcontroller doesn't output anything on any line (checked with a scope). On top of this, after adding pullup resistors the rise time on the pulses is very slow so I can't use too high a frequency (with 10k pullups I'm limited to about 250kHz SCK, switching to 330R about 4MHz). I am working on a breadboard, but even then with AVR and messier wiring I could get a 4MHz SPI working no problem without any added resistors and the waveforms were cleaner.

Here are 2 pictures (sorry for the abysmal state of my scope screen) transmitting the byte 0b01110010 at a 250kHz clock. Top trace is SCK, bottom is MOSI. First picture is with 10k pullups and the second with 330R pullups that make the waveforms much nicer (but shouldn't be needed).

I'd appreciate some help to figure out what's going on.

![10k pullups and 250kHz clock](https://i.sstatic.net/CZlqD.jpg)

![330R pullups and 250kHz make waveform a lot nicer](https://i.sstatic.net/8TEkn.jpg)

The relevant parts of my code are:
```
#define SS_LOW		GPIOA->BSRR |= 1 << 4 + 16;
#define SS_HIGH		GPIOA->BSRR |= 1 << 4;

// SPI GPIO configuration
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIOA->CRL |= 0b0011 << 4 * 4;	// Set pin A4 as PP out 50mHz for SS
GPIOA->CRL |= 0b1011 << 5 * 4;	// Set pin A5 AltFunc PP out 50mHz for SCK
GPIOA->CRL |= 0b1011 << 7 * 4;	// Set pin A7 AltFunc PP out 50mHz for MOSI
SS_HIGH;

// SPI1 configuration 	
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;		// Enable SPI1 clock
SPI1->CR1 |= SPI_CR1_SSM;		// Software SS
SPI1->CR1 |= SPI_CR1_SSI;
SPI1->CR1 |= SPI_CR1_BR_0;		// Set prescaler
SPI1->CR1 |= SPI_CR1_BR_1;
SPI1->CR1 |= SPI_CR1_BR_2;
SPI1->CR1 |= SPI_CR1_MSTR;		// Master mode
SPI1->CR1 |= SPI_CR1_SPE;		// Enable SPI

// Transmit byte
SS_LOW;
SPI1->DR = 0b01110010;
while(!(SPI1->SR & SPI_SR_TXE));
while(SPI1->SR & SPI_SR_BSY);
SS_HIGH;
```

 [1]: https://i.sstatic.net/CZlqD.jpg
 [2]: https://i.sstatic.net/8TEkn.jpg