From 72ea613a127f526029ca1f14b4faa247345c60a7 Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Thu, 31 Oct 2019 10:51:59 +0800 Subject: [PATCH] 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 --- targets/TARGET_NUVOTON/TARGET_M2351/i2c_api.c | 31 +++++++++++++++++++ targets/TARGET_NUVOTON/TARGET_M251/i2c_api.c | 28 +++++++++++++++++ targets/TARGET_NUVOTON/TARGET_M261/i2c_api.c | 28 +++++++++++++++++ targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c | 28 +++++++++++++++++ targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c | 28 +++++++++++++++++ .../TARGET_NUVOTON/TARGET_NANO100/i2c_api.c | 28 +++++++++++++++++ .../TARGET_NUVOTON/TARGET_NUC472/i2c_api.c | 28 +++++++++++++++++ 7 files changed, 199 insertions(+) diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M2351/i2c_api.c index d872ee9cc2..a7819b6bbe 100644 --- a/targets/TARGET_NUVOTON/TARGET_M2351/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M2351/i2c_api.c @@ -147,6 +147,37 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) 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) { return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1); diff --git a/targets/TARGET_NUVOTON/TARGET_M251/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M251/i2c_api.c index da70f4abb8..3652ca3dde 100644 --- a/targets/TARGET_NUVOTON/TARGET_M251/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M251/i2c_api.c @@ -137,6 +137,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) 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) { return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1); diff --git a/targets/TARGET_NUVOTON/TARGET_M261/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M261/i2c_api.c index 41929021bd..4075f57d6d 100644 --- a/targets/TARGET_NUVOTON/TARGET_M261/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M261/i2c_api.c @@ -142,6 +142,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) 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) { return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1); diff --git a/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c index 0cbdac75e9..23ee8a7fd7 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c @@ -150,6 +150,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) 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) { return i2c_do_trsn(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk, 1); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c index d0e554f5aa..021f7dc6e7 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c @@ -141,6 +141,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) 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) { return i2c_do_trsn(obj, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk, 1); diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_NANO100/i2c_api.c index 719f2dda78..2d30a1fe3d 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/i2c_api.c @@ -166,6 +166,34 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) 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) { return i2c_do_trsn(obj, I2C_CON_START_Msk | I2C_CON_I2C_STS_Msk, 1); diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c index 23525d325c..0c514d26de 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c @@ -172,6 +172,34 @@ int i2c_start(i2c_t *obj) 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) { return i2c_do_trsn(obj, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk, 1);