Sonoma (MAXREFDES14#) Code Documentation  V01.00
Isolated EMP (Energy Measurement Processor)
 All Data Structures Files Functions Variables Macros Pages
utilities.c
Go to the documentation of this file.
1 
29 /*
30  * Copyright (C) 2012 Maxim Integrated Products, All Rights Reserved.
31  *
32  * Permission is hereby granted, free of charge, to any person obtaining a
33  * copy of this software and associated documentation files (the "Software"),
34  * to deal in the Software without restriction, including without limitation
35  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
36  * and/or sell copies of the Software, and to permit persons to whom the
37  * Software is furnished to do so, subject to the following conditions:
38  *
39  * The above copyright notice and this permission notice shall be included
40  * in all copies or substantial portions of the Software.
41  *
42  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
43  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45  * IN NO EVENT SHALL MAXIM INTEGRATED PRODUCTS BE LIABLE FOR ANY CLAIM, DAMAGES
46  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
47  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
48  * OTHER DEALINGS IN THE SOFTWARE.
49  *
50  * Except as contained in this notice, the name of Maxim Integrated Products
51  * shall not be used except as stated in the Maxim Integrated Products
52  * Branding Policy.
53  *
54  * The mere transfer of this software does not imply any licenses
55  * of trade secrets, proprietary technology, copyrights, patents,
56  * trademarks, maskwork rights, or any other form of intellectual
57  * property whatsoever. Maxim Integrated Products retains all ownership rights.
58  *
59  ***************************************************************************/
60 
61 #include "utilities.h"
62 #include "MAXREFDES14.h"
63 
64 void print_asterisks(int nQuantity)
72 {
73  int i=0;
74  for(i=0;i<nQuantity;i++)
75  printf("*");
76 }
77 
78 int SpiRW( u32 unPeripheralAddressSPI, unsigned int unCPHA, unsigned int unCPOL,
79  u8* auchWriteBuf, u8* auchReadBuf, int unNumBytes, u8 uchCsActiveHigh )
101 {
102  int i;
103  unsigned int unControlData = 0x00000186;
104 
105  //If CPHA or CPOL = 1, we need to set the corresponding bits in the control register
106  unControlData = unControlData | (unCPHA << 4);
107  unControlData = unControlData | (unCPOL << 3);
108 
109  //Write config data to SPICR. We need the inhibit bit=1.
110  XSpi_WriteReg(unPeripheralAddressSPI, 0x60, unControlData);
111 
112  //Deassert CS to 1 to ensure SPI slave is inactive
113  if( uchCsActiveHigh )
114  XSpi_WriteReg(unPeripheralAddressSPI, 0x70, 0xFFFFFFFE);
115  else
116  XSpi_WriteReg(unPeripheralAddressSPI, 0x70, 0xFFFFFFFF);
117 
118  for( i = 0; i < unNumBytes; i++)
119  {
120  if( auchWriteBuf != 0 )
121  {
122  //Write data to SPIDTR. This is the data that will be transferred to the SPI slave.
123  XSpi_WriteReg(unPeripheralAddressSPI, 0x68, auchWriteBuf[ i ]);
124  //Debug//printf( "Write %02x; ", auchWriteBuf[i]);
125  }
126  else
127  {
128  //Write data to SPIDTR. This is the data that will be transferred to the SPI slave.
129  XSpi_WriteReg(unPeripheralAddressSPI, 0x68, 0x00);
130  }
131 
132  //Write config data to SPICR. We need the inhibit bit=1.
133  XSpi_WriteReg(unPeripheralAddressSPI, 0x60, unControlData);
134 
135  //Assert CS for our PMOD part
136  if( uchCsActiveHigh )
137  XSpi_WriteReg(unPeripheralAddressSPI, 0x70, 0xFFFFFFFF);
138  else
139  XSpi_WriteReg(unPeripheralAddressSPI, 0x70, 0xFFFFFFFE);
140 
141  //Un-inhibit our SPI master to transfer the data
142  XSpi_WriteReg(unPeripheralAddressSPI, 0x60, unControlData & 0xFFFFFEFF);
143 
144  //Wait for transaction to complete. Check to see if Tx_Empty flag is set before proceeding.
145  while( !(XSpi_ReadReg( unPeripheralAddressSPI, 0x64 ) & 0x00000004) )
146  ;
147 
148  //Inhibit SPI master to prevent further action
149  XSpi_WriteReg(unPeripheralAddressSPI, 0x60, unControlData);
150 
151  //Read received data
152  if( (auchReadBuf != 0) )
153  {
154  auchReadBuf[ i ] = XSpi_ReadReg(unPeripheralAddressSPI, 0x6C);
155  //Debug//printf( "Read %02x\r\n", auchReadBuf[i]);
156  }
157  }
158  if( uchCsActiveHigh )
159  XSpi_WriteReg(unPeripheralAddressSPI, 0x70, 0xFFFFFFFE);
160  else
161  XSpi_WriteReg(unPeripheralAddressSPI, 0x70, 0xFFFFFFFF);
162  return 0;
163 }
164 
165 void delay(int nStopValue)
176 {
177  int i=0;
178  int a=0;
179 
180  for(i=0;i<nStopValue;i++)
181  {
182  a=i;
183  }
184 }
185 
186 void led_knight_rider(XGpio *pLED_GPIO, int nNumberOfTimes)
197 {
198  int i=0;
199  int j=0;
200  u8 uchLedStatus=0;
201 
202  // Blink the LEDs back and forth nNumberOfTimes
203  for(i=0;i<nNumberOfTimes;i++)
204  {
205  for(j=0;j<8;j++) // Scroll the LEDs up
206  {
207  uchLedStatus = 1 << j;
208  XGpio_DiscreteWrite(pLED_GPIO, 1, uchLedStatus);
209  delay(ABOUT_ONE_SECOND / 15);
210  }
211 
212  for(j=0;j<8;j++) // Scroll the LEDs up
213  {
214  uchLedStatus = 8 >> j;
215  XGpio_DiscreteWrite(pLED_GPIO, 1, uchLedStatus);
216  delay(ABOUT_ONE_SECOND / 15);
217  }
218  }
219 }
220 
221 void max_configure_PMOD_port(u8 uchPmodPortA, u8 uchPmodPortB, u8 uchPmodPortC, u8 uchPmodPortD)
240 {
241  XGpio xGpioPmodPortMuxIO;
242  u8 uchPmodPortSelectBits=0;
243  // The PMOD ports are configured with an 8 bit word sent to GPIO2
244  // Bits 1:0 are for port #A
245  // Bits 3:2 are for port #B
246  // Bits 5:4 are for port #C
247  // Bits 7:6 are for Port #D
248 
249  //S = 2'b00 => UART active (PMOD_PORT_TYPE_UART)
250  //S= 2'b01 => SPI active (PMOD_PORT_TYPE_SPI)
251  //S = 2'b10 => GPIO active (PMOD_PORT_TYPE_GPIO)
252  //S = 2'b11 => I2C active (PMOD_PORT_TYPE_I2C)
253 
254  uchPmodPortSelectBits = (uchPmodPortD << 6) + (uchPmodPortC << 4) + (uchPmodPortB << 2) + uchPmodPortA;
255 
256  XGpio_Initialize(&xGpioPmodPortMuxIO, XPAR_AXI_GPIO_2_DEVICE_ID);
257  XGpio_SetDataDirection(&xGpioPmodPortMuxIO, 1, 0x00); // Set the GPIO2 direction to outputs
258  XGpio_DiscreteWrite(&xGpioPmodPortMuxIO, 1, uchPmodPortSelectBits);
259 }
260 
272 {
273  XGpio xGpioPmodPortA;
274  unsigned int unGpioPortData = 0;
275  int nReturnVal=FALSE;
276 
277  // Configure Port A to be GPIO
279 
280  // Set SCL and SDA to be inputs
281  XGpio_Initialize(&xGpioPmodPortA, XPAR_AXI_GPIO_0_DEVICE_ID);
282  XGpio_SetDataDirection(&xGpioPmodPortA, 1, 0x0C); // Set the all pins to outputs, except pins SDA (pin3) and SCL (pin2)
283  unGpioPortData = XGpio_DiscreteRead(&xGpioPmodPortA, 1);
284  if(((unGpioPortData >> 2) & 0x03)==0x03)
285  {
286  printf("I2C Device is present\r\n");
287  nReturnVal=TRUE;
288  }
289  else
290  {
291  nReturnVal=FALSE;
292  print_asterisks(74);
293  printf("******WARNING: Could not find pull-ups on SDA nor SCL ********************\r\n");
294  printf("******Attempts to read/write may hang CPU ********************************\r\n");
295  printf("******Recommend to go back to main menu and double-check I2C device.******\r\n");
296  print_asterisks(74);
297  delay(ABOUT_ONE_SECOND * 3);
298  }
299 
300  delay(ABOUT_ONE_SECOND / 10);
301  // Set the ports back to the standard configuration
303  delay(ABOUT_ONE_SECOND / 10);
304 
305 return(nReturnVal);
306 }
307 
308 int number_raised_to_power(int nBase, int nExponent)
321 {
322  int i=0;
323  int nValue=0;
324  if(nExponent==0)
325  nValue=1;
326  else
327  {
328  nValue = nBase;
329  for(i=1;i<nExponent;i++)
330  {
331  nValue = nValue * nBase;
332  }
333  }
334  return(nValue);
335 }
336 
337 int receive_byte_with_timeout(u32 unUartAddress, int nTimeoutInTenthsOfSeconds, u8 *uchRxData)
347 {
348  int j=0;
349  int nReturnVal = TRUE;
350  u8 uchInput = 0;
351 
352  // Check if there is a character in the UART Rx buffer
353  // Continue checking every 10th of a second for nTimeoutInSeconds
354  while(XUartLite_IsReceiveEmpty(unUartAddress) && (j < nTimeoutInTenthsOfSeconds))
355  {
356  j++;
358  }
359 
360  if(XUartLite_IsReceiveEmpty(unUartAddress))
361  nReturnVal = FALSE;
362  else
363  {
364  uchInput = XUartLite_RecvByte(unUartAddress);
365  // Check if it is an escape sequence
366  if(uchInput==27) // Escape sequence (likely an arrow key)
367  {
368  if(XUartLite_IsReceiveEmpty(unUartAddress))
369  nReturnVal = FALSE;
370  else
371  {
372  uchInput = XUartLite_RecvByte(unUartAddress);
373  if(uchInput==91) // Left bracket (part #2 of the 3 part escape sequence)
374  {
375  if(XUartLite_IsReceiveEmpty(unUartAddress))
376  nReturnVal = FALSE;
377  else
378  {
379  uchInput = XUartLite_RecvByte(unUartAddress);
380  if(uchInput==75)
381  uchInput = 244; // We have defined KEYPRESS_END as 244
382  }
383  }
384  }
385 
386  }
387  *uchRxData = uchInput;
388  nReturnVal = TRUE;
389  }
390  return(nReturnVal);
391 }
392 
393 int GetLine( char* sInputString, unsigned int unMaxSize )
404 {
405  u8 uchInputChar = 0;
406  unsigned int unInputStringIndex = 0;
407 
409  while( (uchInputChar != '\r') && (uchInputChar != '\n') && (unInputStringIndex < unMaxSize-1) )
410  {
411  sInputString[ unInputStringIndex ] = (char)uchInputChar;
412  unInputStringIndex++;
414  }
415  sInputString[ unInputStringIndex ] = '\0';
416 
417  return (unInputStringIndex < unMaxSize) ? unInputStringIndex : -1;
418 }
419 
420 void printf_temp(float fTemp, u8 uchPrintCelsius, u8 uchAddCarriageReturn)
433 {
434  if(uchPrintCelsius==TRUE)
435  printf("%.1f deg C",fTemp);
436  else
437  printf("%.1f deg F",((fTemp*1.8f)+32.0f));
438  if(uchAddCarriageReturn==TRUE)
439  printf("\r\n");
440 }
441 
442 u8 getUartByte(u32 nUartAddress)
450 {
451  u8 uchInput;
452 
453  uchInput = XUartLite_RecvByte(nUartAddress);
454  return(uchInput);
455 }
456 
457 int htoi(char *sStr)
458 {
459  int nRet=0;
460  u8 uchEnd=0;
461  u8 uchCount;
462  for(uchCount=0;uchCount<100;uchCount++)
463  {
464  switch(sStr[uchCount])
465  {
466  case '0': nRet=nRet<<4; nRet=nRet+0; break;
467  case '1': nRet=nRet<<4; nRet=nRet+1; break;
468  case '2': nRet=nRet<<4; nRet=nRet+2; break;
469  case '3': nRet=nRet<<4; nRet=nRet+3; break;
470  case '4': nRet=nRet<<4; nRet=nRet+4; break;
471  case '5': nRet=nRet<<4; nRet=nRet+5; break;
472  case '6': nRet=nRet<<4; nRet=nRet+6; break;
473  case '7': nRet=nRet<<4; nRet=nRet+7; break;
474  case '8': nRet=nRet<<4; nRet=nRet+8; break;
475  case '9': nRet=nRet<<4; nRet=nRet+9; break;
476  case 'a': nRet=nRet<<4; nRet=nRet+10; break;
477  case 'b': nRet=nRet<<4; nRet=nRet+11; break;
478  case 'c': nRet=nRet<<4; nRet=nRet+12; break;
479  case 'd': nRet=nRet<<4; nRet=nRet+13; break;
480  case 'e': nRet=nRet<<4; nRet=nRet+14; break;
481  case 'f': nRet=nRet<<4; nRet=nRet+15; break;
482  case 'A': nRet=nRet<<4; nRet=nRet+10; break;
483  case 'B': nRet=nRet<<4; nRet=nRet+11; break;
484  case 'C': nRet=nRet<<4; nRet=nRet+12; break;
485  case 'D': nRet=nRet<<4; nRet=nRet+13; break;
486  case 'E': nRet=nRet<<4; nRet=nRet+14; break;
487  case 'F': nRet=nRet<<4; nRet=nRet+15; break;
488  default: uchEnd=1; break;
489  }
490  if(uchEnd)
491  {
492  break;
493  }
494  }
495  return nRet;
496 }