Skip to content

Commit

Permalink
Improve GPIO code
Browse files Browse the repository at this point in the history
- Add CPU_GPIO_TogglePinState.
- Implemented it at platform level (API exists for all platforms except ESP32 on which it was done with the usual approach read-toggle-write).
- Rework code at GpioPin::Toggle to use this.
- Rework code at GpioPin::Toggle and GpioPin::Write to check for callbacks and post event.
- Update assembly declaration.
  • Loading branch information
josesimoes committed Oct 22, 2020
1 parent fcec675 commit df1fe10
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 15 deletions.
11 changes: 11 additions & 0 deletions src/PAL/Include/CPU_GPIO_decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,17 @@ GpioPinValue CPU_GPIO_GetPinState(GPIO_PIN Pin);
// Set state of output gpio pin
void CPU_GPIO_SetPinState(GPIO_PIN Pin, GpioPinValue PinState);

//
// CPU_GPIO_TogglePinState
//
// Parameters :-
//
// pinNumber
// The number of the output pin for which the state is to be toggled.
// Return Value
//
void CPU_GPIO_TogglePinState(GPIO_PIN pinNumber);

// Check if pin is already reserved
// Returns true if pin is already reserved
bool CPU_GPIO_PinIsBusy(GPIO_PIN Pin);
Expand Down
2 changes: 1 addition & 1 deletion src/System.Device.Gpio/sys_dev_gpio_native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Device_Gpio =
"System.Device.Gpio",
0xB6D0ACC1,
method_lookup,
{ 100, 1, 0, 3 }
{ 100, 1, 0, 4 }
};

// clang-format on
5 changes: 2 additions & 3 deletions src/System.Device.Gpio/sys_dev_gpio_native.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ struct Library_sys_dev_gpio_native_System_Device_Gpio_GpioPin
static const int FIELD___pinMode = 3;
static const int FIELD___debounceTimeout = 4;
static const int FIELD___callbacks = 5;
static const int FIELD___lastOutputValue = 6;
static const int FIELD___lastInputValue = 7;
static const int FIELD___disposedValue = 8;
static const int FIELD___lastInputValue = 6;
static const int FIELD___disposedValue = 7;

NANOCLR_NATIVE_DECLARE(Read___SystemDeviceGpioPinValue);
NANOCLR_NATIVE_DECLARE(Toggle___VOID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,13 @@ HRESULT Library_sys_dev_gpio_native_System_Device_Gpio_GpioPin::Toggle___VOID(CL
// sanity check for drive mode set to output so we don't mess up writing to an input pin
if (driveMode >= GpioPinDriveMode_Output)
{
// Not all lower level API offer a 'toggle', so need to rely on the last output value field and toggle that
// one
GpioPinValue newState =
(GpioPinValue)(GpioPinValue_High ^ (GpioPinValue)pThis[FIELD___lastOutputValue].NumericByRef().s4);
CPU_GPIO_TogglePinState(pinNumber);

// ...write back to the GPIO...
CPU_GPIO_SetPinState(pinNumber, newState);

// ... and finally store it
pThis[FIELD___lastOutputValue].NumericByRef().s4 = newState;
// fire event, only if there are callbacks registered
if (pThis[FIELD___callbacks].Dereference() != NULL)
{
PostManagedEvent(EVENT_GPIO, 0, (uint16_t)pinNumber, (uint32_t)CPU_GPIO_GetPinState(pinNumber));
}
}
}
NANOCLR_NOCLEANUP();
Expand Down Expand Up @@ -282,8 +279,11 @@ HRESULT Library_sys_dev_gpio_native_System_Device_Gpio_GpioPin::Write(CLR_RT_Hea
{
CPU_GPIO_SetPinState(pinNumber, (GpioPinValue)pinValue);

// store the output value in the field
gpioPin[FIELD___lastOutputValue].NumericByRef().s4 = pinValue;
// fire event if there are callbacks registered
if (gpioPin[FIELD___callbacks].Dereference() != NULL)
{
PostManagedEvent(EVENT_GPIO, 0, (uint16_t)pinNumber, (uint32_t)pinValue);
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ void CPU_GPIO_SetPinState(GPIO_PIN pin, GpioPinValue PinState)
palWriteLine(GetIoLine(pin), (int)PinState);
}

void CPU_GPIO_TogglePinState(GPIO_PIN pinNumber)
{
palToggleLine(GetIoLine(pinNumber));
}

bool CPU_GPIO_EnableInputPin(
GPIO_PIN pinNumber,
CLR_UINT64 debounceTimeMilliseconds,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,15 @@ void CPU_GPIO_SetPinState(GPIO_PIN pin, GpioPinValue PinState)
gpio_set_level((gpio_num_t)pin, (uint32_t)PinState);
}

// Toggle pin state
void CPU_GPIO_TogglePinState(GPIO_PIN pinNumber)
{
// platform DOES NOT support toggle
// need to do it "the hard way"
GpioPinValue newState = (GpioPinValue)(gpio_get_level((gpio_num_t)pinNumber) ^ GpioPinValue_High);
gpio_set_level((gpio_num_t)pinNumber, (uint32_t)newState);
}

// ISR called by IDF
static void gpio_isr(void *arg)
{
Expand Down

0 comments on commit df1fe10

Please sign in to comment.