lpspi_shared_function.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
73 #include <assert.h>
74 #include "lpspi_hw_access.h"
75 
76 /*******************************************************************************
77  * Variables
78  ******************************************************************************/
79 
82 
85 
86 /* Pointer to runtime state structure.*/
88 
89 /*******************************************************************************
90  * Code
91  ******************************************************************************/
92 
103 void LPSPI_DRV_IRQHandler(uint32_t instance)
104 {
105  if(instance < LPSPI_INSTANCE_COUNT)
106  {
107  const LPSPI_Type *base = g_lpspiBase[instance];
108 
109  if (LPSPI_IsMaster(base))
110  {
111  /* Master mode.*/
112  LPSPI_DRV_MasterIRQHandler(instance);
113  }
114  else
115  {
116  /* Slave mode.*/
117  LPSPI_DRV_SlaveIRQHandler(instance);
118  }
119  }
120 }
126 void LPSPI_DRV_FillupTxBuffer(uint32_t instance)
127 {
128  /* Instantiate local variable of type dspi_master_state_t and point to global state. */
129  lpspi_state_t * lpspiState = g_lpspiStatePtr[instance];
130  LPSPI_Type *base = g_lpspiBase[instance];
131  uint32_t wordToSend = 0;
132  uint16_t numOfBytes;
133  uint8_t availableSpace = (uint8_t)(lpspiState->fifoSize - (uint8_t)LPSPI_ReadTxCount(base));
134 
135  /* Fill the TX buffer. */
136  while(availableSpace != 0U)
137  {
138  if (lpspiState->isPcsContinuous == true)
139  {
140  if(lpspiState->txCount == 1U)
141  {
142  /* Disable continuous PCS */
143  LPSPI_ClearContCBit(base);
144  lpspiState->txCount = 0U;
145  break;
146  }
147  }
148  /* Get the number of bytes which can be written in a single 32 bits word. */
149  if ((lpspiState->bytesPerFrame - lpspiState->txFrameCnt) <= (uint16_t)4)
150  {
151  numOfBytes = (uint16_t)(lpspiState->bytesPerFrame - lpspiState->txFrameCnt);
152  }
153  else
154  {
155  numOfBytes = 4U;
156  }
157  wordToSend = 0;
158 
159  if (lpspiState->txBuff != NULL)
160  {
161  switch(lpspiState->bytesPerFrame)
162  {
163  case 1:
164  wordToSend = *((const uint8_t *)(lpspiState->txBuff));
165  lpspiState->txBuff += sizeof(uint8_t);
166  break;
167  case 2:
168  wordToSend = *((const uint16_t *)(lpspiState->txBuff));
169  lpspiState->txBuff += sizeof(uint16_t);
170  break;
171  default:
172  wordToSend = *((const uint32_t *)(lpspiState->txBuff));
173  lpspiState->txBuff += sizeof(uint32_t);
174  break;
175  }
176  lpspiState->txFrameCnt = (uint16_t)((lpspiState->txFrameCnt + numOfBytes) % lpspiState->bytesPerFrame);
177  }
178  LPSPI_WriteData(base, wordToSend);
179  /* Update internal variable used in transmission. */
180  lpspiState->txCount = (uint16_t)(lpspiState->txCount - numOfBytes);
181  /* Verify if all bytes were send. */
182  if (lpspiState->txCount == 0U)
183  {
184  break;
185  }
186  availableSpace = (uint8_t)(availableSpace - 1U);
187  }
188 }
195 void LPSPI_DRV_ReadRXBuffer(uint32_t instance)
196 {
197  lpspi_state_t * lpspiState = g_lpspiStatePtr[instance];
198  const LPSPI_Type *base = g_lpspiBase[instance];
199  uint32_t receivedWord;
200  uint16_t numOfBytes;
201  uint16_t j;
202  uint16_t index;
203  uint8_t filledSpace = (uint8_t)LPSPI_ReadRxCount(base);
204  while (filledSpace!= 0U)
205  {
206  receivedWord = LPSPI_ReadData(base);
207  /* Get the number of bytes which can be read from this 32 bites */
208  if ((lpspiState->bytesPerFrame - lpspiState->rxFrameCnt) <= (uint16_t)4)
209  {
210  numOfBytes = (uint16_t)(lpspiState->bytesPerFrame - lpspiState->rxFrameCnt);
211  }
212  else
213  {
214  numOfBytes = 4U;
215  }
216  /* Generate the word which will be write in buffer. */
217  if ((lpspiState->lsb == false) && (lpspiState->bytesPerFrame > 4U))
218  {
219  index = (uint16_t)(lpspiState->bytesPerFrame - lpspiState->rxFrameCnt - 1U);
220  for (j = numOfBytes; j > 0U; j--)
221  {
222  lpspiState->rxBuff[index] = (uint8_t)(receivedWord >> ((j - 1U) * 8U));
223  index--;
224  }
225  lpspiState->rxFrameCnt = (uint16_t)((lpspiState->rxFrameCnt + numOfBytes) % lpspiState->bytesPerFrame);
226  if (lpspiState->rxFrameCnt == 0U)
227  {
228  lpspiState->rxBuff = lpspiState->rxBuff + lpspiState->bytesPerFrame;
229  }
230  }
231  else
232  {
233  for (j = 0; j < numOfBytes; j++)
234  {
235  *(lpspiState->rxBuff) = (uint8_t)(receivedWord >> (j * 8U));
236  lpspiState->rxBuff++;
237  }
238  lpspiState->rxFrameCnt = (uint16_t)((lpspiState->rxFrameCnt + numOfBytes) % lpspiState->bytesPerFrame);
239  }
240 
241  /* Update internal variable used in transmission. */
242  lpspiState->rxCount = (uint16_t)(lpspiState->rxCount - numOfBytes);
243  /* Verify if all bytes were sent. */
244  if (lpspiState->rxCount == 0U)
245  {
246  break;
247  }
248  filledSpace = (uint8_t)(filledSpace - 1U);
249  }
250 }
251 
256 void LPSPI_DRV_DisableTEIEInterrupts(uint32_t instance)
257 {
258  LPSPI_Type *base = g_lpspiBase[instance];
259 
260  LPSPI_SetIntMode(base, LPSPI_TRANSMIT_ERROR, false);
261  LPSPI_SetIntMode(base, LPSPI_RECEIVE_ERROR, false);
262  (void)LPSPI_ClearStatusFlag(base, LPSPI_TRANSMIT_ERROR);
263  (void)LPSPI_ClearStatusFlag(base, LPSPI_RECEIVE_ERROR);
264 }
265 
266 /*******************************************************************************
267  * EOF
268  ******************************************************************************/
volatile uint16_t rxFrameCnt
#define LPSPI_INSTANCE_COUNT
Definition: S32K118.h:6049
volatile uint16_t txFrameCnt
Runtime state structure for the LPSPI master driver.
void LPSPI_DRV_ReadRXBuffer(uint32_t instance)
Read all data from RX FIFO This function will read all data from RX FIFO and will transfer this infro...
LPSPI_Type * g_lpspiBase[LPSPI_INSTANCE_COUNT]
Table of base pointers for SPI instances.
void LPSPI_DRV_FillupTxBuffer(uint32_t instance)
Fill up the TX FIFO with data. This function fills up the TX FIFO with data based on the bytes/frame...
volatile uint16_t rxCount
void LPSPI_DRV_MasterIRQHandler(uint32_t instance)
Interrupt handler for LPSPI master mode. This handler uses the buffers stored in the lpspi_master_sta...
volatile uint16_t txCount
IRQn_Type
Defines the Interrupt Numbers definitions.
Definition: S32K118.h:188
void LPSPI_DRV_IRQHandler(uint32_t instance)
The function LPSPI_DRV_IRQHandler passes IRQ control to either the master or slave driver...
#define LPSPI_IRQS
Definition: S32K118.h:6070
void LPSPI_DRV_DisableTEIEInterrupts(uint32_t instance)
Disable the TEIE interrupts at the end of a transfer. Disable the interrupts and clear the status for...
lpspi_state_t * g_lpspiStatePtr[LPSPI_INSTANCE_COUNT]
#define FEATURE_LPSPI_STATE_STRUCTURES_NULL
const uint8_t * txBuff
void LPSPI_DRV_SlaveIRQHandler(uint32_t instance)
Interrupt handler for LPSPI slave mode. This handler uses the buffers stored in the lpspi_master_stat...
#define LPSPI_BASE_PTRS
Definition: S32K118.h:6064
IRQn_Type g_lpspiIrqId[LPSPI_INSTANCE_COUNT]
Table to save LPSPI IRQ enumeration numbers defined in the CMSIS header file.