1 //*****************************************************************************
\r
3 // pdc.c - Driver for the Peripheral Device Controller (PDC) on the Stellaris
\r
4 // development board.
\r
6 // Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved.
\r
8 // Software License Agreement
\r
10 // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
\r
11 // exclusively on LMI's Stellaris Family of microcontroller products.
\r
13 // The software is owned by LMI and/or its suppliers, and is protected under
\r
14 // applicable copyright laws. All rights are reserved. Any use in violation
\r
15 // of the foregoing restrictions may subject the user to criminal sanctions
\r
16 // under applicable laws, as well as to civil liability for the breach of the
\r
17 // terms and conditions of this license.
\r
19 // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
\r
20 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
\r
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
\r
22 // LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
\r
23 // CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
\r
25 // This is part of revision 635 of the Stellaris Driver Library.
\r
27 //*****************************************************************************
\r
29 //*****************************************************************************
\r
31 //! \addtogroup utilities_api
\r
34 //*****************************************************************************
\r
36 #include "hw_memmap.h"
\r
37 #include "hw_types.h"
\r
44 //*****************************************************************************
\r
46 //! Initializes the connection to the PDC.
\r
48 //! This function will enable clocking to the SSI and GPIO A modules, configure
\r
49 //! the GPIO pins to be used for an SSI interface, and it will configure the
\r
50 //! SSI as a 1 Mbps master device, operating in MOTO mode. It will also enable
\r
51 //! the SSI module, and will enable the chip select for the PDC on the
\r
52 //! Stellaris development board.
\r
54 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
55 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
59 //*****************************************************************************
\r
64 // Enable the peripherals used to drive the PDC.
\r
66 SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI);
\r
67 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
\r
70 // Configure the appropriate pins to be SSI instead of GPIO.
\r
72 GPIODirModeSet(GPIO_PORTA_BASE, SSI_CLK | SSI_TX | SSI_RX,
\r
74 GPIODirModeSet(GPIO_PORTA_BASE, SSI_CS, GPIO_DIR_MODE_OUT);
\r
75 GPIOPadConfigSet(GPIO_PORTA_BASE, SSI_CLK, GPIO_STRENGTH_4MA,
\r
76 GPIO_PIN_TYPE_STD_WPU);
\r
79 // Configure the SSI port.
\r
81 SSIConfigSetExpClk(SSI_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
\r
82 SSI_MODE_MASTER, 1000000, 8);
\r
83 SSIEnable(SSI_BASE);
\r
86 // Reset the PDC SSI state machine. The chip select needs to be held low
\r
87 // for 100ns; the procedure call overhead more than accounts for this time.
\r
89 GPIOPinWrite(GPIO_PORTA_BASE, PDC_CS, 0);
\r
90 GPIOPinWrite(GPIO_PORTA_BASE, PDC_CS, PDC_CS);
\r
93 //*****************************************************************************
\r
95 //! Read a PDC register.
\r
97 //! \param ucAddr specifies the PDC register to read.
\r
99 //! This function will perform the SSI transfers required to read a register in
\r
100 //! the PDC on the Stellaris development board.
\r
102 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
103 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
105 //! \return Returns the value read from the PDC.
\r
107 //*****************************************************************************
\r
109 PDCRead(unsigned char ucAddr)
\r
111 unsigned long ulTemp;
\r
114 // Send address and read command.
\r
116 SSIDataPut(SSI_BASE, (ucAddr & 0x0F) | PDC_RD);
\r
119 // Dummy write to force read.
\r
121 SSIDataPut(SSI_BASE, 0x00);
\r
124 // Flush data read during address write.
\r
126 SSIDataGet(SSI_BASE, &ulTemp);
\r
129 // If the LCD control register or RAM is being read, then an additional
\r
130 // byte needs to be transferred.
\r
132 if((ucAddr == PDC_LCD_CSR) || (ucAddr == PDC_LCD_RAM))
\r
135 // Dummy write to force read.
\r
137 SSIDataPut(SSI_BASE, 0x00);
\r
140 // Flush read data.
\r
142 SSIDataGet(SSI_BASE, &ulTemp);
\r
146 // Read valid data.
\r
148 SSIDataGet(SSI_BASE, &ulTemp);
\r
151 // Return the data read.
\r
153 return(ulTemp & 0xFF);
\r
156 //*****************************************************************************
\r
158 //! Write a PDC register.
\r
160 //! \param ucAddr specifies the PDC register to write.
\r
161 //! \param ucData specifies the data to write.
\r
163 //! This function will perform the SSI transfers required to write a register
\r
164 //! in the PDC on the Stellaris development board.
\r
166 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
167 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
171 //*****************************************************************************
\r
173 PDCWrite(unsigned char ucAddr, unsigned char ucData)
\r
175 unsigned long ulTemp;
\r
178 // Send address and write command.
\r
180 SSIDataPut(SSI_BASE, (ucAddr & 0x0F) | PDC_WR);
\r
185 SSIDataPut(SSI_BASE, ucData);
\r
188 // Flush data read during address write.
\r
190 SSIDataGet(SSI_BASE, &ulTemp);
\r
193 // Flush data read during data write.
\r
195 SSIDataGet(SSI_BASE, &ulTemp);
\r
198 //*****************************************************************************
\r
200 //! Read the current value of the PDC DIP switches.
\r
202 //! This function will read the current value of the DIP switches attached to
\r
203 //! the PDC on the Stellaris development board.
\r
205 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
206 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
208 //! \return The current state of the DIP switches.
\r
210 //*****************************************************************************
\r
214 return(PDCRead(PDC_DSW));
\r
217 //*****************************************************************************
\r
219 //! Write to the PDC LEDs.
\r
221 //! \param ucLED value to write to the LEDs.
\r
223 //! This function set the state of the LEDs connected to the PDC on the
\r
224 //! Stellaris development board.
\r
226 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
227 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
231 //*****************************************************************************
\r
233 PDCLEDWrite(unsigned char ucLED)
\r
235 PDCWrite(PDC_LED, ucLED);
\r
238 //*****************************************************************************
\r
240 //! Read the current status of the PDC LEDs.
\r
242 //! This function will read the state of the LEDs connected to the PDC on the
\r
243 //! Stellaris development board.
\r
245 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
246 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
248 //! \return The value currently displayed by the LEDs.
\r
250 //*****************************************************************************
\r
254 return(PDCRead(PDC_LED));
\r
257 //*****************************************************************************
\r
259 //! Initializes the LCD display.
\r
261 //! This function will set up the LCD display for writing. It will set the
\r
262 //! data bus to 8 bits, set the number of lines to 2, and the font size to
\r
263 //! 5x10. It will also turn the display off, clear the display, turn the
\r
264 //! display back on, and enable the backlight.
\r
266 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
267 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
269 //! \note The PDC must be initialized via the PDCInit() function before this
\r
270 //! function can be called. Also, it may be necessary to adjust the contrast
\r
271 //! potentiometer in order to discern any output on the LCD display.
\r
275 //*****************************************************************************
\r
279 unsigned char pucCfg[] =
\r
281 0x3C, // Number of lines = 2 / font = 5x10
\r
282 0x08, // Display off
\r
283 0x01, // Display clear
\r
284 0x06, // Entry mode [cursor dir][shift]
\r
285 0x0C, // Display on [display on][curson on][blinking on]
\r
287 unsigned long ulIdx;
\r
290 // Set the data bus width to eight bits.
\r
292 PDCWrite(PDC_LCD_CSR, 0x30);
\r
295 // Wait for 4.1ms by reading the PDC version register enough times to
\r
296 // guarantee that amount of time has passed.
\r
298 for(ulIdx = 0; ulIdx < 257; ulIdx++)
\r
304 // Set the data bus width to eight bits.
\r
306 PDCWrite(PDC_LCD_CSR, 0x30);
\r
309 // Wait for 100us by reading the PDC version register enough times to
\r
310 // guarantee that amount of time has passed. This works out to 112us plus
\r
313 for(ulIdx = 0; ulIdx < 7; ulIdx++)
\r
319 // Set the data bus width to eight bits.
\r
321 PDCWrite(PDC_LCD_CSR, 0x30);
\r
324 // Configure the LCD.
\r
326 for(ulIdx = 0; ulIdx < (sizeof(pucCfg) / sizeof(pucCfg[0])); ulIdx++)
\r
329 // Wait until the LCD has finished executing any previous command.
\r
331 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
336 // Write the next configuration byte.
\r
338 PDCWrite(PDC_LCD_CSR, pucCfg[ulIdx]);
\r
342 //*****************************************************************************
\r
344 //! Turns on the backlight.
\r
346 //! This function turns on the backlight on the LCD.
\r
348 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
349 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
353 //*****************************************************************************
\r
355 PDCLCDBacklightOn(void)
\r
357 PDCWrite(PDC_CSR, 0x01);
\r
360 //*****************************************************************************
\r
362 //! Turn off the backlight.
\r
364 //! This function turns off the backlight on the LCD.
\r
366 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
367 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
371 //*****************************************************************************
\r
373 PDCLCDBacklightOff(void)
\r
375 PDCWrite(PDC_CSR, 0x00);
\r
378 //*****************************************************************************
\r
380 //! Clear the screen.
\r
382 //! This function clears the contents of the LCD screen. The cursor will be
\r
383 //! returned to the upper left corner.
\r
385 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
386 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
390 //*****************************************************************************
\r
395 // Wait until the LCD has finished executing any previous command.
\r
397 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
402 // Write the clear display command.
\r
404 PDCWrite(PDC_LCD_CSR, LCD_CLEAR);
\r
407 //*****************************************************************************
\r
409 //! Write a character pattern to the LCD.
\r
411 //! \param ucChar is the character index to create. Valid values are zero
\r
413 //! \param pucData is the data for the character pattern. It contains eight
\r
414 //! bytes, with the first byte being the top row of the pattern. In each byte,
\r
415 //! the LSB is the right pixel of the pattern.
\r
417 //! This function will write a character pattern into the LCD for use as a
\r
418 //! character to be displayed. After writing the pattern, it can be used on
\r
419 //! the LCD by writing the corresponding character index to the display.
\r
421 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
422 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
426 //*****************************************************************************
\r
428 PDCLCDCreateChar(unsigned char ucChar, unsigned char *pucData)
\r
431 // Check the arguments.
\r
433 ASSERT(ucChar < 8);
\r
436 // Wait until the LCD has finished executing any previous command.
\r
438 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
443 // Write the character pattern memory address.
\r
445 PDCWrite(PDC_LCD_CSR, LCD_CGADDR + (ucChar * 8));
\r
448 // Write the pattern to chacter pattern memory.
\r
450 for(ucChar = 0; ucChar < 8; ucChar++)
\r
453 // Wait until the LCD has finished executing any previous command.
\r
455 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
460 // Write this row of the pattern.
\r
462 PDCWrite(PDC_LCD_RAM, *pucData++);
\r
466 //*****************************************************************************
\r
468 //! Set the position of the cursor.
\r
470 //! \param ucX is the horizontal position. Valid values are zero through
\r
472 //! \param ucY is the vertical position.. Valid values are zero and one.
\r
474 //! This function will move the cursor to the specified position. All
\r
475 //! characters written to the LCD are placed at the current cursor position,
\r
476 //! which is automatically advanced.
\r
478 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
479 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
483 //*****************************************************************************
\r
485 PDCLCDSetPos(unsigned char ucX, unsigned char ucY)
\r
488 // Check the arguments.
\r
494 // Wait until the LCD has finished executing any previous command.
\r
496 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
501 // Set the cursor position.
\r
503 PDCWrite(PDC_LCD_CSR, LCD_DDADDR | (0x40 * ucY) + ucX);
\r
506 //*****************************************************************************
\r
508 //! Writes a string to the LCD display.
\r
510 //! \param pcStr pointer to the string to be displayed.
\r
511 //! \param ulCount is the number of characters to be displayed.
\r
513 //! This function will display a string on the LCD at the current cursor
\r
514 //! position. It is the caller's responsibility to position the cursor to the
\r
515 //! place where the string should be displayed (either explicitly via
\r
516 //! PDCLCDSetPos() or implicitly from where the cursor was left after a
\r
517 //! previous call to PDCLCDWrite()), and to properly account for the LCD
\r
518 //! boundary (line wrapping is not automatically performed). Null characters
\r
519 //! are not treated special and are written to the LCD, which interprets it as
\r
520 //! a special programmable character glyph (see PDCLCDCreateChar()).
\r
522 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
523 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
527 //*****************************************************************************
\r
529 PDCLCDWrite(const char *pcStr, unsigned long ulCount)
\r
532 // Write the string to the LCD.
\r
537 // Wait until the LCD has finished executing any previous command.
\r
539 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
544 // Write this character to the LCD.
\r
546 PDCWrite(PDC_LCD_RAM, *pcStr++);
\r
550 //*****************************************************************************
\r
552 //! Reads a GPIO direction register.
\r
554 //! \param ucIdx is the index of the GPIO direction register to read; valid
\r
555 //! values are 0, 1, and 2.
\r
557 //! This function reads one of the GPIO direction registers in the PDC. The
\r
558 //! direction bit is set for pins that are outputs and clear for pins that are
\r
561 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
562 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
564 //! \return The contents of the direction register.
\r
566 //*****************************************************************************
\r
568 PDCGPIODirRead(unsigned char ucIdx)
\r
571 // Check the argument.
\r
573 ASSERT((ucIdx == 0) || (ucIdx == 1) || (ucIdx == 2));
\r
576 // Read the requested direction register.
\r
580 return(PDCRead(PDC_GPXDIR));
\r
582 else if(ucIdx == 1)
\r
584 return(PDCRead(PDC_GPYDIR));
\r
588 return(PDCRead(PDC_GPZDIR));
\r
592 //*****************************************************************************
\r
594 //! Write a GPIO direction register.
\r
596 //! \param ucIdx is the index of the GPIO direction register to write; valid
\r
597 //! values are 0, 1, and 2.
\r
598 //! \param ucValue is the value to write to the GPIO direction register.
\r
600 //! This function writes ones of the GPIO direction registers in the PDC. The
\r
601 //! direction bit should be set for pins that are to be outputs and clear for
\r
602 //! pins that are to be inputs.
\r
604 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
605 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
609 //*****************************************************************************
\r
611 PDCGPIODirWrite(unsigned char ucIdx, unsigned char ucValue)
\r
614 // Check the arguments.
\r
616 ASSERT((ucIdx == 0) || (ucIdx == 1) || (ucIdx == 2));
\r
619 // Write the requested direction register.
\r
623 PDCWrite(PDC_GPXDIR, ucValue);
\r
625 else if(ucIdx == 1)
\r
627 PDCWrite(PDC_GPYDIR, ucValue);
\r
631 PDCWrite(PDC_GPZDIR, ucValue);
\r
635 //*****************************************************************************
\r
637 //! Reads a GPIO data register.
\r
639 //! \param ucIdx is the index of the GPIO direction register to read; valid
\r
640 //! values are 0, 1, and 2.
\r
642 //! This function reads one of the GPIO data registers in the PDC. The value
\r
643 //! returned for a pin is the value being driven out for outputs or the value
\r
644 //! being read for inputs.
\r
646 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
647 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
649 //! \return The contents of the data register.
\r
651 //*****************************************************************************
\r
653 PDCGPIORead(unsigned char ucIdx)
\r
656 // Check the argument.
\r
658 ASSERT((ucIdx == 0) || (ucIdx == 1) || (ucIdx == 2));
\r
661 // Read the requested data register.
\r
665 return(PDCRead(PDC_GPXDAT));
\r
667 else if(ucIdx == 1)
\r
669 return(PDCRead(PDC_GPYDAT));
\r
673 return(PDCRead(PDC_GPZDAT));
\r
677 //*****************************************************************************
\r
679 //! Write a GPIO data register.
\r
681 //! \param ucIdx is the index of the GPIO data register to write; valid values
\r
682 //! are 0, 1, and 2.
\r
683 //! \param ucValue is the value to write to the GPIO data register.
\r
685 //! This function writes one of the GPIO direction registers in the PDC. The
\r
686 //! written to a pin is driven out for output pins and ignored for input pins.
\r
688 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
689 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
693 //*****************************************************************************
\r
695 PDCGPIOWrite(unsigned char ucIdx, unsigned char ucValue)
\r
698 // Check the arguments.
\r
700 ASSERT((ucIdx == 0) || (ucIdx == 1) || (ucIdx == 2));
\r
703 // Write the requested data register.
\r
707 PDCWrite(PDC_GPXDAT, ucValue);
\r
709 else if(ucIdx == 1)
\r
711 PDCWrite(PDC_GPYDAT, ucValue);
\r
715 PDCWrite(PDC_GPZDAT, ucValue);
\r
719 //*****************************************************************************
\r
721 // Close the Doxygen group.
\r
724 //*****************************************************************************
\r