This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Ecan GPIO switching

I am having some issues when I am trying to switch the pins on the GPIO pins being used for CAN on the DSP.  When the program boots up it we default for Can A to be pins 18/19.  But when I give it the command to switch pins for Ecan it does not work.  I want to know if I am missing something in the process of switching the GPIO pins.  Any help would be greatly appreciated.  Let me know If you need to see more of the code but below is the section I use to select the GPIO pins.    

CanAValue can be 0 or 1.

void InitECanaGpio(Uint16 CanAValue)
{

EALLOW;

switch (CanAValue){

case 0:
//default setting
/* Enable internal pull-up for the selected CAN pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.


GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up for GPIO18 (CANRXA)
GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; // Enable pull-up for GPIO19 (CANTXA)

/* Set qualification for selected CAN pins to asynch only */
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.

GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch qual for GPIO18 (CANRXA)


/* Configure eCAN-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAN functional pins.

GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // Configure GPIO18 for CANRXA operation
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 3; // Configure GPIO19 for CANTXA operation
GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; //Configure CANTXA as output


break;

case 1:

/* Enable internal pull-up for the selected CAN pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0; // Enable pull-up for GPIO30 (CANRXA)
GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0; // Enable pull-up for GPIO31 (CANTXA)


/* Set qualification for selected CAN pins to asynch only */
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.

GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3; // Asynch qual for GPIO30 (CANRXA)

/* Configure eCAN-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAN functional pins.

GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1; // Configure GPIO30 for CANRXA operation
GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1; // Configure GPIO31 for CANTXA operation
GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; //Configure CANTXA as output


break;
}


EDIS;
}

  • David,

    My guess would be that after you have setup the eCAN to work with one set of pins, you do not turn off those pins before switching to the other set.  I would recommend before changing the gpio mux to point to the eCAN, change the pins back to normal GPIOs.

    Let me know if that fixes it.

    Regards,

    Trey

  • How should I go about doing that?

  • Replace this:

    case 0:
    //default setting
    /* Enable internal pull-up for the selected CAN pins */
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.


    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up for GPIO18 (CANRXA)
    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; // Enable pull-up for GPIO19 (CANTXA)

    /* Set qualification for selected CAN pins to asynch only */
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch qual for GPIO18 (CANRXA)


    /* Configure eCAN-A pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // Configure GPIO18 for CANRXA operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 3; // Configure GPIO19 for CANTXA operation
    GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; //Configure CANTXA as output


    break;

    case 1:

    /* Enable internal pull-up for the selected CAN pins */
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0; // Enable pull-up for GPIO30 (CANRXA)
    GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0; // Enable pull-up for GPIO31 (CANTXA)


    /* Set qualification for selected CAN pins to asynch only */
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3; // Asynch qual for GPIO30 (CANRXA)

    /* Configure eCAN-A pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1; // Configure GPIO30 for CANRXA operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1; // Configure GPIO31 for CANTXA operation
    GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; //Configure CANTXA as output


    break;

    With this:

    case 0:
    //default setting
    /* Enable internal pull-up for the selected CAN pins */
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.


    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up for GPIO18 (CANRXA)
    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; // Enable pull-up for GPIO19 (CANTXA)

    /* Set qualification for selected CAN pins to asynch only */
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch qual for GPIO18 (CANRXA)


    /* Configure eCAN-A pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    // Turn off other CAN pins
     GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 0; // Configure GPIO30 for GPIO operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0; // Configure GPIO31 for GPIOoperation


    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // Configure GPIO18 for CANRXA operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 3; // Configure GPIO19 for CANTXA operation
    //GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; //Configure CANTXA as output
    // Setting the direction of pins under peripheral control is un-neccessary


    break;

    case 1:

    /* Enable internal pull-up for the selected CAN pins */
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0; // Enable pull-up for GPIO30 (CANRXA)
    GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0; // Enable pull-up for GPIO31 (CANTXA)


    /* Set qualification for selected CAN pins to asynch only */
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3; // Asynch qual for GPIO30 (CANRXA)

    /* Configure eCAN-A pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    // Turn off other CAN pins
     GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0; // Configure GPIO18 for GPIO operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0; // Configure GPIO19 for GPIO operation


    GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1; // Configure GPIO30 for CANRXA operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1; // Configure GPIO31 for CANTXA operation
    //GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; //Configure CANTXA as output


    break;

    Regards,
    Trey
  • I think both of you forgot that the GPxMUX - registers are EALLOW - protected.

  • I thought Eallow allowed you access and edis closed the access.

  • That is correct.  If you called EALLOW before this code without calling EDIS, you should be ok.  In practice though, you should always call EALLOW right before you are accessing a protected register and call EDIS right afterward.  This is to protect your system in the case the processor "goes into the weeds" so to speak.  Imagine if your device was driving some power electronics connected to 3 phase mains and the GPIOs controlling the gate drive got messed up....

    Trey

  • The GPIO ports are still not switching correctly.  

    I have another function for can B which will be show below which is pretty much identical to Can A but with different GPIO.  When Can B is switched from 16/17 to 08/10.  The pin on GPIO 8 drops low but the data is still comming out 16.

    This is what happens on GPIO 08

    This is what happens on GPIO 16(correct but wrong pin)

    void InitECanbGpio(Uint16 CanBValue)
    {
    EALLOW;
    switch (CanBValue){

    case 0:



    //default
    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; // Enable pull-up for GPIO16 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; // Enable pull-up for GPIO17 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch qual for GPIO17 (CANRXB)

    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // Configure GPIO10 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // Configure GPIO13 for CANRXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // Configure GPIO21 for CANRXB operation

    // Configure eCAN-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2; // Configure GPIO17 for CANRXB operation
    //GpioCtrlRegs.GPADIR.bit.GPIO16 = 1; //Configure CANTXB as output


    break;

    case 1:

    GpioCtrlRegs.GPAPUD.bit.GPIO8 = 0; // Enable pull-up for GPIO08 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0; // Enable pull-up for GPIO10 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL1.bit.GPIO10 = 3; // Asynch qual for GPIO10 (CANRXB)

    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // Configure GPIO17 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // Configure GPIO13 for CANRXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // Configure GPIO21 for CANRXB operation

    // Configure eCAN-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 2; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 2; // Configure GPIO10 for CANRXB operation
    //GpioCtrlRegs.GPADIR.bit.GPIO8 = 1; //Configure CANTXB as output


    break;

    case 2:

    GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0; // Enable pull-up for GPIO12 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0; // Enable pull-up for GPIO13 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3; // Asynch qual for GPIO13 (CANRXB)

    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // Configure GPIO17 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // Configure GPIO10 for CANRXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // Configure GPIO21 for CANRXB operation

    // Configure eCAN-B pins using GPIO regs
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 2; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 2; // Configure GPIO13 for CANRXB operation
    //GpioCtrlRegs.GPADIR.bit.GPIO12 = 1; //Configure CANTXB as output



    break;


    case 3:

    GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0; // Enable pull-up for GPIO20 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0; // Enable pull-up for GPIO21 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 3; // Asynch qual for GPIO21 (CANRXB)

    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // Configure GPIO17 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // Configure GPIO10 for CANRXB operatio
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // Configure GPIO13 for CANRXB operationn

    // Configure eCAN-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2; // Configure GPIO21 for CANRXB operation
    //GpioCtrlRegs.GPADIR.bit.GPIO20 = 1; //Configure CANTXB as output


    break;
    }



    EDIS;
    }
  • David,

    The above code looks good, but I have to wonder how the CAN peripheral is interpretting this GPIO switch.  When we switch the GPIO mux, we have no idea what state the internal nets are that connect to the CAN controller.  I think we should also take the CAN controller off the bus before we change the GPIOs associated with the CAN peripheral.  Try setting the CCR bit before you change the GPIO mux configuration, and then clear the bit after you have the GPIO mux how you want it.

    Let me know how this works for you.

    Regards,

    Trey

  • The CCR is set  then unset in the CAnshadow function.  Could the error we occuring in the function nused to transmit the command :

    [TX] - TMS CANB-SEND;ID=00h;Data=012345h<CR><LF>

    	else if(strcmp(mode,"-SEND")==0){
    InitECanbGpio(CanB_Value);
    ptr = strtok (0,";");
    ptr += 3;
    for(i=0;i<4;i++)
    ph[i] = *ptr++;
    c = sscanf(ph,"%x",&ID); //write address

    ptr = strtok (0,";");
    ptr += 5;
    i = 0;
    ph[2] = 0;
    while(c != 0){
    ph[0] = *ptr++;
    ph[1] = *ptr++;
    c = sscanf(ph,"%x",&Data[i]); //write address
    ++i;
    }
    data_length = i-1;
    //set message ID
    ECanbMboxes.MBOX0.MSGID.all = 0;
    ECanbMboxes.MBOX0.MSGID.bit.STDMSGID = ID;
    //configure Mailbox0 as transmit
    ECanbShadow.CANMD.all = ECanbRegs.CANMD.all;
    ECanbShadow.CANMD.bit.MD0 = 0;
    ECanbRegs.CANMD.all = ECanbShadow.CANMD.all;
    // Enable Mailbox0
    ECanbShadow.CANME.all = ECanbRegs.CANME.all;
    ECanbShadow.CANME.bit.ME0 = 1;
    ECanbRegs.CANME.all = ECanbShadow.CANME.all;

    if(data_length<=8){
    ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = data_length;
    }
    else{
    SciaTx(String_err);
    SciaTx(": Too many Bytes");
    return;
    }

    ECanbMboxes.MBOX0.MDH.all = 0;
    ECanbMboxes.MBOX0.MDL.all = 0;
    switch (data_length){
    case 8:
    ECanbMboxes.MBOX0.MDH.byte.BYTE7 = Data[7];
    case 7:
    ECanbMboxes.MBOX0.MDH.byte.BYTE6 = Data[6];
    case 6:
    ECanbMboxes.MBOX0.MDH.byte.BYTE5 = Data[5];
    case 5:
    ECanbMboxes.MBOX0.MDH.byte.BYTE4 = Data[4];
    case 4:
    ECanbMboxes.MBOX0.MDL.byte.BYTE3 = Data[3];
    case 3:
    ECanbMboxes.MBOX0.MDL.byte.BYTE2 = Data[2];
    case 2:
    ECanbMboxes.MBOX0.MDL.byte.BYTE1 = Data[1];
    case 1:
    ECanbMboxes.MBOX0.MDL.byte.BYTE0 = Data[0];
    }

    ECanbShadow.CANTRS.all = 0;
    ECanbShadow.CANTRS.bit.TRS0 = 1; // Set TRS for mailbox 0
    ECanbRegs.CANTRS.all = ECanbShadow.CANTRS.all;
    Msg_Flags.bit.Timeout = 0;
    CpuTimer0Regs.TCR.bit.TSS = 0; //start Timer0 to catch runaway while loop
    do{
    ECanbShadow.CANTA.all = ECanbRegs.CANTA.all;
    if(Msg_Flags.bit.Timeout == 1){
    SciaTx(String_err);
    SciaTx(": Timeout");
    return;
    }
    } while(ECanbShadow.CANTA.bit.TA0 == 0 ); // Wait for TA5 bit to be set..
    CpuTimer0Regs.TCR.bit.TSS = 0; //stop Timer0 since while successful
    CpuTimer0Regs.TCR.bit.TRB = 1; //reload Timer0
    ECanbShadow.CANTA.all = 0;
    ECanbShadow.CANTA.bit.TA0 = 1; // Clear TA5
    ECanbRegs.CANTA.all = ECanbShadow.CANTA.all;

    //set ID in response message
    String_CAN_ID[7]=command[17];
    String_CAN_ID[8]=command[18];
    //send ID Response
    SciaTx(String_CAN_ID);
    SciaTx(String_crlf);
    SciaTxByte(data_length);

    }

  • David,

    You should only need to set the CCR bit when you are changing the bit rate or when you want to go bus off.  I don't see in the above code that you posted where CCR is set.  Give my suggestion a shot and let me know if it works.


    Trey

  • This didn't work either.  I really am stuck.  Even though the line appears to swtich, nothing comes out on the new line.  it only comes out on the old line we are trying to switch from

  • David,

    That is really wierd.  We must be missing something.

    Can you check that the writes to the MUX registers are actually writing?  Once you set the bits to 0 you shouldn't see anything come out of the old pin.

    Trey

  • you can see right here i close all the mux ports first.  And the when the line is activated the line drops low.

    switch (CanBValue){

    case 0:
    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // Configure GPIO10 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // Configure GPIO13 for CANRXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // Configure GPIO21 for CANRXB operation

    //default
    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; // Enable pull-up for GPIO16 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; // Enable pull-up for GPIO17 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch qual for GPIO17 (CANRXB)


    // Configure eCAN-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2; // Configure GPIO17 for CANRXB operation
    //GpioCtrlRegs.GPADIR.bit.GPIO16 = 1; //Configure CANTXB as output


    break;

    case 1:

    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // Configure GPIO17 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // Configure GPIO13 for CANRXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // Configure GPIO21 for CANRXB operation

    GpioCtrlRegs.GPAPUD.bit.GPIO8 = 0; // Enable pull-up for GPIO08 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0; // Enable pull-up for GPIO10 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL1.bit.GPIO10 = 3; // Asynch qual for GPIO10 (CANRXB)


    // Configure eCAN-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 2; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 2; // Configure GPIO10 for CANRXB operation
    //GpioCtrlRegs.GPADIR.bit.GPIO8 = 1; //Configure CANTXB as output


    break;

  • I know in your code you close them, but there could be something else at play here.  Please check in the memory  or registers window that the bits are being set as programmed in your code.  There is no reason the old pins should still spit out data after they have been turned off.

    Trey

  • After using the watch window I could see the bits switching but the program still doesn't work.  What is the next thing to check.

    bit {...} bit {...} bit {...}
    GPIO0 0 GPIO0 0 GPIO0 0
    GPIO1 0 GPIO1 0 GPIO1 0
    GPIO2 0 GPIO2 0 GPIO2 0
    GPIO3 0 GPIO3 0 GPIO3 0
    GPIO4 0 GPIO4 0 GPIO4 0
    GPIO5 0 GPIO5 0 GPIO5 0
    GPIO6 0 GPIO6 0 GPIO6 0
    GPIO7 0 GPIO7 0 GPIO7 0
    GPIO8 0 GPIO8 10 GPIO8 0
    GPIO9 0 GPIO9 0 GPIO9 0
    GPIO10 0 GPIO10 10 GPIO10 0
    GPIO11 0 GPIO11 0 GPIO11 0
    GPIO12 0 GPIO12 0 GPIO12 0
    GPIO13 0 GPIO13 0 GPIO13 0
    GPIO14 0 GPIO14 0 GPIO14 0
    GPIO15 0 GPIO15 0 GPIO15 0
    GPAMUX2 {...} GPAMUX2 {...} GPAMUX2 {...}
    all 4278190080 all 83886080 all 83886090
    bit {...} bit {...} bit {...}
    GPIO16 0 GPIO16 0 GPIO16 10
    GPIO17 0 GPIO17 0 GPIO17 10
    GPIO18 0 GPIO18 0 GPIO18 0
    GPIO19 0 GPIO19 0 GPIO19 0
    GPIO20 0 GPIO20 0 GPIO20 0
    GPIO21 0 GPIO21 0 GPIO21 0
    GPIO22 0 GPIO22 0 GPIO22 0
    GPIO23 0 GPIO23 0 GPIO23 0
    GPIO24 0 GPIO24 0 GPIO24 0
    GPIO25 0 GPIO25 0 GPIO25 0
    GPIO26 0 GPIO26 0 GPIO26 0
    GPIO27 0 GPIO27 0 GPIO27 0
    GPIO28 11 GPIO28 1 GPIO28 1
    GPIO29 11 GPIO29 1 GPIO29 1
    GPIO30 11 GPIO30 0 GPIO30 0
    GPIO31 11 GPIO31 0 GPIO31 0

  • David,

    Are you in fact taking the CAN peripheral off bus before you switch the GPIO it is trying to use?  If not try setting the CCR bit and waiting until CCE is asserted before changing the GPIO.  Then clear CCR once the GPIO switch is complete.

    If you're already doing this, then I'm running out of ideas.  Would you mind posting your project, or a testcase which shows this failing condition?

    Trey

  • How exactly do I take the CAN peripheral off the bus.  I don't believe  the CCR is touched in this part of the code.  It is only mentioned in shadow function.  

  • Exactly how I stated in the previous post.  Write a 1 to teh CCR bit in the control register and poll on the CCE bit in the status register.  Once CCE is set, do your GPIO switch.  After you switch the GPIOs clear the CCR bit and resume CAN operations.

    Trey

  • I still can't get it to work.  Am I enabling the CCR correctly:

    void InitECanbGpio(Uint16 CanBValue)
    {
    struct ECAN_REGS ECanbShadow;
    EALLOW;

    ECanbShadow.CANMC.bit.CCR = 1 ; // Set CCR = 1

    switch (CanBValue){

    case 0:
    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // Configure GPIO10 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // Configure GPIO13 for CANRXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // Configure GPIO21 for CANRXB operation

    //default
    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; // Enable pull-up for GPIO16 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; // Enable pull-up for GPIO17 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch qual for GPIO17 (CANRXB)


    // Configure eCAN-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2; // Configure GPIO17 for CANRXB operation
    GpioCtrlRegs.GPADIR.bit.GPIO16 = 1; //Configure CANTXB as output


    break;

    case 1:

    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // Configure GPIO17 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // Configure GPIO13 for CANRXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // Configure GPIO21 for CANRXB operation

    GpioCtrlRegs.GPAPUD.bit.GPIO8 = 0; // Enable pull-up for GPIO08 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0; // Enable pull-up for GPIO10 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL1.bit.GPIO10 = 3; // Asynch qual for GPIO10 (CANRXB)


    // Configure eCAN-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 2; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 2; // Configure GPIO10 for CANRXB operation
    GpioCtrlRegs.GPADIR.bit.GPIO8 = 1; //Configure CANTXB as output


    break;

    case 2:

    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // Configure GPIO17 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // Configure GPIO10 for CANRXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // Configure GPIO21 for CANRXB operation

    GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0; // Enable pull-up for GPIO12 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0; // Enable pull-up for GPIO13 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3; // Asynch qual for GPIO13 (CANRXB)


    // Configure eCAN-B pins using GPIO regs
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 2; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 2; // Configure GPIO13 for CANRXB operation
    GpioCtrlRegs.GPADIR.bit.GPIO12 = 1; //Configure CANTXB as output


    break;


    case 3:

    // Turn off other CAN pins
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // Configure GPIO16 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // Configure GPIO17 for CANRXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; // Configure GPIO08 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // Configure GPIO10 for CANRXB operatio
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // Configure GPIO12 for CANTXB operation
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // Configure GPIO13 for CANRXB operationn

    GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0; // Enable pull-up for GPIO20 (CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0; // Enable pull-up for GPIO21 (CANRXB)

    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 3; // Asynch qual for GPIO21 (CANRXB)


    // Configure eCAN-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2; // Configure GPIO20 for CANTXB operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2; // Configure GPIO21 for CANRXB operation
    GpioCtrlRegs.GPADIR.bit.GPIO20 = 1; //Configure CANTXB as output


    break;
    }

    ECanbShadow.CANMC.bit.CCR = 0 ; // Set CCR = 0
    EDIS;
    }
    #endif // if DSP28_ECANB

  • No you are not. The shadow registers exist such that you can do bitwise operations on them and then copy them to the active registers.  This prevents a read-modify-write operation which can cause problems with registers that change state when they are read or written.

    Set or clear the CCR bit in the active registers.

    Trey

  • Trey,

    Can you please be more specific.  I do not know how to set or clear the CCr bit in the active register.  What do i need to reference?

  • David,

    The shadow registers are just a chunk of RAM which is linked to be an exact replica of the ECan register structure.  They are not real register, just RAM locations.  Writing to them alone will do nothing to the CAN module.

    I assume you are using a 2834x device?  If you look in common/source a the ECan.c file you'll see in the InitECana function where it makes a copy of the actual register into the shadow register, modifies a bit in the  shadowed copy and then writes it back to the active register.  You'll want to do something similar to this to set and clear the CCR bit.  When you poll on the CCE bit in the status register you'll need to make sure you are looking at the actual register, NOT the shadow register.

    Does that help?

    Trey

  • That helps but I have no idea how to do any of that.  I am also using the F28335?  I see the area you were talking about but i don't know what exactly i'm looking for.  

    void InitECana(void) // Initialize eCAN-A module
    {
    /* Create a shadow register structure for the CAN control registers. This is
    needed, since only 32-bit access is allowed to these registers. 16-bit access
    to these registers could potentially corrupt the register contents or return
    false data. This is especially true while writing to/reading from a bit
    (or group of bits) among bits 16 - 31 */

    struct ECAN_REGS ECanaShadow;

    EALLOW; // EALLOW enables access to protected bits

    /* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/

    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

    /* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */
    // HECC mode also enables time-stamping feature

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.SCB = 1;
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    /* Initialize all bits of 'Master Control Field' to zero */
    // Some bits of MSGCTRL register come up in an unknown state. For proper operation,
    // all bits (including reserved bits) of MSGCTRL must be initialized to zero

    ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;

    // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
    // as a matter of precaution.

    ECanaRegs.CANTA.all = 0xFFFFFFFF; /* Clear all TAn bits */

    ECanaRegs.CANRMP.all = 0xFFFFFFFF; /* Clear all RMPn bits */

    ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;


    /* Configure bit timing parameters for eCANA*/
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 1 ; // Set CCR = 1
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    ECanaShadow.CANES.all = ECanaRegs.CANES.all;

    do
    {
    ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 ); // Wait for CCE bit to be set..

    ECanaShadow.CANBTC.all = 0;

    #if (CPU_FRQ_150MHZ) // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h
    /* The following block for all 150 MHz SYSCLKOUT - default. Bit rate = 250kbps */
    //ECanaShadow.CANBTC.bit.BRPREG = 19; //250kbps
    ECanaShadow.CANBTC.bit.BRPREG = 4; //1Mbps, as requested for rev 11
    ECanaShadow.CANBTC.bit.TSEG2REG = 2;
    ECanaShadow.CANBTC.bit.TSEG1REG = 10;
    #endif
    #if (CPU_FRQ_100MHZ) // CPU_FRQ_100MHz is defined in DSP2833x_Examples.h
    /* The following block is only for 100 MHz SYSCLKOUT. Bit rate = 1 Mbps */
    ECanaShadow.CANBTC.bit.BRPREG = 9;
    ECanaShadow.CANBTC.bit.TSEG2REG = 1;
    ECanaShadow.CANBTC.bit.TSEG1REG = 6;
    #endif


    ECanaShadow.CANBTC.bit.SAM = 1;
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 0 ; // Set CCR = 0
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    ECanaShadow.CANES.all = ECanaRegs.CANES.all;

    do
    {
    ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 ); // Wait for CCE bit to be cleared..

    /* Disable all Mailboxes */
    ECanaRegs.CANME.all = 0; // Required before writing the MSGIDs

    EDIS;
    }

  • David,

    Ok, let me explain some more.  Look at this snippet of code:

    struct ECAN_REGS ECanaShadow;

    EALLOW; // EALLOW enables access to protected bits

    /* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/

    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    The first thing you'll notice is that we declare a struct of type ECAN_REGS and it is named ECanaShadow.  This is a struct which has the same layout as the ECAN registers, but it is sitting on the stack (since it was declared in a function) not on the actual peripheral memory. 

    Next thing to notice is the EALLOW which is required to write to protected registers.  I'm not sure exactly which registers are protected in the CAN controller, but the user guide should have this information.

    Finally, You see 3 lines that modify the CANTIOC register.  The first line makes a copy of the actual register value into the shadow register (which remember is just located in normal RAM). The second line modifies the TXFUNC bit in the copy of the register in RAM (the Shadow register).  The third line write the whole shadow register back into the actual peripheral register.

    Long story short, when you set the CCR bit don't do it like this:

    ECanbShadow.CANMC.bit.CCR = 1 ; // Set CCR = 1

    Do it like this:

    ECanbRegs.CANMC.bit.CCR = 1 ; // Set CCR = 1


    Trey

  • Trey and other readers,

    I know it has been sometime but I have kept at this problem.  I am able to get the GPIOS to switch!  YAY!  It turns out that they were switching all along but you have to do something odd first.  The code switches whether you set the CCR or not.  But for some reason the GPIOs do not switch right off the bat.  I have to send a command to the DSP to switch between the GPIOS I have defined first.  So I have to switch between 08/10, 12/13, 16/17, and 20/21.  Usually only one of these GPIOS is inhibiting the ports from switching.  Here's an example of how it is working right now.

    If I send the command to switch 8/10.  The line will not go high.  But if I call 12/13 and then 8/10 the line will switch.  Some my question is why do I have to initilize a random GPIO before I can switch?

  • David,

    That's really odd.  You should be able to switch without going to another pair of GPIOs first.  If you post a copy of your project (or a stripped down project), I'd be happy to take a look at it.

    Trey

  • Is there an easier way for me to just e-mail you the contents of the project?

  • Probably the easiest way is to just zip up the project and post it here to the forums.

  • I would feel more comfortable e-mailing this to you since I do not wish to post the entire project online for everyone to see.