Nuvoton: Add i2c_free

1.  Disable interrupt
2.  Disable IP clock
3.  Free up pins

Support targets:

-   NUMAKER_PFM_NANO130
-   NUMAKER_PFM_NUC472
-   NUMAKER_PFM_M453
-   NUMAKER_PFM_M487/NUMAKER_IOT_M487
-   NU_PFM_M2351*
-   NUMAKER_IOT_M263A
-   NUMAKER_M252KG
pull/11780/head
Chun-Chieh Li 2019-10-31 10:51:59 +08:00
parent 3abd02614a
commit 72ea613a12
7 changed files with 199 additions and 0 deletions

View File

@ -147,6 +147,37 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
i2c_modinit_mask |= 1 << i; i2c_modinit_mask |= 1 << i;
} }
void i2c_free(i2c_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
/* Disable I2C interrupt */
NVIC_DisableIRQ(modinit->irq_n);
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
/* Disable I2C module */
I2C_Close(i2c_base);
/* Disable IP clock
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
CLK_DisableModuleClock_S(modinit->clkidx);
// Mark this module to be deinited.
int i = modinit - i2c_modinit_tab;
i2c_modinit_mask &= ~(1 << i);
/* Free up pins */
gpio_set(obj->i2c.pin_sda);
gpio_set(obj->i2c.pin_scl);
obj->i2c.pin_sda = NC;
obj->i2c.pin_scl = NC;
}
int i2c_start(i2c_t *obj) int i2c_start(i2c_t *obj)
{ {
return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1); return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1);

View File

@ -137,6 +137,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
i2c_modinit_mask |= 1 << i; i2c_modinit_mask |= 1 << i;
} }
void i2c_free(i2c_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
/* Disable I2C interrupt */
NVIC_DisableIRQ(modinit->irq_n);
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
/* Disable I2C module */
I2C_Close(i2c_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
// Mark this module to be deinited.
int i = modinit - i2c_modinit_tab;
i2c_modinit_mask &= ~(1 << i);
/* Free up pins */
gpio_set(obj->i2c.pin_sda);
gpio_set(obj->i2c.pin_scl);
obj->i2c.pin_sda = NC;
obj->i2c.pin_scl = NC;
}
int i2c_start(i2c_t *obj) int i2c_start(i2c_t *obj)
{ {
return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1); return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1);

View File

@ -142,6 +142,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
i2c_modinit_mask |= 1 << i; i2c_modinit_mask |= 1 << i;
} }
void i2c_free(i2c_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
/* Disable I2C interrupt */
NVIC_DisableIRQ(modinit->irq_n);
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
/* Disable I2C module */
I2C_Close(i2c_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
// Mark this module to be deinited.
int i = modinit - i2c_modinit_tab;
i2c_modinit_mask &= ~(1 << i);
/* Free up pins */
gpio_set(obj->i2c.pin_sda);
gpio_set(obj->i2c.pin_scl);
obj->i2c.pin_sda = NC;
obj->i2c.pin_scl = NC;
}
int i2c_start(i2c_t *obj) int i2c_start(i2c_t *obj)
{ {
return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1); return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1);

View File

@ -150,6 +150,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
i2c_modinit_mask |= 1 << i; i2c_modinit_mask |= 1 << i;
} }
void i2c_free(i2c_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
/* Disable I2C interrupt */
NVIC_DisableIRQ(modinit->irq_n);
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
/* Disable I2C module */
I2C_Close(i2c_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
// Mark this module to be deinited.
int i = modinit - i2c_modinit_tab;
i2c_modinit_mask &= ~(1 << i);
/* Free up pins */
gpio_set(obj->i2c.pin_sda);
gpio_set(obj->i2c.pin_scl);
obj->i2c.pin_sda = NC;
obj->i2c.pin_scl = NC;
}
int i2c_start(i2c_t *obj) int i2c_start(i2c_t *obj)
{ {
return i2c_do_trsn(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk, 1); return i2c_do_trsn(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk, 1);

View File

@ -141,6 +141,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
i2c_modinit_mask |= 1 << i; i2c_modinit_mask |= 1 << i;
} }
void i2c_free(i2c_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
/* Disable I2C interrupt */
NVIC_DisableIRQ(modinit->irq_n);
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
/* Disable I2C module */
I2C_Close(i2c_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
// Mark this module to be deinited.
int i = modinit - i2c_modinit_tab;
i2c_modinit_mask &= ~(1 << i);
/* Free up pins */
gpio_set(obj->i2c.pin_sda);
gpio_set(obj->i2c.pin_scl);
obj->i2c.pin_sda = NC;
obj->i2c.pin_scl = NC;
}
int i2c_start(i2c_t *obj) int i2c_start(i2c_t *obj)
{ {
return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1); return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1);

View File

@ -166,6 +166,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
i2c_modinit_mask |= 1 << i; i2c_modinit_mask |= 1 << i;
} }
void i2c_free(i2c_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
/* Disable I2C interrupt */
NVIC_DisableIRQ(modinit->irq_n);
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
/* Disable I2C module */
I2C_Close(i2c_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
// Mark this module to be deinited.
int i = modinit - i2c_modinit_tab;
i2c_modinit_mask &= ~(1 << i);
/* Free up pins */
gpio_set(obj->i2c.pin_sda);
gpio_set(obj->i2c.pin_scl);
obj->i2c.pin_sda = NC;
obj->i2c.pin_scl = NC;
}
int i2c_start(i2c_t *obj) int i2c_start(i2c_t *obj)
{ {
return i2c_do_trsn(obj, I2C_CON_START_Msk | I2C_CON_I2C_STS_Msk, 1); return i2c_do_trsn(obj, I2C_CON_START_Msk | I2C_CON_I2C_STS_Msk, 1);

View File

@ -172,6 +172,34 @@ int i2c_start(i2c_t *obj)
return i2c_do_trsn(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk, 1); return i2c_do_trsn(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk, 1);
} }
void i2c_free(i2c_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
/* Disable I2C interrupt */
NVIC_DisableIRQ(modinit->irq_n);
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
/* Disable I2C module */
I2C_Close(i2c_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
// Mark this module to be deinited.
int i = modinit - i2c_modinit_tab;
i2c_modinit_mask &= ~(1 << i);
/* Free up pins */
gpio_set(obj->i2c.pin_sda);
gpio_set(obj->i2c.pin_scl);
obj->i2c.pin_sda = NC;
obj->i2c.pin_scl = NC;
}
int i2c_stop(i2c_t *obj) int i2c_stop(i2c_t *obj)
{ {
return i2c_do_trsn(obj, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk, 1); return i2c_do_trsn(obj, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk, 1);