mirror of
https://github.com/apache/nuttx.git
synced 2026-10-04 04:38:10 +00:00
arm/nrf52,nrf53,nrf91: fix GPIOTE driver bugs
- set_port_event checked the wrong port when deciding whether the PORT interrupt can be disabled - set_event could pick a free channel instead of the one already assigned to the pin - LATCH registers were cleared by writing zeros - header declared nrfxx_gpio_set_task for a function defined as nrfxx_gpiote_set_task Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
This commit is contained in:
parent
f86b05351f
commit
c8f699a4e3
6 changed files with 106 additions and 58 deletions
|
|
@ -315,7 +315,7 @@ void nrf52_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg)
|
|||
|
||||
for (i = 0; i < NRF52_GPIO_NPORTS; i++)
|
||||
{
|
||||
if (g_gpiote_port_callback[port].callback)
|
||||
if (g_gpiote_port_callback[i].callback)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -465,36 +465,52 @@ int nrf52_gpiote_set_event(uint32_t pinset,
|
|||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Get free channel or channel already used by pinset */
|
||||
/* Get channel already used by pinset */
|
||||
|
||||
for (i = 0; i < GPIOTE_CHANNELS; i++)
|
||||
{
|
||||
if (g_gpiote_ch_callbacks[i].callback == NULL ||
|
||||
if (g_gpiote_ch_callbacks[i].callback != NULL &&
|
||||
g_gpiote_ch_callbacks[i].pinset == pinset)
|
||||
{
|
||||
g_gpiote_ch_callbacks[i].pinset = pinset;
|
||||
|
||||
/* Configure channel */
|
||||
|
||||
nrf52_gpiote_set_ch_event(pinset, i,
|
||||
risingedge, fallingedge,
|
||||
func, arg);
|
||||
|
||||
/* Return the channel index */
|
||||
|
||||
ret = i;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise get a free channel */
|
||||
|
||||
if (i == GPIOTE_CHANNELS && func != NULL)
|
||||
{
|
||||
for (i = 0; i < GPIOTE_CHANNELS; i++)
|
||||
{
|
||||
if (g_gpiote_ch_callbacks[i].callback == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < GPIOTE_CHANNELS)
|
||||
{
|
||||
g_gpiote_ch_callbacks[i].pinset = pinset;
|
||||
|
||||
/* Configure channel */
|
||||
|
||||
nrf52_gpiote_set_ch_event(pinset, i,
|
||||
risingedge, fallingedge,
|
||||
func, arg);
|
||||
|
||||
/* Return the channel index */
|
||||
|
||||
ret = i;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_gpio_set_task
|
||||
* Name: nrf52_gpiote_set_task
|
||||
*
|
||||
* Description:
|
||||
* Configure GPIO in TASK mode (to be controlled via tasks).
|
||||
|
|
@ -579,10 +595,10 @@ int nrf52_gpiote_init(void)
|
|||
{
|
||||
/* Clear LATCH register(s) */
|
||||
|
||||
putreg32(0, NRF52_GPIO_P0_BASE + NRF52_GPIO_LATCH_OFFSET);
|
||||
putreg32(0xffffffff, NRF52_GPIO_P0_BASE + NRF52_GPIO_LATCH_OFFSET);
|
||||
|
||||
#ifdef CONFIG_NRF52_HAVE_PORT1
|
||||
putreg32(0, NRF52_GPIO_P1_BASE + NRF52_GPIO_LATCH_OFFSET);
|
||||
putreg32(0xffffffff, NRF52_GPIO_P1_BASE + NRF52_GPIO_LATCH_OFFSET);
|
||||
#endif
|
||||
|
||||
/* Reset GPIOTE data */
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ void nrf52_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg);
|
|||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_gpio_set_task
|
||||
* Name: nrf52_gpiote_set_task
|
||||
*
|
||||
* Description:
|
||||
* Configure GPIO in TASK mode (to be controlled via tasks).
|
||||
|
|
@ -162,7 +162,7 @@ void nrf52_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void nrf52_gpio_set_task(uint32_t pinset, int channel,
|
||||
void nrf52_gpiote_set_task(uint32_t pinset, int channel,
|
||||
bool output_high, enum nrf52_gpiote_outcfg_e outcfg);
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ void nrf53_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg)
|
|||
|
||||
for (i = 0; i < NRF53_GPIO_NPORTS; i++)
|
||||
{
|
||||
if (g_gpiote_port_callback[port].callback)
|
||||
if (g_gpiote_port_callback[i].callback)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -506,34 +506,50 @@ int nrf53_gpiote_set_event(uint32_t pinset,
|
|||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Get free channel or channel already used by pinset */
|
||||
/* Get channel already used by pinset */
|
||||
|
||||
for (i = 0; i < GPIOTE_CHANNELS; i++)
|
||||
{
|
||||
if (g_gpiote_ch_callbacks[i].callback == NULL ||
|
||||
if (g_gpiote_ch_callbacks[i].callback != NULL &&
|
||||
g_gpiote_ch_callbacks[i].pinset == pinset)
|
||||
{
|
||||
g_gpiote_ch_callbacks[i].pinset = pinset;
|
||||
|
||||
nrf53_gpiote_set_ch_event(pinset, i,
|
||||
risingedge, fallingedge,
|
||||
func, arg);
|
||||
|
||||
/* Return the channel index */
|
||||
|
||||
ret = i;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise get a free channel */
|
||||
|
||||
if (i == GPIOTE_CHANNELS && func != NULL)
|
||||
{
|
||||
for (i = 0; i < GPIOTE_CHANNELS; i++)
|
||||
{
|
||||
if (g_gpiote_ch_callbacks[i].callback == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < GPIOTE_CHANNELS)
|
||||
{
|
||||
g_gpiote_ch_callbacks[i].pinset = pinset;
|
||||
|
||||
nrf53_gpiote_set_ch_event(pinset, i,
|
||||
risingedge, fallingedge,
|
||||
func, arg);
|
||||
|
||||
/* Return the channel index */
|
||||
|
||||
ret = i;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf53_gpio_set_task
|
||||
* Name: nrf53_gpiote_set_task
|
||||
*
|
||||
* Description:
|
||||
* Configure GPIO in TASK mode (to be controlled via tasks).
|
||||
|
|
@ -626,8 +642,8 @@ int nrf53_gpiote_init(void)
|
|||
{
|
||||
/* Clear LATCH register(s) */
|
||||
|
||||
putreg32(0, NRF53_GPIO_P0_BASE + NRF53_GPIO_LATCH_OFFSET);
|
||||
putreg32(0, NRF53_GPIO_P1_BASE + NRF53_GPIO_LATCH_OFFSET);
|
||||
putreg32(0xffffffff, NRF53_GPIO_P0_BASE + NRF53_GPIO_LATCH_OFFSET);
|
||||
putreg32(0xffffffff, NRF53_GPIO_P1_BASE + NRF53_GPIO_LATCH_OFFSET);
|
||||
|
||||
/* Reset GPIOTE data */
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ void nrf53_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg);
|
|||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf53_gpio_set_task
|
||||
* Name: nrf53_gpiote_set_task
|
||||
*
|
||||
* Description:
|
||||
* Configure GPIO in TASK mode (to be controlled via tasks).
|
||||
|
|
@ -158,7 +158,7 @@ void nrf53_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void nrf53_gpio_set_task(uint32_t pinset, int channel,
|
||||
void nrf53_gpiote_set_task(uint32_t pinset, int channel,
|
||||
bool output_high, enum nrf53_gpiote_outcfg_e outcfg);
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ void nrf91_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg)
|
|||
|
||||
for (i = 0; i < NRF91_GPIO_NPORTS; i++)
|
||||
{
|
||||
if (g_gpiote_port_callback[port].callback)
|
||||
if (g_gpiote_port_callback[i].callback)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -476,36 +476,52 @@ int nrf91_gpiote_set_event(uint32_t pinset,
|
|||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Get free channel or channel already used by pinset */
|
||||
/* Get channel already used by pinset */
|
||||
|
||||
for (i = 0; i < GPIOTE_CHANNELS; i++)
|
||||
{
|
||||
if (g_gpiote_ch_callbacks[i].callback == NULL ||
|
||||
if (g_gpiote_ch_callbacks[i].callback != NULL &&
|
||||
g_gpiote_ch_callbacks[i].pinset == pinset)
|
||||
{
|
||||
g_gpiote_ch_callbacks[i].pinset = pinset;
|
||||
|
||||
/* Configure channel */
|
||||
|
||||
nrf91_gpiote_set_ch_event(pinset, i,
|
||||
risingedge, fallingedge,
|
||||
func, arg);
|
||||
|
||||
/* Return the channel index */
|
||||
|
||||
ret = i;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise get a free channel */
|
||||
|
||||
if (i == GPIOTE_CHANNELS && func != NULL)
|
||||
{
|
||||
for (i = 0; i < GPIOTE_CHANNELS; i++)
|
||||
{
|
||||
if (g_gpiote_ch_callbacks[i].callback == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < GPIOTE_CHANNELS)
|
||||
{
|
||||
g_gpiote_ch_callbacks[i].pinset = pinset;
|
||||
|
||||
/* Configure channel */
|
||||
|
||||
nrf91_gpiote_set_ch_event(pinset, i,
|
||||
risingedge, fallingedge,
|
||||
func, arg);
|
||||
|
||||
/* Return the channel index */
|
||||
|
||||
ret = i;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf91_gpio_set_task
|
||||
* Name: nrf91_gpiote_set_task
|
||||
*
|
||||
* Description:
|
||||
* Configure GPIO in TASK mode (to be controlled via tasks).
|
||||
|
|
@ -590,10 +606,10 @@ int nrf91_gpiote_init(void)
|
|||
{
|
||||
/* Clear LATCH register(s) */
|
||||
|
||||
putreg32(0, NRF91_GPIO_P0_BASE + NRF91_GPIO_LATCH_OFFSET);
|
||||
putreg32(0xffffffff, NRF91_GPIO_P0_BASE + NRF91_GPIO_LATCH_OFFSET);
|
||||
|
||||
#ifdef CONFIG_NRF91_HAVE_PORT1
|
||||
putreg32(0, NRF91_GPIO_P1_BASE + NRF91_GPIO_LATCH_OFFSET);
|
||||
putreg32(0xffffffff, NRF91_GPIO_P1_BASE + NRF91_GPIO_LATCH_OFFSET);
|
||||
#endif
|
||||
|
||||
/* Reset GPIOTE data */
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ void nrf91_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg);
|
|||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf91_gpio_set_task
|
||||
* Name: nrf91_gpiote_set_task
|
||||
*
|
||||
* Description:
|
||||
* Configure GPIO in TASK mode (to be controlled via tasks).
|
||||
|
|
@ -162,7 +162,7 @@ void nrf91_gpiote_set_port_event(uint32_t pinset, xcpt_t func, void *arg);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void nrf91_gpio_set_task(uint32_t pinset, int channel,
|
||||
void nrf91_gpiote_set_task(uint32_t pinset, int channel,
|
||||
bool output_high, enum nrf91_gpiote_outcfg_e outcfg);
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue