###############################################################################
#                                                                             #
# IAR 8051 C/C++ Compiler V7.30B/W32                    12/Sep/2010  21:57:34 #
# Copyright 2004-2007 IAR Systems. All rights reserved.                       #
#                                                                             #
#    Core               =  plain                                              #
#    Code model         =  banked                                             #
#    Data model         =  large                                              #
#    Calling convention =  xdata reentrant                                    #
#    Constant location  =  data                                               #
#    Dptr setup         =  1,16                                               #
#    Source file        =  C:\Texas Instruments 33\ZStack-1.4.3-1.2.1\Compone #
#                          nts\hal\target\CC2430BB\hal_lcd.c                  #
#    Command line       =  -f "C:\Texas Instruments                           #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\Tools\CC2430DB\f8wRouter.cf #
#                          g" (-DCPU32MHZ -DFORCE_MAC_NEAR                    #
#                          -DROOT=__near_func -DMAC_CFG_APP_PENDING_QUEUE=TRU #
#                          E -DRTR_NWK -DBLINK_LEDS "-DCONST=const __code"    #
#                          -DGENERIC=__generic) -f "C:\Texas Instruments      #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\Tools\CC2430DB\f8wConfig.cf #
#                          g" (-DSECURE=1 -DDEFAULT_CHANLIST=0x04000000       #
#                          -DZDAPP_CONFIG_PAN_ID=0x00FF                       #
#                          -DNWK_START_DELAY=100 -DEXTENDED_JOINING_RANDOM_MA #
#                          SK=0x007F -DBEACON_REQUEST_DELAY=100               #
#                          -DBEACON_REQ_DELAY_MASK=0x00FF                     #
#                          -DROUTE_EXPIRY_TIME=30 -DAPSC_ACK_WAIT_DURATION_PO #
#                          LLED=3000 -DNWK_INDIRECT_MSG_TIMEOUT=7             #
#                          -DMAX_RREQ_ENTRIES=10 -DAPSC_MAX_FRAME_RETRIES=3   #
#                          -DNWK_MAX_DATA_RETRIES=2                           #
#                          -DMAX_POLL_FAILURE_RETRIES=2 -DMAX_BCAST=9         #
#                          -DAPS_MAX_GROUPS=16 -DMAX_RTG_ENTRIES=20           #
#                          -DNWK_MAX_BINDING_ENTRIES=10                       #
#                          -DMAX_BINDING_CLUSTER_IDS=5 "-DDEFAULT_KEY={0x02,  #
#                          0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x00,    #
#                          0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D}"         #
#                          -DRFD_RCVC_ALWAYS_ON=FALSE -DPOLL_RATE=1000        #
#                          -DQUEUED_POLL_RATE=100 -DRESPONSE_POLL_RATE=100)   #
#                          -DREJOIN_POLL_RATE=440 "C:\Texas Instruments       #
#                          33\ZStack-1.4.3-1.2.1\Components\hal\target\CC2430 #
#                          BB\hal_lcd.c" -D CC2430EB -D LOCATION_REFNODE -D   #
#                          xNV_RESTORE -D ZTOOL_P1 -D MT_TASK -D              #
#                          POWER_SAVING -D HAL_UART_BIG_TX_BUF=1 -D           #
#                          SPI_MGR_DEFAULT_MAX_TX_BUFF=1024 -D                #
#                          SPI_MGR_DEFAULT_OVERFLOW=1 -lC "C:\Texas           #
#                          Instruments 33\ZStack-1.4.3-1.2.1\Projects\zstack\ #
#                          Project\Location\CC2430DB\RefNode\List\" -lA       #
#                          "C:\Texas Instruments 33\ZStack-1.4.3-1.2.1\Projec #
#                          ts\zstack\Project\Location\CC2430DB\RefNode\List\" #
#                           --diag_suppress Pe001,Pa010 --diag_remark pe550   #
#                          -o "C:\Texas Instruments                           #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\RefNode\Obj\" -e                     #
#                          --require_prototypes -z9 --no_code_motion --debug  #
#                          --core=plain --dptr=16,1 --data_model=large        #
#                          --code_model=banked --calling_convention=xdata_ree #
#                          ntrant --place_constants=data --nr_virtual_regs 8  #
#                          -I "C:\Texas Instruments                           #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\" -I "C:\Texas Instruments           #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\SOURCE\" -I "C:\Texas             #
#                          Instruments 33\ZStack-1.4.3-1.2.1\Projects\zstack\ #
#                          Project\Location\CC2430DB\..\..\..\ZMAIN\TI2430DB\ #
#                          " -I "C:\Texas Instruments                         #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\MT\" -I    #
#                          "C:\Texas Instruments 33\ZStack-1.4.3-1.2.1\Projec #
#                          ts\zstack\Project\Location\CC2430DB\..\..\..\..\.. #
#                          \COMPONENTS\HAL\INCLUDE\" -I "C:\Texas             #
#                          Instruments 33\ZStack-1.4.3-1.2.1\Projects\zstack\ #
#                          Project\Location\CC2430DB\..\..\..\..\..\COMPONENT #
#                          S\HAL\TARGET\CC2430BB\" -I "C:\Texas Instruments   #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\OSAL\MCU\C #
#                          CSOC\" -I "C:\Texas Instruments                    #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\OSAL\INCLU #
#                          DE\" -I "C:\Texas Instruments                      #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\STACK\AF\" #
#                           -I "C:\Texas Instruments                          #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\STACK\NWK\ #
#                          " -I "C:\Texas Instruments                         #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\STACK\SEC\ #
#                          " -I "C:\Texas Instruments                         #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\STACK\SYS\ #
#                          " -I "C:\Texas Instruments                         #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\STACK\ZDO\ #
#                          " -I "C:\Texas Instruments                         #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\ZMAC\F8W\" #
#                           -I "C:\Texas Instruments                          #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\ZMAC\" -I  #
#                          "C:\Texas Instruments 33\ZStack-1.4.3-1.2.1\Projec #
#                          ts\zstack\Project\Location\CC2430DB\..\..\..\..\.. #
#                          \COMPONENTS\SERVICES\SADDR\" -I "C:\Texas          #
#                          Instruments 33\ZStack-1.4.3-1.2.1\Projects\zstack\ #
#                          Project\Location\CC2430DB\..\..\..\..\..\COMPONENT #
#                          S\SERVICES\SDATA\" -I "C:\Texas Instruments        #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\MAC\INCLUD #
#                          E\" -I "C:\Texas Instruments                       #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\MAC\HIGH_L #
#                          EVEL\" -I "C:\Texas Instruments                    #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\MAC\LOW_LE #
#                          VEL\SRF03\" -I "C:\Texas Instruments               #
#                          33\ZStack-1.4.3-1.2.1\Projects\zstack\Project\Loca #
#                          tion\CC2430DB\..\..\..\..\..\COMPONENTS\MAC\LOW_LE #
#                          VEL\SRF03\SINGLE_CHIP\" -I "C:\Program Files\IAR   #
#                          Systems\Embedded Workbench 4.0 Evaluation          #
#                          version\8051\INC\" -I "C:\Program Files\IAR        #
#                          Systems\Embedded Workbench 4.0 Evaluation          #
#                          version\8051\INC\CLIB\"                            #
#    List file          =  C:\Texas Instruments 33\ZStack-1.4.3-1.2.1\Project #
#                          s\zstack\Project\Location\CC2430DB\RefNode\List\ha #
#                          l_lcd.lst                                          #
#    Object file        =  C:\Texas Instruments 33\ZStack-1.4.3-1.2.1\Project #
#                          s\zstack\Project\Location\CC2430DB\RefNode\Obj\hal #
#                          _lcd.r51                                           #
#                                                                             #
#                                                                             #
###############################################################################

