MAXREFDES71# Code Documentation  V01.00
MAXREFDES71# 2-Channel Analog Input/Analog Output
 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 "xparameters.h" /* EDK generated parameters */
62 #include "stdio.h"
63 #include "utilities.h"
64 #include "MAXREFDES71.h"
65 
66 #define UART_BASEADDR XPAR_XUARTPS_0_BASEADDR
67 
68 #define OLED_VBAT 0x20
69 #define OLED_VDD 0x10;
70 #define OLED_RESET_B 0x08
71 #define OLED_DATA_COMMAND_B 0x04
72 #define OLED_SDIN 0x02
73 #define OLED_SCLK 0x01
74 
75 void delay(int nStopValue)
86 {
87  int i=0;
88  int a=0;
89 
90  for(i=0;i<nStopValue;i++)
91  {
92  a=i;
93  }
94 }
95 
96 void led_knight_rider(XGpio *pLED_GPIO, int nNumberOfTimes)
107 {
108  int i=0;
109  int j=0;
110  u8 uchLedStatus=0;
111 
112  // Blink the LEDs back and forth nNumberOfTimes
113  for(i=0;i<nNumberOfTimes;i++)
114  {
115  for(j=0;j<8;j++) // Scroll the LEDs up
116  {
117  uchLedStatus = 1 << j;
118  XGpio_DiscreteWrite(pLED_GPIO, 1, uchLedStatus);
119  delay(ABOUT_ONE_SECOND / 15);
120  }
121 
122  for(j=0;j<8;j++) // Scroll the LEDs up
123  {
124  uchLedStatus = 8 >> j;
125  XGpio_DiscreteWrite(pLED_GPIO, 1, uchLedStatus);
126  delay(ABOUT_ONE_SECOND / 15);
127  }
128  }
129 }
130 
131 int number_raised_to_power(int nBase, int nExponent)
144 {
145  int i=0;
146  int nValue=0;
147  if(nExponent==0)
148  nValue=1;
149  else
150  {
151  nValue = nBase;
152  for(i=1;i<nExponent;i++)
153  {
154  nValue = nValue * nBase;
155  }
156  }
157  return(nValue);
158 }
159 
160 void print_asterisks(int nQuantity)
168 {
169  int i=0;
170  for(i=0;i<nQuantity;i++)
171  printf("*");
172 }
173 
174 u8 getUartByte(u32 nUartAddress)
182 {
183  u8 uchInput;
184 
185  // Check if the UART base address is the full UART located within the Zynq chip,
186  // if not, assume it is an HDL instantiated AXI-UartLite
187  if(nUartAddress==XPAR_PS7_UART_1_BASEADDR)
188  read(1, (char*)&uchInput, 1); // Get a byte from stdin
189 //MTS No XUartLite hardware or driver.
190 //MTS else
191 //MTS uchInput = XUartLite_RecvByte(nUartAddress);
192  return(uchInput);
193 }
194 
195 void sendUartByte(u32 unUartAddress, u8 uchByte)
204 {
205  if(unUartAddress==DEFAULT_HYPERTERMINAL_UART_ADDRESS)
206  {
207  printf("%c",uchByte);
208  fflush(stdout);
209  }
210 //MTS No XUartLite hardware or driver.
211 //MTS else
212 //MTS XUartLite_SendByte(unUartAddress, uchByte);
213 }
214 
215 u8 checkUartEmpty(u32 unUartAddress)
223 {
224  u8 uchReturnVal=TRUE;
225  u32 unUartStatusRegisterAddress;
226  u32 unStatusRegisterValue;
227  if(unUartAddress==XPAR_PS7_UART_1_BASEADDR)
228  {
229  unUartStatusRegisterAddress = unUartAddress + 0x0000002C;
230  unStatusRegisterValue = Xil_In32(unUartStatusRegisterAddress);
231 
232  // Register UART BASE ADDR + 0x2C. Bit 1 is a (1) when Rx FIFO is empty
233  if((unStatusRegisterValue & 0x00000002)==0x00000002)
234  uchReturnVal=TRUE;
235  else
236  uchReturnVal=FALSE;
237  }
238  else
239  {
240 //MTS No XUartLite hardware or driver.
241 //MTS if(XUartLite_IsReceiveEmpty(unUartAddress)==TRUE)
242 //MTS uchReturnVal=TRUE;
243 //MTS else
244  uchReturnVal=FALSE;
245  }
246 
247  return(uchReturnVal);
248 
249 }
250 
251 
252 void initializeOLED(u8 *pFont)
261 {
262  // First, initialize the global structure that represents the OLED device
263 
264  //GPIO that manages the bit-banged SPI interface to the OLED
265  //XGpio_Initialize(&g_structureOLED.xgpioPort, XPAR_AXI_GPIO_OLED_DEVICE_ID);
266  XGpio_Initialize(&g_structureOLED.xgpioPort, XPAR_AXI_GPIO_OLED_DEVICE_ID);
267  XGpio_SetDataDirection(&g_structureOLED.xgpioPort, 1, 0x00); // Set the OLED peripheral to outputs
268  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, 0x00); // Set all values to zero
269  delay(100);
270 
271  // Set the font in the OLED structure
272  g_structureOLED.font = pFont;
273 
274  // Init the global variable that represents the OLED bit-bang pins
276 
277  // Init and clear the display buffer and the invertered/flipped buffer
280 
281  // Now, Initialize the OLED display (hardware)
282 
283  // Disable VBAT power supply to the OLED integrated switcher
284  // Note: These bits control the Gate voltage on a P-Channel MOSFET
286  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus); // Set all values to zero
288 
289  //Enable VDD power supply to digital logic within OLED
291  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus); // Set all values to zero
293 
294  // Disable reset
296  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus); // Set all values to zero
298 
299  // Set Display Off
300  sendOLEDSPI(0xAE);
301  delay(100);
302 
303  // Set Display Clock Divide Ratio. Oscillator Frequency
304  sendOLEDSPI(0xD5);
305  delay(100);
306  sendOLEDSPI(0x80);
307  delay(100);
308 
309  // Set Multiplex Ratio
310  sendOLEDSPI(0xA8);
311  delay(100);
312  sendOLEDSPI(0x1F);
313  delay(100);
314 
315  // Set Display Offset
316  sendOLEDSPI(0xD3);
317  delay(100);
318  sendOLEDSPI(0x00);
319  delay(100);
320 
321  // Set Display Start Line
322  sendOLEDSPI(0x40);
323  delay(100);
324 
325  // Set Charge Pump
326  sendOLEDSPI(0x8D);
327  delay(100);
328  sendOLEDSPI(0x14);
329  delay(100);
330 
331  // Set Segment Re-Map
332  sendOLEDSPI(0xA1);
333  delay(100);
334 
335  // Set COM Output Scan Direction
336  sendOLEDSPI(0xC8);
337  delay(100);
338 
339  // Set Com Pins Hardware Configuration
340  sendOLEDSPI(0xDA);
341  delay(100);
342  sendOLEDSPI(0x02);
343  delay(100);
344 
345  // Set Contrast Control
346  sendOLEDSPI(0x81);
347  delay(100);
348  sendOLEDSPI(0x8F);
349  delay(100);
350 
351  // Set Pre-Charge Period
352  sendOLEDSPI(0xD9);
353  delay(100);
354  sendOLEDSPI(0xF1);
355  delay(100);
356 
357  // Set VCOMH Deselect Level
358  sendOLEDSPI(0xDB);
359  delay(100);
360  sendOLEDSPI(0x40);
361  delay(100);
362 
363  // Set Entire Display On
364  sendOLEDSPI(0xA4);
365  delay(100);
366 
367  // Set Normal/Inverse Display
368  sendOLEDSPI(0xA6);
369  delay(100);
370 
371  // Enable the VBAT power supply (which is used for the OLED)
373  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus); // Set all values to zero
374  delay(ABOUT_ONE_SECOND/2); // Long delay for internal OLED switcher to stabilize
375 
376  // Set Display On
377  sendOLEDSPI(0xAF);
378  delay(100);
379 }
380 
381 
382 void sendOLEDSPI(u8 uchDataToWrite)
391 {
392  int i;
393 
394  for(i=7;i>=0;i--)
395  {
396  // Set the OLED_SDIN bit
397  if(((uchDataToWrite >> i) & 0x01)==0x01)
399  else
401  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus);
402  delay(100);
403 
404  // Clock in the data via a rising edge of SCLK
406  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus);
407  delay(100);
409  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus);
410  delay(100);
411  }
412 }
413 
414 
415 void clearOLEDBuffer(u8 *pauchBuffer)
424 {
425  int i;
426 
427  for(i=0;i<512;i++)
428  pauchBuffer[i] = 0x00;
429 
430 }
431 
432 void displayOLEDBuffer(u8 *pauchBuffer)
442 {
443  int column=0;
444  int page=0;
445  u8 *p;
446  u8 uchPixelValue=0;
447 
448  // Set the display mode to page based transfers
449  sendOLEDSPI(0x20);
450  delay(100);
451  sendOLEDSPI(0x02);
452  delay(100);
453 
454  // Set the page pointer lower nibble to 0x0
455  sendOLEDSPI(0x00);
456  delay(100);
457 
458  // Set the page pointer upper nibble to 0x0
459  sendOLEDSPI(0x10);
460  delay(100);
461 
462  // Write 4 pages worth of data
463  // Note that the SSD1306 controller can handle 128x64 displays, but the OLED
464  // used on zedboard is only 128x32. Data is provided to the display as (4) pages of 128 bytes each.
465  p = pauchBuffer;
466  for(page=0;page<4;page++)
467  {
468  // Enable Command Mode (shut off data mode)
470  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus); // Set all values to zero
471  delay(100); // Long delay for internal OLED switcher to stabilize
472 
473  // Set the page command by issuing 0xB0 (page0), 0xB1 (page1) etc.
474  sendOLEDSPI((0xB0+page));
475 
476  // Enable the Data mode (shut off command mode)
478  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus); // Set all values to zero
479  delay(100); // Long delay for internal OLED switcher to stabilize
480 
481  for(column=0;column<128;column++)
482  {
483  uchPixelValue = *p;
484  sendOLEDSPI(uchPixelValue); // change this to zero
485  p++;
486  }
487  }
488 
489  // Enable Command Mode (shut off data mode)
491  XGpio_DiscreteWrite(&g_structureOLED.xgpioPort, 1, g_structureOLED.portStatus); // Set all values to zero
492  delay(100); // Long delay for internal OLED switcher to stabilize
493 }
494 
495 void putCharOLED(int x, int y, char chCharacter)
506 {
507  int i;
508  int nDisplayBufferIndex=0;
509  int nFontIndex=0;
510 
511  // Create the index location for the character into the display memory
512  nDisplayBufferIndex = (x * 8) + (y * 16 * 8);
513 
514  // Make sure the character has a valid value, else ignore
515  if(chCharacter >=0 && chCharacter<128)
516  {
517  nFontIndex = chCharacter * 8;
518 
519  for(i=nDisplayBufferIndex;i<nDisplayBufferIndex+8;i++)
520  {
522  nFontIndex++;
523  }
524  }
525 }
526 
527 void printfToBufferOLED(int x, int y,char *chString)
538 {
539  int nStringLength;
540  int nInitialDisplayLocation;
541  int nRemainingDisplayLength;
542  int i;
543  int xIndex=0;
544  int yIndex=0;
545  nStringLength = strlen(chString);
546 
547  // Will the string fit on the display? If not, truncate the length
548  nInitialDisplayLocation = y*16 + x;
549  nRemainingDisplayLength = 64 - nInitialDisplayLocation;
550  if(nStringLength > nRemainingDisplayLength)
551  nStringLength = nRemainingDisplayLength;
552 
553  xIndex = x;
554  yIndex = y;
555  for(i=0;i<nStringLength;i++)
556  {
557  putCharOLED(xIndex,yIndex,chString[i]);
558  xIndex++;
559  if(xIndex==16)
560  {
561  xIndex=0;
562  yIndex++;
563  }
564  }
565 }
566 
567 void printfToOLED(int x, int y,char *chString)
579 {
580  printfToBufferOLED(x,y,chString);
583 }
584 
585 
586 void flipAndCopyDisplayBuffer(u8 *pauchSourceBuffer, u8 *pauchDestinationBuffer)
597 {
598  int i,x,y;
599  u8 uchTempWord1;
600  u8 uchTempWord2;
601  u8 uchTempWord3;
602 
603  for(y=0;y<4;y++)
604  {
605  for(x=0;x<128;x++)
606  {
607  uchTempWord1 = pauchSourceBuffer[511-((y*128)+x)];
608  uchTempWord3 = 0;
609  for(i=0;i<8;i++)
610  {
611  uchTempWord2 = (uchTempWord1 >> (7-i)) & 0x01; // shift the bit to the bit0 location and mask off
612  uchTempWord2 = uchTempWord2 << i; // shift the bit back to the desired location.
613  uchTempWord3 += uchTempWord2;
614  }
615  pauchDestinationBuffer[((y*128)+x)] = uchTempWord3;
616  }
617  }
618 }