##############################################################################
#                                                                            #
# IAR ARM ANSI C/C++ Compiler V4.11A/W32               20/Jul/2004  18:58:50 #
# Copyright 1999-2004 IAR Systems. All rights reserved.                      #
#                                                                            #
#    Cpu mode        =  arm                                                  #
#    Endian          =  little                                               #
#    Stack alignment =  4                                                    #
#    Source file     =  C:\medusa\zl_frame.c                                 #
#    Command line    =  -I "C:\Program Files\IAR Systems\Embedded Workbench  #
#                       4.0\ARM\INC\" -lc C:\medusa\Debug\List\ -la          #
#                       C:\medusa\Debug\List\ -o C:\medusa\Debug\Obj\ -s2    #
#                       --no_cse --no_unroll --no_inline --no_code_motion    #
#                       --no_tbaa --no_clustering --no_scheduling --debug    #
#                       --cpu_mode arm --endian little --cpu ARM7TDMI-S      #
#                       --stack_align 4 -e --fpu None                        #
#                       "-D_DLIB_CONFIG_FILE=C:\Program Files\IAR            #
#                       Systems\Embedded Workbench                           #
#                       4.0\ARM\LIB\dl4tpannl8n.h" C:\medusa\zl_frame.c      #
#    List file       =  C:\medusa\Debug\List\zl_frame.lst                    #
#    Object file     =  C:\medusa\Debug\Obj\zl_frame.r79                     #
#                                                                            #
#                                                                            #
##############################################################################

