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 SSIConfig(SSI_BASE, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8);
\r
82 SSIEnable(SSI_BASE);
\r
85 // Reset the PDC SSI state machine. The chip select needs to be held low
\r
86 // for 100ns; the procedure call overhead more than accounts for this time.
\r
88 GPIOPinWrite(GPIO_PORTA_BASE, PDC_CS, 0);
\r
89 GPIOPinWrite(GPIO_PORTA_BASE, PDC_CS, PDC_CS);
\r
92 //*****************************************************************************
\r
94 //! Read a PDC register.
\r
96 //! \param ucAddr specifies the PDC register to read.
\r
98 //! This function will perform the SSI transfers required to read a register in
\r
99 //! the PDC on the Stellaris development board.
\r
101 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
102 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
104 //! \return Returns the value read from the PDC.
\r
106 //*****************************************************************************
\r
108 PDCRead(unsigned char ucAddr)
\r
110 unsigned long ulTemp;
\r
113 // Send address and read command.
\r
115 SSIDataPut(SSI_BASE, (ucAddr & 0x0F) | PDC_RD);
\r
118 // Dummy write to force read.
\r
120 SSIDataPut(SSI_BASE, 0x00);
\r
123 // Flush data read during address write.
\r
125 SSIDataGet(SSI_BASE, &ulTemp);
\r
128 // If the LCD control register or RAM is being read, then an additional
\r
129 // byte needs to be transferred.
\r
131 if((ucAddr == PDC_LCD_CSR) || (ucAddr == PDC_LCD_RAM))
\r
134 // Dummy write to force read.
\r
136 SSIDataPut(SSI_BASE, 0x00);
\r
139 // Flush read data.
\r
141 SSIDataGet(SSI_BASE, &ulTemp);
\r
145 // Read valid data.
\r
147 SSIDataGet(SSI_BASE, &ulTemp);
\r
150 // Return the data read.
\r
152 return(ulTemp & 0xFF);
\r
155 //*****************************************************************************
\r
157 //! Write a PDC register.
\r
159 //! \param ucAddr specifies the PDC register to write.
\r
160 //! \param ucData specifies the data to write.
\r
162 //! This function will perform the SSI transfers required to write a register
\r
163 //! in the PDC on the Stellaris development board.
\r
165 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
166 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
170 //*****************************************************************************
\r
172 PDCWrite(unsigned char ucAddr, unsigned char ucData)
\r
174 unsigned long ulTemp;
\r
177 // Send address and write command.
\r
179 SSIDataPut(SSI_BASE, (ucAddr & 0x0F) | PDC_WR);
\r
184 SSIDataPut(SSI_BASE, ucData);
\r
187 // Flush data read during address write.
\r
189 SSIDataGet(SSI_BASE, &ulTemp);
\r
192 // Flush data read during data write.
\r
194 SSIDataGet(SSI_BASE, &ulTemp);
\r
197 //*****************************************************************************
\r
199 //! Read the current value of the PDC DIP switches.
\r
201 //! This function will read the current value of the DIP switches attached to
\r
202 //! the PDC on the Stellaris development board.
\r
204 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
205 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
207 //! \return The current state of the DIP switches.
\r
209 //*****************************************************************************
\r
213 return(PDCRead(PDC_DSW));
\r
216 //*****************************************************************************
\r
218 //! Write to the PDC LEDs.
\r
220 //! \param ucLED value to write to the LEDs.
\r
222 //! This function set the state of the LEDs connected to the PDC on the
\r
223 //! Stellaris development board.
\r
225 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
226 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
230 //*****************************************************************************
\r
232 PDCLEDWrite(unsigned char ucLED)
\r
234 PDCWrite(PDC_LED, ucLED);
\r
237 //*****************************************************************************
\r
239 //! Read the current status of the PDC LEDs.
\r
241 //! This function will read the state of the LEDs connected to the PDC on the
\r
242 //! Stellaris development board.
\r
244 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
245 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
247 //! \return The value currently displayed by the LEDs.
\r
249 //*****************************************************************************
\r
253 return(PDCRead(PDC_LED));
\r
256 //*****************************************************************************
\r
258 //! Initializes the LCD display.
\r
260 //! This function will set up the LCD display for writing. It will set the
\r
261 //! data bus to 8 bits, set the number of lines to 2, and the font size to
\r
262 //! 5x10. It will also turn the display off, clear the display, turn the
\r
263 //! display back on, and enable the backlight.
\r
265 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
266 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
268 //! \note The PDC must be initialized via the PDCInit() function before this
\r
269 //! function can be called. Also, it may be necessary to adjust the contrast
\r
270 //! potentiometer in order to discern any output on the LCD display.
\r
274 //*****************************************************************************
\r
278 unsigned char pucCfg[] =
\r
280 0x3C, // Number of lines = 2 / font = 5x10
\r
281 0x08, // Display off
\r
282 0x01, // Display clear
\r
283 0x06, // Entry mode [cursor dir][shift]
\r
284 0x0C, // Display on [display on][curson on][blinking on]
\r
286 unsigned long ulIdx;
\r
289 // Set the data bus width to eight bits.
\r
291 PDCWrite(PDC_LCD_CSR, 0x30);
\r
294 // Wait for 4.1ms by reading the PDC version register enough times to
\r
295 // guarantee that amount of time has passed.
\r
297 for(ulIdx = 0; ulIdx < 257; ulIdx++)
\r
303 // Set the data bus width to eight bits.
\r
305 PDCWrite(PDC_LCD_CSR, 0x30);
\r
308 // Wait for 100us by reading the PDC version register enough times to
\r
309 // guarantee that amount of time has passed. This works out to 112us plus
\r
312 for(ulIdx = 0; ulIdx < 7; ulIdx++)
\r
318 // Set the data bus width to eight bits.
\r
320 PDCWrite(PDC_LCD_CSR, 0x30);
\r
323 // Configure the LCD.
\r
325 for(ulIdx = 0; ulIdx < (sizeof(pucCfg) / sizeof(pucCfg[0])); ulIdx++)
\r
328 // Wait until the LCD has finished executing any previous command.
\r
330 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
335 // Write the next configuration byte.
\r
337 PDCWrite(PDC_LCD_CSR, pucCfg[ulIdx]);
\r
341 //*****************************************************************************
\r
343 //! Turns on the backlight.
\r
345 //! This function turns on the backlight on the LCD.
\r
347 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
348 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
352 //*****************************************************************************
\r
354 PDCLCDBacklightOn(void)
\r
356 PDCWrite(PDC_CSR, 0x01);
\r
359 //*****************************************************************************
\r
361 //! Turn off the backlight.
\r
363 //! This function turns off the backlight on the LCD.
\r
365 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
366 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
370 //*****************************************************************************
\r
372 PDCLCDBacklightOff(void)
\r
374 PDCWrite(PDC_CSR, 0x00);
\r
377 //*****************************************************************************
\r
379 //! Clear the screen.
\r
381 //! This function clears the contents of the LCD screen. The cursor will be
\r
382 //! returned to the upper left corner.
\r
384 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
385 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
389 //*****************************************************************************
\r
394 // Wait until the LCD has finished executing any previous command.
\r
396 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
401 // Write the clear display command.
\r
403 PDCWrite(PDC_LCD_CSR, LCD_CLEAR);
\r
406 //*****************************************************************************
\r
408 //! Write a character pattern to the LCD.
\r
410 //! \param ucChar is the character index to create. Valid values are zero
\r
412 //! \param pucData is the data for the character pattern. It contains eight
\r
413 //! bytes, with the first byte being the top row of the pattern. In each byte,
\r
414 //! the LSB is the right pixel of the pattern.
\r
416 //! This function will write a character pattern into the LCD for use as a
\r
417 //! character to be displayed. After writing the pattern, it can be used on
\r
418 //! the LCD by writing the corresponding character index to the display.
\r
420 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
421 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
425 //*****************************************************************************
\r
427 PDCLCDCreateChar(unsigned char ucChar, unsigned char *pucData)
\r
430 // Check the arguments.
\r
432 ASSERT(ucChar < 8);
\r
435 // Wait until the LCD has finished executing any previous command.
\r
437 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
442 // Write the character pattern memory address.
\r
444 PDCWrite(PDC_LCD_CSR, LCD_CGADDR + (ucChar * 8));
\r
447 // Write the pattern to chacter pattern memory.
\r
449 for(ucChar = 0; ucChar < 8; ucChar++)
\r
452 // Wait until the LCD has finished executing any previous command.
\r
454 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
459 // Write this row of the pattern.
\r
461 PDCWrite(PDC_LCD_RAM, *pucData++);
\r
465 //*****************************************************************************
\r
467 //! Set the position of the cursor.
\r
469 //! \param ucX is the horizontal position. Valid values are zero through
\r
471 //! \param ucY is the vertical position.. Valid values are zero and one.
\r
473 //! This function will move the cursor to the specified position. All
\r
474 //! characters written to the LCD are placed at the current cursor position,
\r
475 //! which is automatically advanced.
\r
477 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
478 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
482 //*****************************************************************************
\r
484 PDCLCDSetPos(unsigned char ucX, unsigned char ucY)
\r
487 // Check the arguments.
\r
493 // Wait until the LCD has finished executing any previous command.
\r
495 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
500 // Set the cursor position.
\r
502 PDCWrite(PDC_LCD_CSR, LCD_DDADDR | (0x40 * ucY) + ucX);
\r
505 //*****************************************************************************
\r
507 //! Writes a string to the LCD display.
\r
509 //! \param pcStr pointer to the string to be displayed.
\r
510 //! \param ulCount is the number of characters to be displayed.
\r
512 //! This function will display a string on the LCD at the current cursor
\r
513 //! position. It is the caller's responsibility to position the cursor to the
\r
514 //! place where the string should be displayed (either explicitly via
\r
515 //! PDCLCDSetPos() or implicitly from where the cursor was left after a
\r
516 //! previous call to PDCLCDWrite()), and to properly account for the LCD
\r
517 //! boundary (line wrapping is not automatically performed). Null characters
\r
518 //! are not treated special and are written to the LCD, which interprets it as
\r
519 //! a special programmable character glyph (see PDCLCDCreateChar()).
\r
521 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
522 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
526 //*****************************************************************************
\r
528 PDCLCDWrite(const char *pcStr, unsigned long ulCount)
\r
531 // Write the string to the LCD.
\r
536 // Wait until the LCD has finished executing any previous command.
\r
538 while((PDCRead(PDC_LCD_CSR) & LCD_B_BUSY))
\r
543 // Write this character to the LCD.
\r
545 PDCWrite(PDC_LCD_RAM, *pcStr++);
\r
549 //*****************************************************************************
\r
551 //! Reads a GPIO direction register.
\r
553 //! \param ucIdx is the index of the GPIO direction register to read; valid
\r
554 //! values are 0, 1, and 2.
\r
556 //! This function reads one of the GPIO direction registers in the PDC. The
\r
557 //! direction bit is set for pins that are outputs and clear for pins that are
\r
560 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
561 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
563 //! \return The contents of the direction register.
\r
565 //*****************************************************************************
\r
567 PDCGPIODirRead(unsigned char ucIdx)
\r
570 // Check the argument.
\r
572 ASSERT((ucIdx == 0) || (ucIdx == 1) || (ucIdx == 2));
\r
575 // Read the requested direction register.
\r
579 return(PDCRead(PDC_GPXDIR));
\r
581 else if(ucIdx == 1)
\r
583 return(PDCRead(PDC_GPYDIR));
\r
587 return(PDCRead(PDC_GPZDIR));
\r
591 //*****************************************************************************
\r
593 //! Write a GPIO direction register.
\r
595 //! \param ucIdx is the index of the GPIO direction register to write; valid
\r
596 //! values are 0, 1, and 2.
\r
597 //! \param ucValue is the value to write to the GPIO direction register.
\r
599 //! This function writes ones of the GPIO direction registers in the PDC. The
\r
600 //! direction bit should be set for pins that are to be outputs and clear for
\r
601 //! pins that are to be inputs.
\r
603 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
604 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
608 //*****************************************************************************
\r
610 PDCGPIODirWrite(unsigned char ucIdx, unsigned char ucValue)
\r
613 // Check the arguments.
\r
615 ASSERT((ucIdx == 0) || (ucIdx == 1) || (ucIdx == 2));
\r
618 // Write the requested direction register.
\r
622 PDCWrite(PDC_GPXDIR, ucValue);
\r
624 else if(ucIdx == 1)
\r
626 PDCWrite(PDC_GPYDIR, ucValue);
\r
630 PDCWrite(PDC_GPZDIR, ucValue);
\r
634 //*****************************************************************************
\r
636 //! Reads a GPIO data register.
\r
638 //! \param ucIdx is the index of the GPIO direction register to read; valid
\r
639 //! values are 0, 1, and 2.
\r
641 //! This function reads one of the GPIO data registers in the PDC. The value
\r
642 //! returned for a pin is the value being driven out for outputs or the value
\r
643 //! being read for inputs.
\r
645 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
646 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
648 //! \return The contents of the data register.
\r
650 //*****************************************************************************
\r
652 PDCGPIORead(unsigned char ucIdx)
\r
655 // Check the argument.
\r
657 ASSERT((ucIdx == 0) || (ucIdx == 1) || (ucIdx == 2));
\r
660 // Read the requested data register.
\r
664 return(PDCRead(PDC_GPXDAT));
\r
666 else if(ucIdx == 1)
\r
668 return(PDCRead(PDC_GPYDAT));
\r
672 return(PDCRead(PDC_GPZDAT));
\r
676 //*****************************************************************************
\r
678 //! Write a GPIO data register.
\r
680 //! \param ucIdx is the index of the GPIO data register to write; valid values
\r
681 //! are 0, 1, and 2.
\r
682 //! \param ucValue is the value to write to the GPIO data register.
\r
684 //! This function writes one of the GPIO direction registers in the PDC. The
\r
685 //! written to a pin is driven out for output pins and ignored for input pins.
\r
687 //! This function is contained in <tt>utils/pdc.c</tt>, with
\r
688 //! <tt>utils/pdc.h</tt> containing the API definition for use by applications.
\r
692 //*****************************************************************************
\r
694 PDCGPIOWrite(unsigned char ucIdx, unsigned char ucValue)
\r
697 // Check the arguments.
\r
699 ASSERT((ucIdx == 0) || (ucIdx == 1) || (ucIdx == 2));
\r
702 // Write the requested data register.
\r
706 PDCWrite(PDC_GPXDAT, ucValue);
\r
708 else if(ucIdx == 1)
\r
710 PDCWrite(PDC_GPYDAT, ucValue);
\r
714 PDCWrite(PDC_GPZDAT, ucValue);
\r
718 //*****************************************************************************
\r
720 // Close the Doxygen group.
\r
723 //*****************************************************************************
\r