Question
SPI not working on port B
Posted on February 17, 2016 at 12:57
Hi to all,
I tried to build my own acquisition board using a STM32F030K6 microcontroller and I am experiencing problems with SPI interface. At present only microcontroller is mounted, no other devices on board. As I am using PA5, PA6 and PA7 as analog input I use PB3, PB4, PB5 for SPI interface. I send thorugh SPI interface the value 0x80, but if MISO and MOSI pins are unconnected I receive 0xFF (and this is ok), but when I shortcut them together I receive 0x00 instead of 0x80. Hereafter there is my code: ===================================== &sharpdefine SPISCK 3 // GPIOB &sharpdefine SPIMISO 4 // GPIOB &sharpdefine SPIMOSI 5 // GPIOB &sharpdefine A0 6 // GPIOB - SS0 &sharpdefine A1 7 // GPIOB - SS1 &sharpdefine A2 1 // GPIOB - SS2 MYSPI::MYSPI() { /* SPI PIN */ if(!(RCC->AHBENR & RCC_AHBENR_GPIOBEN)) RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // Enable GPIOB clock GPIOB->MODER &= ~(0x03<<(2*SPISCK) | 0x03<<(2*SPIMISO) | 0x03<<(2*SPIMOSI)); //Alternate function GPIOB->MODER |= 0x02<<(2*SPISCK) | 0x02<<(2*SPIMISO) | 0x02<<(2*SPIMOSI); GPIOB->OSPEEDR &= ~(0x03<<(2*SPISCK) | 0x03<<(2*SPIMISO) | 0x03<<(2*SPIMOSI)); //Pin speed GPIOB->OSPEEDR |= 0x03<<(2*SPISCK) | 0x03<<(2*SPIMISO) | 0x03<<(2*SPIMOSI); GPIOB->PUPDR &= ~(0x03<<(2*SPISCK) | 0x03<<(2*SPIMISO) | 0x03<<(2*SPIMOSI)); //Pull up GPIOB->PUPDR |= 0x01<<(2*SPISCK) | 0x01<<(2*SPIMISO) | 0x01<<(2*SPIMOSI); GPIOB->OTYPER &= ~(0x01<<SPISCK | 0x01<<SPIMISO | 0x01<<SPIMOSI); //PushPull GPIOB->OTYPER |= 0x00<<SPISCK | 0x00<<SPIMISO | 0x00<<SPIMOSI; GPIOB->AFR[0] &= 0xFF000FFF; //Alternate function 0 (SPI1) // GPIOB->AFR[0] &= (uint32_t) ~(0xF<<(4*SPISCK) | 0xF<<(4*SPIMISO) | 0xF<<(4*SPIMOSI)); //Alternate function 0 (SPI1) (This line doesn't work) GPIOB->AFR[0] |= 0x00<<(4*SPISCK) | 0x00<<(4*SPIMISO) | 0x00<<(4*SPIMOSI); RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Enable SPI1 clock SPI1->CR1 = 0x0000; // Disable and reset SPI SPI1->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI | 0x02<<3 | SPI_CR1_MSTR | SPI_CR1_CPHA; // Bidirectional | Fclk/8 | Master | CPOL = 0 | CPHA = 1 SPI1->CR2 = 0x0700; // Reset CR2 SPI1->CR2 |= SPI_CR2_FRXTH | 0x07<<8; // RX full = 1/4 (8bit) | 8 bit SPI1->I2SCFGR &= (uint16_t)(~SPI_I2SCFGR_I2SMOD); // not found in DM00091010-ReferenceManual SPI1->CR1 |= SPI_CR1_SPE; // Enable SPI /* SLAVE SELECT PIN */ if(!(RCC->AHBENR & RCC_AHBENR_GPIOBEN)) RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // Enable GPIOB clock (redundant) GPIOB->MODER &= ~(0x03<<(2*A0) | 0x03<<(2*A1) | 0x03<<(2*A2)); //Alternate function = output GPIOB->MODER |= 0x01<<(2*A0) | 0x01<<(2*A1) | 0x01<<(2*A2); GPIOB->OTYPER &= ~(0x01<<A0 | 0x01<<A1 | 0x01<<A2); //Output push-pull GPIOB->OTYPER |= 0x00<<A0 | 0x00<<A1 | 0x00<<A2; GPIOB->OSPEEDR &= ~(0x03<<(2*A0) | 0x03<<(2*A1) | 0x03<<(2*A2)); //Pin speed = low speed GPIOB->OSPEEDR |= 0x00<<(2*A0) | 0x00<<(2*A1) | 0x00<<(2*A2); GPIOB->PUPDR &= ~(0x03<<(2*A0) | 0x03<<(2*A1) | 0x03<<(2*A2)); //Pull up GPIOB->PUPDR |= 0x01<<(2*A0) | 0x01<<(2*A1) | 0x01<<(2*A2); } uint8_t MYSPI::Transfer8(uint8_t slave, uint8_t c, uint8_t cpol, uint8_t cpha) { uint8_t t; SPI1->CR1 &= ~(SPI_CR1_CPOL | SPI_CR1_CPHA); SPI1->CR1 |= cpol<<1 | cpha; // Set the correct CPOL and CPHA SPI1->CR2 &= ~(SPI_CR2_FRXTH | 0x0F00); // Reset CR2 SPI1->CR2 |= SPI_CR2_FRXTH | 0x07<<8; // RX full = 1/4 (8bit) | 8 bit SlaveLow(slave); while(SPI1->SR & SPI_SR_BSY); // Wait for SPI transmission finished SPI1->DR = c; while(SPI1->SR & SPI_SR_BSY); // Wait for SPI transmission finished t = SPI1->DR; SlaveHigh(slave); myusart1.PrintString((uint8_t *) ''SPI '', ' ', 0); myusart1.PrintHex(t); myusart1.PrintChar('\n'); return t; } ================================= This code on port A and discovery board works, so what's wrong with port B? Any hint? Thank you Freya #portb #spi