C:\Texas Instruments 33\ZStack-1.4.3-1.2.1\Components\hal\target\CC2430BB\hal_lcd.c
      1          /**************************************************************************************************
      2            Filename:       hal_lcd.c
      3            Revised:        $Date: 2007-11-01 08:44:53 -0700 (Thu, 01 Nov 2007) $
      4            Revision:       $Revision: 15821 $
      5          
      6            Description:    This file contains the interface to the HAL LCD Service.
      7          
      8          
      9            Copyright 2006-2007 Texas Instruments Incorporated. All rights reserved.
     10          
     11            IMPORTANT: Your use of this Software is limited to those specific rights
     12            granted under the terms of a software license agreement between the user
     13            who downloaded the software, his/her employer (which must be your employer)
     14            and Texas Instruments Incorporated (the "License").  You may not use this
     15            Software unless you agree to abide by the terms of the License. The License
     16            limits your use, and you acknowledge, that the Software may not be modified,
     17            copied or distributed unless embedded on a Texas Instruments microcontroller
     18            or used solely and exclusively in conjunction with a Texas Instruments radio
     19            frequency transceiver, which is integrated into your product.  Other than for
     20            the foregoing purpose, you may not use, reproduce, copy, prepare derivative
     21            works of, modify, distribute, perform, display or sell this Software and/or
     22            its documentation for any purpose.
     23          
     24            YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
     25            PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
     26            INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, 
     27            NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
     28            TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
     29            NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
     30            LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
     31            INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
     32            OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
     33            OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
     34            (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
     35          
     36            Should you have any questions regarding your right to use this Software,
     37            contact Texas Instruments Incorporated at www.TI.com. 
     38          **************************************************************************************************/
     39          
     40          /**************************************************************************************************
     41           *                                           INCLUDES
     42           **************************************************************************************************/
     43          #include "hal_types.h"
     44          #include "hal_lcd.h"
     45          #include "OSAL.h"
     46          #include "OnBoard.h"
     47          
     48          #ifdef ZTOOL_PORT
     49            #include "DebugTrace.h"
     50          #endif
     51          
     52          /**************************************************************************************************
     53           *                                          CONSTANTS
     54           **************************************************************************************************/
     55          #define LCD_MAX_BUF 25
     56          
     57          // General I/O definitions
     58          #define IO_GIO  0  // General purpose I/O
     59          #define IO_PER  1  // Peripheral function
     60          #define IO_IN   0  // Input pin
     61          #define IO_OUT  1  // Output pin
     62          #define IO_PUD  0  // Pullup/pulldn input
     63          #define IO_TRI  1  // Tri-state input
     64          #define IO_PUP  0  // Pull-up input pin
     65          #define IO_PDN  1  // Pull-down input pin
     66          
     67          // LCD port/bit definitions
     68          #define LCD_CLK_PORT  2
     69          #define LCD_CLK_PIN   0  // P2_0
     70          #define LCD_DATA_PORT 1
     71          #define LCD_DATA_PIN  2  // P1_2
     72          
     73          /* LCD Line Address */
     74          #define LCD_LINE1_ADDR  0x80
     75          #define LCD_LINE2_ADDR  0xC0
     76          
     77          // LCD device definitions
     78          #define LCD_ADDR  0x76  // SM-Bus address of the LCD controller
     79          #define CH1_ADDR  0x08
     80          #define LCD_RS_0  0x00  // RS = 0 => selects instruction register for write/busy flag
     81          #define LCD_RS_1  0x40  // RS = 1 => selects the data register for both read and write
     82          
     83          /**************************************************************************************************
     84           *                                           MACROS
     85           **************************************************************************************************/
     86          
     87          // Removed to allow PNAME macro to expand -
     88          // Problem: in ioCC2430.h, #define P PSW_bit.P
     89          #undef P
     90          
     91            /* I/O PORT CONFIGURATION */
     92          #define CAT1(x,y) x##y  // Concatenates 2 strings
     93          #define CAT2(x,y) CAT1(x,y)  // Forces evaluation of CAT1
     94          
     95          // LCD port I/O defintions
     96          // Builds I/O port name: PNAME(1,INP) ==> P1INP
     97          #define PNAME(y,z) CAT2(P,CAT2(y,z))
     98          // Builds I/O bit name: BNAME(1,2) ==> P1_2
     99          #define BNAME(port,pin) CAT2(CAT2(P,port),CAT2(_,pin))
    100          
    101          #define LCD_SCL BNAME(LCD_CLK_PORT, LCD_CLK_PIN)
    102          #define LCD_SDA BNAME(LCD_DATA_PORT, LCD_DATA_PIN)
    103          
    104          // LCD port I/O defintions
    105          #define LCD_SCL BNAME(LCD_CLK_PORT, LCD_CLK_PIN)
    106          #define LCD_SDA BNAME(LCD_DATA_PORT, LCD_DATA_PIN)
    107          
    108          #define IO_DIR_PORT_PIN(port, pin, dir) \
    109          {\
    110            if ( dir == IO_OUT ) \
    111              PNAME(port,DIR) |= (1<<(pin)); \
    112            else \
    113              PNAME(port,DIR) &= ~(1<<(pin)); \
    114          }
    115          
    116          #define LCD_DATA_HIGH()\
    117          { \
    118            IO_DIR_PORT_PIN(LCD_DATA_PORT, LCD_DATA_PIN, IO_IN); \
    119          }
    120          
    121          #define LCD_DATA_LOW() \
    122          { \
    123            IO_DIR_PORT_PIN(LCD_DATA_PORT, LCD_DATA_PIN, IO_OUT); \
    124            LCD_SDA = 0;\
    125          }
    126          
    127          #define IO_FUNC_PORT_PIN(port, pin, func) \
    128          { \
    129            if( port < 2 ) \
    130            { \
    131              if ( func == IO_PER ) \
    132                PNAME(port,SEL) |= (1<<(pin)); \
    133              else \
    134                PNAME(port,SEL) &= ~(1<<(pin)); \
    135            } \
    136            else \
    137            { \
    138              if ( func == IO_PER ) \
    139                P2SEL |= (1<<(pin>>1)); \
    140              else \
    141                P2SEL &= ~(1<<(pin>>1)); \
    142            } \
    143          }
    144          
    145          #define IO_IMODE_PORT_PIN(port, pin, mode) \
    146          { \
    147            if ( mode == IO_TRI ) \
    148              PNAME(port,INP) |= (1<<(pin)); \
    149            else \
    150              PNAME(port,INP) &= ~(1<<(pin)); \
    151          }
    152          
    153          #define IO_PUD_PORT(port, dir) \
    154          { \
    155            if ( dir == IO_PDN ) \
    156              P2INP |= (1<<(port+5)); \
    157            else \
    158              P2INP &= ~(1<<(port+5)); \
    159          }
    160          
    161          /**************************************************************************************************
    162           *                                          TYPEDEFS
    163           **************************************************************************************************/
    164          
    165          
    166          /**************************************************************************************************
    167           *                                       GLOBAL VARIABLES
    168           **************************************************************************************************/
    169          #ifdef LCD_HW
    170          static uint8 *Lcd_Line1;
    171          #endif
    172          
    173          /**************************************************************************************************
    174           *                                       FUNCTIONS - API
    175           **************************************************************************************************/
    176          #if (defined LCD_HW) && (HAL_LCD == TRUE)
    177          static void initLcd( void );
    178          static void initSmb( void );
    179          static void lcdUpdateLine( uint8 line, uint8 *pLine );
    180          static byte lcdConvertChar( byte aChar );
    181          static void smbSend( uint8 *buffer, uint8 len );
    182          static bool smbSendByte( uint8 dByte );
    183          static void smbWrite( bool dBit );
    184          static void smbClock( bool dir );
    185          static void smbStart( void );
    186          static void smbStop( void );
    187          static void smbWait( void );
    188          #endif
    189          
    190          /**************************************************************************************************
    191           * @fn      HalLcdInit
    192           *
    193           * @brief   Initilize LCD Service
    194           *
    195           * @param   init - pointer to void that contains the initialized value
    196           *
    197           * @return  None
    198           **************************************************************************************************/

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
    199          void HalLcdInit(void)
   \                     HalLcdInit:
    200          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
    201          #if (HAL_LCD == TRUE)
    202          
    203          #ifdef LCD_HW
    204            Lcd_Line1 = NULL;
    205            initLcd();
    206          #endif
    207          
    208          #endif /* HAL_LCD */
    209          
    210          }
   \   000000   02....       LJMP    ?BRET
    211          
    212          /*************************************************************************************************
    213           *                    LCD EMULATION FUNCTIONS
    214           *
    215           * Some evaluation boards are equipped with Liquid Crystal Displays
    216           * (LCD) which may be used to display diagnostic information. These
    217           * functions provide LCD emulation, sending the diagnostic strings
    218           * to Z-Tool via the RS232 serial port. These functions are enabled
    219           * when the "LCD_SUPPORTED" compiler flag is placed in the makefile.
    220           *
    221           * Most applications update both lines (1 and 2) of the LCD whenever
    222           * text is posted to the device. This emulator assumes that line 1 is
    223           * updated first (saved locally) and the formatting and send operation
    224           * is triggered by receipt of line 2. Nothing will be transmitted if
    225           * only line 1 is updated.
    226           *
    227           *************************************************************************************************/
    228          
    229          
    230          /**************************************************************************************************
    231           * @fn      HalLcdWriteString
    232           *
    233           * @brief   Write a string to the LCD
    234           *
    235           * @param   str    - pointer to the string that will be displayed
    236           *          option - display options
    237           *
    238           * @return  None
    239           **************************************************************************************************/

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
    240          void HalLcdWriteString ( char *str, uint8 option)
   \                     HalLcdWriteString:
    241          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
    242          #if (HAL_LCD == TRUE)
    243          
    244          #ifdef LCD_SD
    245            byte x;
    246            byte bln;
    247            byte sln;
    248            char *buf;
    249          
    250            if ( Lcd_Line1 == NULL )
    251            {
    252              // Set up system start-up message
    253              Lcd_Line1 = osal_mem_alloc( MAX_LCD_CHARS+1 );
    254              HalLcdWriteString( "Figure8 Wireless", HAL_LCD_LINE_1 );
    255            }
    256          
    257            sln = (byte)osal_strlen( str );
    258          
    259            // Check boundries
    260            if ( sln > MAX_LCD_CHARS )
    261              sln = MAX_LCD_CHARS;
    262          
    263            if ( option == HAL_LCD_LINE_1 ) {
    264              // Line 1 gets saved for later
    265              osal_memcpy( Lcd_Line1, str, sln );
    266              Lcd_Line1[sln] = '\0';
    267            }
    268            else {
    269              // Line 2 triggers action
    270              x = (byte)osal_strlen( (char*)Lcd_Line1 );
    271              bln = x + 1 + sln + 1;
    272              buf = osal_mem_alloc( bln );
    273              if ( buf != NULL ) {
    274                // Concatenate strings
    275                osal_memcpy( buf, Lcd_Line1, x );
    276                buf[x++] = ' ';
    277                osal_memcpy( &buf[x], str, sln );
    278                buf[x+sln] = '\0';
    279                // Send it out
    280          #ifdef ZTOOL_PORT
    281                debug_str( (byte*)buf );
    282          #endif
    283                osal_mem_free( buf );
    284              }
    285            }
    286          #endif // LCD_SD
    287          
    288          #ifdef LCD_HW
    289            lcdUpdateLine( option, (byte*)str );
    290          #endif
    291          
    292          #endif /* HAL_LCD */
    293          
    294          }
   \   000000   02....       LJMP    ?BRET
    295          
    296          /**************************************************************************************************
    297           * @fn      HalLcdWriteValue
    298           *
    299           * @brief   Write a value to the LCD
    300           *
    301           * @param   value  - value that will be displayed
    302           *          radix  - 8, 10, 16
    303           *          option - display options
    304           *
    305           * @return  None
    306           **************************************************************************************************/

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
    307          void HalLcdWriteValue ( uint32 value, const uint8 radix, uint8 option)
   \                     HalLcdWriteValue:
    308          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
    309          #if (HAL_LCD == TRUE)
    310            uint8 buf[LCD_MAX_BUF];
    311          
    312            _ltoa( value, &buf[0], radix );
    313            HalLcdWriteString( (char*)buf, option );
    314          #endif /* HAL_LCD */
    315          }
   \   000000   02....       LJMP    ?BRET
    316          
    317          /**************************************************************************************************
    318           * @fn      HalLcdWriteScreen
    319           *
    320           * @brief   Write a value to the LCD
    321           *
    322           * @param   line1  - string that will be displayed on line 1
    323           *          line2  - string that will be displayed on line 2
    324           *
    325           * @return  None
    326           **************************************************************************************************/

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
    327          void HalLcdWriteScreen( char *line1, char *line2 )
   \                     HalLcdWriteScreen:
    328          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
    329          #if (HAL_LCD == TRUE)
    330            HalLcdWriteString( line1, HAL_LCD_LINE_1 );
    331            HalLcdWriteString( line2, HAL_LCD_LINE_2 );
    332          #endif /* HAL_LCD */
    333          }
   \   000000   02....       LJMP    ?BRET
    334          
    335          /**************************************************************************************************
    336           * @fn      HalLcdWriteStringValue
    337           *
    338           * @brief   Write a string followed by a value to the LCD
    339           *
    340           * @param   title  -
    341           *          value  -
    342           *          format -
    343           *          line   -
    344           *
    345           * @return  None
    346           **************************************************************************************************/

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
    347          void HalLcdWriteStringValue( char *title, uint16 value, uint8 format, uint8 line )
   \                     HalLcdWriteStringValue:
    348          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
    349          #if (HAL_LCD == TRUE)
    350            uint8 tmpLen;
    351            uint8 buf[LCD_MAX_BUF];
    352            uint32 err;
    353          
    354            tmpLen = (uint8)osal_strlen( (char*)title );
    355            osal_memcpy( buf, title, tmpLen );
    356            buf[tmpLen] = ' ';
    357            err = (uint32)(value);
    358            _ltoa( err, &buf[tmpLen+1], format );
    359            HalLcdWriteString( (char*)buf, line );		
    360          #endif /* HAL_LCD */
    361          }
   \   000000   02....       LJMP    ?BRET
    362          
    363          /**************************************************************************************************
    364           * @fn      HalLcdWriteStringValue
    365           *
    366           * @brief   Write a string followed by a value to the LCD
    367           *
    368           * @param   title   -
    369           *          value1  -
    370           *          format1 -
    371           *          value2  -
    372           *          format2 -
    373           *          line    -
    374           *
    375           * @return  None
    376           **************************************************************************************************/

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
    377          void HalLcdWriteStringValueValue( char *title, uint16 value1, uint8 format1,
   \                     HalLcdWriteStringValueValue:
    378                                            uint16 value2, byte format2, uint8 line )
    379          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
    380          #if (HAL_LCD == TRUE)
    381            uint8 tmpLen;
    382            uint8 buf[LCD_MAX_BUF];
    383            uint32 err;
    384          
    385            tmpLen = (uint8)osal_strlen( (char*)title );
    386            if ( tmpLen )
    387            {
    388              osal_memcpy( buf, title, tmpLen );
    389              buf[tmpLen++] = ' ';
    390            }
    391          
    392            err = (uint32)(value1);
    393            _ltoa( err, &buf[tmpLen], format1 );
    394            tmpLen = (uint8)osal_strlen( (char*)buf );
    395          
    396            buf[tmpLen++] = ',';
    397            buf[tmpLen++] = ' ';
    398            err = (uint32)(value2);
    399            _ltoa( err, &buf[tmpLen], format2 );
    400          
    401            HalLcdWriteString( (char *)buf, line );		
    402          #endif /* HAL_LCD */
    403          }
   \   000000   02....       LJMP    ?BRET
    404          
    405          /**************************************************************************************************
    406           * @fn      HalLcdDisplayPercentBar
    407           *
    408           * @brief   Display percentage bar on the LCD
    409           *
    410           * @param   title   -
    411           *          value   -
    412           *
    413           * @return  None
    414           **************************************************************************************************/

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
    415          void HalLcdDisplayPercentBar( char *title, uint8 value )
   \                     HalLcdDisplayPercentBar:
    416          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
    417          #if (HAL_LCD == TRUE)
    418            uint8 percent;
    419            uint8 leftOver;
    420            uint8 buf[17];
    421            uint32 err;
    422            uint8 x;
    423          
    424            /* Write the title: */
    425            HalLcdWriteString( title, HAL_LCD_LINE_1 );
    426          
    427            if ( value > 100 )
    428              value = 100;
    429          
    430            /* convert to blocks */
    431            percent = (byte)(value / 10);
    432            leftOver = (byte)(value % 10);
    433          
    434            /* Make window */
    435            osal_memcpy( buf, "[          ]  ", 15 );
    436          
    437            for ( x = 0; x < percent; x ++ )
    438            {
    439              buf[1+x] = '>';
    440            }
    441          
    442            if ( leftOver >= 5 )
    443              buf[1+x] = '+';
    444          
    445            err = (uint32)value;
    446            _ltoa( err, (uint8*)&buf[13], 10 );
    447          
    448            HalLcdWriteString( (char*)buf, HAL_LCD_LINE_2 );
    449          #endif /* HAL_LCD */
    450          }
   \   000000   02....       LJMP    ?BRET

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??HalLcdInit?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    HalLcdInit

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??HalLcdWriteString?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    HalLcdWriteString

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??HalLcdWriteValue?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    HalLcdWriteValue

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??HalLcdWriteScreen?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    HalLcdWriteScreen

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??HalLcdWriteStringValue?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    HalLcdWriteStringValue

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??HalLcdWriteStringValueValue?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    HalLcdWriteStringValueValue

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??HalLcdDisplayPercentBar?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    HalLcdDisplayPercentBar
    451          
    452          #if (defined LCD_HW) && (HAL_LCD == TRUE)
    453          /*********************************************************************
    454           * @fn      initLcd
    455           * @brief   Initializes LCD I/O bus and LCD device
    456           * @param   void
    457           * @return  void
    458           */
    459          static void initLcd( void )
    460          {
    461            uint8 buffer[8];
    462          
    463            // Initialize the serial I/O bus
    464            initSmb();
    465          
    466            // Load LCD initialization message
    467            buffer[0] = LCD_ADDR;
    468            buffer[1] = LCD_RS_0;  // Instruction Register
    469            buffer[2] = 0x0C;      // Display control         D =  1:      Display On
    470            //                                                C =  0:      Cursor Off
    471            //                                                B =  0:      Cursor character blink off
    472            buffer[3] = 0x21;      // Function set            H =  1:      Use extended instruction set
    473            buffer[4] = 0xA0;      // Set DDRAM address       ADD = 0x20
    474            buffer[5] = 0x07;      // Display configuration   P =  1:      Column data right to left
    475            //                                                Q =  1:      Row data, bottom to top
    476            buffer[6] = 0x34;      // Function set            DL=  0:      4 bits
    477            //                                                M =  1:      2-line by 16 display
    478            //                                                SL=  0:      MUX1:18
    479            //                                                H =  0:      Use basic instruction set
    480            buffer[7] = 0x01;      // Clearing display
    481          
    482            // Send message to LCD device
    483            smbSend( buffer, 8 );
    484          
    485          }
    486          
    487          /*********************************************************************
    488           * @fn      lcdUpdateLine
    489           * @brief   Updates one line of the LCD display
    490           * @param   line - LCD line numberptr to string going to LCD line 1
    491           * @param   p2 - ptr to string going to LCD line 2
    492           * @return  void
    493           */
    494          static void lcdUpdateLine( uint8 line, uint8 *pLine )
    495          {
    496            uint8 i;
    497            uint8 chr;
    498            uint8 addr;
    499            uint8 *buffer;
    500          
    501            if ( line == HAL_LCD_LINE_1 )
    502              addr = LCD_LINE1_ADDR;
    503            else
    504              addr = LCD_LINE2_ADDR;
    505          
    506            // Get a buffer to work with
    507            buffer = osal_mem_alloc( 2+HAL_LCD_MAX_CHARS );
    508            if ( buffer != NULL )
    509            {
    510              // Build and send control string
    511              buffer[0] = LCD_ADDR;
    512              buffer[1] = LCD_RS_0;
    513              buffer[2] = addr;
    514              smbSend( buffer, 3 );
    515          
    516              // Build and send message string
    517              buffer[0] = LCD_ADDR;
    518              buffer[1] = LCD_RS_1;
    519              // Convert and save message bytes
    520              for( i = 2; i < 2+HAL_LCD_MAX_CHARS; i++ )
    521              {
    522                chr = *pLine++;
    523                if ( chr == '\0' )
    524                {
    525                  chr = lcdConvertChar( ' ' );
    526                  break;
    527                }
    528                else
    529                  buffer[i] = lcdConvertChar( chr );
    530              }
    531          
    532              // Fill remainder of line with blanks
    533              for( ; i < 2+HAL_LCD_MAX_CHARS; i++ )
    534                buffer[i] = chr;
    535          
    536              // Put it on the display
    537              smbSend( buffer, 2+HAL_LCD_MAX_CHARS );
    538          
    539              // Give back buffer memory
    540              osal_mem_free( buffer );
    541            }
    542          }
    543          
    544          /*********************************************************************
    545           * @fn      lcdConvertChar
    546           * @brief   Converts an ASCII character to an LCD character (R sheet)
    547           * @param   aChar - ASCII character
    548           * @return  lChar - LCD character
    549           */
    550          static byte lcdConvertChar( byte aChar )
    551          {
    552            uint8 lChar;
    553          
    554            if ((aChar >= 'a') && (aChar <= 'z'))
    555              // Lower case
    556              lChar = aChar + ('a' - 0xE1);
    557            else if ((aChar >= 'A') && (aChar <= 'Z'))
    558              // Upper case
    559              lChar = aChar + ('A' - 0xC1);
    560            else if (((aChar >= ' ') && (aChar <= '#')) ||
    561                     ((aChar >= '%') && (aChar <= '?')))
    562              // Sonme symbols
    563              lChar = aChar + (' ' - 0xA0);
    564            else
    565            {
    566              switch ( aChar )
    567              {
    568                case '$':
    569                   lChar = 0x82;
    570                   break;
    571                case '§':
    572                   lChar = 0xDF;
    573                   break;
    574                case '£':
    575                   lChar = 0x81;
    576                   break;
    577                case '@':
    578                   lChar = 0x80;
    579                   break;
    580                case '[':
    581                   lChar = 0x8A;
    582                   break;
    583                case ']':
    584                   lChar = 0x54;
    585                   break;
    586                case '_':
    587                   lChar = 0x5A;
    588                   break;
    589                case 'æ':
    590                   lChar = 0x9D;
    591                   break;
    592                case 'ø':
    593                   lChar = 0x8C;
    594                   break;
    595                case 'å':
    596                   lChar = 0x8F;
    597                   break;
    598                case 'Æ':
    599                   lChar = 0x9C;
    600                   break;
    601                case 'Ø':
    602                   lChar = 0x8B;
    603                   break;
    604                case 'Å':
    605                   lChar = 0x8E;
    606                   break;
    607                case 0x10:
    608                   lChar = 0x10;  // Left arrow
    609                   break;
    610                case 0x11:
    611                   lChar = 0x20;  // Right arrow
    612                   break;
    613                case 0x12:
    614                   lChar = 0x12;  // Up arrow
    615                   break;
    616                case 0x13:
    617                   lChar = 0x30;  // Down arrow
    618                   break;
    619                default:
    620                   lChar = 0x30;
    621                   break;
    622              }
    623            }
    624          
    625            return ( lChar );
    626          }
    627          
    628          /*********************************************************************
    629           * @fn      initSmb
    630           * @brief   Initializes two-wire serial I/O bus
    631           * @param   void
    632           * @return  void
    633           */
    634          static void initSmb( void )
    635          {
    636            // Set port pins as inputs
    637            IO_DIR_PORT_PIN( LCD_CLK_PORT, LCD_CLK_PIN, IO_IN );
    638            IO_DIR_PORT_PIN( LCD_DATA_PORT, LCD_DATA_PIN, IO_IN );
    639          
    640            // Set for general I/O operation
    641            IO_FUNC_PORT_PIN( LCD_CLK_PORT, LCD_CLK_PIN, IO_GIO );
    642            IO_FUNC_PORT_PIN( LCD_DATA_PORT, LCD_DATA_PIN, IO_GIO );
    643          
    644            // Set I/O mode for pull-up/pull-down
    645            IO_IMODE_PORT_PIN( LCD_CLK_PORT, LCD_CLK_PIN, IO_PUD );
    646            IO_IMODE_PORT_PIN( LCD_DATA_PORT, LCD_DATA_PIN, IO_PUD );
    647          
    648            // Set pins to pull-up
    649            IO_PUD_PORT( LCD_CLK_PORT, IO_PUP );
    650            IO_PUD_PORT( LCD_DATA_PORT, IO_PUP );
    651          }
    652          
    653          /*********************************************************************
    654           * @fn      smbSend
    655           * @brief   Sends buffer contents to SM-Bus device
    656           * @param   buffer - ptr to buffered data to send
    657           * @param   len - number of bytes in buffer
    658           * @return  void
    659           */
    660          static void smbSend( uint8 *buffer, uint8 len )
    661          {
    662            uint8 i;
    663          
    664            smbStart();
    665            for ( i = 0; i < len; i++ )
    666            {
    667              while ( !smbSendByte( buffer[i] ) );  // Send until ACK received
    668            }
    669            smbStop();
    670          }
    671          
    672          /*********************************************************************
    673           * @fn      smbSendByte
    674           * @brief   Serialize and send one byte to SM-Bus device
    675           * @param   dByte - data byte to send
    676           * @return  ACK status - 0=none, 1=received
    677           */
    678          static bool smbSendByte( uint8 dByte )
    679          {
    680            uint8 i;
    681          
    682            for ( i = 0; i < 8; i++ )
    683            {
    684              // Send the MSB
    685              smbWrite( dByte & 0x80 );
    686              // Next bit into MSB
    687              dByte <<= 1;
    688            }
    689            smbClock( 0 );
    690            LCD_DATA_HIGH();
    691            smbClock( 1 );
    692          
    693            return ( !LCD_SDA );  // Return ACK status
    694          }
    695          
    696          /*********************************************************************
    697           * @fn      smbWrite
    698           * @brief   Send one bit to SM-Bus device
    699           * @param   dBit - data bit to clock onto SM-Bus
    700           * @return  void
    701           */
    702          static void smbWrite( bool dBit )
    703          {
    704            smbClock( 0 );
    705            smbWait();
    706            if ( dBit )
    707            {
    708              LCD_DATA_HIGH();
    709            }
    710            else
    711            {
    712              LCD_DATA_LOW();
    713            }
    714            smbClock( 1 );
    715            smbWait();
    716          }
    717          
    718          /*********************************************************************
    719           * @fn      smbClock
    720           * @brief   Clocks the SM-Bus. If a negative edge is going out, the
    721           *          I/O pin is set as an output and driven low. If a positive
    722           *          edge is going out, the pin is set as an input and the pin
    723           *          pull-up drives the line high. This way, the slave device
    724           *          can hold the node low if longer setup time is desired.
    725           * @param   dir - clock line direction
    726           * @return  void
    727           */
    728          static void smbClock( bool dir )
    729          {
    730            if ( dir )
    731            {
    732              IO_DIR_PORT_PIN( LCD_CLK_PORT, LCD_CLK_PIN, IO_IN );
    733            }
    734            else
    735            {
    736              IO_DIR_PORT_PIN( LCD_CLK_PORT, LCD_CLK_PIN, IO_OUT );
    737              LCD_SCL = 0;
    738            }
    739            smbWait();
    740          }
    741          
    742          /*********************************************************************
    743           * @fn      smbStart
    744           * @brief   Initiates SM-Bus communication. Makes sure that both the
    745           *          clock and data lines of the SM-Bus are high. Then the data
    746           *          line is set high and clock line is set low to start I/O.
    747           * @param   void
    748           * @return  void
    749           */
    750          static void smbStart( void )
    751          {
    752            // Wait for both clock and data line high
    753            while ( !( LCD_SCL && LCD_SDA) );
    754            LCD_DATA_LOW();
    755            smbWait();
    756            smbClock( 0 );
    757          }
    758          
    759          /*********************************************************************
    760           * @fn      smbStop
    761           * @brief   Terminates SM-Bus communication. Waits unitl the data line
    762           *          is low and the clock line is high. Then sets the data line
    763           *          high, keeping the clock line high to stop I/O.
    764           * @param   void
    765           * @return  void
    766           */
    767          static void smbStop( void )
    768          {
    769            // Wait for clock high and data low
    770            while ( !( LCD_SCL && !LCD_SDA) );
    771            smbClock( 0 );
    772            LCD_DATA_HIGH();
    773            smbWait();
    774            smbClock( 1 );
    775          }
    776          
    777          /*********************************************************************
    778           * @fn      smbWait
    779           * @brief   Wastes a fixed amount of some time.
    780           * @param   void
    781           * @return  void
    782           */
    783          static void smbWait( void )
    784          {
    785            uint8 i = 0x01;
    786            while ( i-- );
    787          }
    788          #endif // LCD_HW & HAL_LCD
    789          
    790          /**************************************************************************************************
    791          **************************************************************************************************/
    792          
    793          
    794          
    795          

   Maximum stack usage in bytes:

     Function                    ISTACK PSTACK XSTACK
     --------                    ------ ------ ------
     HalLcdDisplayPercentBar         0      0      0
     HalLcdInit                      0      0      0
     HalLcdWriteScreen               0      0      0
     HalLcdWriteString               0      0      0
     HalLcdWriteStringValue          0      0      1
     HalLcdWriteStringValueValue     0      0      4
     HalLcdWriteValue                0      0      1


   Segment part sizes:

     Function/Label                 Bytes
     --------------                 -----
     HalLcdInit                        3
     HalLcdWriteString                 3
     HalLcdWriteValue                  3
     HalLcdWriteScreen                 3
     HalLcdWriteStringValue            3
     HalLcdWriteStringValueValue       3
     HalLcdDisplayPercentBar           3
     ??HalLcdInit?relay                6
     ??HalLcdWriteString?relay         6
     ??HalLcdWriteValue?relay          6
     ??HalLcdWriteScreen?relay         6
     ??HalLcdWriteStringValue?relay    6
     ??HalLcdWriteStringValueValue?relay
                                       6
     ??HalLcdDisplayPercentBar?relay
                                       6

 
 21 bytes in segment BANKED_CODE
 42 bytes in segment BANK_RELAYS
 
 63 bytes of CODE memory

Errors: none
Warnings: none