C:\medusa\zl_frame.c
      1          #include "archinc.h"
      2          #include "cli.h"
      3          #include "strutil.h"
      4          #include "zarlink.h"
      5          
      6          #ifdef CONFIG_INCLUDE_ZARLINK
      7          
      8          #include <stdio.h>
      9          #include <stdlib.h>
     10          
     11          static unsigned char frameStatusData[8];
     12          
     13          /*
     14           * Zarlink CPU Frame Send
     15           *
     16           * 1. Poll COMMAND&STATUS[4] until it is asserted.
     17           * 2. Write Transmit Frame Status (8 bytes) (described in Section 6.0, ?Processor Frame Format? on page 12) to
     18           *    CPU_ FRAME_REG.
     19           * 3. Poll COMMAND&STATUS[4] again (to verify that FIFO has space for incoming data) until it is asserted.
     20           * 4. Once COMMAND&STATUS[4] is asserted, one can write up to 16 bytes of data at a time. In 8-bit mode, write
     21           *    each byte in increasing order to CPU_ FRAME_REG [7:0]. (See CPU Frame General Structure for Memory
     22           *    Request section in Section 7.0, ?Control Command Format? on page 17 for further details on writing in increasing
     23           *    order). In 16-bit mode, write 2 bytes in increasing order; write even bytes in CPU_FRAME_REG [7:0] and
     24           *    odd bytes in CPU_FRAME_ REG [15:8]. After the 16 bytes are written to the FIFO, the frame engine transfers
     25           *    the data from the FIFO to the external frame data buffer.
     26           * 5. Repeat step 3 and 4 until the whole Ethernet frame is complete. Pad the frame with 0?s so the frame aligns to an
     27           *    8-byte boundary.
     28           * 6. Poll COMMAND&STATUS[4] until it is asserted.
     29           * 7. Write ?h0010 (16-bit mode) or ?h10 (8-bit mode) to COMMAND&STATUS to indicate the end of the frame.
     30           *
     31           */
     32          
     33          int zarlinkEthFrameWrite(unsigned short frameLen, unsigned char * pFrameData, unsigned char port)
     34          {
     35            int i;
     36            unsigned char tmpStatus;
     37            unsigned short padBytes;
     38            unsigned short totalBytes;
     39            unsigned short * p16;
     40          
     41            union {
     42              unsigned short u16;
     43              unsigned char u8[2];
     44              } u;
     45          
     46            if (pFrameData == NULL)
     47              return -1;
     48          
     49            if (frameLen < 64)  // always send at least 64 bytes
     50              frameLen = 64;
     51          
     52            // initialize frame status data (which is mostly zero)
     53            for(i=0;i<8;i++)
     54              frameStatusData[i] = 0x00;
     55          
     56            padBytes = 0;
     57          
     58            // Pad the frame length to ensure it ends on an 8-byte boundary
     59            if ((frameLen & 0x0007) != 0) {
     60              padBytes = (8 - (frameLen & 0x0007));
     61              }
     62            
     63            totalBytes = ((frameLen + padBytes) & 0x3fff); // 14 bits of length
     64            u.u16 = totalBytes;
     65          
     66            // frame length in bits [13:0] and '1' in bit [14]
     67            frameStatusData[0] = u.u8[0];
     68            frameStatusData[1] = u.u8[1] | 0x40; // frame status (bit 14) must be 1
     69          
     70            // destination port in bits [51:48], device ID (0) in [54:52], '0' in [55]
     71          
     72          #if 1
     73            u.u16 = (unsigned short)(0x01 << port);
     74            u.u16 &= 0x03ff; // 10 bit port mask
     75          
     76            frameStatusData[6] = u.u8[0];
     77            frameStatusData[7] = (u.u8[1] | 0x04);
     78          #else
     79            frameStatusData[6] = (port & 0x0f);
     80          #endif
     81          
     82          
     83            // bit[63] - substitute frame source when it departs the device (=1 for now)
     84            // bit[62:59] - 4 bits of priority (set zero for now)
     85            // bit[58] - 1 to use port map (set zero)
     86            // bit[57:48] - port map
     87            // bit[57:55] - always zero
     88            // bit[54:52] - device ID (=0 in our case)
     89            // bit[51:48] - destination port
     90          
     91            // poll status reg bit 4
     92            for(i=0;i<1000;i++) {
     93              tmpStatus = zarlinkStatusRead();
     94              if ((tmpStatus & 0x10) != 0) {
     95                break;
     96                }
     97              }
     98          
     99            if ((tmpStatus & 0x10) == 0)
    100              return -1;
    101          
    102            p16 = (unsigned short *)(frameStatusData);
    103            // write frame status data to switch
    104            for(i=0;i<8/2;i++) {
    105              zarlinkFrameWrite(p16[i]);
    106              }
    107          
    108            // poll status reg bit 4
    109            for(i=0;i<1000;i++) {
    110              tmpStatus = zarlinkStatusRead();
    111              if ((tmpStatus & 0x10) != 0)
    112                break;
    113              }
    114          
    115            if ((tmpStatus & 0x10) == 0)
    116              return -2;
    117          
    118            p16 = (unsigned short *)pFrameData;
    119          
    120            while(totalBytes > 0) {
    121              // write totalBytes or 8 bytes, whichever is less, and check 
    122              for(i=0;((totalBytes > 0) && (i<16/2)); totalBytes -= 2, i++) {
    123                if (totalBytes > padBytes) {
    124                  // get data from the packet buffer
    125                  zarlinkFrameWrite(*p16++);
    126                  }
    127                else {
    128                  zarlinkFrameWrite(0x00);
    129                  // write pad data (0x00)
    130                  }
    131                } // for
    132          
    133              // poll status reg bit 4
    134              for(i=0;i<1000;i++) {
    135                tmpStatus = zarlinkStatusRead();
    136                if ((tmpStatus & 0x10) != 0)
    137                  break;
    138                }
    139          
    140              if ((tmpStatus & 0x10) == 0) {
    141                return -3;
    142                }
    143              } // while
    144          
    145            // poll status reg bit 4
    146            for(i=0;i<1000;i++) {
    147              tmpStatus = zarlinkStatusRead();
    148              if ((tmpStatus & 0x10) != 0)
    149                break;
    150              }
    151          
    152            if ((tmpStatus & 0x10) == 0)
    153              return -4;
    154          
    155            // write 0x10 to command reg to signal end-of-frame and that's it!
    156            zarlinkCommandWrite(0x10);
    157          
    158            return 0;
    159          }
    160          
    161          /*
    162           * Zarlink CPU Frame Read
    163           *
    164           * 1. Wait for a hardware interrupt. Read interrupt register (direct register 5). When bit 0 is set, it indicates an Ethernet
    165           *    frame waiting is asserted. Interrupt is de-asserted when first byte of frame is read out. The interrupt can be
    166           *    dynamically masked when the CPU is busy and does not want to be interrupted. The register INT_MASK0 programs
    167           *    the mask.
    168           * 2. Read 8 bytes of Receive Frame Status/ Ethernet frame (see Section 6.0, ?Processor Frame Format? on page
    169           *    12). In 8-bit mode, each byte is read out in increasing order from CPU_FRAME_REG [7:0]. In 16-bit mode,
    170           *    every 2 bytes are read out in increasing order; even bytes are read out from CPU_FRAME_REG[7:0] and odd
    171           *    bytes from CPU_FRAME_REG [15:8].
    172           * 3. Poll COMMAND&STATUS[3] until asserted.
    173           * 4. Read COMMAND&STATUS[5]; if asserted, the last 8 bytes needs to be read out (step 5), otherwise, repeat
    174           *    steps 2 and 3.
    175           * 5. Read last 8 byte of Ethernet frame.
    176           * 6. Write ?h0008 (16-bit mode) or ?h08 (8-bit mode) to COMMAND&STATUS to indicate the end of the frame.
    177           */
    178          
    179          static char recvFrameBuffer[1536];
    180          static unsigned short lastRecvFrameLen;
    181          
    182          int zarlinkEthFrameRead(unsigned short * pFrameLen, unsigned char * pFrameData)
    183          {
    184            int i;
    185            int retVal = -1;
    186            unsigned char tmpStatus;
    187            unsigned int frameLen;
    188            unsigned short * p16;
    189            boolean lastOctet;
    190          
    191            if (pFrameData == NULL) {
    192              pFrameData = recvFrameBuffer;
                                ^
Warning[Pe513]: a value of type "char *" cannot be assigned to an entity of
          type "unsigned char *"
    193              }
    194          
    195            p16 = (unsigned short *)frameStatusData;
    196            lastOctet = false;
    197          
    198            // read frame status data from switch
    199            for(i=0;i<8/2;i++) {
    200              p16[i] = zarlinkFrameRead();
    201              }
    202          
    203            for(i=0;i<1000;i++) {
    204              tmpStatus = zarlinkStatusRead();
    205              if ((tmpStatus & 0x08) != 0) {
    206                break;
    207                }
    208              }
    209          
    210            if ((tmpStatus & 0x08) == 0) {
    211              retVal = -1;
    212              }
    213          
    214            if ((tmpStatus & 0x20) == 0x20) {
    215              lastOctet = true;
    216              }
    217          
    218            frameLen = 0;
    219            lastRecvFrameLen = 0;
    220            p16 = (unsigned short *)pFrameData;
    221          
    222            for(;;) {
    223              // get 8 bytes of data
    224              for(i=0; i<8/2; i++) {
    225                *p16++ = zarlinkFrameRead();
    226                frameLen += 2;
    227                }
    228          
    229              if (lastOctet == false) {
    230                for(i=0;i<1000;i++) {
    231                  tmpStatus = zarlinkStatusRead();
    232                  if ((tmpStatus & 0x08) != 0) {
    233                    break;
    234                    }
    235                  }
    236          
    237                if ((tmpStatus & 0x08) == 0) {
    238                  retVal = -2;
    239                  break;
    240                  }
    241          
    242                tmpStatus = zarlinkStatusRead();  
    243                if ((tmpStatus & 0x20) == 0x20) {
    244                  lastOctet = true;
    245                  }
    246                }
    247              else {
    248                retVal = 0;
    249                break;
    250                }
    251              }
    252          
    253            // write 0x08 to command reg to signal end-of-receive and that's it!
    254            zarlinkCommandWrite(0x08);
    255          
    256            if (pFrameLen != NULL) {
    257              *pFrameLen = frameLen;
    258              }
    259          
    260            lastRecvFrameLen = frameLen;
    261          
    262            return retVal;
    263          }
    264          
    265          static int fsendHandler(int argc, char * argv[], int flags)
    266          {
    267            int retVal = -1;
    268            int bufLen;
    269            char * pOutBuf;
    270            unsigned char sendPort;
    271          
    272            pOutBuf = clicharGetOutputBuffer(&bufLen);
    273          
    274            if (argc < 2) {
    275              sprintf(pOutBuf, "%s: sending eth frame on all ports!\n", argv[0]);
    276              sendPort = 0x1f;
    277              }
    278            else if (argc == 2) {
    279              sendPort = (unsigned char)strtol(argv[1], (char **)NULL, 16);
    280              sprintf(pOutBuf, "%s: sending eth frame on port [%d]\r\n", argv[0], sendPort);
    281              }
    282            else {
    283              return retVal;
    284              }
    285          
    286            clicharSendOutputBuffer(pOutBuf, bufLen);
    287          
    288            return zarlinkEthFrameWrite(0, NULL, sendPort);
    289          }
    290          
    291          static int frecvHandler(int argc, char * argv[], int flags)
    292          {
    293            int retVal = -1;
    294            int bufLen;
    295            char * pOutBuf;
    296            unsigned short recvBytes;
    297          
    298            pOutBuf = clicharGetOutputBuffer(&bufLen);
    299          
    300            retVal = zarlinkEthFrameRead(&recvBytes, NULL);
    301          
    302            if (retVal == 0) {
    303              sprintf(pOutBuf, "%s: received [%u] bytes in packet buffer\r\n", argv[0], recvBytes);
    304              }
    305            else {
    306              sprintf(pOutBuf, "%s: packet receive error [%d]\r\n", argv[0], retVal);
    307              }
    308          
    309            clicharSendOutputBuffer(pOutBuf, bufLen);
    310          
    311            return retVal;
    312          }
    313          
    314          static int fshowHandler(int argc, char * argv[], int flags)
    315          {
    316            int retVal = -1;
    317          
    318            if (lastRecvFrameLen != 0) {
    319              strutilHexdump(recvFrameBuffer, lastRecvFrameLen);
    320              retVal = 0;
    321              }
    322          
    323            return retVal;
    324          }
    325          
    326          int zarlinkFrameInit(void)
    327          {
    328            cliRegisterCommand("fsend", fsendHandler, "fsend [port] - sends a 128 byte ethernet frame on switch port");
    329            cliRegisterCommand("frecv", frecvHandler, "frecv - receives a packet into internal memory");
    330            cliRegisterCommand("fshow", fshowHandler, "fshow - shows a hex dump of the last received packet");  
    331          }
                 ^
