- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Overview
The BCM2073x supports up to 40 GPIOs, the majority of GPIOs have multiple functions. About more information about GPIOs, please refer to the section” GPIO” in “WICED-Smart-Hardware-Interfaces.pdf” in SDK doc directory.
In WICED Smart SDK, some GPIOs can be configured to the predefined function, these GPIOs is initialized and controlled by ROM code. Besides these GPIOs, developers configure the other GPIOs for any purpose as they want. This document describes these two types of GPIO and APIs.
GPIO that Configured to Predefined Usage
Predefined Usage
The GPIOs that used for predefined usage are identified by ROM code to implement the corresponding action.
The following predefined usage is in bleprofile.h.
#define GPIO_WP 0x0010
#define GPIO_BAT 0x0020
#define GPIO_BUTTON 0x0100
#define GPIO_BUTTON1 0x0100
#define GPIO_BUTTON2 0x0200
#define GPIO_BUTTON3 0x0400
#define GPIO_LED 0x1000
#define GPIO_BUZ 0x2000
GPIO_WP is used for EEPROM write protection.
GPIO_BAT is used for battery ADC.
GPIO_BUTTONx is used for button. WICED Smart SDK max support 3 buttons.
GPIO_LED is used to control LED.
GPIO_BUZ is used to control buzzer.
Configure GPIOs to Predefined Usage
WICED Smart SDK provides the structure BLE_PROFILE_GPIO_CFG to configure these GPIOs and GPIO’s settings.
The following code is in platform.h, the GPIO PIN and GPIO setting is declared.
//GPIO-0 used for GPIO_BUTTON function, GPIO settings: input, initialization level is low, interrupt
#define GPIO_PIN_BUTTON 0
#define GPIO_SETTINGS_BUTTON (GPIO_INPUT | GPIO_INIT_LOW | GPIO_BUTTON | GPIO_INT)//GPIO-1 used for GPIO_WP function, GPIO settings: output, initialization level is low
#define GPIO_PIN_WP 1
#define GPIO_SETTINGS_WP (GPIO_OUTPUT | GPIO_INIT_LOW | GPIO_WP)//GPIO-14 used for GPIO_LED function, GPIO settings: output, initialization level is high
#define GPIO_PIN_LED 14
#define GPIO_SETTINGS_LED (GPIO_OUTPUT | GPIO_INIT_HIGH | GPIO_LED)//GPIO-15 used for GPIO_BAT function, GPIO settings: input, initialization level is low
#define GPIO_PIN_BATTERY 15
#define GPIO_SETTINGS_BATTERY (GPIO_INPUT | GPIO_INIT_LOW | GPIO_BAT)//GPIO-28 used for GPIO_BUZ function, GPIO settings: output, initialization level is low
#define GPIO_PIN_BUZZER 28
#define GPIO_SETTINGS_BUZZER (GPIO_OUTPUT | GPIO_INIT_LOW | GPIO_BUZ)
The following sample code if in hello_sensor.c,
the GPIO PIN number and GPIO setting is filled to structure BLE_PROFILE_GPIO_CFG.
const BLE_PROFILE_GPIO_CFG hello_sensor_gpio_cfg =
{
/*.gpio_pin =*/
{
GPIO_PIN_WP, // This need to be used to enable/disable NVRAM write protect
GPIO_PIN_BUTTON, // Button GPIO is configured to trigger either direction of interrupt
GPIO_PIN_LED, // LED GPIO, optional to provide visual effects
GPIO_PIN_BATTERY, // Battery monitoring GPIO.
GPIO_PIN_BUZZER, // Buzzer GPIO, optional to provide audio effects
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // other GPIOs are not used
},/*.gpio_settings =*/
{
GPIO_SETTINGS_WP,
GPIO_SETTINGS_BUTTON,
GPIO_SETTINGS_LED,
GPIO_SETTINGS_BATTERY,
GPIO_SETTINGS_BUZZER,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}
};
APIs
The following APIs for predefined GPIOs function is in bleprofile.h.
void bleprofile_GPIOInit(BLE_PROFILE_GPIO_CFG *p_gpio_cfg);
Initialize all GPIOs that configured to predefined usages, it should be called in application creation function.
The following code is hello_sensor.c.
void hello_sensor_create(void)
{
…
//initialize the GPIOs that used for predefined usages
bleprofile_GPIOInit(bleprofile_gpio_p_cfg);
…
}
void bleprofile_regIntCb(BLEPROFILE_SINGLE_PARAM_CB callback);
Register callback function for the interrupt of predefined GPIO, the GPIO usually is used for button.
The following sample code is in platform.h, the button GPIO is configured an interrupt PIN.
//GPIO-0 used for GPIO_BUTTON function, has interrupt
#define GPIO_PIN_BUTTON 0
#define GPIO_SETTINGS_BUTTON (GPIO_INPUT | GPIO_INIT_LOW | GPIO_BUTTON | GPIO_INT)
The following code is in hello_sensor.c.
// Following structure defines GPIO configuration used by the application
const BLE_PROFILE_GPIO_CFG hello_sensor_gpio_cfg =
{
/*.gpio_pin =*/
{
…
GPIO_PIN_BUTTON, // Button GPIO is configured to trigger either direction of interrupt
…
},
/*.gpio_flag =*/
{
…
GPIO_SETTINGS_BUTTON,
…
}
};void hello_sensor_create(void)
{
…
// register the callback function for button interrupt
bleprofile_regIntCb((BLEPROFILE_SINGLE_PARAM_CB) hello_sensor_interrupt_handler);
…
}//the callback function for button interrupt
void hello_sensor_interrupt_handler(UINT8 value)
{
BLEPROFILE_DB_PDU db_pdu;
ble_trace3("\r(INT)But1:%d But2:%d But3:%d", value&0x01, (value& 0x02) >> 1, (value & 0x04) >> 2);
…
}
GPIO that NOT Configured to Predefined Usages
The GPIOs that not configured to predefined usages can be configured and controlled by user application, these APIs that declared in gpiodriver.h.
APIs
voidm gpio_configurePin(BYTE port, BYTE pin, UINT16 config, BYTE outputVal);
void gpio_configurePinWithSingleBytePortPinNum(BYTE gpio, UINT16 config, BYTE outputVal);
UINT16 gpio_getPinConfig(BYTE port, BYTE pin);
Set/Get GPIO configuration by pin or port.
The “config” can set multiple GPIO features, such as input, output, interrupt trigger, pull up, pull down, driver strength etc. The following features are defined in gpiodriver.h.
enum
{
/// GPIO configuration bit 0, Interrupt type defines
GPIO_EDGE_TRIGGER_MASK = 0x0001,
GPIO_EDGE_TRIGGER = 0x0001,
GPIO_LEVEL_TRIGGER = 0x0000,/// GPIO configuration bit 1, Interrupt polarity defines
GPIO_TRIGGER_POLARITY_MASK = 0x0002,
GPIO_TRIGGER_NEG = 0x0002,/// GPIO configuration bit 2, single/dual edge defines
GPIO_DUAL_EDGE_TRIGGER_MASK = 0x0004,
GPIO_EDGE_TRIGGER_BOTH = 0x0004,
GPIO_EDGE_TRIGGER_SINGLE = 0x0000,/// GPIO configuration bit 3, interrupt enable/disable defines
GPIO_INTERRUPT_ENABLE_MASK = 0x0008,
GPIO_INTERRUPT_ENABLE = 0x0008,
GPIO_INTERRUPT_DISABLE = 0x0000,/// GPIO configuration bit 0:3, Summary of Interrupt enabling type
GPIO_EN_INT_MASK = GPIO_EDGE_TRIGGER_MASK | GPIO_TRIGGER_POLARITY_MASK | GPIO_DUAL_EDGE_TRIGGER_MASK | GPIO_INTERRUPT_ENABLE_MASK,
GPIO_EN_INT_LEVEL_HIGH = GPIO_INTERRUPT_ENABLE | GPIO_LEVEL_TRIGGER,
GPIO_EN_INT_LEVEL_LOW = GPIO_INTERRUPT_ENABLE | GPIO_LEVEL_TRIGGER | GPIO_TRIGGER_NEG,
GPIO_EN_INT_RISING_EDGE = GPIO_INTERRUPT_ENABLE | GPIO_EDGE_TRIGGER,
GPIO_EN_INT_FALLING_EDGE = GPIO_INTERRUPT_ENABLE | GPIO_EDGE_TRIGGER | GPIO_TRIGGER_NEG,
GPIO_EN_INT_BOTH_EDGE = GPIO_INTERRUPT_ENABLE | GPIO_EDGE_TRIGGER | GPIO_EDGE_TRIGGER_BOTH,/// GPIO configuration bit 4:5,and 14 output enable control and muxing control
GPIO_INPUT_ENABLE = 0x0000,
GPIO_OUTPUT_DISABLE = 0x0000,
GPIO_OUTPUT_ENABLE = 0x4000,
GPIO_KS_OUTPUT_ENABLE = 0x0010, //Keyscan Output enable
GPIO_OUTPUT_FN_SEL_MASK = 0x0030,
GPIO_OUTPUT_FN_SEL_SHIFT = 4,
/// GPIO configuration bit 6, "Global_input_disable" Disable bit
GPIO_GLOBAL_INPUT_ENABLE = 0x0000,
GPIO_GLOBAL_INPUT_DISABLE = 0x0040,/// GPIO configuration bit 9 and bit 10, pull- up and pull-down enable
GPIO_PULL_UP_DOWN_NONE = 0x0000, //[0,0]
GPIO_PULL_UP = 0x0400, //[1,0]
GPIO_PULL_DOWN = 0x0200, //[0,1]
GPIO_INPUT_DISABLE = 0x0600, //[1,1] //input disables the GPIO/// iocfg_p0[11] controls the drive strength of the following GPIOs p[0:25], p[30:39];
/// iocfg_p26[11] controls the drive strength of the GPIOs p[26:29]
GPIO_DRIVE_SEL_MASK = 0x0800,
GPIO_DRIVE_SEL_LOWEST = 0x0000, // 2mA @ 1.8V
GPIO_DRIVE_SEL_MIDDLE_0 = 0x0000, // 4mA @ 3.3v
GPIO_DRIVE_SEL_MIDDLE_1 = 0x0800, // 4mA @ 1.8v
GPIO_DRIVE_SEL_HIGHEST = 0x0800, // 8mA @ 3.3v/// iocfg_p0[13] controls the hysteresis of the following GPIOs p[0:25], p[30:39];
/// iocfg_p26[13] controls the hysteresis of the GPIOs p[26:29]
GPIO_HYSTERESIS_MASK = 0x2000,
GPIO_HYSTERESIS_ON = 0x2000,
GPIO_HYSTERESIS_OFF = 0x0000,
};
void gpio_setPinOutput(BYTE port, BYTE pin, BYTE val);
void gpio_setPortOutput(BYTE port, UINT16 val) ;
BYTE gpio_getPinOutput(BYTE port, BYTE pin);
UINT16 gpio_getPortOutput(BYTE port);
Set or Get GPIO output value by pin or port.
UINT16 gpio_getPortInput(BYTE port);
BYTE gpio_getPinInput(BYTE port, BYTE pin);
Get the GPIO input value by pin or port.
void gpio_registerForInterrupt(UINT16 masks[], void (*userfn)(void*, UINT8), void* userdata);
Register the callback function for GPIO interrupt.
BYTE gpio_getPinInterruptStatus(BYTE port, BYTE pin)
UINT16 gpio_getPortInterruptStatus(BYTE port);
Get GPIO interrupt status by pin or port, returns 1 if an interrupt is detected.
void gpio_clearPinInterruptStatus(BYTE port, BYTE pin);
void gpio_clearPortInterruptStatus(BYTE port, UINT16 mask);
Clear GPIO interrupt status by pin or port.
Sample Code
Input GPIO, no interrupt
#define TEST_PIN 28 // test PIN
#define TEST_PIN2 29 // test PIN 2
#define PORT_ TEST (TEST _PIN >> 4) // PORT number of test PIN
#define PIN_ TEST (TEST _PIN & 0x0f) // PIN number in PORT//configure the PIN28 to input, pull down
gpio_configurePin( PORT_ TEST , PIN_TEST, GPIO_INPUT_ENABLE | GPIO_PULL_DOWN, GPIO_PIN_OUTPUT_HIGH );//configure the PIN29 to input, pull up
gpio_configurePinWithSingleBytePortPinNum( GPIO_INPUT_ENABLE | GPIO_PULL_UP, GPIO_PIN_OUTPUT_HIGH );//get the value of input GPIO
value 1= gpio_getPinInput(PORT_ TEST , PORT_PIN);
value2 = gpio_getPinInput( TEST_PIN2 >>4, TEST_PIN2 &0x0f);
Input GPIO, have interrupt
The following sample code of GPIO interrupt is in i2c_temperature_sensor.c.
// The GPIO port number to which the ALERT pin is connected.
#define LM73_ALERT_INTERRUPT_PORT (0)// The GPIO pin number to which the ALERT pin is connected
#define LM73_ALERT_INTERRUPT_PIN (4)UINT8 temperature_sensor_initialize(void)
{
…
// Set up the interrupt mask for the GPIO interrupt
interrupt_handler_mask[LM73_ALERT_INTERRUPT_PORT] |= (1 << LM73_ALERT_INTERRUPT_PIN);// Now register the interrupt handler.
gpio_registerForInterrupt(interrupt_handler_mask, temperature_sensor_gpio_interrupt_handler, NULL);// Now configure the pin. We will use both edges so that we know when the upper and lower thresholds are crossed.
gpio_configurePin(LM73_ALERT_INTERRUPT_PORT, LM73_ALERT_INTERRUPT_PIN,
GPIO_EN_INT_BOTH_EDGE | GPIO_PULL_UP, GPIO_PIN_OUTPUT_LOW);
…
}//the callback function for GPIO interrupt
void temperature_sensor_gpio_interrupt_handler(void* parameter, UINT8 arg)
{
…
//clear the interrupt status
gpio_clearPinInterruptStatus(LM73_ALERT_INTERRUPT_PORT, LM73_ALERT_INTERRUPT_PIN);
…
}
About how to use one callback function to handle multi GPIO interrupts, please refer to forum link http://community.broadcom.com/thread/1994 .
Output GPIO
The following code is in bleaio.c.
// use P15 for CS
#define CS_PORT 0
#define CS_PIN 15// CS is active low
#define CS_ASSERT 0
#define CS_DEASSERT 1void spiffy2_master_initialize(void)
{
…
// Configure the CS pin to output, the initialized level is high.
// If enabling output, you only need to configure once. Use gpio_setPinOutput to toggle value
gpio_configurePin(CS_PORT, CS_PIN, GPIO_OUTPUT_ENABLE | GPIO_INPUT_DISABLE, CS_DEASSERT);
…
}void cmd_reset(void)
{
…
// pull CSB low to start the command
gpio_setPinOutput(CS_PORT, CS_PIN, CS_ASSERT); // Assert chipselect, CS pin output low
bleapputils_delayUs(1000);spiffyd_txData(SPIFFYD_2, 1 ,&byteToSend); // send reset sequence
bleapputils_delayUs(3000); // wait for the reset sequence timing// pull CSB high to finish the command
gpio_setPinOutput(CS_PORT, CS_PIN, CS_DEASSERT); // Deassert chipselect, CS pin output high}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for sharing this. It's very useful.