Post Go back to editing

How to multiplex the GPIO pins of the ADSP-BF706?

There are two bits to select one of four possible connections for each GPIO pin.

How to control those two bits?

Parents
  • If it helps, Here is a function I wrote to provide the control I needed for GPIO or Peripherals connecting to the physical pin.

    #define FOS_PORT_A_FER_REGISTER              0x20040000

    #define FOS_PORT_A_MUX_REGISTER              0x20040030

    #define FOS_PORT_B_FER_REGISTER              0x20040080

    #define FOS_PORT_B_MUX_REGISTER              0x200400B0

    #define FOS_PORT_C_FER_REGISTER              0x20040100

    #define FOS_PORT_C_MUX_REGISTER              0x20040130

    /*******************************************************************************
     *
     *  Function:       fosGpioPinControl
     *
     *  Inputs:         int gpio                 The Pin number to setup  0-47
     *                  int forceAsPeripheral    Flag that indicates GPIO or Peripheral  0 or 1
     *                  u32 peripheralMux        The mux value of the peripherail. 0,1,2 or 3
     *
     *  Outputs:        -1 for error, otherwise 0
     *
     *  Description:    This function will setup the pin to work as a GPIO or as
     *                  a peripheral.  If it is a peripheral, it will set the correct
     *                  mux value to get the correct peripheral out to the pin.
     *                  Pin number 0-15 portA 0:15, 16-31 portB 0:15, 32-47 portC 0:15
     *
     *  Cautions:       None
     *
     ******************************************************************************/
    int fosGpioPinControl(int gpio, int forceAsPeripheral, u32 peripheralMux)
    {
       u32              gpioMask;
       u32              gpioMuxMask;
       volatile u32*    gpioFerRegister;
       volatile u32*    gpioMuxRegister;
       u32              data;
       
       /* There is not any looping going on.  The while loop allows for
        * a convenient way to find the condition and then exit out.
        */
       do
       {
          if (gpio < 16)
          {  /* Port F is 0 to 15 */
             gpioFerRegister = (volatile u32*) FOS_PORT_A_FER_REGISTER;
             gpioMuxRegister = (volatile u32*) FOS_PORT_A_MUX_REGISTER;
             break;
          }
          if (gpio < 32)
          {/* Port G is 16 to 31 */
             gpioFerRegister = (volatile u32*) FOS_PORT_B_FER_REGISTER;
             gpioMuxRegister = (volatile u32*) FOS_PORT_B_MUX_REGISTER;
             gpio -= 16;
             break;
          }
          if (gpio < 48)
          {/* Port H is 32 to 47 */
             gpioFerRegister = (volatile u32*) FOS_PORT_C_FER_REGISTER;
             gpioMuxRegister = (volatile u32*) FOS_PORT_C_MUX_REGISTER;
             gpio -= 32;
             break;
          }
          return -1; /* The gpio value is out of range */
       } while(1); /* End fake while loop */
       
       gpioMask = (0x1 << gpio);
       gpioMuxMask = (0x3 << (gpio * 2));
       peripheralMux &= 0x3;  /* limit the mask to 2 bits */
       peripheralMux = (peripheralMux << (gpio * 2));
       
       if (forceAsPeripheral == 1)
       {
          /* Connect the peripherial to the external pin */
          data = *gpioFerRegister;
          data |= gpioMask;
          *gpioFerRegister =  data;
          asm("ssync;");
          
          /* Calculate and set the requested mux level */
          data = *gpioMuxRegister;
          /* Clear out old mux bits first */
          data &= ~(gpioMuxMask);
          /* Set GPIO pins for the requested mux function */
          data |= peripheralMux;
          *gpioMuxRegister =  data;
          asm("ssync;");
       }
       else
       {
          /* Connect the GPIO functionality to the external pin */
          data = *gpioFerRegister;
          data &= ~(gpioMask);
          *gpioFerRegister =  data;
          asm("ssync;");
       }
       return 0;
    }