Warning[Pe940]: missing return statement at end of non-void function
          "zarlinkFrameInit"
    332          
    333          #endif
    334          

   Maximum stack usage in bytes:

     Function             CSTACK
     --------             ------
     frecvHandler            32
     fsendHandler            32
     fshowHandler            20
     zarlinkEthFrameRead     36
     zarlinkEthFrameWrite    40
     zarlinkFrameInit         4


   Segment part sizes:

     Function/Label                 Bytes
     --------------                 -----
     frameStatusData                   8
     zarlinkEthFrameWrite            756
     recvFrameBuffer                1536
     lastRecvFrameLen                  2
     zarlinkEthFrameRead             424
     fsendHandler                    188
     frecvHandler                    148
     fshowHandler                     80
     zarlinkFrameInit                 92
     ??DataTable7                      4
     ??DataTable11                     4
     ??DataTable12                     4
     ?<Constant "%s: sending eth frame...">
                                      40
     ?<Constant "%s: sending eth frame...">_1
                                      40
     ?<Constant "%s: received [%u] byt...">
                                      44
     ?<Constant "%s: packet receive er...">
                                      32
     ?<Constant "fsend">               8
     ?<Constant "fsend [port] - sends ...">
                                      64
     ?<Constant "frecv">               8
     ?<Constant "frecv - receives a pa...">
                                      48
     ?<Constant "fshow">               8
     ?<Constant "fshow - shows a hex d...">
                                      56
      Others                         132

 
 1 820 bytes in segment CODE
   348 bytes in segment DATA_C
 1 546 bytes in segment DATA_Z
    12 bytes in segment INITTAB
 
 1 700 bytes of CODE  memory (+ 132 bytes shared)
   348 bytes of CONST memory
 1 546 bytes of DATA  memory

Errors: none
Warnings: 2
