Probleme bei Adressenauswahl von einem Makro



  • Guiekalle schrieb:

    Dachte func verhält sich nun wie eine Variable...

    so ist es doch auch. in func kannst du die adresse jeder funktion speichern, die die signatur void f (uint16, uint16) hat.
    🙂



  • Okay... 🙂

    Muss ich beim Verwenden etwas beachten...?

    [b]UINT16* const  piWritePD   = (UINT16*)(&func);   :confused: 
    
    /*anstelle von  UINT16* const piWritePD = (UINT16*)( ABCC_PARALLEL_BASE_ADDRESS + 0x3800 ); */[/b]
    

    Und falls es stimmt dann:

    #define WriteParallel([b]&func[/b],adr,val)
    
    void task2(void)
    
    {
    
      register uint16 tl,th;
      register uint8  temp;
    
       taskinit ();
    
       firsttime  = 1;
       pbinitdone = 0;
    
       WriteParallel([b]piWritePD[/b],0x3800,0x11); /*Schreiben von Wert 11 in 0x3800*/
    
       pbtim = ticks(1500000); /*delay*/
    
       while(pbtim);
    
       MWA_Block = rdlmode(0x3800); /*einlesen*/
    
       putshex(ZS(21,00),MWA_Block,NORML(BLK,WHT)); */ausgeben*/
    

    Bin mir bei der Übergabe nicht so sicher... 😞



  • Guiekalle schrieb:

    Bin mir bei der Übergabe nicht so sicher...

    #include <stdio.h>
    // *** fricky's little function pointer tutorial ***
    
    // erstmal eine funktion ...
    void f1 (void)
    {
       puts ("hello, i'm f1 !");
    }
    
    // ...und noch eine funktion
    void f2 (void)
    {
       puts ("what? me worry");
    }
    
    // wir bauen uns nun einen typ für unseren function pointer
    typedef void (*fptr)(void);
    
    // hier ist die main funktion. alle c-programme fangen so an
    int main (void)
    {
      // nun brauchen wir erstmal einen function pointer
      // wir verwenden dabei unser neues typedef
      fptr func;
    
      // den function pointer lassen wir jetzt auf unsere erste funktion zeigen
      func = f1;
    
      // mal sehen, ob's auch geklappt hat
      func();
    
      // na fein! nun versuchen wir es mal mit der anderen funktion
      // aber mit dem selben(!) function pointer
      func = f2;
    
      // und???
      func();
    
      // perfekt!
      puts ("vielen dank, dass sie dieses tutorial so aufmerksam durchgearbeitet haben. bis zum naechsten mal!");
    }
    

    🙂



  • Echt spitze deine Anleitung... 👍

    Ich hab es hinbekommen einen Wert 11 mit func zu schreiben...*freu*... 😉

    So jetzt muss ich func in einen anderen Pointer einlagern...überleg

    UINT16* const piWritePD = (UINT16*)(func); ... :warning:
    

    ...und mit diesem dann ein Schreiben auslösen...*hui*

    WriteParallel(piWritePD,0x3800,0x11); /*Schreiben von Wert 11 in 0x3800*/
    

    Melde mich...schade nur,dass ich das System von 7uhr-16uhr habe...aber wird schon...Bis bald...



  • #include <stdio.h>
    // hallo, liebe c-freunde. willkommen zum zweiten teil von fricky's fptr tutorial
    // heute lernen wir, wie man funktionspointer an andere funktionen weitergeben kann 
    
    // erstmal brauchen wir wieder eine funktion. ohne die geht gar nichts.
    void f1 (void)
    {
       puts ("hallo, ich bin die hauptfunktion");
    }
    
    // auch hier wieder: unser neuer typ für einen function pointer
    typedef void (*fptr)(void);
    
    // hier haben wir jetzt eine funktion, die einen function pointer entegennehmen kann
    // wie ihr alle sehen könnt, erscheint unser neuer typ in der argumentenliste als einziges argument namens 'fp'
    void intermediate_func (fptr fp)
    {
      puts ("hallo ich bin die zwischenfunktion");
      // na, ob das wohl so klappt?
      fp();
    }
    
    // wir wollen es gleich ausprobieren und brauchen dafür wieder eine main funktion...
    int main (void)
    {
      // ... und unsereren schon bekannten function pointer
      // den wir jetzt sofort auf unsere f1-funktion zeigen lassen
      fptr func = f1;
    
      // so, jetzt kommt der augenblick der wahrheit ~zitter~
      intermediate_func (func);
    
      // unglaublich! das ging ja! mal sehen, ob's auch direkt geht ~bibber~
      intermediate_func (f1);
    
      // funzt!!! that's coool! C ist ja so unglaublich geil!!!
      puts ("so, das war's mal wieder fuer heute. vielen dank fuer euer interesse und - bis bald\n");
    }
    

    🙂



  • Einfach klasse... 👍 ...werde mir beides ausdrucken und zu meinen Unterlagen geben... :p

    So noch mal zu meinem Code - funktioniert prima.

    #define wrlmode(adr,val) (outword (MOD1ADR+0x10,(adr)),outword (MOD1ADR+0x008,(val)))
    #define rdlmode(adr)     (outword (MOD1ADR+0x10,(adr)),inword  (MOD1ADR+0x108))
    
    void wrlmode_function (UINT16 adr, UINT16 val)
    
    {
    
    [b]wrlmode(0x3800,0x11);[/b]
    
    }
    
    typedef void (*fptr)(UINT16, UINT16);
    
    void f(void)
    
    {
      fptr func;
      func = wrlmode_function;
      func (1,2);
    
    		#define WriteParallel(func)
    
    		WriteParallel(func);
    
    		pbtim = ticks(1500000);
    
    		while(pbtim);
    
    		MWA_Block = rdlmode(0x3800);
    
    		putshex(ZS(21,00),MWA_Block,NORML(BLK,WHT));
    
    }
    

    Habe nun folgende Frage an die Cracks:

    Im Moment bin ich abhängig von dem Wert,der in wrlmode_function geschrieben wird.Das wäre in diesem Fall 0x11 in 0x3800.
    Ich hätte es aber gerne,dass die Adresse und der Wert noch später (z.B. in der Hauptfunktion) übergeben werden.
    So etwa:

    #define WriteParallel(func,adr,val)
    
    WriteParallel(func,adr,val);
    

    --> So soll func den Kontakt herstellen und adr und val kann man beliebig anpassen.

    Kann auch über meine Email mal meine C-File Vorlage des Herstellers zukommen lassen,damit man sieht, was ich versuche umzusetzen...Danke... 👍



  • Guiekalle schrieb:

    #define wrlmode(adr,val) (outword (MOD1ADR+0x10,(adr)),outword (MOD1ADR+0x008,(val)))
    #define rdlmode(adr)     (outword (MOD1ADR+0x10,(adr)),inword  (MOD1ADR+0x108))
    
    void wrlmode_function (UINT16 adr, UINT16 val)
    
    {
    
    [b]wrlmode(0x3800,0x11);[/b]  //<-- dann trag hier: [b]wrlmode(adr, val);[/b] ein!
    
    }
    
    }
    

    Habe nun folgende Frage an die Cracks:

    Im Moment bin ich abhängig von dem Wert,der in wrlmode_function geschrieben wird.Das wäre in diesem Fall 0x11 in 0x3800.

    siehe im Code.

    Gruß mcr



  • Werde es morgen noch mal am System testen,dann auch diesen Schritt durchspielen,hoffe es klappt...hmm... 😕

    **Falls es nicht klappt,setze ich mal eine Vorlage online.**Danke.



  • Hab es gerade getestet,leider kein Erfolg... 😞

    #define wrlmode(adr,val) (outword (MOD1ADR+0x10,(adr)),outword (MOD1ADR+0x008,(val)))
    #define rdlmode(adr)     (outword (MOD1ADR+0x10,(adr)),inword  (MOD1ADR+0x108))
    
    void wrlmode_function (UINT16 adr, UINT16 val)
    
    {
    
    wrlmode(adr,val);
    
    }
    
    typedef void (*fptr)(UINT16, UINT16);
    
    void f(void)
    
    {
      fptr func;
      func = wrlmode_function;
      func (1,2);
    
            #define WriteParallel(func,adr,val)
    
            WriteParallel(func,0x3800,0x11);
    
            pbtim = ticks(1500000);
    
            while(pbtim);
    
            MWA_Block = rdlmode(0x3800);
    
            putshex(ZS(21,00),MWA_Block,NORML(BLK,WHT));
    
    }
    

    ...hmmmmmm... 😕



  • Habe noch mal das Programm, in das ich

    [b]#define wrlmode(adr,val) (outword (MOD1ADR+0x10,(adr)),outword (MOD1ADR+0x008,(val))) [/b]
    

    einbauen möchte.

    Diese Adresse des Makro´s entspricht ABCC_PARALLEL_BASE_ADDRESS + 0x3800 (dick hervorgehoben).

    So muss ich nun meinen Makro (besser dessen Adresse anstelle von der BASE_ADDRESS+0x3800) irgendwie dort einbauen.Habe es mit eurer Hilfe mit einem Funktionspointer umgesetzt.Jedoch bin ich an den Wert in der Funktion wrlmode_funktion gebunden.
    Ziel ist es später den Wert zu übergeben -->siehe WriteParallel !

    Hier nun zum Programm,auf das ich hinaus will.

    /*******************************************************************************
    **
    ** Public Globals
    **
    ********************************************************************************
    */
    
    /*
    ** bSw1 and bSw2 represent two DIP-switches (or similar) which are used to set
    ** the fieldbus node adress and baudrate.
    */
    
    #ifdef USE_DIPSWITCHES
       UINT8                      bSw1;
       UINT8                      bSw2;
    #endif
    
    /*
    ** Working copies of the status and control registers
    */
    
    UINT8                         bControlReg = ABP_CTRL_R_BIT;
    UINT8                         bStatusReg  = 0x80;
    
    /*
    ** State variable that keeps track of which initialization command to send next
    */
    
    #ifdef USE_DIPSWITCHES
       CmdStateType               eCmdState   = MSG_NODE_ADR;
    #else
       CmdStateType               eCmdState   = MSG_MAP_IO_1;
    #endif
    
    /*
    ** This variable keeps track of if there are any commands which we have not yet 
    ** received a response to.
    */
    
    UINT8 bOutstandingCmds = 0;
    
    /*
    ** The application data instances (ADIs for short)
    ** This is the data which will be exchanged on the fieldbus
    ** In this simple example we only have eight UINT16 parameters
    */
    
    UINT16                        aiApplicationData[ NUMBER_OF_ADIS ] = { 0, 1, 2, 3, 4, 5, 6, 7 };
    
    /*
    ** The names of each application data instance (ADI for short)
    ** These strings should be changed to reflect the proper names of the ADIs.
    */
    
    const char* const             apbADINames[ NUMBER_OF_ADIS ] = { "1st ADI",
                                                                    "2nd ADI",
                                                                    "3rd ADI",
                                                                    "4th ADI",
                                                                    "5th ADI",
                                                                    "6th ADI",
                                                                    "7th ADI",
                                                                    "8th ADI" };
    
    /*
    ** This variable is used to indicate the network data format.
    ** Little endian or big endian.
    */
    
    NetFormatType                 eNetFormat = NET_UNKNOWN;
    
    /*******************************************************************************
    **
    ** Private Globals
    **
    ********************************************************************************
    */
    
    /*
    ** Pointers to process data, messages and registers in the Anybus-CC.
    */
    
    #ifdef ABCC_PARALLEL_DIRECT_ACCESS_THROUGH_PTR
       [b]UINT16* const         piWritePD    = (UINT16*)( ABCC_PARALLEL_BASE_ADDRESS + 0x3800 );[/b]
       UINT16* const         piReadPD     = (UINT16*)( ABCC_PARALLEL_BASE_ADDRESS + 0x3900 );
       ABP_MsgType* const    psWriteMsg   = (ABP_MsgType*)( ABCC_PARALLEL_BASE_ADDRESS + 0x3B00 );
       ABP_MsgType* const    psReadMsg    = (ABP_MsgType*)( ABCC_PARALLEL_BASE_ADDRESS + 0x3D00 );
       volatile UINT8* const pbControlReg = (UINT8*)( ABCC_PARALLEL_BASE_ADDRESS + 0x3FFE );
       volatile UINT8* const pbStatusReg  = (UINT8*)( ABCC_PARALLEL_BASE_ADDRESS + 0x3FFF );
    #else
       UINT16                aiWritePDBuffer[ 2 ];
       UINT16                aiReadPDBuffer[ 2 ];
       UINT16* const         piWritePD    = aiWritePDBuffer;
       UINT16* const         piReadPD     = aiReadPDBuffer;
       ABP_MsgType           sMsgBuffer;
       ABP_MsgType* const    psWriteMsg   = &sMsgBuffer;
       ABP_MsgType* const    psReadMsg    = &sMsgBuffer;
    #endif
    
    /*******************************************************************************
    **
    ** Public Functions
    **
    ********************************************************************************
    */
    
    /*------------------------------------------------------------------------------
    ** Main()
    **------------------------------------------------------------------------------
    */
    
    void Main( void )
    {
       UINT8 bNewStatusReg1, bNewStatusReg2;
    #ifdef USE_DIPSWITCHES
       static UINT8 bLastSw1, bLastSw2;
    #endif
    
       /*
       ** Read the status register.
       ** The status register must doublechecked since we are not using the 
       ** interrupt feature.
       */
    
       do
       {
    #ifdef ABCC_PARALLEL_DIRECT_ACCESS_THROUGH_PTR
          bNewStatusReg1 = *pbStatusReg;
          bNewStatusReg2 = *pbStatusReg;
    #else
          ReadParallel( &bNewStatusReg1, 0x3FFF, 1 );
          ReadParallel( &bNewStatusReg2, 0x3FFF, 1 );
    #endif
       }
       while( bNewStatusReg1 != bNewStatusReg2 );
    
       /*
       ** Check if the toggle bit in the status register has toggled.
       */
    
       if( ( bNewStatusReg1 & ABP_STAT_T_BIT ) ==
           ( bStatusReg & ABP_STAT_T_BIT ) )
       {
          /*
          ** Toggle bit has not toggled: Modul is still busy
          */
    
          return;
       }
    
       bStatusReg = bNewStatusReg1;
    
       bControlReg &= ~ABP_CTRL_M_BIT;
       bControlReg ^= ABP_CTRL_T_BIT;
    
       if( bStatusReg & ABP_STAT_M_BIT )
       {
          /*
          ** There is a message available.
          */
    
    #ifndef ABCC_PARALLEL_DIRECT_ACCESS_THROUGH_PTR
          ReadParallel( psReadMsg, 0x3D00, sizeof( ABP_MsgHeaderType ) );
          ReadParallel( psReadMsg->abData,
                        0x3D00 + sizeof( ABP_MsgHeaderType ),
                        psReadMsg->sHeader.bDataSize );
    #endif
    
          if( psReadMsg->sHeader.bCmd & ABP_MSG_HEADER_C_BIT )
          {
             /*
             ** The message is a command
             ** First we copy the header to prepare the response.
             */
    
             psWriteMsg->sHeader = psReadMsg->sHeader;
             psWriteMsg->sHeader.bCmd = psReadMsg->sHeader.bCmd & ~ABP_MSG_HEADER_C_BIT;
    
             switch( psReadMsg->sHeader.bDestObj )
             {
             case ABP_OBJ_NUM_APPD:
    
                /*
                ** Command to the application data object
                */
    
                ApplicationDataObject();
                bControlReg |= ABP_CTRL_M_BIT;
    
                break;
    
             default:
    
                /*
                ** Command to a unsupported object.
                */
    
                SetMsgError( psWriteMsg, 1, ABP_ERR_UNSUP_OBJ );
                bControlReg |= ABP_CTRL_M_BIT;
    
                break;
             }
          }
          else
          {
             /*
             ** The message is a reponse to a command we have sent.
             */
    
             bOutstandingCmds--;
    
             switch( psReadMsg->sHeader.bSourceId )
             {
    #ifdef USE_DIPSWITCHES
             case MSG_NODE_ADR:
             case MSG_BAUDRATE:
    
                /*
                ** It is a response to a command to set one of the DIP-switch values.
                ** This response shall normally be ignored, even if the error bit is set.
                ** 
                */
    
                break;
    #endif
             case MSG_MAP_IO_1:
             case MSG_MAP_IO_2:
             case MSG_MAP_IO_3:
             case MSG_MAP_IO_4:
             case MSG_SETUP_COMPLETE:
    
                /*
                ** It is a response to a mapping command or to the setup complete command.
                ** Check if everything went well.
                */
    
                if( psReadMsg->sHeader.bCmd & ABP_MSG_HEADER_E_BIT )
                {
                   /*
                   ** The Modul has responded with the error bit set. This means
                   ** something is wrong.
                   ** PORTING ALERT!
                   ** Application specific error handling can optinally be inserted
                   ** here. For example: Indicate to user that something is wrong
                   ** with the Modul.
                   ** psReadMsg contains information about exactly which command
                   ** caused the error and what the error is.
                   */
                }
    
                break;
    
             case MSG_DATA_FORMAT:
    
                /*
                ** It is a response to the 'get data format' command
                */
    
                if( psReadMsg->abData[ 0 ] > 1 )
                {
                   /*
                   ** The Modul responded with a unknown data format type.
                   ** This is a unexpected error. Application specific error
                   ** handling can optinally be inserted here.
                   ** PORTING ALERT!
                   ** For example: Indicate to user that something is wrong.
                   */
    
                   eNetFormat = NET_UNKNOWN;
                }
                else
                {
                   /*
                   ** The Modul responded with a correct data format type.
                   ** Store it for later use.
                   */
    
                   eNetFormat = psReadMsg->abData[ 0 ];
                }
    
                break;
    
             default:
    
                   /*
                   ** The Modul has responded with a source ID which is unknown 
                   ** to us. This means something is wrong.
                   ** PORTING ALERT!
                   ** Application specific error handling can optinally be inserted
                   ** here.
                   ** For example: Indicate to user that something is wrong.
                   */
    
                break;
    
             } /* end switch( Source ID ) */
    
          } /* end if( message is a command ) */
    
       } /* end if( message available ) */
    
       if( ( bStatusReg & ABP_STAT_R_BIT ) &&
          !( bControlReg & ABP_CTRL_M_BIT ) )
       {
          /*
          ** The Modul is ready to accept commands, and the WriteMsg buffer is free
          */
    
          switch( eCmdState )
          {
    #ifdef USE_DIPSWITCHES
          case MSG_NODE_ADR:
    
             psWriteMsg->sHeader.bSourceId          = MSG_NODE_ADR;
             psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NC;
             psWriteMsg->sHeader.iInstance          = iTOiLe( ABP_NC_INST_NUM_SW1 );
             psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_CMD_SET_ATTR;
             psWriteMsg->sHeader.bDataSize          = 1;
             psWriteMsg->sHeader.bCmdExt0           = ABP_NC_VAR_IA_VALUE;
             psWriteMsg->sHeader.bCmdExt1           = 0;
             psWriteMsg->abData[ 0 ]                = bLastSw1 = bSw1;
             bControlReg                           |= ABP_CTRL_M_BIT;
             eCmdState                              = MSG_BAUDRATE;
    
             break;
    
          case MSG_BAUDRATE:
    
             psWriteMsg->sHeader.bSourceId          = MSG_BAUDRATE;
             psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NC;
             psWriteMsg->sHeader.iInstance          = iTOiLe( ABP_NC_INST_NUM_SW2 );
             psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_CMD_SET_ATTR;
             psWriteMsg->sHeader.bDataSize          = 1;
             psWriteMsg->sHeader.bCmdExt0           = ABP_NC_VAR_IA_VALUE;
             psWriteMsg->sHeader.bCmdExt1           = 0;
             psWriteMsg->abData[ 0 ]                = bLastSw2 = bSw2;
             bControlReg                           |= ABP_CTRL_M_BIT;
             eCmdState                              = MSG_MAP_IO_1;
    
             break;
    #endif
          case MSG_MAP_IO_1:
    
             psWriteMsg->sHeader.bSourceId          = MSG_MAP_IO_1;
             psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NW;
             psWriteMsg->sHeader.iInstance          = iTOiLe( 1 );
             psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_NW_CMD_MAP_ADI_WRITE_AREA;
             psWriteMsg->sHeader.bDataSize          = 4;
             *(UINT16*)&psWriteMsg->sHeader.bCmdExt0 = iTOiLe( 1 );
             psWriteMsg->abData[ 0 ]                = ABP_UINT16;
             psWriteMsg->abData[ 1 ]                = 1;
             *(UINT16*)&psWriteMsg->abData[ 2 ]     = iTOiLe( 1 );
             bControlReg                           |= ABP_CTRL_M_BIT;
             eCmdState                              = MSG_MAP_IO_2;
    
             break;
    
          case MSG_MAP_IO_2:
    
             psWriteMsg->sHeader.bSourceId          = MSG_MAP_IO_2;
             psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NW;
             psWriteMsg->sHeader.iInstance          = iTOiLe( 1 );
             psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_NW_CMD_MAP_ADI_WRITE_AREA;
             psWriteMsg->sHeader.bDataSize          = 4;
             *(UINT16*)&psWriteMsg->sHeader.bCmdExt0 = iTOiLe( 2 );
             psWriteMsg->abData[ 0 ]                = ABP_UINT16;
             psWriteMsg->abData[ 1 ]                = 1;
             *(UINT16*)&psWriteMsg->abData[ 2 ]     = iTOiLe( 2 );
             bControlReg                           |= ABP_CTRL_M_BIT;
             eCmdState                              = MSG_MAP_IO_3;
    
             break;
    
          case MSG_MAP_IO_3:
    
             psWriteMsg->sHeader.bSourceId          = MSG_MAP_IO_3;
             psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NW;
             psWriteMsg->sHeader.iInstance          = iTOiLe( 1 );
             psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_NW_CMD_MAP_ADI_READ_AREA;
             psWriteMsg->sHeader.bDataSize          = 4;
             *(UINT16*)&psWriteMsg->sHeader.bCmdExt0 = iTOiLe( 3 );
             psWriteMsg->abData[ 0 ]                = ABP_UINT16;
             psWriteMsg->abData[ 1 ]                = 1;
             *(UINT16*)&psWriteMsg->abData[ 2 ]     = iTOiLe( 3 );
             bControlReg                           |= ABP_CTRL_M_BIT;
             eCmdState                              = MSG_MAP_IO_4;
    
             break;
    
          case MSG_MAP_IO_4:
    
             psWriteMsg->sHeader.bSourceId          = MSG_MAP_IO_4;
             psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NW;
             psWriteMsg->sHeader.iInstance          = iTOiLe( 1 );
             psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_NW_CMD_MAP_ADI_READ_AREA;
             psWriteMsg->sHeader.bDataSize          = 4;
             *(UINT16*)&psWriteMsg->sHeader.bCmdExt0 = iTOiLe( 4 );
             psWriteMsg->abData[ 0 ]                = ABP_UINT16;
             psWriteMsg->abData[ 1 ]                = 1;
             *(UINT16*)&psWriteMsg->abData[ 2 ]     = iTOiLe( 4 );
             bControlReg                           |= ABP_CTRL_M_BIT;
             eCmdState                              = MSG_DATA_FORMAT;
    
             break;
    
          case MSG_DATA_FORMAT:
    
             psWriteMsg->sHeader.bSourceId          = MSG_DATA_FORMAT;
             psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NW;
             psWriteMsg->sHeader.iInstance          = iTOiLe( 1 );
             psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_CMD_GET_ATTR;
             psWriteMsg->sHeader.bDataSize          = 0;
             psWriteMsg->sHeader.bCmdExt0           = ABP_NW_IA_DATA_FORMAT;
             psWriteMsg->sHeader.bCmdExt1           = 0;
             bControlReg                           |= ABP_CTRL_M_BIT;
             eCmdState                              = MSG_SETUP_COMPLETE;
    
             break;
    
          case MSG_SETUP_COMPLETE:
    
             /*
             ** End the setup phase by sending the SETUP_COMPLETE command after
             ** we have received the responses to all commands which we have sent.
             */
    
             if( bOutstandingCmds == 0 )
             {
                /*
                ** All the configuration commands have been processed by the Modul.
                ** Go ahead and end the setup phase by sending SETUP_COMPLETE.
                */
    
                psWriteMsg->sHeader.bSourceId          = MSG_SETUP_COMPLETE;
                psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_ANB;
                psWriteMsg->sHeader.iInstance          = iTOiLe( 1 );
                psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_CMD_SET_ATTR;
                psWriteMsg->sHeader.bDataSize          = ABP_BOOL_SIZEOF;
                psWriteMsg->sHeader.bCmdExt0           = ABP_ANB_IA_SETUP_COMPLETE;
                psWriteMsg->sHeader.bCmdExt1           = 0;
                psWriteMsg->abData[ 0 ]                = TRUE;
                bControlReg                           |= ABP_CTRL_M_BIT;
                eCmdState                              = MSG_DONE;
             }
    
             break;
    
          case MSG_DONE:
    
             /*
             ** All the initialization commands have already been sent.
             ** Check the node adress or baudrate DIP-switches if available, send
             ** a update to the Modul if they have changed.
             */
    #ifdef USE_DIPSWITCHES
             if( bSw1 != bLastSw1 )
             {
                /*
                ** DIP switch 1 (node adress) has changed.
                ** Send a update to the Modul.
                */
    
                psWriteMsg->sHeader.bSourceId          = MSG_NODE_ADR;
                psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NC;
                psWriteMsg->sHeader.iInstance          = iTOiLe( ABP_NC_INST_NUM_SW1 );
                psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_CMD_SET_ATTR;
                psWriteMsg->sHeader.bDataSize          = 1;
                psWriteMsg->sHeader.bCmdExt0           = ABP_NC_VAR_IA_VALUE;
                psWriteMsg->sHeader.bCmdExt1           = 0;
                psWriteMsg->abData[ 0 ]                = bLastSw1 = bSw1;
                bControlReg                           |= ABP_CTRL_M_BIT;
             }
             else if( bSw2 != bLastSw2 )
             {
                /*
                ** DIP switch 2 (baudrate) has changed.
                ** Send a update to the Modul.
                */
    
                psWriteMsg->sHeader.bSourceId          = MSG_BAUDRATE;
                psWriteMsg->sHeader.bDestObj           = ABP_OBJ_NUM_NC;
                psWriteMsg->sHeader.iInstance          = iTOiLe( ABP_NC_INST_NUM_SW2 );
                psWriteMsg->sHeader.bCmd               = ABP_MSG_HEADER_C_BIT | ABP_CMD_SET_ATTR;
                psWriteMsg->sHeader.bDataSize          = 1;
                psWriteMsg->sHeader.bCmdExt0           = ABP_NC_VAR_IA_VALUE;
                psWriteMsg->sHeader.bCmdExt1           = 0;
                psWriteMsg->abData[ 0 ]                = bLastSw2 = bSw2;
                bControlReg                           |= ABP_CTRL_M_BIT;
             }
             else
    #endif
             {
                /*
                ** New commands can be added here.
                */
             }
    
             break;
    
          } /* end switch( command state ) */
    
          if( bControlReg & ABP_CTRL_M_BIT )
          {
             /*
             ** A new command has been posted to the Modul.
             ** Increment counter for outstanding commands.
             */
    
             bOutstandingCmds++;
          }
    
       } /* end if( it's OK to send a command ) */
    
    #ifndef ABCC_PARALLEL_DIRECT_ACCESS_THROUGH_PTR
       if( bControlReg & ABP_CTRL_M_BIT )
       {
          /*
          ** Copy the message to the Modul.
          ** This is only necessary if psWriteMsg does not already point directly 
          ** into the Modul.
          */
    
          WriteParallel( psWriteMsg, 0x3B00, psWriteMsg->sHeader.bDataSize + sizeof( ABP_MsgHeaderType ) );
       }
    #endif
    
       /*
       ** Send new "write process data" to the Modul.
       ** The data format of the process data is is network specific.
       ** Convert our data accordingly.
       */
    
       if( eNetFormat == NET_BIGENDIAN )
       {
          piWritePD[ 0 ] = iTOiBe( aiApplicationData[ 0 ] );
          piWritePD[ 1 ] = iTOiBe( aiApplicationData[ 1 ] );
       }
       else /* NET_LITTLEENDIAN */
       {
          piWritePD[ 0 ] = iTOiLe( aiApplicationData[ 0 ] );
          piWritePD[ 1 ] = iTOiLe( aiApplicationData[ 1 ] );
       }
    
    #ifndef ABCC_PARALLEL_DIRECT_ACCESS_THROUGH_PTR
       [b]WriteParallel( piWritePD, 0x3800, 4 );[/b]
    #endif
    
       if( ( bStatusReg & ABP_STAT_S_BITS ) == ABP_ANB_STATE_PROCESS_ACTIVE )
       {
          /*
          ** The "read process data" is only valid in the PROCESS_ACTIVE state.
          ** Retrieve the new "read process data" from the Modul.
          ** The data format of the process data is network specific.
          ** Convert it to our native format.
          */
    
    #ifndef ABCC_PARALLEL_DIRECT_ACCESS_THROUGH_PTR
          ReadParallel( piReadPD, 0x3900, 4 );
    #endif
    
          if( eNetFormat == NET_BIGENDIAN )
          {
             aiApplicationData[ 2 ] = iBeTOi( piReadPD[ 0 ] );
             aiApplicationData[ 3 ] = iBeTOi( piReadPD[ 1 ] );
          }
          else /* NET_LITTLEENDIAN */
          {
             aiApplicationData[ 2 ] = iLeTOi( piReadPD[ 0 ] );
             aiApplicationData[ 3 ] = iLeTOi( piReadPD[ 1 ] );
          }
       }
    
       /*
       ** We are now done accessing the Modul memory.
       ** Time to perform the handshaking with the Modul.
       */
    
    #ifdef ABCC_PARALLEL_DIRECT_ACCESS_THROUGH_PTR
       *pbControlReg = bControlReg;
    #else
       WriteParallel( &bControlReg, 0x3FFE, 1 );
    #endif
    
    } /* end of Main() */
    
    /*------------------------------------------------------------------------------
    ** ApplicationDataObject()
    **------------------------------------------------------------------------------
    */
    
    void ApplicationDataObject( void )
    {
       switch( iLeTOi( psReadMsg->sHeader.iInstance ) )
       {
       case ABP_INST_OBJ: /* The object instance */
    
          switch( psReadMsg->sHeader.bCmd & ABP_MSG_HEADER_CMD_BITS )
          {
          case ABP_CMD_GET_ATTR:
    
             switch( psReadMsg->sHeader.bCmdExt0 )
             {
             case ABP_OA_NAME: /* Name */
    
                memcpy( psWriteMsg->abData, "Application data", 16 );
                psWriteMsg->sHeader.bDataSize = 16;
    
                break;
    
             case ABP_OA_REV: /* Revision */
    
                psWriteMsg->abData[ 0 ] = 1;
                psWriteMsg->sHeader.bDataSize = ABP_OA_REV_DS;
    
                break;
    
             case ABP_OA_NUM_INST: /* Number of instances */
    
                *(UINT16*)&psWriteMsg->abData[ 0 ] = iTOiLe( NUMBER_OF_ADIS );
                psWriteMsg->sHeader.bDataSize = ABP_OA_NUM_INST_DS;
    
                break;
    
             case ABP_OA_HIGHEST_INST: /* Highest instance no. */
    
                *(UINT16*)&psWriteMsg->abData[ 0 ] = iTOiLe( NUMBER_OF_ADIS );
                psWriteMsg->sHeader.bDataSize = ABP_OA_HIGHEST_INST_DS;
    
                break;
    
             default: /* Unsupported attribute */
    
                SetMsgError( psWriteMsg, 1, ABP_ERR_INV_CMD_EXT_0 );
    
                break;
    
             } /* end switch( attribute ) */
    
             break;
    
          case ABP_APPD_CMD_GET_INST_BY_ORDER:
    
             if( ( iLeTOi( *(UINT16*)&psReadMsg->sHeader.bCmdExt0 ) == 0 ) ||
                 ( iLeTOi( *(UINT16*)&psReadMsg->sHeader.bCmdExt0 ) > NUMBER_OF_ADIS ) )
             {
                /*
                ** Requested order number does not exist.
                */
    
                SetMsgError( psWriteMsg, 1, ABP_ERR_INV_CMD_EXT_0 );
             }
             else
             {
                /*
                ** In this simple application there are no gaps between application
                ** data instances. This means that the instance numbers are equal to
                ** the order number.
                */
    
                *(UINT16*)&psWriteMsg->abData[ 0 ] = *(UINT16*)&psReadMsg->sHeader.bCmdExt0;
                psWriteMsg->sHeader.bDataSize = ABP_UINT16_SIZEOF;
             }
    
             break;
    
          default:
    
             SetMsgError( psWriteMsg, 1, ABP_ERR_UNSUP_CMD );
    
             break;
    
          } /* end switch( command ) */
    
          break;
    
       case 1: /* Application Data Instance 1 */
       case 2: /* Application Data Instance 2 */
       case 3: /* Application Data Instance 3 */
       case 4: /* Application Data Instance 4 */
       case 5: /* Application Data Instance 5 */
       case 6: /* Application Data Instance 6 */
       case 7: /* Application Data Instance 7 */
       case 8: /* Application Data Instance 8 */
    
          /*
          ** Because all eight application data instances (ADIs) are of the same
          ** data type, we can handle all eight in the same way.
          */
    
          switch( psReadMsg->sHeader.bCmd & ABP_MSG_HEADER_CMD_BITS )
          {
          case ABP_CMD_GET_ATTR:
    
             switch( psReadMsg->sHeader.bCmdExt0 )
             {
             case ABP_APPD_IA_NAME: /* Instance name */
    
                /*
                ** Get the name of the requested ADI
                */
    
                strcpy( (char*)psWriteMsg->abData, apbADINames[ iLeTOi( psReadMsg->sHeader.iInstance ) - 1 ] );
                psWriteMsg->sHeader.bDataSize = strlen( apbADINames[ iLeTOi( psReadMsg->sHeader.iInstance ) - 1 ] );
    
                break;
    
             case ABP_APPD_IA_DATA_TYPE: /* Data type */
    
                /*
                ** In this simple application, all the application data instances
                ** are of the same type
                */
    
                psWriteMsg->abData[ 0 ] = ABP_UINT16;
                psWriteMsg->sHeader.bDataSize = ABP_APPD_IA_DATA_TYPE_DS;
    
                break;
    
             case ABP_APPD_IA_NUM_ELEM: /* Number of elements */
    
                /*
                ** There are no arrays in this simple application, so the number
                ** of elements is 1 for all application data instances
                */
    
                psWriteMsg->abData[ 0 ] = 1;
                psWriteMsg->sHeader.bDataSize = ABP_APPD_IA_NUM_ELEM_DS;
    
                break;
    
             case ABP_APPD_IA_DESCRIPTOR: /* Descriptor */
    
                /*
                ** All application data instances have full access rights in
                ** this simple application
                */
    
                psWriteMsg->abData[ 0 ] = ABP_APPD_DESCR_GET_ACCESS | ABP_APPD_DESCR_SET_ACCESS;
                psWriteMsg->sHeader.bDataSize = ABP_APPD_IA_DESCRIPTOR_DS;
    
                break;
    
             case ABP_APPD_IA_VALUE: /* Value */
    
                /*
                ** A request to read the application data instance value
                ** The data format of ADI values is network specific.
                ** Convert our native data format accordingly.
                */
    
                if( eNetFormat == NET_BIGENDIAN )
                {
                   *(UINT16*)&psWriteMsg->abData[ 0 ] = iTOiBe( aiApplicationData[ iLeTOi( psReadMsg->sHeader.iInstance ) - 1 ] );
                }
                else /* NET_LITTLEENDIAN */
                {
                   *(UINT16*)&psWriteMsg->abData[ 0 ] = iTOiLe( aiApplicationData[ iLeTOi( psReadMsg->sHeader.iInstance ) - 1 ] );
                }
    
                psWriteMsg->sHeader.bDataSize = ABP_UINT16_SIZEOF;
    
                break;
    
             default: /* Unsupported attribute */
    
                SetMsgError( psWriteMsg, 1, ABP_ERR_INV_CMD_EXT_0 );
    
                break;
    
             } /* end switch( attribute ) */
    
             break;
    
          case ABP_CMD_SET_ATTR:
    
             switch( psReadMsg->sHeader.bCmdExt0 )
             {
             case 1: /* Instance name */
             case 2: /* Data type */
             case 3: /* Number of elements */
             case 4: /* Descriptor */
    
                SetMsgError( psWriteMsg, 1, ABP_ERR_ATTR_NOT_SETABLE );
    
                break;
    
             case 5: /* Value */
    
                if( psReadMsg->sHeader.bDataSize > ABP_UINT16_SIZEOF )
                {
                   SetMsgError( psWriteMsg, 1, ABP_ERR_TOO_MUCH_DATA );
                }
                else if( psReadMsg->sHeader.bDataSize < ABP_UINT16_SIZEOF )
                {
                   SetMsgError( psWriteMsg, 1, ABP_ERR_NOT_ENOUGH_DATA );
                }
                else
                {
                   /*
                   ** Write the parameter value.
                   ** The data format of ADI values is network specific.
                   ** Convert it to our native data format.
                   */
    
                   if( eNetFormat == NET_BIGENDIAN )
                   {
                      aiApplicationData[ iLeTOi( psReadMsg->sHeader.iInstance ) - 1 ] = iBeTOi( *(UINT16*)&psReadMsg->abData[ 0 ] );
                   }
                   else /* NET_LITTLEENDIAN */
                   {
                      aiApplicationData[ iLeTOi( psReadMsg->sHeader.iInstance ) - 1 ] = iLeTOi( *(UINT16*)&psReadMsg->abData[ 0 ] );
                   }
                }
    
                break;
    
             default: /* Unsupported attribute */
    
                SetMsgError( psWriteMsg, 1, ABP_ERR_INV_CMD_EXT_0 );
    
                break;
    
             } /* end switch( attribute ) */
    
             break;
    
          default:
    
             SetMsgError( psWriteMsg, 1, ABP_ERR_UNSUP_CMD );
    
             break;
    
          } /* end switch( command ) */
    
          break;
    
       default:
    
          SetMsgError( psWriteMsg, 1, ABP_ERR_UNSUP_INST );
    
          break;
    
       } /* end switch( instance ) */
    
    } /* end of ApplicationDataObject() */
    
    /*******************************************************************************
    **
    ** End 
    **
    ********************************************************************************
    */
    


  • Was soll das hier eigentlich machen?

    #define WriteParallel(func,adr,val)
    
    WriteParallel(func,0x3800,0x11);
    


  • Badestrand schrieb:

    Was soll das hier eigentlich machen?

    #define WriteParallel(func,adr,val)
    
    WriteParallel(func,0x3800,0x11);
    

    Im vollständigen Programm gibt es auch einen WriteParallel-Befehl (hervorgehoben),indem Parameter des Pointers,Adresse und Wert übergeben werden.
    Hätte es auch gerne so gemacht,jedoch findet mein Schreiben durch Aufrufen einer Funktion (wrlmode-function) statt.
    Problem liegt daran,dass ich einen Makro,und das Programm eine feste Adresse als BASE_ADDRESS verwendet... 😞



  • Hat keiner einen Tip für mich...? Vielleicht lässt es sich ja auch anders lösen...Würde mich freuen,wenn ihr mal drüberschaut...Danke... 😕



  • Bin zwar kein C-Pro wie fricky, kann mich aber dennoch des Eindrucks nicht erwehren, dass du nicht mal selbst weisst, was du eigentlich umsetzen willst, wenn du zB. immer noch von irgendwelchen Adressen von Macros erzaehlst und sowas hier "#define WriteParallel(func,adr,val)" fabrizierst, ohne es erklaeren zu koennen.
    In diesem Fall kann dir natuerlich auch niemand helfen.

    Also mein Vorschlag: Geh nochmal in dich und denke erstmal scharf darueber nach, was du eigentlich vor hast. Dann formuliere nochmal eine genaue Fragestellung, bei der du wirklich genau weisst, wovon du ueberhaupt sprichst. Also evtl. weniger Speziell als bisher und bitte auch keine 500 Zeilen spaerlich kommentierten Code zur Erklaerung. Die liest sich eh niemand durch, um hinterher so schlau zu sein wie vorher.



  • Nobuo T schrieb:

    ...C-Pro wie fricky

    danke für die lorbeeren. bin glatt rot geworden.
    🙂


Anmelden zum Antworten