SPI slave program to enable communication between the FPGA and the STM32L432 board.

Dependencies:   mbed

Committer:
Zbyszek
Date:
Thu Mar 07 01:16:48 2019 +0000
Revision:
9:9ed9dffd602a
Parent:
8:e87027349167
Child:
10:5b96211275d4
Got the DMA working to some extent. Disabling the PINC bit solves the transmission problem to some extent but still facing problems such as getting 100% of the data to send properly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Zbyszek 8:e87027349167 1 #include "mbed.h"
Zbyszek 8:e87027349167 2 #include "DMA_SPI.h"
Zbyszek 8:e87027349167 3
Zbyszek 9:9ed9dffd602a 4 int16_t data_to_transmit[12];
Zbyszek 9:9ed9dffd602a 5 int16_t received_data[12];
Zbyszek 9:9ed9dffd602a 6 DigitalOut myled(LED1);
Zbyszek 9:9ed9dffd602a 7
Zbyszek 9:9ed9dffd602a 8 void SPI_DMA_init() {
Zbyszek 9:9ed9dffd602a 9 myled = 1; //toggle LED on
Zbyszek 9:9ed9dffd602a 10
Zbyszek 9:9ed9dffd602a 11 //Deinitialise
Zbyszek 9:9ed9dffd602a 12 SPI_DMA_SLAVE_deinit();
Zbyszek 9:9ed9dffd602a 13 deinitDMA();
Zbyszek 9:9ed9dffd602a 14
Zbyszek 9:9ed9dffd602a 15 //Initialise
Zbyszek 9:9ed9dffd602a 16 initDMA();
Zbyszek 9:9ed9dffd602a 17 SPI_DMA_SLAVE_init();
Zbyszek 9:9ed9dffd602a 18
Zbyszek 9:9ed9dffd602a 19 //Start DMA communication
Zbyszek 9:9ed9dffd602a 20 startCommunication();
Zbyszek 9:9ed9dffd602a 21 }
Zbyszek 9:9ed9dffd602a 22
Zbyszek 9:9ed9dffd602a 23 /* Starting DMA communication according to STM32L432 Reference Manual p1317-p1318*/
Zbyszek 9:9ed9dffd602a 24 void startCommunication() {
Zbyszek 9:9ed9dffd602a 25
Zbyszek 9:9ed9dffd602a 26 SET_SPI1_CR2_RXDMAEN_BIT(); //Enable RX DMA buffer
Zbyszek 9:9ed9dffd602a 27 DMA1_CH3_ENABLE(); //Enable DMA channel 3
Zbyszek 9:9ed9dffd602a 28 DMA1_CH2_ENABLE(); //Enable DMA channel 2
Zbyszek 9:9ed9dffd602a 29 SET_SPI1_CR2_TXDMAEN_BIT(); //Enable TX DMA buffer
Zbyszek 9:9ed9dffd602a 30 SPI1_ENABLE(); //SPI module enabled
Zbyszek 9:9ed9dffd602a 31 }
Zbyszek 9:9ed9dffd602a 32
Zbyszek 9:9ed9dffd602a 33
Zbyszek 9:9ed9dffd602a 34 //====================================================DEINITIALISE=========================================================================
Zbyszek 9:9ed9dffd602a 35 void SPI_DMA_SLAVE_deinit() {
Zbyszek 9:9ed9dffd602a 36 //Disable the clocks
Zbyszek 9:9ed9dffd602a 37 //RCC->AHB2ENR &= ~(RCC_AHB2ENR_GPIOAEN);
Zbyszek 9:9ed9dffd602a 38 //RCC->APB2ENR &= ~(RCC_APB2ENR_SPI1EN);
Zbyszek 9:9ed9dffd602a 39 //Clear pin settings
Zbyszek 9:9ed9dffd602a 40 GPIOA->MODER&=~((3u<<(2*CS_slave))); //clear GPIOA pin mode (in input mode when reset)
Zbyszek 9:9ed9dffd602a 41
Zbyszek 9:9ed9dffd602a 42 GPIOA->MODER&=~( //clear GPIOB
Zbyszek 9:9ed9dffd602a 43 (3u<<(2*SCK_slave))
Zbyszek 9:9ed9dffd602a 44 |(3u<<(2*MISO_slave))
Zbyszek 9:9ed9dffd602a 45 |(3u<<(2*MOSI_slave))
Zbyszek 9:9ed9dffd602a 46 |0x03
Zbyszek 9:9ed9dffd602a 47 );
Zbyszek 9:9ed9dffd602a 48
Zbyszek 9:9ed9dffd602a 49 GPIOA->AFR[0]&=~( //clear alternate function selector bits
Zbyszek 9:9ed9dffd602a 50 (0x0f<<(4*SCK_slave))
Zbyszek 9:9ed9dffd602a 51 |(0x0f<<(4*MISO_slave))
Zbyszek 9:9ed9dffd602a 52 |(15u<<(4*MOSI_slave))
Zbyszek 9:9ed9dffd602a 53 );
Zbyszek 9:9ed9dffd602a 54
Zbyszek 9:9ed9dffd602a 55 //Clear SPI bits
Zbyszek 9:9ed9dffd602a 56 SPI1_DISABLE();
Zbyszek 9:9ed9dffd602a 57 CLEAR_SPI1_CR1_MSTR_BIT();
Zbyszek 9:9ed9dffd602a 58 CLEAR_SPI1_CR1_BR_BITS();
Zbyszek 9:9ed9dffd602a 59 CLEAR_SPI1_CR1_SSM_BIT();
Zbyszek 9:9ed9dffd602a 60 CLEAR_SPI1_CR1_SSI_BIT();
Zbyszek 9:9ed9dffd602a 61 CLEAR_SPI1_CR1_CPOL_BIT();
Zbyszek 9:9ed9dffd602a 62 CLEAR_SPI1_CR1_CPHA_BIT();
Zbyszek 9:9ed9dffd602a 63
Zbyszek 9:9ed9dffd602a 64
Zbyszek 9:9ed9dffd602a 65 CLEAR_SPI1_CR2_DS_BITS();
Zbyszek 9:9ed9dffd602a 66 CLEAR_SPI1_CR2_RXDMAEN_BIT();
Zbyszek 9:9ed9dffd602a 67 CLEAR_SPI1_CR2_TXDMAEN_BIT();
Zbyszek 9:9ed9dffd602a 68 CLEAR_SPI1_CR2_RXEIE_BIT();
Zbyszek 9:9ed9dffd602a 69 CLEAR_SPI1_CR2_TXEIE_BIT();
Zbyszek 9:9ed9dffd602a 70
Zbyszek 9:9ed9dffd602a 71 CLEAR_SPI1_CR1_CRC_BIT();
Zbyszek 9:9ed9dffd602a 72
Zbyszek 9:9ed9dffd602a 73 RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST;
Zbyszek 9:9ed9dffd602a 74 RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST;
Zbyszek 9:9ed9dffd602a 75 }
Zbyszek 9:9ed9dffd602a 76
Zbyszek 9:9ed9dffd602a 77 void deinitDMA() {
Zbyszek 9:9ed9dffd602a 78 //RCC->AHB1ENR &= ~(RCC_AHB1ENR_DMA1EN); //Disable the DMA1 clock
Zbyszek 9:9ed9dffd602a 79 RCC->AHB1RSTR |= RCC_AHB1RSTR_DMA1RST;
Zbyszek 9:9ed9dffd602a 80 RCC->AHB1RSTR &= ~RCC_AHB1RSTR_DMA1RST;
Zbyszek 9:9ed9dffd602a 81
Zbyszek 9:9ed9dffd602a 82 //Disable channels
Zbyszek 9:9ed9dffd602a 83 DMA1_CH2_DISABLE();
Zbyszek 9:9ed9dffd602a 84 DMA1_CH3_DISABLE();
Zbyszek 9:9ed9dffd602a 85
Zbyszek 9:9ed9dffd602a 86 CLEAR_DMA1_SPI1RX_CSELR_BITS(); //deselect SPI1_Rx on DMA1 Channel 2
Zbyszek 9:9ed9dffd602a 87 CLEAR_DMA1_SPI1TX_CSELR_BITS(); //deselect SPI1_Tx on DMA1 Channel 3
Zbyszek 9:9ed9dffd602a 88
Zbyszek 9:9ed9dffd602a 89
Zbyszek 9:9ed9dffd602a 90 //-----------------------------------------------Receive-----------------------------------------------------
Zbyszek 9:9ed9dffd602a 91 //Clear configuration bits
Zbyszek 9:9ed9dffd602a 92 CLEAR_DMA1_CH2_CCR_DIR_BIT();
Zbyszek 9:9ed9dffd602a 93 CLEAR_DMA1_CH2_CCR_PSIZE_BITS();
Zbyszek 9:9ed9dffd602a 94 CLEAR_DMA1_CH2_CCR_MSIZE_BITS();
Zbyszek 9:9ed9dffd602a 95 CLEAR_DMA1_CH2_CCR_MINC_BIT();
Zbyszek 9:9ed9dffd602a 96 CLEAR_DMA1_CH2_CCR_PINC_BIT();
Zbyszek 9:9ed9dffd602a 97 CLEAR_DMA1_CH2_CCR_TCIE_BIT();
Zbyszek 9:9ed9dffd602a 98 CLEAR_DMA1_CH2_CCR_CIRC_BIT();
Zbyszek 9:9ed9dffd602a 99 CLEAR_DMA1_CH2_CCR_MEM2MEM_BIT();
Zbyszek 9:9ed9dffd602a 100 CLEAR_DMA1_CH2_CCR_PL_BITS();
Zbyszek 9:9ed9dffd602a 101 CLEAR_DMA1_CH2_CCR_TEIE_BIT();
Zbyszek 9:9ed9dffd602a 102
Zbyszek 9:9ed9dffd602a 103 CLEAR_DMA1_CH2_CNDTR_BITS();
Zbyszek 9:9ed9dffd602a 104 CLEAR_DMA1_CH2_CPAR_BITS();
Zbyszek 9:9ed9dffd602a 105 CLEAR_DMA1_CH2_CMAR_BITS();
Zbyszek 9:9ed9dffd602a 106 //-----------------------------------------------Receive-----------------------------------------------------
Zbyszek 9:9ed9dffd602a 107
Zbyszek 9:9ed9dffd602a 108 //-----------------------------------------------Transmission------------------------------------------------
Zbyszek 9:9ed9dffd602a 109 //Clear configuration bits
Zbyszek 9:9ed9dffd602a 110 CLEAR_DMA1_CH3_CCR_DIR_BIT();
Zbyszek 9:9ed9dffd602a 111 CLEAR_DMA1_CH3_CCR_PSIZE_BITS();
Zbyszek 9:9ed9dffd602a 112 CLEAR_DMA1_CH3_CCR_MSIZE_BITS();
Zbyszek 9:9ed9dffd602a 113 CLEAR_DMA1_CH3_CCR_MINC_BIT();
Zbyszek 9:9ed9dffd602a 114 CLEAR_DMA1_CH3_CCR_PINC_BIT();
Zbyszek 9:9ed9dffd602a 115 CLEAR_DMA1_CH3_CCR_TCIE_BIT();
Zbyszek 9:9ed9dffd602a 116 CLEAR_DMA1_CH3_CCR_CIRC_BIT();
Zbyszek 9:9ed9dffd602a 117 CLEAR_DMA1_CH3_CCR_MEM2MEM_BIT();
Zbyszek 9:9ed9dffd602a 118 CLEAR_DMA1_CH3_CCR_PL_BITS();
Zbyszek 9:9ed9dffd602a 119 CLEAR_DMA1_CH3_CCR_TEIE_BIT();
Zbyszek 9:9ed9dffd602a 120
Zbyszek 9:9ed9dffd602a 121 CLEAR_DMA1_CH3_CNDTR_BITS();
Zbyszek 9:9ed9dffd602a 122 CLEAR_DMA1_CH3_CPAR_BITS();
Zbyszek 9:9ed9dffd602a 123 CLEAR_DMA1_CH3_CMAR_BITS();
Zbyszek 9:9ed9dffd602a 124
Zbyszek 9:9ed9dffd602a 125 //-----------------------------------------------Transmission------------------------------------------------
Zbyszek 9:9ed9dffd602a 126
Zbyszek 9:9ed9dffd602a 127 NVIC->ISER[0]&= ~(1u<<12); //Disable DMA1 channel 2 interrupt
Zbyszek 9:9ed9dffd602a 128 NVIC->ISER[0]&= ~(1u<<13); //Disable DMA1 channel 3 interrupt
Zbyszek 9:9ed9dffd602a 129
Zbyszek 9:9ed9dffd602a 130 }
Zbyszek 9:9ed9dffd602a 131 //====================================================DEINITIALISE=========================================================================
Zbyszek 9:9ed9dffd602a 132
Zbyszek 9:9ed9dffd602a 133
Zbyszek 9:9ed9dffd602a 134
Zbyszek 9:9ed9dffd602a 135 void SPI_DMA_SLAVE_init() {
Zbyszek 9:9ed9dffd602a 136 RCC->AHB2ENR|= (RCC_AHB2ENR_GPIOAEN); //GPIO A clock enable
Zbyszek 9:9ed9dffd602a 137 RCC->APB2ENR|=RCC_APB2ENR_SPI1EN; //Enable SPI1 Clock
Zbyszek 9:9ed9dffd602a 138
Zbyszek 9:9ed9dffd602a 139 //SET SCK, MISO, MOSI and CS pins
Zbyszek 9:9ed9dffd602a 140 GPIOA->MODER|=(
Zbyszek 9:9ed9dffd602a 141 (2u<<(2*SCK_slave))
Zbyszek 9:9ed9dffd602a 142 |(2u<<(2*MISO_slave))
Zbyszek 9:9ed9dffd602a 143 |(2u<<(2*MOSI_slave))
Zbyszek 9:9ed9dffd602a 144 |0x01
Zbyszek 9:9ed9dffd602a 145 );
Zbyszek 9:9ed9dffd602a 146
Zbyszek 9:9ed9dffd602a 147 //SET pins to function as SPI pins
Zbyszek 9:9ed9dffd602a 148 GPIOA->AFR[0]|=(
Zbyszek 9:9ed9dffd602a 149 (5u<<(4*SCK_slave))
Zbyszek 9:9ed9dffd602a 150 |(5u<<(4*MISO_slave))
Zbyszek 9:9ed9dffd602a 151 |(5u<<(4*MOSI_slave))
Zbyszek 9:9ed9dffd602a 152 );
Zbyszek 9:9ed9dffd602a 153
Zbyszek 9:9ed9dffd602a 154 SET_SPI1_CR1_BR_BITS(); //baud rate bits set 1/16 giving 1MHz SCK frequency
Zbyszek 9:9ed9dffd602a 155 SET_SPI1_CR1_CPOL_BIT(); //CPOL = 1
Zbyszek 9:9ed9dffd602a 156 SET_SPI1_CR1_CPHA_BIT(); //CPHA = 1
Zbyszek 9:9ed9dffd602a 157
Zbyszek 9:9ed9dffd602a 158
Zbyszek 9:9ed9dffd602a 159 SET_SPI1_CR2_DS_BITS(); //Data Size = 16 bits
Zbyszek 9:9ed9dffd602a 160 SET_SPI1_CR2_RXDMAEN_BIT(); //Rx buffer DMA enable
Zbyszek 9:9ed9dffd602a 161 SET_SPI1_CR2_TXDMAEN_BIT(); //Tx buffer DMA enable
Zbyszek 9:9ed9dffd602a 162
Zbyszek 9:9ed9dffd602a 163
Zbyszek 9:9ed9dffd602a 164 }
Zbyszek 9:9ed9dffd602a 165
Zbyszek 9:9ed9dffd602a 166
Zbyszek 8:e87027349167 167
Zbyszek 8:e87027349167 168 void initDMA() {
Zbyszek 9:9ed9dffd602a 169 RCC->AHB1ENR|= (RCC_AHB1ENR_DMA1EN); //Enable the DMA1 clock
Zbyszek 9:9ed9dffd602a 170
Zbyszek 9:9ed9dffd602a 171 DMA1_CH2_DISABLE(); //Disable DMA channel 2
Zbyszek 9:9ed9dffd602a 172 DMA1_CH3_DISABLE(); //Disable DMA channel 3
Zbyszek 8:e87027349167 173
Zbyszek 9:9ed9dffd602a 174 SET_DMA1_SPI1RX_CSELR_BITS(); //Select SPI1_Rx on DMA1 Channel 2
Zbyszek 9:9ed9dffd602a 175 SET_DMA1_SPI1TX_CSELR_BITS(); //Select SPI1_Tx on DMA1 Channel 3
Zbyszek 8:e87027349167 176
Zbyszek 9:9ed9dffd602a 177 //-----------------------------------------------Receive-----------------------------------------------------
Zbyszek 9:9ed9dffd602a 178 CLEAR_DMA1_CH2_CCR_DIR_BIT(); //Peripheral->Memory
Zbyszek 9:9ed9dffd602a 179 SET_DMA1_CH2_CCR_PSIZE_BITS(); //16 bits
Zbyszek 9:9ed9dffd602a 180 SET_DMA1_CH2_CCR_MSIZE_BITS(); //16 bits
Zbyszek 9:9ed9dffd602a 181 //SET_DMA1_CH2_CCR_MINC_BIT(); //Memory increment mode
Zbyszek 9:9ed9dffd602a 182 //SET_DMA1_CH2_CCR_PINC_BIT(); //Peripheral increment mode
Zbyszek 9:9ed9dffd602a 183 SET_DMA1_CH2_CCR_TCIE_BIT(); //Transfer complete interrupt enable
Zbyszek 9:9ed9dffd602a 184 //SET_DMA1_CH2_CCR_CIRC_BIT(); //Circular Buffer mode
Zbyszek 9:9ed9dffd602a 185 SET_DMA1_CH2_CCR_PL_BITS(); //Priority Level = Highest
Zbyszek 8:e87027349167 186
Zbyszek 9:9ed9dffd602a 187 DMA1_Channel2->CNDTR = 12; //number of data to transfer from the peripheral to memory.
Zbyszek 9:9ed9dffd602a 188 DMA1_Channel2->CPAR = (int32_t)&SPI1->DR; //Source Adddress = SPI data register
Zbyszek 9:9ed9dffd602a 189 DMA1_Channel2->CMAR = (int32_t)received_data; //Destination address = received_data array
Zbyszek 9:9ed9dffd602a 190 //-----------------------------------------------Receive-----------------------------------------------------
Zbyszek 9:9ed9dffd602a 191
Zbyszek 9:9ed9dffd602a 192 //-----------------------------------------------Transmission------------------------------------------------
Zbyszek 9:9ed9dffd602a 193
Zbyszek 9:9ed9dffd602a 194 SET_DMA1_CH3_CCR_DIR_BIT(); //Memory->Peripheral
Zbyszek 9:9ed9dffd602a 195 SET_DMA1_CH3_CCR_PSIZE_BITS(); //16 bits
Zbyszek 9:9ed9dffd602a 196 SET_DMA1_CH3_CCR_MSIZE_BITS(); //16 bits
Zbyszek 9:9ed9dffd602a 197 SET_DMA1_CH3_CCR_MINC_BIT(); //Memory increment mode
Zbyszek 9:9ed9dffd602a 198 // SET_DMA1_CH3_CCR_PINC_BIT(); //Peripheral increment mode
Zbyszek 9:9ed9dffd602a 199 SET_DMA1_CH3_CCR_TCIE_BIT(); //Transfer complete interrupt enable
Zbyszek 9:9ed9dffd602a 200 SET_DMA1_CH3_CCR_CIRC_BIT(); //Circular Buffer mode
Zbyszek 9:9ed9dffd602a 201 SET_DMA1_CH3_CCR_PL_BITS(); //Priority Level = Highest
Zbyszek 9:9ed9dffd602a 202
Zbyszek 9:9ed9dffd602a 203 DMA1_Channel3->CNDTR = 12; //number of data to transfer from memory to the peripheral
Zbyszek 9:9ed9dffd602a 204 DMA1_Channel3->CPAR = (int32_t)&SPI1->DR; //Destination address = SPI data register
Zbyszek 9:9ed9dffd602a 205 DMA1_Channel3->CMAR = (int32_t)data_to_transmit; //Source address = data_to_transmit
Zbyszek 9:9ed9dffd602a 206 //-----------------------------------------------Transmission------------------------------------------------
Zbyszek 8:e87027349167 207
Zbyszek 8:e87027349167 208
Zbyszek 9:9ed9dffd602a 209 // NVIC->ISER[0]|= (1u<<12); //Enable DMA1 channel 2 interrupt
Zbyszek 9:9ed9dffd602a 210 // NVIC->ISER[0]|= (1u<<13); //Enable DMA1 channel 3 interrupt
Zbyszek 9:9ed9dffd602a 211 // NVIC_EnableIRQ(DMA1_Channel2_IRQn);
Zbyszek 9:9ed9dffd602a 212 // NVIC_EnableIRQ(DMA1_Channel3_IRQn);
Zbyszek 8:e87027349167 213
Zbyszek 8:e87027349167 214 }
Zbyszek 9:9ed9dffd602a 215
Zbyszek 9:9ed9dffd602a 216
Zbyszek 9:9ed9dffd602a 217 //Interrupt Handler for DMA1 Channel 2
Zbyszek 9:9ed9dffd602a 218 void DMA1_Channel2_IRQHandler(void) {
Zbyszek 9:9ed9dffd602a 219 myled = 0; //Toggle LED off
Zbyszek 9:9ed9dffd602a 220 CLEAR_DMA1_CH2_IFCR_GFLAG(); //Clear Global Interrupt flag
Zbyszek 9:9ed9dffd602a 221 }
Zbyszek 9:9ed9dffd602a 222
Zbyszek 9:9ed9dffd602a 223
Zbyszek 9:9ed9dffd602a 224 //Interrupt Handler for DMA1 Channel 3
Zbyszek 9:9ed9dffd602a 225 void DMA1_Channel3_IRQHandler(void) {
Zbyszek 9:9ed9dffd602a 226 myled = 0;
Zbyszek 9:9ed9dffd602a 227 CLEAR_DMA1_CH3_IFCR_GFLAG(); //Clear Global Interrupt flag
Zbyszek 9:9ed9dffd602a 228 }
Zbyszek 9:9ed9dffd602a 229