Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/source/mbed_board.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ WEAK MBED_NORETURN void mbed_die(void)

#ifdef LED1
gpio_t led_err;
memset(&led_err, 0, sizeof(gpio_t));
gpio_init_out(&led_err, LED1);
#endif

Expand Down
130 changes: 46 additions & 84 deletions targets/TARGET_Ambiq_Micro/TARGET_Apollo3/device/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,94 +66,50 @@ void gpio_init(gpio_t *obj, PinName pin)
void gpio_mode(gpio_t *obj, PinMode mode)
{
MBED_ASSERT(gpio_is_connected(obj));
MBED_ASSERT(mode < (PinMode)PinModeElements);
am_hal_gpio_pincfg_allow_t pinConfigBools = {0};

obj->cfg.uFuncSel = AP3_PINCFG_FUNCSEL_GPIO; // gpio

if (mode & (PinMode)PowerSwNone) {
obj->cfg.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE;
pinConfigBools.ePowerSw = true;
}
if (mode & (PinMode)PowerSwVDD) {
obj->cfg.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_VDD;
pinConfigBools.ePowerSw = true;
}
if (mode & (PinMode)PowerSwVSS) {
obj->cfg.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_VSS;
pinConfigBools.ePowerSw = true;
}
// Configure pull-up or pull-down
pinConfigBools.ePullup = true;

if (mode & (PinMode)PullNone) {
if(!(mode & OpenDrain) && obj->isOutput) {
// Push-pull output, do not allow pullup
obj->cfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE;
pinConfigBools.ePullup = true;
}
if (mode & (PinMode)PullUp) {
obj->cfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_WEAK;
pinConfigBools.ePullup = true;
}
if (mode & (PinMode)PullDown) {
else if (mode & (PinMode)PullUp) {
MBED_ASSERT(obj->pad != IO_20); // pullup not supported on IO 20

if(obj->pad == IO_0 || obj->pad == IO_1 || obj->pad == IO_5 || obj->pad == IO_6 || obj->pad == IO_8
|| obj->pad == IO_9 || obj->pad == IO_25 || obj->pad == IO_27 || obj->pad == IO_39 ||
obj->pad == IO_40 || obj->pad == IO_42 || obj->pad == IO_43 || obj->pad == IO_48 || obj->pad == IO_49) {
// These pads (with I2C support) need a different constant to get the same resistance
obj->cfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K;
}
else{
obj->cfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_WEAK;
}
}
else if (mode & (PinMode)PullDown) {
MBED_ASSERT(obj->pad == IO_20); // pulldown only supported on IO 20
obj->cfg.ePullup = AM_HAL_GPIO_PIN_PULLDOWN;
pinConfigBools.ePullup = true;
}

if (mode & (PinMode)DriveStrength2mA) {
obj->cfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_2MA;
pinConfigBools.eDriveStrength = true;
}
if (mode & (PinMode)DriveStrength4mA) {
obj->cfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_4MA;
pinConfigBools.eDriveStrength = true;
}
if (mode & (PinMode)DriveStrength8mA) {
obj->cfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_8MA;
pinConfigBools.eDriveStrength = true;
}
if (mode & (PinMode)DriveStrength12mA) {
obj->cfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA;
pinConfigBools.eDriveStrength = true;
}

if (mode & (PinMode)OutDisable) {
obj->cfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE;
pinConfigBools.eGPOutcfg = true;
}
if (mode & (PinMode)OutPushPull) {
obj->cfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL;
pinConfigBools.eGPOutcfg = true;
}
if (mode & (PinMode)OutOpenDrain) {
obj->cfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_OPENDRAIN;
pinConfigBools.eGPOutcfg = true;
}
if (mode & (PinMode)OutTristate) {
obj->cfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_TRISTATE;
pinConfigBools.eGPOutcfg = true;
else {
obj->cfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE;
}

if (mode & (PinMode)InAuto) {
obj->cfg.eGPInput = AM_HAL_GPIO_PIN_INPUT_AUTO;
pinConfigBools.eGPInput = true;
}
if (mode & (PinMode)InNone) {
obj->cfg.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE;
pinConfigBools.eGPInput = true;
// Configure output type
obj->openDrain = mode & OpenDrain;
pinConfigBools.eGPOutcfg = true;
if(obj->isOutput) {
obj->cfg.eGPOutcfg = obj->openDrain ? AM_HAL_GPIO_PIN_OUTCFG_OPENDRAIN : AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL;
}
if (mode & (PinMode)InEnable) {
obj->cfg.eGPInput = AM_HAL_GPIO_PIN_INPUT_ENABLE;
pinConfigBools.eGPInput = true;
else {
obj->cfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE;
}

if (mode & (PinMode)ReadPin) {
obj->cfg.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN;
pinConfigBools.eGPRdZero = true;
}
if (mode & (PinMode)ReadZero) {
obj->cfg.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_ZERO;
pinConfigBools.eGPRdZero = true;
}

ap3_hal_gpio_pinconfig_partial((uint32_t)(obj->pad), obj->cfg, pinConfigBools); //padRegMsk.byte, GPConfigMsk.byte, padAltCfgMsk.byte); // apply configuration
MBED_ASSERT(ap3_hal_gpio_pinconfig_partial((uint32_t)(obj->pad), obj->cfg, pinConfigBools) == AM_HAL_STATUS_SUCCESS);
}

/** Set the pin direction
Expand All @@ -167,23 +123,33 @@ void gpio_dir(gpio_t *obj, PinDirection direction)
MBED_ASSERT(direction < (PinDirection)PIN_DIR_ELEMENTS);
am_hal_gpio_pincfg_allow_t pinConfigBools= {0};

// Always enable the input on the pin, so that we can read it if it is open drain.
pinConfigBools.eGPInput = true;
pinConfigBools.eGPRdZero = true;
obj->cfg.eGPInput = AM_HAL_GPIO_PIN_INPUT_ENABLE;
obj->cfg.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN;

if (direction == (PinDirection)PIN_INPUT) {
obj->cfg.eGPInput = AM_HAL_GPIO_PIN_INPUT_ENABLE;
pinConfigBools.eGPInput = true;
obj->isOutput = false;
obj->cfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE;
pinConfigBools.eGPOutcfg = true;
} else if (direction == (PinDirection)PIN_OUTPUT) {
obj->cfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL;
obj->isOutput = true;
obj->cfg.eGPOutcfg = obj->openDrain ? AM_HAL_GPIO_PIN_OUTCFG_OPENDRAIN : AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL;
pinConfigBools.eGPOutcfg = true;
obj->cfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA;
pinConfigBools.eDriveStrength = true;
obj->cfg.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE;
pinConfigBools.eGPInput = true;

// Clear any configured pullup if set to open-drain
if(!obj->openDrain) {
pinConfigBools.ePullup = true;
obj->cfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE;
}
} else {
MBED_ASSERT(false);
}

ap3_hal_gpio_pinconfig_partial((uint32_t)(obj->pad), obj->cfg, pinConfigBools); //padRegMsk.byte, GPConfigMsk.byte, padAltCfgMsk.byte); // apply configuration
ap3_hal_gpio_pinconfig_partial((uint32_t)(obj->pad), obj->cfg, pinConfigBools);
}

/** Set the output value
Expand All @@ -205,12 +171,8 @@ void gpio_write(gpio_t *obj, int value)
int gpio_read(gpio_t *obj)
{
MBED_ASSERT(gpio_is_connected(obj));
uint32_t ui32BaseAddr = (obj->pad) / 8;
uint32_t ui32BaseShift = (((obj->pad) % 8) * 4) + 1;
uint8_t output = ((AM_REGVAL(&GPIO->CFGA + ui32BaseAddr) >> ui32BaseShift) & 0x03);

return (output) ? (int)am_hal_gpio_output_read(obj->pad) : (int)am_hal_gpio_input_read(obj->pad);
return 0;
return am_hal_gpio_input_read(obj->pad);
}

/** Get the pins that support all GPIO tests
Expand Down
83 changes: 17 additions & 66 deletions targets/TARGET_Ambiq_Micro/TARGET_Apollo3/device/objects_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,78 +43,29 @@ typedef enum {
PIN_DIR_ELEMENTS
} PinDirection;

enum sPinMode {
sPowerSwNone = 0x00,
sPowerSwVDD,
sPowerSwVSS,
sPullNone,
sPullUp,
sPullDown,
sPullUp1K5,
sPullUp6K,
sPullUp12K,
sPullUp24K,
sDriveStrength2mA,
sDriveStrength4mA,
sDriveStrength8mA,
sDriveStrength12mA,
sOutDisable,
sOutPushPull,
sOutOpenDrain,
sOutTristate,
sInAuto,
sInNone,
sInEnable,
sReadPin,
sReadZero,

sPinModeElements
};

#define PinModeEntry(e) e = (1 << s##e)

typedef enum {
PinModeEntry(PowerSwNone),
PinModeEntry(PowerSwVDD),
PinModeEntry(PowerSwVSS),
PowerSwDefault = PowerSwNone,

PinModeEntry(PullNone),
PinModeEntry(PullUp),
PinModeEntry(PullDown),
PinModeEntry(PullUp1K5),
PinModeEntry(PullUp6K),
PinModeEntry(PullUp12K),
PinModeEntry(PullUp24K),
PullDefault = PullNone,

PinModeEntry(DriveStrength2mA),
PinModeEntry(DriveStrength4mA),
PinModeEntry(DriveStrength8mA),
PinModeEntry(DriveStrength12mA),
DriveStrengthDefault = DriveStrength12mA,

PinModeEntry(OutDisable),
PinModeEntry(OutPushPull),
PinModeEntry(OutOpenDrain),
PinModeEntry(OutTristate),
OutDefault = OutPushPull,

PinModeEntry(InAuto),
PinModeEntry(InNone),
PinModeEntry(InEnable),
InDefault = InEnable,

PinModeEntry(ReadPin),
PinModeEntry(ReadZero),
ReadDefault = ReadPin,

PinModeEntry(PinModeElements)

PullNone = 0,

// Supported on all IOs except IO 20. Actual resistance 13-27kOhm
PullUp = 1 << 0,

// Only supported on IO 20, Actual resistance 26-40kOhm
PullDown = 1 << 1,

OpenDrain = 1 << 2,
OpenDrainPullUp = OpenDrain | PullUp, ///< Open-drain mode with pull up. Supported on all IOs except IO 20.
OpenDrainPullDown = OpenDrain | PullDown, ///< Open-drain mode with pull down. Only supported on IO 20.
OpenDrainNoPull = OpenDrain, ///< Open-drain mode with no pullup/pulldown. Supported on all IOs.

PullDefault = PullNone
} PinMode;

typedef struct _gpio_t {
ap3_gpio_pad_t pad;
am_hal_gpio_pincfg_t cfg;
bool openDrain; ///< Whether the pin is configured open drain as of the last gpio_mode() call
bool isOutput; ///< Whether the pin is configured as an output as of the last gpio_dir() call
} gpio_t;

typedef struct ap3_gpio_irq_control_t {
Expand Down