foxBMS  1.1.2
The foxBMS Battery Management System API Documentation
dma.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file dma.c
44  * @author foxBMS Team
45  * @date 2019-12-12 (date of creation)
46  * @updated 2021-07-14 (date of last update)
47  * @ingroup DRIVERS
48  * @prefix DMA
49  *
50  * @brief Driver for the DMA module.
51  *
52  */
53 
54 /*========== Includes =======================================================*/
55 #include "dma.h"
56 
57 #include "io.h"
58 #include "mic_dma.h"
59 #include "spi.h"
60 
61 /*========== Macros and Definitions =========================================*/
62 
63 /*========== Static Constant and Variable Definitions =======================*/
64 
65 /*========== Extern Constant and Variable Definitions =======================*/
66 
67 /*========== Static Function Prototypes =====================================*/
68 
69 /*========== Static Function Implementations ================================*/
70 
71 /*========== Extern Function Implementations ================================*/
72 
73 void DMA_Initialize(void) {
74  /* - configuring dma control packets */
75  g_dmaCTRL dma_controlPacketTx = {
76  .SADD = (uint32_t)NULL_PTR, /* source address */
77  .DADD = (uint32_t)NULL_PTR, /* destination address */
78  .CHCTRL = 0U, /* channel chain control */
79  .FRCNT = 0U, /* frame count */
80  .ELCNT = 1U, /* element count */
81  .ELDOFFSET = 0U, /* element destination offset */
82  .ELSOFFSET = 0U, /* element destination offset */
83  .FRDOFFSET = 0U, /* frame destination offset */
84  .FRSOFFSET = 0U, /* frame destination offset */
85  .PORTASGN = PORTA_READ_PORTB_WRITE, /* port assignment */
86  .RDSIZE = ACCESS_16_BIT, /* read size */
87  .WRSIZE = ACCESS_16_BIT, /* write size */
88  .TTYPE = FRAME_TRANSFER, /* transfer type */
89  .ADDMODERD = ADDR_INC1, /* address mode read */
90  .ADDMODEWR = ADDR_FIXED, /* address mode write */
91  .AUTOINIT = AUTOINIT_OFF /* autoinit */
92  };
93 
94  g_dmaCTRL dma_controlPacketRx = {
95  .SADD = (uint32_t)NULL_PTR, /* source address */
96  .DADD = (uint32_t)NULL_PTR, /* destination address */
97  .CHCTRL = 0U, /* channel chain control */
98  .FRCNT = 0U, /* frame count */
99  .ELCNT = 1U, /* element count */
100  .ELDOFFSET = 0U, /* element destination offset */
101  .ELSOFFSET = 0U, /* element destination offset */
102  .FRDOFFSET = 0U, /* frame destination offset */
103  .FRSOFFSET = 0U, /* frame destination offset */
104  .PORTASGN = PORTB_READ_PORTA_WRITE, /* port assignment */
105  .RDSIZE = ACCESS_16_BIT, /* read size */
106  .WRSIZE = ACCESS_16_BIT, /* write size */
107  .TTYPE = FRAME_TRANSFER, /* transfer type */
108  .ADDMODERD = ADDR_FIXED, /* address mode read */
109  .ADDMODEWR = ADDR_INC1, /* address mode write */
110  .AUTOINIT = AUTOINIT_OFF /* autoinit */
111  };
112 
113  dmaEnable();
114 
115  for (uint8_t i = 0u; i < DMA_NUMBER_SPI_INTERFACES; i++) {
116  /* assign dma request to Tx channel */
117  dmaReqAssign((dmaChannel_t)dma_spiDmaChannels[i].txChannel, (dmaRequest_t)dma_spiDmaRequests[i].txRequest);
118  /* assign dma request to Rx channel */
119  dmaReqAssign((dmaChannel_t)dma_spiDmaChannels[i].rxChannel, (dmaRequest_t)dma_spiDmaRequests[i].rxRequest);
120 
121  /* Enable Interrupt after reception of data
122  Group A - Interrupts (FTC, LFS, HBC, and BTC) are routed to the ARM CPU
123  User software should configure only Group A interrupts */
124  /* Only use Rx to determine when SPI over DMA transaction is finished */
125  dmaEnableInterrupt(
126  (dmaChannel_t)(dmaChannel_t)dma_spiDmaChannels[i].rxChannel, (dmaInterrupt_t)BTC, (dmaIntGroup_t)DMA_INTA);
127 
128  dma_controlPacketTx.DADD = (uint32_t)(&(dma_spiInterfaces[i]->DAT1)) + DMA_BIG_ENDIAN_ADDRESS_16BIT;
129  dma_controlPacketRx.SADD = (uint32_t)(&(dma_spiInterfaces[i]->BUF)) + DMA_BIG_ENDIAN_ADDRESS_16BIT;
130 
131  /* Set dma control packet for Tx */
132  dmaSetCtrlPacket((dmaChannel_t)dma_spiDmaChannels[i].txChannel, dma_controlPacketTx);
133 
134  /* Set dma control packet for Rx */
135  dmaSetCtrlPacket((dmaChannel_t)dma_spiDmaChannels[i].rxChannel, dma_controlPacketRx);
136 
137  /* Set the dma channels to trigger on h/w request */
138  dmaSetChEnable((dmaChannel_t)dma_spiDmaChannels[i].txChannel, (dmaTriggerType_t)DMA_HW);
139  dmaSetChEnable((dmaChannel_t)dma_spiDmaChannels[i].rxChannel, (dmaTriggerType_t)DMA_HW);
140  }
141 }
142 
143 /** Function called on DMA complete interrupts (TX and RX). Defined as weak in HAL. */
144 void UNIT_TEST_WEAK_IMPL dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel) {
145  if (inttype == (dmaInterrupt_t)BTC) {
146  /* Search for SPI index with DAM Rx channel */
147  uint8_t spiIndex = 0U;
148  for (uint8_t i = 0u; i < DMA_NUMBER_SPI_INTERFACES; i++) {
149  if ((uint32_t)dma_spiDmaChannels[i].rxChannel == channel) {
150  spiIndex = i;
151  break;
152  }
153  }
154 
155  /* Software deactivate CS */
156  IO_PinSet(spi_dmaTransmission[spiIndex].pGioPort, spi_dmaTransmission[spiIndex].csPin);
157 
158  /* Disable DMA_REQ_Enable */
159  spi_dmaTransmission[spiIndex].pNode->INT0 &= ~DMAREQEN_BIT;
160  if (spi_dmaTransmission[spiIndex].channel < spi_nrBusyFlags) {
162  }
163 
164  /* DMA seems to only be able to use FMT0, restore saved FMT0 values */
165  spi_dmaTransmission[spiIndex].pNode->FMT0 = spi_saveFmt0[spiIndex];
166 
167  /* Specific calls for measurement ICs */
168  if (spiIndex == 0U) {
169  MIC_DmaCallback(inttype, channel);
170  }
171  }
172 }
173 
174 /*========== Externalized Static Function Implementations (Unit Test) =======*/
void DMA_Initialize(void)
Enables the DMA module.
Definition: dma.c:73
void UNIT_TEST_WEAK_IMPL dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel)
Definition: dma.c:144
Headers for the driver for the DMA module.
DMA_REQUEST_CONFIG_s dma_spiDmaRequests[DMA_NUMBER_SPI_INTERFACES]
Definition: dma_cfg.c:77
spiBASE_t * dma_spiInterfaces[DMA_NUMBER_SPI_INTERFACES]
Definition: dma_cfg.c:86
DMA_CHANNEL_CONFIG_s dma_spiDmaChannels[DMA_NUMBER_SPI_INTERFACES]
Definition: dma_cfg.c:68
#define DMA_BIG_ENDIAN_ADDRESS_16BIT
Definition: dma_cfg.h:88
#define DMA_NUMBER_SPI_INTERFACES
Definition: dma_cfg.h:69
#define DMAREQEN_BIT
Definition: dma_cfg.h:90
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:66
#define UNIT_TEST_WEAK_IMPL
Definition: general.h:104
void IO_PinSet(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin by writing in pin output register.
Definition: io.c:70
Header for the driver for the IO module.
Headers for the driver for the general DMA module of monitoring ICs.
void MIC_DmaCallback(dmaInterrupt_t inttype, uint32 channel)
Function called by DMA block transfer callback.
Headers for the driver for the SPI module.
SPI_INTERFACE_CONFIG_s spi_dmaTransmission[]
Variable used for SPI over DMA transmission. Retains the CS pin to deactivate in DMA callback.
Definition: spi_cfg.c:229
SPI_BUSY_STATE_e spi_busyFlags[]
Definition: spi_cfg.c:281
uint32_t spi_saveFmt0[]
Definition: spi_cfg.c:272
const uint8_t spi_nrBusyFlags
Definition: spi_cfg.c:290
@ SPI_IDLE
Definition: spi_cfg.h:93
SPI_INTERFACE_e channel
Definition: spi_cfg.h:108
spiBASE_t * pNode
Definition: spi_cfg.h:110