Reply
  • If it helps, Here is a function I wrote to provide the control I needed for GPIO or Peripherals connecting to the physical pin.

    #define FOS_PORT_A_FER_REGISTER              0x20040000

    #define FOS_PORT_A_MUX_REGISTER              0x20040030

    #define FOS_PORT_B_FER_REGISTER              0x20040080

    #define FOS_PORT_B_MUX_REGISTER              0x200400B0

    #define FOS_PORT_C_FER_REGISTER              0x20040100

    #define FOS_PORT_C_MUX_REGISTER              0x20040130

    /*******************************************************************************
     *
     *  Function:       fosGpioPinControl
     *
     *  Inputs:         int gpio                 The Pin number to setup  0-47
     *                  int forceAsPeripheral    Flag that indicates GPIO or Peripheral  0 or 1
     *                  u32 peripheralMux        The mux value of the peripherail. 0,1,2 or 3
     *
     *  Outputs:        -1 for error, otherwise 0
     *
     *  Description:    This function will setup the pin to work as a GPIO or as
     *                  a peripheral.  If it is a peripheral, it will set the correct
     *                  mux value to get the correct peripheral out to the pin.
     *                  Pin number 0-15 portA 0:15, 16-31 portB 0:15, 32-47 portC 0:15
     *
     *  Cautions:       None
     *
     ******************************************************************************/
    int fosGpioPinControl(int gpio, int forceAsPeripheral, u32 peripheralMux)
    {
       u32              gpioMask;
       u32              gpioMuxMask;
       volatile u32*    gpioFerRegister;
       volatile u32*    gpioMuxRegister;
       u32              data;
       
       /* There is not any looping going on.  The while loop allows for
        * a convenient way to find the condition and then exit out.
        */
       do
       {
          if (gpio < 16)
          {  /* Port F is 0 to 15 */
             gpioFerRegister = (volatile u32*) FOS_PORT_A_FER_REGISTER;
             gpioMuxRegister = (volatile u32*) FOS_PORT_A_MUX_REGISTER;
             break;
          }
          if (gpio < 32)
          {/* Port G is 16 to 31 */
             gpioFerRegister = (volatile u32*) FOS_PORT_B_FER_REGISTER;
             gpioMuxRegister = (volatile u32*) FOS_PORT_B_MUX_REGISTER;
             gpio -= 16;
             break;
          }
          if (gpio < 48)
          {/* Port H is 32 to 47 */
             gpioFerRegister = (volatile u32*) FOS_PORT_C_FER_REGISTER;
             gpioMuxRegister = (volatile u32*) FOS_PORT_C_MUX_REGISTER;
             gpio -= 32;
             break;
          }
          return -1; /* The gpio value is out of range */
       } while(1); /* End fake while loop */
       
       gpioMask = (0x1 << gpio);
       gpioMuxMask = (0x3 << (gpio * 2));
       peripheralMux &= 0x3;  /* limit the mask to 2 bits */
       peripheralMux = (peripheralMux << (gpio * 2));
       
       if (forceAsPeripheral == 1)
       {
          /* Connect the peripherial to the external pin */
          data = *gpioFerRegister;
          data |= gpioMask;
          *gpioFerRegister =  data;
          asm("ssync;");
          
          /* Calculate and set the requested mux level */
          data = *gpioMuxRegister;
          /* Clear out old mux bits first */
          data &= ~(gpioMuxMask);
          /* Set GPIO pins for the requested mux function */
          data |= peripheralMux;
          *gpioMuxRegister =  data;
          asm("ssync;");
       }
       else
       {
          /* Connect the GPIO functionality to the external pin */
          data = *gpioFerRegister;
          data &= ~(gpioMask);
          *gpioFerRegister =  data;
          asm("ssync;");
       }
       return 0;
    }

Children
No Data