1 | //init spi gpio for digital input shift register
|
2 | void dig_in_init(){
|
3 | gpio_pin_config(CS_PORT,CS_PIN,OUT|PP|MHZ_50); //chip select, connected to clk_inhibit, always low
|
4 | gpio_pin_config(SH_LD_PORT,SH_LD_PIN,OUT|PP|MHZ_50); //shift/load
|
5 | CS_PORT->BRR = (1<<CS_PIN); //chip select, connected to clk_inhibit, always low
|
6 |
|
7 | gpio_pin_config(CLK_PORT,CLK_PIN,AF|PP); //spi clk to alternate function push/pull
|
8 | gpio_pin_config(MISO_PORT,MISO_PIN,AF|PP); //spi miso to alternate function push/pull
|
9 | CLK_PORT->AFR[1] |= (5<<((CLK_PIN-8)*4)); //AF5 (SPI2 CLK)
|
10 | MISO_PORT->AFR[1] |= (5<<((MISO_PIN-8)*4)); //AF5 (SPI2 MISO)
|
11 |
|
12 | RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; //enable clock for spi2
|
13 |
|
14 | SPI2->CR1 |= SPI_CR1_BR; //baudrate fPCLK/256
|
15 | SPI2->CR1 |= SPI_CR1_CPHA|SPI_CR1_CPOL; //clock 1 when idle, rising edge sample (to have some time between transmission start and first rising edge)
|
16 | SPI2->CR1 &= ~(SPI_CR1_BIDIMODE|SPI_CR1_RXONLY); //2-line mode, full duplex
|
17 | SPI2->CR2 |= SPI_CR2_DS; //16bit data size
|
18 | SPI2->CR1 &= ~SPI_CR1_LSBFIRST; //MSB first
|
19 | SPI2->CR1 &= ~SPI_CR1_SSM; //Software slave management disabled
|
20 | SPI2->CR2 &= ~SPI_CR2_SSOE; //disable SS output
|
21 | SPI2->CR2 &= ~SPI_CR2_FRF; //disable TI protocol
|
22 | SPI2->CR2 &= ~SPI_CR2_NSSP; //no NSS pulse mode
|
23 | SPI2->CR2 &= ~SPI_CR2_FRXTH; //FIFO threshold to 16bit
|
24 | SPI2->CR1 &= ~SPI_CR1_CRCEN; //no CRC
|
25 | SPI2->CR1 |= SPI_CR1_MSTR; //master mode
|
26 | SPI2->CR2 |= SPI_CR2_RXNEIE; //receive buffer not empty interrupt enable
|
27 | SPI2->CR1 |= SPI_CR1_SPE; //enable SPI
|
28 | NVIC_EnableIRQ(SPI2_IRQn); //enable SPI2 global Interrupt
|
29 |
|
30 | //start cycle
|
31 | dig_in_sr_state = STATE_LOAD;
|
32 | SH_LD_PORT->BRR = (1<<SH_LD_PIN); //shift/load to load
|
33 | SPI2->DR = 0xF0F0; //put dummy bytes into data register to start transmission
|
34 | }
|
35 |
|
36 | //spi2 ISR
|
37 | void SPI2_IRQHandler(void){if(dig_in_sr_state==STATE_LOAD){
|
38 | not_used = SPI2->DR; //dummy read values from data register to reset interrupt
|
39 | SH_LD_PORT->BSRR = (1<<SH_LD_PIN); //shift/load to shift
|
40 | SPI2->DR = 0x0F0F; //put dummy bytes into data register to start communication
|
41 | dig_in_sr_state=STATE_SHIFT;
|
42 | }
|
43 | else if(dig_in_sr_state==STATE_SHIFT){
|
44 | digital_values = SPI2->DR; //read values from data register (resets interrupt)
|
45 | SH_LD_PORT->BRR = (1<<SH_LD_PIN); //shift/load to load
|
46 | SPI2->DR = 0xF0F0; //put dummy bytes into data register to start communication
|
47 | dig_in_sr_state=STATE_LOAD;
|
48 | }
|
49 | }
|