iLLD_TC27xC  1.0
IfxHssl_Hssl.c
Go to the documentation of this file.
1 /**
2  * \file IfxHssl_Hssl.c
3  * \brief HSSL HSSL details
4  *
5  * \version iLLD_0_1_0_10
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  *
24  */
25 
26 /******************************************************************************/
27 /*----------------------------------Includes----------------------------------*/
28 /******************************************************************************/
29 
30 #include "IfxHssl_Hssl.h"
31 
32 /** \addtogroup IfxLld_Hssl_Hssl_SimpleCom
33  * \{ */
34 
35 /******************************************************************************/
36 /*-----------------------Private Function Prototypes--------------------------*/
37 /******************************************************************************/
38 
39 /** \brief serves the frame request (read, write, trigger frame and read id)
40  * \param channel channel handle
41  * \param frameRequest frame request
42  * \param address address of the location (to be written into / read from)
43  * \param data data to be written
44  * \param dataLength length of the data
45  * \return module status (ok, busy, error)
46  */
47 static IfxHssl_Hssl_Status IfxHssl_Hssl_singleFrameRequest(IfxHssl_Hssl_Channel *channel, IfxHssl_Hssl_FrameRequest frameRequest, uint32 address, uint32 data, IfxHssl_DataLength dataLength);
48 
49 /** \} */
50 
51 /** \addtogroup IfxLld_Hssl_Hssl_ErrorHandling
52  * \{ */
53 
54 /******************************************************************************/
55 /*-----------------------Private Function Prototypes--------------------------*/
56 /******************************************************************************/
57 
58 /** \brief a simple software delay
59  * \param hssl HSSL handle
60  * \return None
61  */
62 static void IfxHssl_Hssl_delay(IfxHssl_Hssl *hssl);
63 
64 /** \} */
65 
66 /******************************************************************************/
67 /*-------------------------Function Implementations---------------------------*/
68 /******************************************************************************/
69 
71 {
72  Ifx_HSSL *hsslSFR = hssl->hssl; // pointer to HSSL registers
73 
74  // store the errors in the structure //
75  if (hsslSFR->MFLAGS.B.NACK != 0)
76  {
78  }
79 
80  if (hsslSFR->MFLAGS.B.TTE != 0)
81  {
83  }
84 
85  if (hsslSFR->MFLAGS.B.TIMEOUT != 0)
86  {
87  hssl->errorFlags.timeoutError = 1;
88  }
89 
90  if (hsslSFR->MFLAGS.B.UNEXPECTED != 0)
91  {
92  hssl->errorFlags.unexpectedError = 1;
93  }
94 
95  if (hsslSFR->MFLAGS.B.MAV != 0)
96  {
98  }
99 
100  if (hsslSFR->MFLAGS.B.SRIE != 0)
101  {
102  hssl->errorFlags.busAccessError = 1;
103  }
104 
105  if (hsslSFR->MFLAGS.B.PIE1 != 0)
106  {
108  }
109 
110  if (hsslSFR->MFLAGS.B.PIE2 != 0)
111  {
112  hssl->errorFlags.dataLengthError = 1;
113  }
114 
115  if (hsslSFR->MFLAGS.B.CRCE != 0)
116  {
117  hssl->errorFlags.crcError = 1;
118  }
119 }
120 
121 
123 {
126  hssl->errorFlags.timeoutError = 0;
127  hssl->errorFlags.unexpectedError = 0;
129  hssl->errorFlags.busAccessError = 0;
131  hssl->errorFlags.dataLengthError = 0;
132  hssl->errorFlags.crcError = 0;
133 }
134 
135 
136 static void IfxHssl_Hssl_delay(IfxHssl_Hssl *hssl)
137 {
138  uint32 i, j;
139 
140  for (i = 0; i < 1000; i++)
141  {
142  for (j = 0; j < 500; j++)
143  {
144  __nop();
145  }
146  }
147 }
148 
149 
151 {
152  channel->hssl = channelConfig->hssl; // adding HSSL register pointer to channel handle
153  channel->hsct = channelConfig->hsct; // adding HSCT register pointer to channel handle
154 
155  channel->channelId = channelConfig->channelId; // adding channel id to channel handle
156  channel->currentFrameRequest = IfxHssl_Hssl_FrameRequest_noAction; // default request, no action
157 
158  channel->streamingModeOn = FALSE; // command mode (used in waitAcknowledge function)
159  channel->streamingMode = channelConfig->streamingMode; // adding streaming mode to channel handle
160  channel->loopBack = channelConfig->loopBack; // adding loopback selection to channel handle
161 }
162 
163 
165 {
166  channelConfig->hssl = hssl->hssl;
167  channelConfig->hsct = hssl->hsct;
168 
169  channelConfig->channelId = IfxHssl_ChannelId_0; // default channel 0
170  channelConfig->streamingMode = IfxHssl_StreamingMode_single; // default streaming mode continuous
171  channelConfig->loopBack = FALSE; // default with out loopback
172 }
173 
174 
176 {
177  Ifx_HSSL *hsslSFR = config->hssl; // pointer to HSSL registers
178  Ifx_HSCT *hsctSFR = config->hsct; // pointer to HSCT registers
179 
180  hssl->hssl = hsslSFR; // adding HSSL register pointer to module handle
181  hssl->hsct = hsctSFR; // adding HSCT register pointer to module handle
182 
183  // Pad initialisiation //
188 
189  // select the clock direction //
191  {
193  }
194  else
195  {
196  IfxPort_setPinModeInput(&MODULE_P20, 0, IfxPort_InputMode_pullDown); // CLKIN
197  }
198 
199  // LVDS configuration //
200  {
202  IfxScuWdt_clearCpuEndinit(psw); // clears the endinit protection
203 
204 #if 0
205  P21_LPCR1.B.RDIS_CTRL = 1;
206  P21_LPCR1.B.RX_DIS = 0;
207 #else
208  // FIXME: change to original code once new IfxPort_reg.h is available //
209  P21_LPCR1.B_P21.RDIS_CTRL = 1;
210  P21_LPCR1.B_P21.RX_DIS = 0;
211 #endif
212  P21_LPCR2.B.TDIS_CTRL = 1;
213  P21_LPCR2.B.TX_DIS = 0;
214  P21_LPCR2.B.TX_PD = 0;
215 
216  IfxScuWdt_setCpuEndinit(psw); // sets the endinit protection back on
217  }
218 
219  // HSCT initialisation //
220  IfxHssl_enableHsctModule(hsctSFR); // enabling the HSCT module
221 
222  hsctSFR->IRQCLR.B.TXTECLR = 1; // due to AI
223 
224  // slave interface initialisation //
225  if (config->interfaceMode == IfxHssl_InterfaceMode_slave) // slave mode initialisation
226  {
227  hsctSFR->INIT.B.IFM = IfxHssl_InterfaceMode_slave; // slave mode
228  hsctSFR->INIT.B.SYS_CLK_EN = 0; // disabling the system clock
229  hsctSFR->INIT.B.SRCF = IfxHssl_ClockFrequencyRate_20Mhz; // Reference Clock Frequency rate 20 MHz
230  hsctSFR->CONFIGPHY.B.OSCCLKEN = IfxHssl_PllReferenceClock_hsctSystemClockInput; // PLL reference clock is hsct system clock input
231  hsctSFR->CONFIGPHY.B.PHYRST = 0; // disable PHY reset
232  hsctSFR->CONFIGPHY.B.PLLWMF = 16; // PLL frequency control word multiplication factor
233 
234  // enable slave Tx channel (Rx disable to Rx low peed) //
236 
237  // change from low speed to high speed //
238  if (config->highSpeedMode)
239  {
240  hsctSFR->CONFIGPHY.B.OSCCLKEN = IfxHssl_PllReferenceClock_oscillatorInput; // PLL reference clock is Oscillator input
241 
242  // Slave interface clock multiplier off to Slave interface high speed clock
244 
245  // change the speed of slave Rx channel (Tx low speed to Tx high peed)
247 
248  // change the speed of slave Tx channel (Rx disable to Rx low peed)
250  }
251  }
252 
253  // master interface initialisation //
254  else // master mode initialisation
255  {
256  hsctSFR->INIT.B.IFM = IfxHssl_InterfaceMode_master; // master mode
257  hsctSFR->INIT.B.SYS_CLK_EN = 1; // enabling the system clock
258  hsctSFR->INIT.B.SRCF = IfxHssl_ClockFrequencyRate_20Mhz; // Reference Clock Frequency rate 20 MHz
259  hsctSFR->CONFIGPHY.B.OSCCLKEN = IfxHssl_PllReferenceClock_oscillatorInput; // PLL reference clock is Oscillator input
260  hsctSFR->CONFIGPHY.B.PHYRST = 0; // disable PHY reset
261  hsctSFR->CONFIGPHY.B.PLLPON = 1; // PLL power on
262  hsctSFR->CONFIGPHY.B.PLLWMF = 16; // PLL frequency control word multiplication factor
263  hsctSFR->IFCTRL.B.MTXSPEED = IfxHssl_MasterModeTxSpeed_lowSpeed; // Tx low speed
264  hsctSFR->IFCTRL.B.MRXSPEED = IfxHssl_MasterModeRxSpeed_lowSpeed; // Rx low speed
265 
266  // change from low speed to high speed //
267  if (config->highSpeedMode)
268  {
269  hsctSFR->IFCTRL.B.MTXSPEED = IfxHssl_MasterModeTxSpeed_highSpeed; // Tx high speed
270  hsctSFR->IFCTRL.B.MRXSPEED = IfxHssl_MasterModeRxSpeed_highSpeed; // Rx high speed
271  }
272 
273  while (hsctSFR->STATPHY.B.PLOCK == 0) // wait until pll is locked
274  {}
275  }
276 
277  hsctSFR->DISABLE.U = 0;
278 
279  // HSSL initialisation //
280  IfxHssl_enableHsslModule(hsslSFR); // enabling the HSSL module
281  hsslSFR->CFG.B.PREDIV = config->preDivider; // predivivder
282 
283  // Access windows //
284  hsslSFR->AW[0].AWSTART.U = config->accessWindow0.start; // start of access window
285  hsslSFR->AW[0].AWEND.U = config->accessWindow0.end; // end of access window
286  hsslSFR->AW[1].AWSTART.U = config->accessWindow1.start; // start of access window
287  hsslSFR->AW[1].AWEND.U = config->accessWindow1.end; // end of access window
288  hsslSFR->AW[2].AWSTART.U = config->accessWindow2.start; // start of access window
289  hsslSFR->AW[2].AWEND.U = config->accessWindow2.end; // end of access window
290  hsslSFR->AW[3].AWSTART.U = config->accessWindow3.start; // start of access window
291  hsslSFR->AW[3].AWEND.U = config->accessWindow3.end; // end of access window
292 
293  hsslSFR->AR.U = 0x000000ff; // allow read/write access for all windows
294 
295  hsslSFR->MFLAGSCL.B.INIC = 1; // chnage into run mode
296 
297  while (hsslSFR->MFLAGS.B.INI) // wait until the mode changes
298  {}
299 
300  hssl->loopBack = config->loopBack; // adding loopback selection to module handle
301 }
302 
303 
304 void IfxHssl_Hssl_initModuleConfig(IfxHssl_Hssl_Config *config, Ifx_HSSL *hssl, Ifx_HSCT *hsct)
305 {
306  config->hssl = hssl;
307  config->hsct = hsct;
308 
309  // Access windows //
310  config->accessWindow0.start = 0x00000000; // start of access window
311  config->accessWindow0.end = 0xffffffff; // end of access window
312  config->accessWindow1.start = 0x00000000; // start of access window
313  config->accessWindow1.end = 0xffffffff; // end of access window
314  config->accessWindow2.start = 0x00000000; // start of access window
315  config->accessWindow2.end = 0xffffffff; // end of access window
316  config->accessWindow3.start = 0x00000000; // start of access window
317  config->accessWindow3.end = 0xffffffff; // end of access window
318 
319  // predivider //
320  config->preDivider = 256;
321 
322  // interface mode //
324 
325  // high speed mode disabled //
326  config->highSpeedMode = FALSE;
327 
328  config->loopBack = FALSE; // default with out loopback
329 }
330 
331 
333 {
334  IfxHssl_ChannelId channelId = channel->channelId;
335 
336  // target start address to memeroy block 0 on target device (writing into HSSL_TSSA0 of the target) //
337  IfxHssl_Hssl_singleFrameRequest(channel, IfxHssl_Hssl_FrameRequest_writeFrame, (uint32)&HSSL_TSSA0, slaveTargetAddress, IfxHssl_DataLength_32bit);
338 
340  {}
341 
342  // memory count into target reload count register on target device //
343  IfxHssl_Hssl_singleFrameRequest(channel, IfxHssl_Hssl_FrameRequest_writeFrame, (uint32)&HSSL_TSFC, count, IfxHssl_DataLength_16bit);
344 
346  {}
347 
348  // incase of transfers between two different devices (loopback off) //
349  if (!channel->loopBack)
350  {
351  channel->channelId = IfxHssl_ChannelId_2; // channel 2 for for setting the target device into streaming mode
352 
353  // enable streaming mode (single) of channel 2 on target device //
354  IfxHssl_Hssl_singleFrameRequest(channel, IfxHssl_Hssl_FrameRequest_writeFrame, (uint32)&HSSL_CFG, 0x00070100, IfxHssl_DataLength_32bit);
355 
357  {}
358 
359  // since channel 2 is set to streaming mode register access is no longer possible through it //
360  channel->channelId = channelId; // back to original channel for register access to set MFLGSSET.TSES bit of target device
361 
362  // enable streaming on target device //
363  IfxHssl_Hssl_singleFrameRequest(channel, IfxHssl_Hssl_FrameRequest_writeFrame, (uint32)&HSSL_MFLAGSSET, 0x10000000, IfxHssl_DataLength_32bit);
364 
366  {}
367  }
368 
369  channel->streamingModeOn = TRUE; // for waitAcknowledge function
370  // preperation was successful //
371  return IfxHssl_Hssl_Status_ok;
372 }
373 
374 
376 {
377  uint32 data = 0; // not required, data will be read back
378  return IfxHssl_Hssl_singleFrameRequest(channel, IfxHssl_Hssl_FrameRequest_readFrame, address, data, dataLength); // initiate the read request
379 }
380 
381 
383 {
384  Ifx_HSCT *hsctSFR = hssl->hsct;
385 
386  hsctSFR->IFCTRL.B.IFCVS = command; // write the command into the register
387  hsctSFR->IFCTRL.B.SIFCV = 1; // activate the command
388 
389  IfxHssl_Hssl_delay(hssl); //wait until the change happens
390 }
391 
392 
393 static IfxHssl_Hssl_Status IfxHssl_Hssl_singleFrameRequest(IfxHssl_Hssl_Channel *channel, IfxHssl_Hssl_FrameRequest frameRequest, uint32 address, uint32 data, IfxHssl_DataLength dataLength)
394 {
395  Ifx_HSSL_I *hsslI = (Ifx_HSSL_I *)&channel->hssl->I[channel->channelId];
396 
398  {
400  }
401 
402  channel->hssl->CFG.B.SCM = 0; // command mode
403  hsslI->ICON.B.DATLEN = dataLength; // 0x2 -> word size
404  hsslI->ICON.B.TOREL = 0xff; // max reload value
405 
406  switch (frameRequest)
407  {
409  hsslI->ICON.B.RWT = IfxHssl_Command_readFrame;
410  hsslI->IRWA.U = address;
411  break;
413  hsslI->ICON.B.RWT = IfxHssl_Command_writeFrame;
414  hsslI->IWD.U = data;
415  hsslI->IRWA.U = address;
416  break;
418  hsslI->ICON.B.RWT = IfxHssl_Command_triggerFrame;
419  hsslI->IWD.U = data; // dummy
420  hsslI->IRWA.U = address; // dummy
421  break;
423  // request an ID frame //
424  channel->hssl->TIDADD.U = address;
425  hsslI->ICON.B.IDQ = 1;
426  break;
427  default:
428  // invalid request //
430  }
431 
432  channel->currentFrameRequest = frameRequest;
433 
434  return IfxHssl_Hssl_Status_ok;
435 }
436 
437 
439 {
440  uint32 requestType = channel->currentFrameRequest;
441  IfxHssl_ChannelId channelId = channel->channelId;
442 
443  if ((channelId == IfxHssl_ChannelId_2) && (channel->streamingModeOn))
444  {
445  while (channel->hssl->MFLAGS.B.ISB)
446  {
447  // transfer in progress
448  }
449  }
450  else
451  {
453  {
454  requestType = 1;
455  }
456 
457  // expect a read frame when requestType == IfxHssl_Hssl_FrameRequest_readId //
459  {
460  requestType = 2;
461  }
462 
464  {
465  requestType = 3;
466  }
467 
468  uint32 qFlags = channel->hssl->QFLAGS.U;
469  uint32 mFlags = channel->hssl->MFLAGS.U;
470  uint32 acknwoledgeFlagsMask = ((requestType << (16 + (channel->channelId * 2))) | (1 << channel->channelId));
471  uint32 errorFlagsMask = ((0x03E00000) | (4369 << channel->channelId)); // all the possible errors
472 
473  if (qFlags & acknwoledgeFlagsMask) // transfer in progress?
474  {
475  if (mFlags & errorFlagsMask) // check for errors
476  {
477  return IfxHssl_Hssl_Status_error; // return error status in case of an error
478  }
479  else
480  {
481  return IfxHssl_Hssl_Status_busy; // return busy status in case of no error
482  }
483  }
484 
485  // transfer is finished //
487  }
488 
489  return IfxHssl_Hssl_Status_ok;
490 }
491 
492 
494 {
495  return IfxHssl_Hssl_singleFrameRequest(channel, IfxHssl_Hssl_FrameRequest_writeFrame, address, data, dataLength);
496 }
497 
498 
500 {
501  Ifx_HSSL *hsslSFR = hssl->hssl;
502  Ifx_HSSL_IS *hsslIS = (Ifx_HSSL_IS *)&hsslSFR->IS;
504 
505  // single memory block streaming //
506  hsslIS->SA[0].U = (uint32)data; // initiator start address to memeroy block 0
507 
508  hsslIS->FC.B.RELCOUNT = count; // memory count into initiator reload count register
509 
510  hsslSFR->CFG.B.SCM = 1; // enable streaming mode of channel 2 on the initiator
511  hsslSFR->CFG.B.SMT = streamingMode; // set transmitter streaming mode ( single / continuous ) on the initiator
512  hsslSFR->CFG.B.SMR = streamingMode; // set receiver streaming mode ( single / continuous ) on the initiator
513 
514  // incase of transfers within the device(loopback on) //
515  if (hssl->loopBack)
516  {
517  hsslSFR->MFLAGSSET.B.TSES = 1; // enable target
518  }
519 
520  // initiate the transfer //
521  hsslSFR->MFLAGSSET.B.ISBS = 1;
522 
523  // streaming started //
524  return IfxHssl_Hssl_Status_ok;
525 }