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

Dependencies:   mbed

Committer:
Zbyszek
Date:
Fri Mar 08 01:33:51 2019 +0000
Revision:
10:5b96211275d4
Parent:
9:9ed9dffd602a
Child:
11:366f1186c121
Solved the problem with Interrupts not working with DMA. Needed to add "extern "C"" in fornt of the interrupt service routines.

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 10:5b96211275d4 204 DMA1_Channel3->CPAR = (uint32_t)&SPI1->DR; //Destination address = SPI data register
Zbyszek 10:5b96211275d4 205 DMA1_Channel3->CMAR = (uint32_t)data_to_transmit; //Source address = data_to_transmit
Zbyszek 9:9ed9dffd602a 206 //-----------------------------------------------Transmission------------------------------------------------
Zbyszek 8:e87027349167 207
Zbyszek 8:e87027349167 208
Zbyszek 10:5b96211275d4 209 // NVIC->ISER[0] |= (1u<<12); //Enable DMA1 channel 2 interrupt
Zbyszek 10:5b96211275d4 210 NVIC->ISER[0] |= (1u<<13); //Enable DMA1 channel 3 interrupt
Zbyszek 10:5b96211275d4 211 // NVIC_EnableIRQ(DMA1_Channel2_IRQn);
Zbyszek 10:5b96211275d4 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 10:5b96211275d4 218 extern "C" 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 10:5b96211275d4 225 extern "C" void DMA1_Channel3_IRQHandler(void) {
Zbyszek 10:5b96211275d4 226 if(myled == 1) {
Zbyszek 9:9ed9dffd602a 227 myled = 0;
Zbyszek 10:5b96211275d4 228 }
Zbyszek 10:5b96211275d4 229 else {
Zbyszek 10:5b96211275d4 230 myled = 1;
Zbyszek 10:5b96211275d4 231 }
Zbyszek 10:5b96211275d4 232 if(DMA1->ISR&(1u<<9)) { //Check whteher data transmit transfer is complete
Zbyszek 10:5b96211275d4 233 //Read data from the array that stores received data
Zbyszek 10:5b96211275d4 234 for(int x = 0; x <= 12; x++) {
Zbyszek 10:5b96211275d4 235 data_to_transmit[x] = x+1;
Zbyszek 10:5b96211275d4 236 }
Zbyszek 10:5b96211275d4 237 CLEAR_DMA1_CH3_IFCR_GFLAG(); //Clear global channel interrupt flag for channel 3
Zbyszek 10:5b96211275d4 238 } //Clear Global Interrupt flag
Zbyszek 9:9ed9dffd602a 239 }
Zbyszek 9:9ed9dffd602a 240