Merge pull request #11152 from OpenNuvoton/nuvoton_fpga-ci

Nuvoton: Fix FPGA CI test failing
pull/11307/head
Martin Kojtal 2019-08-23 10:02:19 +02:00 committed by GitHub
commit 48b5939b33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 2682 additions and 1864 deletions

View File

@ -64,6 +64,10 @@ void test_basic_input_output(PinName pin)
gpio_init(&gpio, pin);
TEST_ASSERT_NOT_EQUAL(0, gpio_is_connected(&gpio));
// Some targets don't support input pull mode.
#if !defined(TARGET_NANO100) && \
!defined(TARGET_NUC472) && \
!defined(TARGET_M451)
// Test GPIO used as an input.
gpio_dir(&gpio, PIN_INPUT);
@ -105,6 +109,7 @@ void test_basic_input_output(PinName pin)
TEST_ASSERT_EQUAL_INT(0, gpio_read(&gpio));
tester.gpio_write(MbedTester::LogicalPinGPIO0, 1, true);
TEST_ASSERT_EQUAL_INT(1, gpio_read(&gpio));
#endif
// Test GPIO used as an output.
tester.gpio_write(MbedTester::LogicalPinGPIO0, 0, false);
@ -221,7 +226,12 @@ void test_explicit_output(PinName pin)
Case cases[] = {
Case("generic init, input & output", all_ports<GPIOPort, DefaultFormFactor, test_basic_input_output>),
// Some targets don't support input pull mode.
#if !defined(TARGET_NANO100) && \
!defined(TARGET_NUC472) && \
!defined(TARGET_M451)
Case("explicit init, input", all_ports<GPIOPort, DefaultFormFactor, test_explicit_input>),
#endif
Case("explicit init, output", all_ports<GPIOPort, DefaultFormFactor, test_explicit_output>),
};

View File

@ -51,6 +51,19 @@ void test_i2c_init_free(PinName sda, PinName scl)
memset(&obj, 0, sizeof(obj));
i2c_init(&obj, sda, scl);
i2c_frequency(&obj, 100000);
/* Free up I2C pins
*
* The most suitable place to free up I2C pins is in i2c_free(). Due to
* i2c_free() not available in I2C HAL, we free up I2C pins manually by
* configuring them back to GPIO.
*
* Without free-up of I2C pins, SDA/SCL pins of the same I2C peripheral may
* share by multiple ports due to 'all ports' tests here, and the following
* I2C tests would be subject to interference by shared ports.
*/
gpio_set(sda);
gpio_set(scl);
}
void i2c_test_write(PinName sda, PinName scl)

View File

@ -510,51 +510,28 @@ const PinMap PinMap_SPI_MISO[] = {
const PinMap PinMap_SPI_SCLK[] = {
{PA_2, SPI_0, SYS_GPA_MFPL_PA2MFP_SPI0_CLK},
{PA_4, SPI_0, SYS_GPA_MFPL_PA4MFP_SPI0_I2SMCLK},
{PA_5, SPI_1, SYS_GPA_MFPL_PA5MFP_SPI1_I2SMCLK},
{PA_7, SPI_1, SYS_GPA_MFPL_PA7MFP_SPI1_CLK},
{PA_10, SPI_2, SYS_GPA_MFPH_PA10MFP_SPI2_CLK},
{PA_13, SPI_2, SYS_GPA_MFPH_PA13MFP_SPI2_CLK},
{PB_0, SPI_0, SYS_GPB_MFPL_PB0MFP_SPI0_I2SMCLK},
{PB_1, SPI_1, SYS_GPB_MFPL_PB1MFP_SPI1_I2SMCLK},
{NU_PINNAME_BIND(PB_1, SPI_1), SPI_1, SYS_GPB_MFPL_PB1MFP_SPI1_I2SMCLK},
{PB_1, SPI_3, SYS_GPB_MFPL_PB1MFP_SPI3_I2SMCLK},
{NU_PINNAME_BIND(PB_1, SPI_3), SPI_3, SYS_GPB_MFPL_PB1MFP_SPI3_I2SMCLK},
{PB_3, SPI_1, SYS_GPB_MFPL_PB3MFP_SPI1_CLK},
{PB_11, SPI_0, SYS_GPB_MFPH_PB11MFP_SPI0_I2SMCLK},
{NU_PINNAME_BIND(PB_11, SPI_0), SPI_0, SYS_GPB_MFPH_PB11MFP_SPI0_I2SMCLK},
{PB_11, SPI_3, SYS_GPB_MFPH_PB11MFP_SPI3_CLK},
{NU_PINNAME_BIND(PB_11, SPI_3), SPI_3, SYS_GPB_MFPH_PB11MFP_SPI3_CLK},
{PB_14, SPI_0, SYS_GPB_MFPH_PB14MFP_SPI0_CLK},
{PC_1, SPI_1, SYS_GPC_MFPL_PC1MFP_SPI1_CLK},
{PC_2, SPI_5, SYS_GPC_MFPL_PC2MFP_SPI5_CLK},
{PC_4, SPI_1, SYS_GPC_MFPL_PC4MFP_SPI1_I2SMCLK},
{PC_10, SPI_3, SYS_GPC_MFPH_PC10MFP_SPI3_CLK},
{PC_13, SPI_2, SYS_GPC_MFPH_PC13MFP_SPI2_I2SMCLK},
{PD_2, SPI_0, SYS_GPD_MFPL_PD2MFP_SPI0_CLK},
{PD_5, SPI_1, SYS_GPD_MFPL_PD5MFP_SPI1_CLK},
{PD_13, SPI_0, SYS_GPD_MFPH_PD13MFP_SPI0_I2SMCLK},
{NU_PINNAME_BIND(PD_13, SPI_0), SPI_0, SYS_GPD_MFPH_PD13MFP_SPI0_I2SMCLK},
{PD_13, SPI_1, SYS_GPD_MFPH_PD13MFP_SPI1_I2SMCLK},
{NU_PINNAME_BIND(PD_13, SPI_1), SPI_1, SYS_GPD_MFPH_PD13MFP_SPI1_I2SMCLK},
{PD_14, SPI_0, SYS_GPD_MFPH_PD14MFP_SPI0_I2SMCLK},
{NU_PINNAME_BIND(PD_14, SPI_0), SPI_0, SYS_GPD_MFPH_PD14MFP_SPI0_I2SMCLK},
{PD_14, SPI_3, SYS_GPD_MFPH_PD14MFP_SPI3_I2SMCLK},
{NU_PINNAME_BIND(PD_14, SPI_3), SPI_3, SYS_GPD_MFPH_PD14MFP_SPI3_I2SMCLK},
{PE_4, SPI_3, SYS_GPE_MFPL_PE4MFP_SPI3_CLK},
{NU_PINNAME_BIND(PE_4, SPI_3), SPI_3, SYS_GPE_MFPL_PE4MFP_SPI3_CLK},
{PE_4, SPI_5, SYS_GPE_MFPL_PE4MFP_SPI5_CLK},
{NU_PINNAME_BIND(PE_4, SPI_5), SPI_5, SYS_GPE_MFPL_PE4MFP_SPI5_CLK},
{PE_6, SPI_3, SYS_GPE_MFPL_PE6MFP_SPI3_I2SMCLK},
{PE_8, SPI_2, SYS_GPE_MFPH_PE8MFP_SPI2_CLK},
{PE_12, SPI_2, SYS_GPE_MFPH_PE12MFP_SPI2_I2SMCLK},
{PF_8, SPI_0, SYS_GPF_MFPH_PF8MFP_SPI0_CLK},
{PF_10, SPI_0, SYS_GPF_MFPH_PF10MFP_SPI0_I2SMCLK},
{PG_3, SPI_2, SYS_GPG_MFPL_PG3MFP_SPI2_CLK},
{PG_11, SPI_5, SYS_GPG_MFPH_PG11MFP_SPI5_CLK},
{PH_6, SPI_1, SYS_GPH_MFPL_PH6MFP_SPI1_CLK},
{PH_8, SPI_1, SYS_GPH_MFPH_PH8MFP_SPI1_CLK},
{PH_10, SPI_1, SYS_GPH_MFPH_PH10MFP_SPI1_I2SMCLK},
{NC, NC, 0}
};

View File

@ -173,6 +173,9 @@ typedef enum {
BUTTON1 = SW2,
BUTTON2 = SW3,
// Force PinName to 32-bit required by NU_PINNAME_BIND(...)
FORCE_ENUM_PINNAME_32BIT = 0x7FFFFFFF,
} PinName;
#ifdef __cplusplus

View File

@ -53,37 +53,39 @@ void analogin_init(analogin_t *obj, PinName pin)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->adc);
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
if (! eadc_modinit_mask) {
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
/* Select IP clock source
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
CLK_SetModuleClock_S(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
/* Enable IP clock
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
CLK_EnableModuleClock_S(modinit->clkidx);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
// Set the ADC internal sampling time, input mode as single-end and enable the A/D converter
EADC_Open(eadc_base, EADC_CTL_DIFFEN_SINGLE_END);
}
uint32_t chn = NU_MODSUBINDEX(obj->adc);
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
// Configure the sample module Nmod for analog input channel Nch and software trigger source
EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn);

View File

@ -53,6 +53,11 @@ void analogout_init(dac_t *obj, PinName pin)
uint32_t chn = NU_MODSUBINDEX(obj->dac);
MBED_ASSERT(chn < NU_DACCHN_MAXNUM);
obj->pin = pin;
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac);
/* Module-level setup from here */
@ -66,12 +71,6 @@ void analogout_init(dac_t *obj, PinName pin)
* channels are deactivated.
*/
if ((! dac_modinit_mask[0]) && (! dac_modinit_mask[1])) {
/* Reset IP
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
/* Select IP clock source and clock divider
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@ -83,7 +82,13 @@ void analogout_init(dac_t *obj, PinName pin)
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
CLK_EnableModuleClock_S(modinit->clkidx);
/* Reset IP
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
/* The conversion settling time is 8us when 12-bit input code transition from
* lowest code (0x000) to highest code (0xFFF). */
DAC_SetDelayTime(dac_base, 8);
@ -98,8 +103,7 @@ void analogout_init(dac_t *obj, PinName pin)
/* Set the software trigger, enable DAC event trigger mode and enable D/A converter */
DAC_Open(dac_base, chn, DAC_SOFTWARE_TRIGGER);
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
/* Mark channel allocated */
dac_modinit_mask[modidx] |= 1 << chn;
@ -125,7 +129,7 @@ void analogout_free(dac_t *obj)
/* Mark channel free */
dac_modinit_mask[modidx] &= ~(1 << chn);
/* Close channel */
DAC_Close(dac_base, chn);
@ -140,6 +144,10 @@ void analogout_free(dac_t *obj)
*/
CLK_DisableModuleClock_S(modinit->clkidx);
}
/* Free up pin */
gpio_set(obj->pin);
obj->pin = NC;
}
void analogout_write(dac_t *obj, float value)

View File

@ -79,7 +79,7 @@ static const nu_modidx_ns_t modidx_ns_tab[] = {
#if defined(SCU_INIT_PNSSET3_VAL) && SCU_INIT_PNSSET3_VAL
{SPI0_RST, SPI0_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 0)},
{SPI1_RST, SPI1_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 1)},
{SPI2_RST, SPI1_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 2)},
{SPI2_RST, SPI2_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 2)},
{SPI3_RST, SPI3_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 3)},
{NU_SYS_MODIDX_UNDEF, NU_CLK_MODIDX_UNDEF, SCU_INIT_PNSSET3_VAL & (1 << 4)},
{SPI5_RST, SPI5_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 5)},

View File

@ -69,18 +69,18 @@ void dma_init(void)
dma_chn_mask = ~NU_PDMA_CH_Msk;
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(dma_modinit.rsetidx);
/* Enable IP clock
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
CLK_EnableModuleClock_S(dma_modinit.clkidx);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(dma_modinit.rsetidx);
/* Check security state of PDMA0/1 match the partition policy above. */
PDMA_T *pdma_base = dma_modbase();
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L)

View File

@ -62,10 +62,23 @@ void gpio_mode(gpio_t *obj, PinMode mode)
return;
}
uint32_t pin_index = NU_PININDEX(obj->pin);
uint32_t port_index = NU_PINPORT(obj->pin);
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
switch (mode) {
case PullNone:
if (mode == PullNone) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_DISABLE);
}
case PullDown:
if (mode == PullDown) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_PULL_DOWN);
}
case PullUp:
if (mode == PullUp) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_PULL_UP);
}
/* H/W doesn't support separate configuration for input pull mode/direction.
* We translate to input-only/push-pull output I/O mode dependent on direction. */
obj->mode = (obj->direction == PIN_INPUT) ? InputOnly : PushPullOutput;
@ -110,10 +123,23 @@ void gpio_dir(gpio_t *obj, PinDirection direction)
obj->direction = direction;
uint32_t pin_index = NU_PININDEX(obj->pin);
uint32_t port_index = NU_PINPORT(obj->pin);
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
switch (obj->mode) {
case PullNone:
if (obj->mode == PullNone) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_DISABLE);
}
case PullDown:
if (obj->mode == PullDown) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_PULL_DOWN);
}
case PullUp:
if (obj->mode == PullUp) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_PULL_UP);
}
/* H/W doesn't support separate configuration for input pull mode/direction.
* We translate to input-only/push-pull output I/O mode dependent on direction. */
obj->mode = (obj->direction == PIN_INPUT) ? InputOnly : PushPullOutput;

View File

@ -85,9 +85,10 @@ static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable
static void i2c_rollback_vector_interrupt(i2c_t *obj);
#endif
#define TRANCTRL_STARTED (1)
#define TRANCTRL_NAKLASTDATA (1 << 1)
#define TRANCTRL_LASTDATANAKED (1 << 2)
#define TRANCTRL_STARTED (1) // Guard I2C ISR from data transfer prematurely
#define TRANCTRL_NAKLASTDATA (1 << 1) // Request NACK on last data
#define TRANCTRL_LASTDATANAKED (1 << 2) // Last data NACKed
#define TRANCTRL_RECVDATA (1 << 3) // Receive data available
uint32_t us_ticker_read(void);
@ -102,11 +103,11 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
obj->i2c.pin_sda = sda;
obj->i2c.pin_scl = scl;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
/* Select IP clock source
*
@ -114,8 +115,11 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
*/
CLK_EnableModuleClock_S(modinit->clkidx);
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
#if DEVICE_I2C_ASYNCH
obj->i2c.dma_usage = DMA_USAGE_NEVER;
@ -597,11 +601,17 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x50 || status == 0x58) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x58) {
i2c_fsm_tranfini(obj, 1);
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
} else {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -610,6 +620,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
} else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
@ -664,12 +675,18 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x80 || status == 0x88) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x88) {
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
} else {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -678,6 +695,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
} else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
@ -700,12 +718,18 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x90 || status == 0x98) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x98) {
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
} else {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -714,6 +738,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
} else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;

View File

@ -105,12 +105,6 @@ void lp_ticker_init(void)
}
ticker_inited = 1;
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(TIMER_MODINIT.rsetidx);
/* Select IP clock source
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@ -123,6 +117,12 @@ void lp_ticker_init(void)
*/
CLK_EnableModuleClock_S(TIMER_MODINIT.clkidx);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Configure clock

View File

@ -42,26 +42,32 @@ struct port_s {
struct analogin_s {
ADCName adc;
PinName pin;
};
struct dac_s {
DACName dac;
PinName pin;
};
struct serial_s {
UARTName uart;
PinName pin_tx;
PinName pin_rx;
PinName pin_rts;
PinName pin_cts;
uint32_t baudrate;
uint32_t databits;
uint32_t parity;
uint32_t stopbits;
void (*vec)(void);
uint32_t irq_handler;
uint32_t irq_id;
uint32_t irq_en;
uint32_t inten_msk;
// Async transfer related fields
DMAUsage dma_usage_tx;
DMAUsage dma_usage_rx;
@ -78,17 +84,20 @@ struct spi_s {
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
// Async transfer related fields
DMAUsage dma_usage;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
uint32_t hdlr_async;
};
struct i2c_s {
I2CName i2c;
PinName pin_sda;
PinName pin_scl;
int slaveaddr_state;
uint32_t tran_ctrl;
@ -107,6 +116,7 @@ struct i2c_s {
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period_us;
uint32_t pulsewidth_us;
};

View File

@ -18,6 +18,7 @@
#include "mbed_assert.h"
#include "pinmap.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "mbed_error.h"
#include "partition_M2351.h"
#include "hal_secure.h"
@ -77,6 +78,21 @@ void pin_mode(PinName pin, PinMode mode)
*/
}
/* List of peripherals excluded from testing */
const PeripheralList *pinmap_restricted_peripherals()
{
static const int perifs[] = {
STDIO_UART // Dedicated to USB VCOM
};
static const PeripheralList peripheral_list = {
sizeof(perifs) / sizeof(perifs[0]),
perifs
};
return &peripheral_list;
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
__NONSECURE_ENTRY
void pin_function_s(int32_t pin, int32_t data)

View File

@ -68,16 +68,10 @@ void pwmout_init(pwmout_t* obj, PinName pin)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->pwm);
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
}
obj->pin = pin;
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
// NOTE: Channels 0/1/2/3/4/5 share a clock source.
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0x3F) == 0) {
@ -94,8 +88,16 @@ void pwmout_init(pwmout_t* obj, PinName pin)
CLK_EnableModuleClock_S(modinit->clkidx);
}
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
}
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
// Default: period = 10 ms, pulse width = 0 ms
obj->period_us = 1000 * 10;
@ -132,6 +134,10 @@ void pwmout_free(pwmout_t* obj)
// Mark this module to be deinited.
int i = modinit - pwm_modinit_tab;
pwm_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->pin);
obj->pin = NC;
}
void pwmout_write(pwmout_t* obj, float value)

View File

@ -85,9 +85,10 @@ static void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable);
static int serial_is_rx_complete(serial_t *obj);
static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch);
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
#endif
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
bool serial_can_deep_sleep(void);
static struct nu_uart_var uart0_var = {
@ -199,13 +200,15 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
if (! var->ref_cnt) {
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
obj->serial.pin_tx = tx;
obj->serial.pin_rx = rx;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
if (! var->ref_cnt) {
/* Select IP clock source
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@ -218,8 +221,11 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
*/
CLK_EnableModuleClock_S(modinit->clkidx);
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
// Configure baudrate
int baudrate = 9600;
@ -315,6 +321,16 @@ void serial_free(serial_t *obj)
int i = modinit - uart_modinit_tab;
uart_modinit_mask &= ~(1 << i);
}
// Free up pins
gpio_set(obj->serial.pin_tx);
gpio_set(obj->serial.pin_rx);
gpio_set(obj->serial.pin_rts);
gpio_set(obj->serial.pin_cts);
obj->serial.pin_tx = NC;
obj->serial.pin_rx = NC;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
}
void serial_baud(serial_t *obj, int baudrate)
@ -361,6 +377,16 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
{
UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart);
// Free up old rts/cts pins when they are different from new ones
if (obj->serial.pin_rts != rxflow) {
gpio_set(obj->serial.pin_rts);
obj->serial.pin_rts = rxflow;
}
if (obj->serial.pin_cts != txflow) {
gpio_set(obj->serial.pin_cts);
obj->serial.pin_cts = txflow;
}
if (rxflow != NC) {
// Check if RTS pin matches.
uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS);
@ -531,7 +557,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->INTSTS & (UART_INTSTS_RDAINT_Msk | UART_INTSTS_RXTOINT_Msk)) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next read.
UART_DISABLE_INT(uart_base, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, RxIrq)) {
// Call irq_handler() only when RxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, RxIrq);
}
}
@ -539,7 +566,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->INTSTS & UART_INTSTS_THREINT_Msk) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next write.
UART_DISABLE_INT(uart_base, UART_INTEN_THREIEN_Msk);
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, TxIrq)) {
// Call irq_handler() only when TxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, TxIrq);
}
}
@ -1179,6 +1207,8 @@ static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch)
}
}
#endif // #if DEVICE_SERIAL_ASYNCH
static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
{
int inten_msk = 0;
@ -1195,8 +1225,6 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
return !! inten_msk;
}
#endif // #if DEVICE_SERIAL_ASYNCH
bool serial_can_deep_sleep(void)
{
bool sleep_allowed = 1;

View File

@ -147,11 +147,15 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(ssel, PinMap_SPI_SSEL);
/* Select IP clock source
*
@ -165,16 +169,11 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
*/
CLK_EnableModuleClock_S(modinit->clkidx);
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(modinit->rsetidx);
#if DEVICE_SPI_ASYNCH
obj->spi.dma_usage = DMA_USAGE_NEVER;
@ -224,6 +223,16 @@ void spi_free(spi_t *obj)
// Mark this module to be deinited.
int i = modinit - spi_modinit_tab;
spi_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->spi.pin_mosi);
gpio_set(obj->spi.pin_miso);
gpio_set(obj->spi.pin_sclk);
gpio_set(obj->spi.pin_ssel);
obj->spi.pin_mosi = NC;
obj->spi.pin_miso = NC;
obj->spi.pin_sclk = NC;
obj->spi.pin_ssel = NC;
}
void spi_format(spi_t *obj, int bits, int mode, int slave)
@ -407,6 +416,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
SPI_ENABLE_SYNC(spi_base);
// Initialize total SPI transfer frames
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
spi_master_write_asynch(obj, spi_fifo_depth(obj) / 2);
@ -677,16 +689,12 @@ static uint32_t spi_event_check(spi_t *obj)
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
max_tx = NU_MIN(max_tx, tx_limit);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while ((n_words < max_tx) && spi_writeable(obj)) {
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
if (spi_is_tx_complete(obj)) {
// Transmit dummy as transmit buffer is empty
SPI_WRITE_TX(spi_base, 0);
@ -709,6 +717,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
obj->tx_buff.pos ++;
}
n_words ++;
obj->spi.txrx_rmn --;
}
//Return the number of words that have been sent
@ -729,15 +738,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
static uint32_t spi_master_read_asynch(spi_t *obj)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while ((n_words < max_rx) && spi_readable(obj)) {
while (spi_readable(obj)) {
if (spi_is_rx_complete(obj)) {
// Disregard as receive buffer is full
SPI_READ_RX(spi_base);

View File

@ -79,12 +79,6 @@ void us_ticker_init(void)
}
ticker_inited = 1;
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(TIMER_MODINIT.rsetidx);
/* Select IP clock source
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@ -97,6 +91,12 @@ void us_ticker_init(void)
*/
CLK_EnableModuleClock_S(TIMER_MODINIT.clkidx);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule_S(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Timer for normal counter

View File

@ -150,11 +150,13 @@ const PinMap PinMap_ADC[] = {
{PB_13, ADC_0_10, SYS_GPB_MFPH_PB13MFP_EADC_CH10},
{PB_14, ADC_0_11, SYS_GPB_MFPH_PB14MFP_EADC_CH11},
{PB_15, ADC_0_12, SYS_GPB_MFPH_PB15MFP_EADC_CH12},
#if defined(TARGET_M45xD_M45xC)
{PD_0, ADC_0_6, SYS_GPD_MFPL_PD0MFP_EADC_CH6},
{PD_1, ADC_0_11, SYS_GPD_MFPL_PD1MFP_EADC_CH11},
{PD_8, ADC_0_7, SYS_GPD_MFPH_PD8MFP_EADC_CH7},
{PD_9, ADC_0_10, SYS_GPD_MFPH_PD9MFP_EADC_CH10},
#endif
{NC, NC, 0}
};
@ -174,7 +176,9 @@ const PinMap PinMap_I2C_SDA[] = {
{PE_0, I2C_1, SYS_GPE_MFPL_PE0MFP_I2C1_SDA},
{PE_5, I2C_1, SYS_GPE_MFPL_PE5MFP_I2C1_SDA},
{PE_9, I2C_1, SYS_GPE_MFPH_PE9MFP_I2C1_SDA},
#if defined(TARGET_M45xD_M45xC)
{PE_11, I2C_1, SYS_GPE_MFPH_PE11MFP_I2C1_SDA},
#endif
{PE_13, I2C_0, SYS_GPE_MFPH_PE13MFP_I2C0_SDA},
{PF_4, I2C_1, SYS_GPF_MFPL_PF4MFP_I2C1_SDA},
@ -187,7 +191,9 @@ const PinMap PinMap_I2C_SCL[] = {
{PD_5, I2C_0, SYS_GPD_MFPL_PD5MFP_I2C0_SCL},
{PE_4, I2C_1, SYS_GPE_MFPL_PE4MFP_I2C1_SCL},
{PE_8, I2C_1, SYS_GPE_MFPH_PE8MFP_I2C1_SCL},
#if defined(TARGET_M45xD_M45xC)
{PE_10, I2C_1, SYS_GPE_MFPH_PE10MFP_I2C1_SCL},
#endif
{PE_12, I2C_0, SYS_GPE_MFPH_PE12MFP_I2C0_SCL},
{PF_3, I2C_1, SYS_GPF_MFPL_PF3MFP_I2C1_SCL},
@ -239,16 +245,24 @@ const PinMap PinMap_UART_TX[] = {
{PA_2, UART_0, SYS_GPA_MFPL_PA2MFP_UART0_TXD},
{PA_8, UART_3, SYS_GPA_MFPH_PA8MFP_UART3_TXD},
{PB_1, UART_2, SYS_GPB_MFPL_PB1MFP_UART2_TXD},
#if defined(TARGET_M45xD_M45xC)
{PB_3, UART_1, SYS_GPB_MFPL_PB3MFP_UART1_TXD},
#endif
{PB_3, UART_3, SYS_GPB_MFPL_PB3MFP_UART3_TXD},
#if defined(TARGET_M45xD_M45xC)
{PB_4, UART_2, SYS_GPB_MFPL_PB4MFP_UART2_TXD},
{PC_0, UART_3, SYS_GPC_MFPL_PC0MFP_UART3_TXD},
#endif
{PC_2, UART_2, SYS_GPC_MFPL_PC2MFP_UART2_TXD},
#if defined(TARGET_M45xD_M45xC)
{PC_6, UART_0, SYS_GPC_MFPL_PC6MFP_UART0_TXD},
#endif
{PD_1, UART_0, SYS_GPD_MFPL_PD1MFP_UART0_TXD},
{PD_12, UART_3, SYS_GPD_MFPH_PD12MFP_UART3_TXD},
{PE_8, UART_1, SYS_GPE_MFPH_PE8MFP_UART1_TXD},
#if defined(TARGET_M45xD_M45xC)
{PE_10, UART_3, SYS_GPE_MFPH_PE10MFP_UART3_TXD},
#endif
{PE_12, UART_1, SYS_GPE_MFPH_PE12MFP_UART1_TXD},
{NC, NC, 0}
@ -259,17 +273,25 @@ const PinMap PinMap_UART_RX[] = {
{PA_3, UART_0, SYS_GPA_MFPL_PA3MFP_UART0_RXD},
{PA_9, UART_3, SYS_GPA_MFPH_PA9MFP_UART3_RXD},
{PB_0, UART_2, SYS_GPB_MFPL_PB0MFP_UART2_RXD},
#if defined(TARGET_M45xD_M45xC)
{PB_2, UART_1, SYS_GPB_MFPL_PB2MFP_UART1_RXD},
#endif
{PB_2, UART_3, SYS_GPB_MFPL_PB2MFP_UART3_RXD},
#if defined(TARGET_M45xD_M45xC)
{PB_5, UART_2, SYS_GPB_MFPL_PB5MFP_UART2_RXD},
{PC_1, UART_3, SYS_GPC_MFPL_PC1MFP_UART3_RXD},
#endif
{PC_3, UART_2, SYS_GPC_MFPL_PC3MFP_UART2_RXD},
#if defined(TARGET_M45xD_M45xC)
{PC_7, UART_0, (int) SYS_GPC_MFPL_PC7MFP_UART0_RXD},
#endif
{PD_0, UART_0, SYS_GPD_MFPL_PD0MFP_UART0_RXD},
{PD_6, UART_0, SYS_GPD_MFPL_PD6MFP_UART0_RXD},
{PD_13, UART_3, SYS_GPD_MFPH_PD13MFP_UART3_RXD},
{PE_9, UART_1, SYS_GPE_MFPH_PE9MFP_UART1_RXD},
#if defined(TARGET_M45xD_M45xC)
{PE_11, UART_3, SYS_GPE_MFPH_PE11MFP_UART3_RXD},
#endif
{PE_13, UART_1, SYS_GPE_MFPH_PE13MFP_UART1_RXD},
{NC, NC, 0}

View File

@ -76,10 +76,31 @@ typedef enum {
// Generic naming
PA_0 = NU_PORT_N_PIN_TO_PINNAME(0, 0), PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, PA_8, PA_9, PA_10, PA_11, PA_12, PA_13, PA_14, PA_15,
#if defined(TARGET_M45xD_M45xC)
PB_0 = NU_PORT_N_PIN_TO_PINNAME(1, 0), PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8, PB_11 = PB_8 + 3, PB_12, PB_13, PB_14, PB_15,
#elif defined(TARGET_M45xG_M45xE)
PB_0 = NU_PORT_N_PIN_TO_PINNAME(1, 0), PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8, PB_9, PB_10, PB_11, PB_12, PB_13, PB_14, PB_15,
#endif
#if defined(TARGET_M45xD_M45xC)
PC_0 = NU_PORT_N_PIN_TO_PINNAME(2, 0), PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_10 = PC_8 + 2, PC_11, PC_12, PC_13,
#elif defined(TARGET_M45xG_M45xE)
PC_0 = NU_PORT_N_PIN_TO_PINNAME(2, 0), PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9, PC_10, PC_11, PC_12, PC_13, PC_14, PC_15,
#endif
#if defined(TARGET_M45xD_M45xC)
PD_0 = NU_PORT_N_PIN_TO_PINNAME(3, 0), PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, PD_12 = PD_9 + 3, PD_13, PD_14, PD_15,
#elif defined(TARGET_M45xG_M45xE)
PD_0 = NU_PORT_N_PIN_TO_PINNAME(3, 0), PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, PD_10, PD_11, PD_12, PD_13, PD_14, PD_15,
#endif
#if defined(TARGET_M45xD_M45xC)
PE_0 = NU_PORT_N_PIN_TO_PINNAME(4, 0), PE_1, PE_3 = PE_1 + 2, PE_4, PE_5, PE_8 = PE_5 + 3, PE_9, PE_10, PE_11, PE_12, PE_13,
#elif defined(TARGET_M45xG_M45xE)
PE_0 = NU_PORT_N_PIN_TO_PINNAME(4, 0), PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_10, PE_11, PE_12, PE_13, PE_14,
#endif
PF_0 = NU_PORT_N_PIN_TO_PINNAME(5, 0), PF_1, PF_2, PF_3, PF_4, PF_5, PF_6, PF_7,
// Arduino UNO naming
@ -134,6 +155,9 @@ typedef enum {
BUTTON1 = SW2,
BUTTON2 = SW3,
// Force PinName to 32-bit required by NU_PINNAME_BIND(...)
FORCE_ENUM_PINNAME_32BIT = 0x7FFFFFFF,
} PinName;
#ifdef __cplusplus

View File

@ -52,29 +52,32 @@ void analogin_init(analogin_t *obj, PinName pin)
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->adc);
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
if (! eadc_modinit_mask) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Set the ADC internal sampling time, input mode as single-end and enable the A/D converter
EADC_Open(eadc_base, EADC_CTL_DIFFEN_SINGLE_END);
EADC_SetInternalSampleTime(eadc_base, 6);
}
uint32_t chn = NU_MODSUBINDEX(obj->adc);
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
// Configure the sample module Nmod for analog input channel Nch and software trigger source
EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn);

View File

@ -52,20 +52,24 @@ void analogout_init(dac_t *obj, PinName pin)
uint32_t chn = NU_MODSUBINDEX(obj->dac);
MBED_ASSERT(chn < NU_DACCHN_MAXNUM);
obj->pin = pin;
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac);
/* Module-level setup from here */
if (! dac_modinit_mask[modidx]) {
/* Reset IP */
SYS_ResetModule(modinit->rsetidx);
/* Select IP clock source and clock divider */
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
/* Enable IP clock */
CLK_EnableModuleClock(modinit->clkidx);
/* Reset IP */
SYS_ResetModule(modinit->rsetidx);
/* The conversion settling time is 8us when 12-bit input code transition from
* lowest code (0x000) to highest code (0xFFF). */
DAC_SetDelayTime(dac_base, 8);
@ -79,9 +83,6 @@ void analogout_init(dac_t *obj, PinName pin)
/* Set the software trigger, enable DAC event trigger mode and enable D/A converter */
DAC_Open(dac_base, chn, DAC_SOFTWARE_TRIGGER);
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
/* Mark channel allocated */
dac_modinit_mask[modidx] |= 1 << chn;
@ -118,6 +119,10 @@ void analogout_free(dac_t *obj)
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
/* Free up pin */
gpio_set(obj->pin);
obj->pin = NC;
}
void analogout_write(dac_t *obj, float value)

View File

@ -52,17 +52,20 @@ void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->can);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
obj->index = 0;
obj->pin_rd = rd;
obj->pin_td = td;
pinmap_pinout(td, PinMap_CAN_TD);
pinmap_pinout(rd, PinMap_CAN_RD);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
obj->index = 0;
/* For M453 mbed Board Transmitter Setting (RS Pin) */
GPIO_SetMode(PA, BIT0| BIT1, GPIO_MODE_OUTPUT);
@ -72,7 +75,7 @@ void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
CAN_Open((CAN_T *)NU_MODBASE(obj->can), hz, CAN_NORMAL_MODE);
can_filter(obj, 0, 0, CANStandard, 0);
}
}
void can_init(can_t *obj, PinName rd, PinName td)
@ -93,6 +96,12 @@ void can_free(can_t *obj)
SYS_ResetModule(modinit->rsetidx);
CLK_DisableModuleClock(modinit->clkidx);
/* Free up pins */
gpio_set(obj->pin_rd);
gpio_set(obj->pin_td);
obj->pin_rd = NC;
obj->pin_td = NC;
}
int can_frequency(can_t *obj, int hz)

View File

@ -50,15 +50,15 @@ void dma_init(void)
dma_inited = 1;
dma_chn_mask = ~NU_PDMA_CH_Msk;
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
// Reset this module
SYS_ResetModule(dma_modinit.rsetidx);
// Enable IP clock
CLK_EnableModuleClock(dma_modinit.clkidx);
// Reset this module
SYS_ResetModule(dma_modinit.rsetidx);
PDMA_Open(0);
NVIC_SetVector(dma_modinit.irq_n, (uint32_t) dma_modinit.var);
NVIC_EnableIRQ(dma_modinit.irq_n);
}

View File

@ -94,9 +94,10 @@ static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable
static void i2c_rollback_vector_interrupt(i2c_t *obj);
#endif
#define TRANCTRL_STARTED (1)
#define TRANCTRL_NAKLASTDATA (1 << 1)
#define TRANCTRL_LASTDATANAKED (1 << 2)
#define TRANCTRL_STARTED (1) // Guard I2C ISR from data transfer prematurely
#define TRANCTRL_NAKLASTDATA (1 << 1) // Request NACK on last data
#define TRANCTRL_LASTDATANAKED (1 << 2) // Last data NACKed
#define TRANCTRL_RECVDATA (1 << 3) // Receive data available
uint32_t us_ticker_read(void);
@ -110,16 +111,19 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->i2c.i2c);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
obj->i2c.pin_sda = sda;
obj->i2c.pin_scl = scl;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_I2C_ASYNCH
obj->i2c.dma_usage = DMA_USAGE_NEVER;
obj->i2c.event = 0;
@ -641,7 +645,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x50 || status == 0x58) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x58) {
@ -653,6 +660,10 @@ static void i2c_irq(i2c_t *obj)
#endif
i2c_fsm_tranfini(obj, 1);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -661,6 +672,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {
@ -719,7 +731,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x80 || status == 0x88) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x88) {
@ -732,6 +747,10 @@ static void i2c_irq(i2c_t *obj)
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -740,6 +759,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {
@ -764,7 +784,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x90 || status == 0x98) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x98) {
@ -777,6 +800,10 @@ static void i2c_irq(i2c_t *obj)
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -785,6 +812,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {

View File

@ -80,15 +80,15 @@ void lp_ticker_init(void)
}
ticker_inited = 1;
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Configure clock

View File

@ -28,10 +28,6 @@ extern "C" {
#endif
struct gpio_irq_s {
//IRQn_Type irq_n;
//uint32_t irq_index;
//uint32_t event;
PinName pin;
uint32_t irq_handler;
uint32_t irq_id;
@ -45,16 +41,21 @@ struct port_s {
struct analogin_s {
ADCName adc;
//PinName pin;
PinName pin;
};
struct dac_s {
DACName dac;
PinName pin;
};
struct serial_s {
UARTName uart;
PinName pin_tx;
PinName pin_rx;
PinName pin_rts;
PinName pin_cts;
uint32_t baudrate;
uint32_t databits;
uint32_t parity;
@ -83,20 +84,18 @@ struct spi_s {
PinName pin_sclk;
PinName pin_ssel;
//void (*vec)(void);
// Async transfer related fields
DMAUsage dma_usage;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
//void (*irq_handler_tx_async)(void);
//void (*irq_handler_rx_async)(void);
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
};
struct i2c_s {
I2CName i2c;
//void (*vec)(void);
PinName pin_sda;
PinName pin_scl;
int slaveaddr_state;
uint32_t tran_ctrl;
@ -114,13 +113,15 @@ struct i2c_s {
struct pwmout_s {
PWMName pwm;
//PinName pin;
PinName pin;
uint32_t period_us;
uint32_t pulsewidth_us;
};
struct can_s {
CANName can;
PinName pin_rd;
PinName pin_td;
char index;
};
#ifdef __cplusplus

View File

@ -17,6 +17,7 @@
#include "mbed_assert.h"
#include "pinmap.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "mbed_error.h"
/**
@ -90,3 +91,18 @@ void pin_mode(PinName pin, PinMode mode)
* 2. PushPullOutput/PIN_INPUT
*/
}
/* List of peripherals excluded from testing */
const PeripheralList *pinmap_restricted_peripherals()
{
static const int perifs[] = {
STDIO_UART // Dedicated to USB VCOM
};
static const PeripheralList peripheral_list = {
sizeof(perifs) / sizeof(perifs[0]),
perifs
};
return &peripheral_list;
}

View File

@ -67,38 +67,41 @@ void pwmout_init(pwmout_t* obj, PinName pin)
const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->pwm);
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
// NOTE: Channels 0/1/2/3/4/5 share a clock source.
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0x3F) == 0) {
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
}
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
}
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
// NOTE: Channels 0/1/2/3/4/5 share a clock source.
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0x3F) == 0) {
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
}
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
// Default: period = 10 ms, pulse width = 0 ms
obj->period_us = 1000 * 10;
obj->pulsewidth_us = 0;
pwmout_config(obj);
// Enable output of the specified PWM channel
PWM_EnableOutput(pwm_base, 1 << chn);
PWM_Start(pwm_base, 1 << chn);
((struct nu_pwm_var *) modinit->var)->en_msk |= 1 << chn;
// Mark this module to be inited.
int i = modinit - pwm_modinit_tab;
pwm_modinit_mask |= 1 << i;
@ -123,6 +126,10 @@ void pwmout_free(pwmout_t* obj)
// Mark this module to be deinited.
int i = modinit - pwm_modinit_tab;
pwm_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->pin);
obj->pin = NC;
}
void pwmout_write(pwmout_t* obj, float value)

View File

@ -81,9 +81,10 @@ static void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable);
static int serial_is_rx_complete(serial_t *obj);
static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch);
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
#endif
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
bool serial_can_deep_sleep(void);
static struct nu_uart_var uart0_var = {
@ -168,18 +169,24 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
MBED_ASSERT(modinit->modname == (int) obj->serial.uart);
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
if (! var->ref_cnt) {
// Reset this module
SYS_ResetModule(modinit->rsetidx);
obj->serial.pin_tx = tx;
obj->serial.pin_rx = rx;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
if (! var->ref_cnt) {
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Configure baudrate
int baudrate = 9600;
@ -270,6 +277,16 @@ void serial_free(serial_t *obj)
int i = modinit - uart_modinit_tab;
uart_modinit_mask &= ~(1 << i);
}
// Free up pins
gpio_set(obj->serial.pin_tx);
gpio_set(obj->serial.pin_rx);
gpio_set(obj->serial.pin_rts);
gpio_set(obj->serial.pin_cts);
obj->serial.pin_tx = NC;
obj->serial.pin_rx = NC;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
}
void serial_baud(serial_t *obj, int baudrate) {
@ -314,6 +331,16 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
{
UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart);
// Free up old rts/cts pins when they are different from new ones
if (obj->serial.pin_rts != rxflow) {
gpio_set(obj->serial.pin_rts);
obj->serial.pin_rts = rxflow;
}
if (obj->serial.pin_cts != txflow) {
gpio_set(obj->serial.pin_cts);
obj->serial.pin_cts = txflow;
}
if (rxflow != NC) {
// Check if RTS pin matches.
uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS);
@ -463,7 +490,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->INTSTS & (UART_INTSTS_RDAINT_Msk | UART_INTSTS_RXTOINT_Msk)) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next read.
UART_DISABLE_INT(uart_base, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, RxIrq)) {
// Call irq_handler() only when RxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, RxIrq);
}
}
@ -471,7 +499,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->INTSTS & UART_INTSTS_THREINT_Msk) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next write.
UART_DISABLE_INT(uart_base, UART_INTEN_THREIEN_Msk);
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, TxIrq)) {
// Call irq_handler() only when TxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, TxIrq);
}
}
@ -1101,6 +1130,8 @@ static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch)
}
}
#endif // #if DEVICE_SERIAL_ASYNCH
static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
{
int inten_msk = 0;
@ -1117,8 +1148,6 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
return !! inten_msk;
}
#endif // #if DEVICE_SERIAL_ASYNCH
bool serial_can_deep_sleep(void)
{
bool sleep_allowed = 1;

View File

@ -131,24 +131,24 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_SPI_ASYNCH
obj->spi.dma_usage = DMA_USAGE_NEVER;
@ -195,6 +195,16 @@ void spi_free(spi_t *obj)
// Mark this module to be deinited.
int i = modinit - spi_modinit_tab;
spi_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->spi.pin_mosi);
gpio_set(obj->spi.pin_miso);
gpio_set(obj->spi.pin_sclk);
gpio_set(obj->spi.pin_ssel);
obj->spi.pin_mosi = NC;
obj->spi.pin_miso = NC;
obj->spi.pin_sclk = NC;
obj->spi.pin_ssel = NC;
}
void spi_format(spi_t *obj, int bits, int mode, int slave)
@ -380,6 +390,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
SPI_ENABLE_SYNC(spi_base);
// Initialize total SPI transfer frames
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
spi_master_write_asynch(obj, NU_SPI_FIFO_DEPTH / 2);
@ -648,16 +661,12 @@ static uint32_t spi_event_check(spi_t *obj)
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
max_tx = NU_MIN(max_tx, tx_limit);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while ((n_words < max_tx) && spi_writeable(obj)) {
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
if (spi_is_tx_complete(obj)) {
// Transmit dummy as transmit buffer is empty
SPI_WRITE_TX(spi_base, 0);
@ -681,6 +690,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
obj->tx_buff.pos ++;
}
n_words ++;
obj->spi.txrx_rmn --;
}
//Return the number of words that have been sent
@ -701,15 +711,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
static uint32_t spi_master_read_asynch(spi_t *obj)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while ((n_words < max_rx) && spi_readable(obj)) {
while (spi_readable(obj)) {
if (spi_is_rx_complete(obj)) {
// Disregard as receive buffer is full
SPI_READ_RX(spi_base);

View File

@ -56,15 +56,15 @@ void us_ticker_init(void)
}
ticker_inited = 1;
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Timer for normal counter

View File

@ -139,6 +139,9 @@ typedef enum {
BUTTON1 = SW2,
BUTTON2 = SW3,
// Force PinName to 32-bit required by NU_PINNAME_BIND(...)
FORCE_ENUM_PINNAME_32BIT = 0x7FFFFFFF,
} PinName;
#ifdef __cplusplus

View File

@ -53,27 +53,30 @@ void analogin_init(analogin_t *obj, PinName pin)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->adc);
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
if (! eadc_modinit_mask) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Set the ADC internal sampling time, input mode as single-end and enable the A/D converter
EADC_Open(eadc_base, EADC_CTL_DIFFEN_SINGLE_END);
}
uint32_t chn = NU_MODSUBINDEX(obj->adc);
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
// Configure the sample module Nmod for analog input channel Nch and software trigger source
EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn);

View File

@ -53,6 +53,11 @@ void analogout_init(dac_t *obj, PinName pin)
uint32_t chn = NU_MODSUBINDEX(obj->dac);
MBED_ASSERT(chn < NU_DACCHN_MAXNUM);
obj->pin = pin;
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac);
/* Module-level setup from here */
@ -66,15 +71,15 @@ void analogout_init(dac_t *obj, PinName pin)
* channels are deactivated.
*/
if ((! dac_modinit_mask[0]) && (! dac_modinit_mask[1])) {
/* Reset IP */
SYS_ResetModule(modinit->rsetidx);
/* Select IP clock source and clock divider */
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
/* Enable IP clock */
CLK_EnableModuleClock(modinit->clkidx);
/* Reset IP */
SYS_ResetModule(modinit->rsetidx);
/* The conversion settling time is 8us when 12-bit input code transition from
* lowest code (0x000) to highest code (0xFFF). */
DAC_SetDelayTime(dac_base, 8);
@ -88,9 +93,6 @@ void analogout_init(dac_t *obj, PinName pin)
/* Set the software trigger, enable DAC event trigger mode and enable D/A converter */
DAC_Open(dac_base, chn, DAC_SOFTWARE_TRIGGER);
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
/* Mark channel allocated */
dac_modinit_mask[modidx] |= 1 << chn;
@ -128,6 +130,10 @@ void analogout_free(dac_t *obj)
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
/* Free up pin */
gpio_set(obj->pin);
obj->pin = NC;
}
void analogout_write(dac_t *obj, float value)

View File

@ -59,22 +59,26 @@ void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->can);
obj->pin_rd = rd;
obj->pin_td = td;
pinmap_pinout(td, PinMap_CAN_TD);
pinmap_pinout(rd, PinMap_CAN_RD);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
NVIC_DisableIRQ(CAN0_IRQn);
NVIC_DisableIRQ(CAN1_IRQn);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
NVIC_DisableIRQ(CAN1_IRQn);
if(obj->can == CAN_1) {
obj->index = 1;
} else
obj->index = 0;
pinmap_pinout(td, PinMap_CAN_TD);
pinmap_pinout(rd, PinMap_CAN_RD);
#if 0
/* TBD: For M487 mbed Board Transmitter Setting (RS Pin) */
GPIO_SetMode(PA, BIT2| BIT3, GPIO_MODE_OUTPUT);
@ -103,6 +107,12 @@ void can_free(can_t *obj)
SYS_ResetModule(modinit->rsetidx);
CLK_DisableModuleClock(modinit->clkidx);
/* Free up pins */
gpio_set(obj->pin_rd);
gpio_set(obj->pin_td);
obj->pin_rd = NC;
obj->pin_td = NC;
}
int can_frequency(can_t *obj, int hz)

View File

@ -51,12 +51,12 @@ void dma_init(void)
dma_chn_mask = ~NU_PDMA_CH_Msk;
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
// Reset this module
SYS_ResetModule(dma_modinit.rsetidx);
// Enable IP clock
CLK_EnableModuleClock(dma_modinit.clkidx);
// Reset this module
SYS_ResetModule(dma_modinit.rsetidx);
PDMA_Open(0);
NVIC_SetVector(dma_modinit.irq_n, (uint32_t) dma_modinit.var);

View File

@ -62,10 +62,23 @@ void gpio_mode(gpio_t *obj, PinMode mode)
return;
}
uint32_t pin_index = NU_PININDEX(obj->pin);
uint32_t port_index = NU_PINPORT(obj->pin);
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
switch (mode) {
case PullNone:
if (mode == PullNone) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_DISABLE);
}
case PullDown:
if (mode == PullDown) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_PULL_DOWN);
}
case PullUp:
if (mode == PullUp) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_PULL_UP);
}
/* H/W doesn't support separate configuration for input pull mode/direction.
* We translate to input-only/push-pull output I/O mode dependent on direction. */
obj->mode = (obj->direction == PIN_INPUT) ? InputOnly : PushPullOutput;
@ -110,10 +123,23 @@ void gpio_dir(gpio_t *obj, PinDirection direction)
obj->direction = direction;
uint32_t pin_index = NU_PININDEX(obj->pin);
uint32_t port_index = NU_PINPORT(obj->pin);
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
switch (obj->mode) {
case PullNone:
if (obj->mode == PullNone) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_DISABLE);
}
case PullDown:
if (obj->mode == PullDown) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_PULL_DOWN);
}
case PullUp:
if (obj->mode == PullUp) {
GPIO_SetPullCtl(gpio_base, 1 << pin_index, GPIO_PUSEL_PULL_UP);
}
/* H/W doesn't support separate configuration for input pull mode/direction.
* We translate to input-only/push-pull output I/O mode dependent on direction. */
obj->mode = (obj->direction == PIN_INPUT) ? InputOnly : PushPullOutput;

View File

@ -85,9 +85,10 @@ static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable
static void i2c_rollback_vector_interrupt(i2c_t *obj);
#endif
#define TRANCTRL_STARTED (1)
#define TRANCTRL_NAKLASTDATA (1 << 1)
#define TRANCTRL_LASTDATANAKED (1 << 2)
#define TRANCTRL_STARTED (1) // Guard I2C ISR from data transfer prematurely
#define TRANCTRL_NAKLASTDATA (1 << 1) // Request NACK on last data
#define TRANCTRL_LASTDATANAKED (1 << 2) // Last data NACKed
#define TRANCTRL_RECVDATA (1 << 3) // Receive data available
uint32_t us_ticker_read(void);
@ -102,14 +103,17 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
obj->i2c.pin_sda = sda;
obj->i2c.pin_scl = scl;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_I2C_ASYNCH
obj->i2c.dma_usage = DMA_USAGE_NEVER;
@ -591,11 +595,17 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x50 || status == 0x58) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x58) {
i2c_fsm_tranfini(obj, 1);
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
} else {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -604,6 +614,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
} else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
@ -658,12 +669,18 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x80 || status == 0x88) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x88) {
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
} else {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -672,6 +689,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
} else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
@ -694,12 +712,18 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x90 || status == 0x98) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x98) {
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
} else {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -708,6 +732,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
} else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;

View File

@ -80,15 +80,15 @@ void lp_ticker_init(void)
}
ticker_inited = 1;
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Configure clock

View File

@ -28,10 +28,6 @@ extern "C" {
#endif
struct gpio_irq_s {
//IRQn_Type irq_n;
//uint32_t irq_index;
//uint32_t event;
PinName pin;
uint32_t irq_handler;
uint32_t irq_id;
@ -45,27 +41,32 @@ struct port_s {
struct analogin_s {
ADCName adc;
//PinName pin;
PinName pin;
};
struct dac_s {
DACName dac;
PinName pin;
};
struct serial_s {
UARTName uart;
PinName pin_tx;
PinName pin_rx;
PinName pin_rts;
PinName pin_cts;
uint32_t baudrate;
uint32_t databits;
uint32_t parity;
uint32_t stopbits;
void (*vec)(void);
uint32_t irq_handler;
uint32_t irq_id;
uint32_t irq_en;
uint32_t inten_msk;
// Async transfer related fields
DMAUsage dma_usage_tx;
DMAUsage dma_usage_rx;
@ -82,30 +83,27 @@ struct spi_s {
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
//void (*vec)(void);
// Async transfer related fields
DMAUsage dma_usage;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
//void (*irq_handler_tx_async)(void);
//void (*irq_handler_rx_async)(void);
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
};
struct i2c_s {
I2CName i2c;
//void (*vec)(void);
PinName pin_sda;
PinName pin_scl;
int slaveaddr_state;
uint32_t tran_ctrl;
char * tran_beg;
char * tran_pos;
char * tran_end;
int inten;
// Async transfer related fields
DMAUsage dma_usage;
uint32_t event;
@ -115,7 +113,7 @@ struct i2c_s {
struct pwmout_s {
PWMName pwm;
//PinName pin;
PinName pin;
uint32_t period_us;
uint32_t pulsewidth_us;
};
@ -126,6 +124,8 @@ struct trng_s {
struct can_s {
CANName can;
PinName pin_rd;
PinName pin_td;
int index;
};
#ifdef __cplusplus

View File

@ -17,6 +17,7 @@
#include "mbed_assert.h"
#include "pinmap.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "mbed_error.h"
/**
@ -80,3 +81,34 @@ void pin_mode(PinName pin, PinMode mode)
* 2. PushPullOutput/PIN_INPUT
*/
}
/* List of pins excluded from testing */
const PinList *pinmap_restricted_pins()
{
static const PinName pins[] = {
USBTX, USBRX, // Dedicated to USB VCOM
#if defined(TARGET_NUMAKER_IOT_M487)
A2, A3, // Dedicated to on-board ESP8266 WiFi module RTS/CTS
#endif
};
static const PinList pin_list = {
sizeof(pins) / sizeof(pins[0]),
pins
};
return &pin_list;
}
/* List of peripherals excluded from testing */
const PeripheralList *pinmap_restricted_peripherals()
{
static const int perifs[] = {
STDIO_UART // Dedicated to USB VCOM
};
static const PeripheralList peripheral_list = {
sizeof(perifs) / sizeof(perifs[0]),
perifs
};
return &peripheral_list;
}

View File

@ -68,6 +68,20 @@ void pwmout_init(pwmout_t* obj, PinName pin)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->pwm);
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
// NOTE: Channels 0/1/2/3/4/5 share a clock source.
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0x3F) == 0) {
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
}
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
// Reset this module if no channel enabled
@ -76,17 +90,6 @@ void pwmout_init(pwmout_t* obj, PinName pin)
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
// NOTE: Channels 0/1/2/3/4/5 share a clock source.
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0x3F) == 0) {
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
}
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
// Default: period = 10 ms, pulse width = 0 ms
obj->period_us = 1000 * 10;
obj->pulsewidth_us = 0;
@ -118,6 +121,10 @@ void pwmout_free(pwmout_t* obj)
// Mark this module to be deinited.
int i = modinit - pwm_modinit_tab;
pwm_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->pin);
obj->pin = NC;
}
void pwmout_write(pwmout_t* obj, float value)

View File

@ -85,9 +85,10 @@ static void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable);
static int serial_is_rx_complete(serial_t *obj);
static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch);
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
#endif
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
bool serial_can_deep_sleep(void);
static struct nu_uart_var uart0_var = {
@ -199,17 +200,23 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
if (! var->ref_cnt) {
// Reset this module
SYS_ResetModule(modinit->rsetidx);
obj->serial.pin_tx = tx;
obj->serial.pin_rx = rx;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
if (! var->ref_cnt) {
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Configure baudrate
int baudrate = 9600;
@ -302,6 +309,16 @@ void serial_free(serial_t *obj)
int i = modinit - uart_modinit_tab;
uart_modinit_mask &= ~(1 << i);
}
// Free up pins
gpio_set(obj->serial.pin_tx);
gpio_set(obj->serial.pin_rx);
gpio_set(obj->serial.pin_rts);
gpio_set(obj->serial.pin_cts);
obj->serial.pin_tx = NC;
obj->serial.pin_rx = NC;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
}
void serial_baud(serial_t *obj, int baudrate)
@ -348,6 +365,16 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
{
UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart);
// Free up old rts/cts pins when they are different from new ones
if (obj->serial.pin_rts != rxflow) {
gpio_set(obj->serial.pin_rts);
obj->serial.pin_rts = rxflow;
}
if (obj->serial.pin_cts != txflow) {
gpio_set(obj->serial.pin_cts);
obj->serial.pin_cts = txflow;
}
if (rxflow != NC) {
// Check if RTS pin matches.
uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS);
@ -518,7 +545,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->INTSTS & (UART_INTSTS_RDAINT_Msk | UART_INTSTS_RXTOINT_Msk)) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next read.
UART_DISABLE_INT(uart_base, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, RxIrq)) {
// Call irq_handler() only when RxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, RxIrq);
}
}
@ -526,7 +554,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->INTSTS & UART_INTSTS_THREINT_Msk) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next write.
UART_DISABLE_INT(uart_base, UART_INTEN_THREIEN_Msk);
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, TxIrq)) {
// Call irq_handler() only when TxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, TxIrq);
}
}
@ -1153,6 +1182,8 @@ static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch)
}
}
#endif // #if DEVICE_SERIAL_ASYNCH
static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
{
int inten_msk = 0;
@ -1169,8 +1200,6 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
return !! inten_msk;
}
#endif // #if DEVICE_SERIAL_ASYNCH
bool serial_can_deep_sleep(void)
{
bool sleep_allowed = 1;

View File

@ -146,24 +146,24 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_SPI_ASYNCH
obj->spi.dma_usage = DMA_USAGE_NEVER;
@ -210,6 +210,16 @@ void spi_free(spi_t *obj)
// Mark this module to be deinited.
int i = modinit - spi_modinit_tab;
spi_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->spi.pin_mosi);
gpio_set(obj->spi.pin_miso);
gpio_set(obj->spi.pin_sclk);
gpio_set(obj->spi.pin_ssel);
obj->spi.pin_mosi = NC;
obj->spi.pin_miso = NC;
obj->spi.pin_sclk = NC;
obj->spi.pin_ssel = NC;
}
void spi_format(spi_t *obj, int bits, int mode, int slave)
@ -393,6 +403,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
SPI_ENABLE_SYNC(spi_base);
// Initialize total SPI transfer frames
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
spi_master_write_asynch(obj, spi_fifo_depth(obj) / 2);
@ -653,16 +666,12 @@ static uint32_t spi_event_check(spi_t *obj)
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
max_tx = NU_MIN(max_tx, tx_limit);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while ((n_words < max_tx) && spi_writeable(obj)) {
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
if (spi_is_tx_complete(obj)) {
// Transmit dummy as transmit buffer is empty
SPI_WRITE_TX(spi_base, 0);
@ -685,6 +694,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
obj->tx_buff.pos ++;
}
n_words ++;
obj->spi.txrx_rmn --;
}
//Return the number of words that have been sent
@ -705,15 +715,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
static uint32_t spi_master_read_asynch(spi_t *obj)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while ((n_words < max_rx) && spi_readable(obj)) {
while (spi_readable(obj)) {
if (spi_is_rx_complete(obj)) {
// Disregard as receive buffer is full
SPI_READ_RX(spi_base);

View File

@ -56,15 +56,15 @@ void us_ticker_init(void)
}
ticker_inited = 1;
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Timer for normal counter

View File

@ -145,11 +145,8 @@ const PinMap PinMap_SPI_MOSI[] = {
{PB_7, SPI_2, SYS_PB_L_MFP_PB7_MFP_SPI2_MOSI0},
{PB_10, SPI_0, SYS_PB_H_MFP_PB10_MFP_SPI0_MOSI0},
{PC_3, SPI_0, SYS_PC_L_MFP_PC3_MFP_SPI0_MOSI0},
{PC_5, SPI_0, SYS_PC_L_MFP_PC5_MFP_SPI0_MOSI1},
{PC_11, SPI_1, SYS_PC_H_MFP_PC11_MFP_SPI1_MOSI0},
{PC_13, SPI_1, SYS_PC_H_MFP_PC13_MFP_SPI1_MOSI1},
{PD_3, SPI_2, SYS_PD_L_MFP_PD3_MFP_SPI2_MOSI0},
{PD_5, SPI_2, SYS_PD_L_MFP_PD5_MFP_SPI2_MOSI1},
{PE_4, SPI_0, SYS_PE_L_MFP_PE4_MFP_SPI0_MOSI0},
{NC, NC, 0}
@ -161,11 +158,8 @@ const PinMap PinMap_SPI_MISO[] = {
{PB_6, SPI_2, SYS_PB_L_MFP_PB6_MFP_SPI2_MISO0},
{PB_11, SPI_0, SYS_PB_H_MFP_PB11_MFP_SPI0_MISO0},
{PC_2, SPI_0, SYS_PC_L_MFP_PC2_MFP_SPI0_MISO0},
{PC_4, SPI_0, SYS_PC_L_MFP_PC4_MFP_SPI0_MISO1},
{PC_10, SPI_1, SYS_PC_H_MFP_PC10_MFP_SPI1_MISO0},
{PC_12, SPI_1, SYS_PC_H_MFP_PC12_MFP_SPI1_MISO1},
{PD_2, SPI_2, SYS_PD_L_MFP_PD2_MFP_SPI2_MISO0},
{PD_4, SPI_2, SYS_PD_L_MFP_PD4_MFP_SPI2_MISO1},
{PE_3, SPI_0, SYS_PE_L_MFP_PE3_MFP_SPI0_MISO0},
{NC, NC, 0}

View File

@ -131,6 +131,9 @@ typedef enum {
BUTTON1 = SW1,
BUTTON2 = SW2,
// Force PinName to 32-bit required by NU_PINNAME_BIND(...)
FORCE_ENUM_PINNAME_32BIT = 0x7FFFFFFF,
} PinName;
#ifdef __cplusplus

View File

@ -50,7 +50,12 @@ void analogin_init(analogin_t *obj, PinName pin)
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT((ADCName) modinit->modname == obj->adc);
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
ADC_T *adc_base = (ADC_T *) NU_MODBASE(obj->adc);
uint32_t chn = NU_MODSUBINDEX(obj->adc);
@ -62,20 +67,21 @@ void analogin_init(analogin_t *obj, PinName pin)
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
if (! adc_modinit_mask) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Set operation mode and enable channel N
ADC_Open(ADC, ADC_INPUT_MODE_SINGLE_END, ADC_OPERATION_MODE_SINGLE_CYCLE, 1 << chn);
// Set reference voltage to AVDD
ADC_SET_REF_VOLTAGE(ADC, ADC_REFSEL_POWER);
// Power on ADC
ADC_POWER_ON(ADC);
} else {
@ -86,9 +92,6 @@ void analogin_init(analogin_t *obj, PinName pin)
adc_modinit_mask |= 1 << chn;
adc_busy_flag = 0;
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
}
void analogin_deinit(PinName pin)

View File

@ -53,20 +53,24 @@ void analogout_init(dac_t *obj, PinName pin)
uint32_t chn = NU_MODSUBINDEX(obj->dac);
MBED_ASSERT(chn < NU_DACCHN_MAXNUM);
obj->pin = pin;
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
DAC_T *dac_base = (DAC_T *) NU_MODBASE(obj->dac);
/* Module-level setup from here */
if (! dac_modinit_mask[modidx]) {
/* Reset IP */
SYS_ResetModule(modinit->rsetidx);
/* Select IP clock source and clock divider */
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
/* Enable IP clock */
CLK_EnableModuleClock(modinit->clkidx);
/* Reset IP */
SYS_ResetModule(modinit->rsetidx);
/* Configure conversion settling time
*
* DAC_Open() is per-channel, but its implementation involves per-module configuration of
@ -83,9 +87,6 @@ void analogout_init(dac_t *obj, PinName pin)
/* Set the software trigger, enable DAC event trigger mode and enable D/A converter */
DAC_Open(dac_base, chn, DAC_WRITE_DAT_TRIGGER);
/* Wire pinout */
pinmap_pinout(pin, PinMap_DAC);
/* Mark channel allocated */
dac_modinit_mask[modidx] |= 1 << chn;
@ -122,6 +123,10 @@ void analogout_free(dac_t *obj)
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
/* Free up pin */
gpio_set(obj->pin);
obj->pin = NC;
}
void analogout_write(dac_t *obj, float value)

View File

@ -55,12 +55,12 @@ void dma_init(void)
dma_chn_mask = ~NU_PDMA_CH_Msk;
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
// Reset this module
SYS_ResetModule(dma_modinit.rsetidx);
// Enable IP clock
CLK_EnableModuleClock(dma_modinit.clkidx);
// Reset this module
SYS_ResetModule(dma_modinit.rsetidx);
PDMA_Open(0);
NVIC_SetVector(dma_modinit.irq_n, (uint32_t) dma_modinit.var);

View File

@ -109,9 +109,10 @@ static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable
static void i2c_teardown_async(i2c_t *obj);
#endif
#define TRANCTRL_STARTED (1)
#define TRANCTRL_NAKLASTDATA (1 << 1)
#define TRANCTRL_LASTDATANAKED (1 << 2)
#define TRANCTRL_STARTED (1) // Guard I2C ISR from data transfer prematurely
#define TRANCTRL_NAKLASTDATA (1 << 1) // Request NACK on last data
#define TRANCTRL_LASTDATANAKED (1 << 2) // Last data NACKed
#define TRANCTRL_RECVDATA (1 << 3) // Receive data available
uint32_t us_ticker_read(void);
@ -125,16 +126,19 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT((I2CName) modinit->modname == obj->i2c.i2c);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
obj->i2c.pin_sda = sda;
obj->i2c.pin_scl = scl;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_I2C_ASYNCH
obj->i2c.dma_usage = DMA_USAGE_NEVER;
obj->i2c.event = 0;
@ -653,7 +657,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x50 || status == 0x58) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x58) {
@ -665,6 +672,10 @@ static void i2c_irq(i2c_t *obj)
#endif
i2c_fsm_tranfini(obj, 1);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CON_I2C_STS_Msk | I2C_CON_ACK_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -673,6 +684,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CON_ACK_Msk;
}
i2c_set_control_reg(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {
@ -731,7 +743,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x80 || status == 0x88) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x88) {
@ -744,6 +759,10 @@ static void i2c_irq(i2c_t *obj)
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CON_I2C_STS_Msk | I2C_CON_ACK_Msk);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CON_I2C_STS_Msk | I2C_CON_ACK_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -752,6 +771,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CON_ACK_Msk;
}
i2c_set_control_reg(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {
@ -776,7 +796,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x90 || status == 0x98) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x98) {
@ -789,6 +812,10 @@ static void i2c_irq(i2c_t *obj)
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CON_I2C_STS_Msk | I2C_CON_ACK_Msk);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CON_I2C_STS_Msk | I2C_CON_ACK_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -797,6 +824,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CON_ACK_Msk;
}
i2c_set_control_reg(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {

View File

@ -82,15 +82,15 @@ void lp_ticker_init(void)
}
ticker_inited = 1;
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Configure clock

View File

@ -42,15 +42,21 @@ struct port_s {
struct analogin_s {
ADCName adc;
PinName pin;
};
struct dac_s {
DACName dac;
PinName pin;
};
struct serial_s {
UARTName uart;
PinName pin_tx;
PinName pin_rx;
PinName pin_rts;
PinName pin_cts;
uint32_t baudrate;
uint32_t databits;
uint32_t parity;
@ -85,11 +91,14 @@ struct spi_s {
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
uint32_t hdlr_async;
};
struct i2c_s {
I2CName i2c;
PinName pin_sda;
PinName pin_scl;
int slaveaddr_state;
uint32_t tran_ctrl;
@ -108,6 +117,7 @@ struct i2c_s {
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period_us;
uint32_t pulsewidth_us;
};

View File

@ -17,6 +17,7 @@
#include "mbed_assert.h"
#include "pinmap.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "mbed_error.h"
/**
@ -76,3 +77,18 @@ void pin_mode(PinName pin, PinMode mode)
* 2. PushPullOutput/PIN_INPUT
*/
}
/* List of peripherals excluded from testing */
const PeripheralList *pinmap_restricted_peripherals()
{
static const int perifs[] = {
STDIO_UART // Dedicated to USB VCOM
};
static const PeripheralList peripheral_list = {
sizeof(perifs) / sizeof(perifs[0]),
perifs
};
return &peripheral_list;
}

View File

@ -71,10 +71,15 @@ void pwmout_init(pwmout_t* obj, PinName pin)
const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT((PWMName) modinit->modname == obj->pwm);
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
// NOTE: Channels 0/1, 2/3 share a clock source.
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0xF) == 0) {
// Select clock source of paired channels
@ -82,23 +87,20 @@ void pwmout_init(pwmout_t* obj, PinName pin)
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
}
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
// Default: period = 10 ms, pulse width = 0 ms
obj->period_us = 1000 * 10;
obj->pulsewidth_us = 0;
pwmout_config(obj);
// enable inverter to ensure the first PWM cycle is correct
pwm_base->CTL |= (PWM_CTL_CH0INV_Msk << (chn * 8));
// Enable output of the specified PWM channel
PWM_EnableOutput(pwm_base, 1 << chn);
PWM_Start(pwm_base, 1 << chn);
((struct nu_pwm_var *) modinit->var)->en_msk |= 1 << chn;
if (((struct nu_pwm_var *) modinit->var)->en_msk) {
// Mark this module to be inited.
int i = modinit - pwm_modinit_tab;
@ -127,6 +129,10 @@ void pwmout_free(pwmout_t* obj)
int i = modinit - pwm_modinit_tab;
pwm_modinit_mask &= ~(1 << i);
}
// Free up pins
gpio_set(obj->pin);
obj->pin = NC;
}
void pwmout_write(pwmout_t* obj, float value)

View File

@ -74,9 +74,10 @@ static void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable);
static int serial_is_rx_complete(serial_t *obj);
static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch);
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
#endif
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
bool serial_can_deep_sleep(void);
static struct nu_uart_var uart0_var = {
@ -133,18 +134,24 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
MBED_ASSERT(modinit->modname == (int) obj->serial.uart);
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
if (! var->ref_cnt) {
// Reset this module
SYS_ResetModule(modinit->rsetidx);
obj->serial.pin_tx = tx;
obj->serial.pin_rx = rx;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
if (! var->ref_cnt) {
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Configure baudrate
int baudrate = 9600;
@ -235,6 +242,16 @@ void serial_free(serial_t *obj)
int i = modinit - uart_modinit_tab;
uart_modinit_mask &= ~(1 << i);
}
// Free up pins
gpio_set(obj->serial.pin_tx);
gpio_set(obj->serial.pin_rx);
gpio_set(obj->serial.pin_rts);
gpio_set(obj->serial.pin_cts);
obj->serial.pin_tx = NC;
obj->serial.pin_rx = NC;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
}
void serial_baud(serial_t *obj, int baudrate) {
@ -275,6 +292,16 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
{
UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart);
// Free up old rts/cts pins when they are different from new ones
if (obj->serial.pin_rts != rxflow) {
gpio_set(obj->serial.pin_rts);
obj->serial.pin_rts = rxflow;
}
if (obj->serial.pin_cts != txflow) {
gpio_set(obj->serial.pin_cts);
obj->serial.pin_cts = txflow;
}
if (rxflow != NC) {
// Check if RTS pin matches.
uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS);
@ -425,7 +452,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->ISR & (UART_ISR_RDA_IS_Msk | UART_ISR_RTO_IS_Msk)) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next read.
UART_DISABLE_INT(uart_base, (UART_IER_RDA_IE_Msk | UART_IER_RTO_IE_Msk));
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, RxIrq)) {
// Call irq_handler() only when RxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, RxIrq);
}
}
@ -433,7 +461,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->ISR & UART_ISR_THRE_IS_Msk) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next write.
UART_DISABLE_INT(uart_base, UART_IER_THRE_IE_Msk);
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, TxIrq)) {
// Call irq_handler() only when TxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, TxIrq);
}
}
@ -1002,6 +1031,8 @@ static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch)
}
}
#endif // #if DEVICE_SERIAL_ASYNCH
static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
{
int ier_msk = 0;
@ -1018,8 +1049,6 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
return !! ier_msk;
}
#endif // #if DEVICE_SERIAL_ASYNCH
bool serial_can_deep_sleep(void)
{
bool sleep_allowed = 1;

View File

@ -158,24 +158,24 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_SPI_ASYNCH
obj->spi.dma_usage = DMA_USAGE_NEVER;
@ -223,6 +223,16 @@ void spi_free(spi_t *obj)
// Mark this module to be deinited.
int i = modinit - spi_modinit_tab;
spi_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->spi.pin_mosi);
gpio_set(obj->spi.pin_miso);
gpio_set(obj->spi.pin_sclk);
gpio_set(obj->spi.pin_ssel);
obj->spi.pin_mosi = NC;
obj->spi.pin_miso = NC;
obj->spi.pin_sclk = NC;
obj->spi.pin_ssel = NC;
}
void spi_format(spi_t *obj, int bits, int mode, int slave)
@ -434,6 +444,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
SPI_ENABLE_SYNC(spi_base);
// Initialize total SPI transfer frames
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
spi_master_write_asynch(obj, NU_SPI_FIFO_DEPTH / 2);
@ -713,17 +726,13 @@ static uint32_t spi_event_check(spi_t *obj)
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
max_tx = NU_MIN(max_tx, tx_limit);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
uint32_t TX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->TX0) : ((uint32_t) &spi_base->TX1);
while ((n_words < max_tx) && spi_writeable(obj)) {
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
if (spi_is_tx_complete(obj)) {
// Transmit dummy as transmit buffer is empty
M32(TX) = 0;
@ -747,6 +756,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
obj->tx_buff.pos ++;
}
n_words ++;
obj->spi.txrx_rmn --;
}
//Return the number of words that have been sent
@ -767,16 +777,13 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
static uint32_t spi_master_read_asynch(spi_t *obj)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
uint32_t RX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->RX0) : ((uint32_t) &spi_base->RX1);
while ((n_words < max_rx) && spi_readable(obj)) {
while (spi_readable(obj)) {
if (spi_is_rx_complete(obj)) {
// Disregard as receive buffer is full
M32(RX);

View File

@ -58,15 +58,15 @@ void us_ticker_init(void)
}
ticker_inited = 1;
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Timer for normal counter

View File

@ -137,6 +137,9 @@ typedef enum {
BUTTON1 = SW1,
BUTTON2 = SW2,
// Force PinName to 32-bit required by NU_PINNAME_BIND(...)
FORCE_ENUM_PINNAME_32BIT = 0x7FFFFFFF,
} PinName;
#ifdef __cplusplus

View File

@ -53,32 +53,35 @@ void analogin_init(analogin_t *obj, PinName pin)
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->adc);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
if (! eadc_modinit_mask) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
// Make EADC_module ready to convert
EADC_Open(eadc_base, 0);
}
uint32_t smp_chn = NU_MODSUBINDEX(obj->adc);
uint32_t smp_mod = NU_MODINDEX(obj->adc) * 8 + smp_chn;
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
if (! eadc_modinit_mask) {
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Make EADC_module ready to convert
EADC_Open(eadc_base, 0);
}
uint32_t smp_chn = NU_MODSUBINDEX(obj->adc);
uint32_t smp_mod = NU_MODINDEX(obj->adc) * 8 + smp_chn;
// Configure the sample module Nmod for analog input channel Nch and software trigger source
EADC_ConfigSampleModule(eadc_base, smp_mod, EADC_SOFTWARE_TRIGGER, smp_chn);
eadc_modinit_mask |= 1 << smp_mod;
}

View File

@ -44,8 +44,8 @@
};
void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
{
void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
{
uint32_t can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
uint32_t can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
obj->can = (CANName)pinmap_merge(can_td, can_rd);
@ -54,21 +54,26 @@
const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->can);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
obj->pin_rd = rd;
obj->pin_td = td;
pinmap_pinout(td, PinMap_CAN_TD);
pinmap_pinout(rd, PinMap_CAN_RD);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
if(obj->can == CAN_1) {
obj->index = 1;
}
else
obj->index = 0;
pinmap_pinout(td, PinMap_CAN_TD);
pinmap_pinout(rd, PinMap_CAN_RD);
/* For NCU 472 mbed Board Transmitter Setting (RS Pin) */
GPIO_SetMode(PA, BIT2| BIT3, GPIO_MODE_OUTPUT);
@ -78,7 +83,7 @@
CAN_Open((CAN_T *)NU_MODBASE(obj->can), hz, CAN_NORMAL_MODE);
can_filter(obj, 0, 0, CANStandard, 0);
}
}
void can_init(can_t *obj, PinName rd, PinName td)
@ -99,6 +104,12 @@ void can_free(can_t *obj)
SYS_ResetModule(modinit->rsetidx);
CLK_DisableModuleClock(modinit->clkidx);
/* Free up pins */
gpio_set(obj->pin_rd);
gpio_set(obj->pin_td);
obj->pin_rd = NC;
obj->pin_td = NC;
}
int can_frequency(can_t *obj, int hz)

View File

@ -50,15 +50,15 @@ void dma_init(void)
dma_inited = 1;
dma_chn_mask = ~NU_PDMA_CH_Msk;
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
// Reset this module
SYS_ResetModule(dma_modinit.rsetidx);
// Enable IP clock
CLK_EnableModuleClock(dma_modinit.clkidx);
// Reset this module
SYS_ResetModule(dma_modinit.rsetidx);
PDMA_Open(0);
NVIC_SetVector(dma_modinit.irq_n, (uint32_t) dma_modinit.var);
NVIC_EnableIRQ(dma_modinit.irq_n);
}

View File

@ -111,9 +111,10 @@ static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable
static void i2c_rollback_vector_interrupt(i2c_t *obj);
#endif
#define TRANCTRL_STARTED (1)
#define TRANCTRL_NAKLASTDATA (1 << 1)
#define TRANCTRL_LASTDATANAKED (1 << 2)
#define TRANCTRL_STARTED (1) // Guard I2C ISR from data transfer prematurely
#define TRANCTRL_NAKLASTDATA (1 << 1) // Request NACK on last data
#define TRANCTRL_LASTDATANAKED (1 << 2) // Last data NACKed
#define TRANCTRL_RECVDATA (1 << 3) // Receive data available
uint32_t us_ticker_read(void);
@ -127,16 +128,19 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->i2c.i2c);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
obj->i2c.pin_sda = sda;
obj->i2c.pin_scl = scl;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_I2C_ASYNCH
obj->i2c.dma_usage = DMA_USAGE_NEVER;
obj->i2c.event = 0;
@ -671,7 +675,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x50 || status == 0x58) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x58) {
@ -683,6 +690,10 @@ static void i2c_irq(i2c_t *obj)
#endif
i2c_fsm_tranfini(obj, 1);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -691,6 +702,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {
@ -749,7 +761,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x80 || status == 0x88) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x88) {
@ -762,6 +777,10 @@ static void i2c_irq(i2c_t *obj)
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -770,6 +789,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {
@ -794,7 +814,10 @@ static void i2c_irq(i2c_t *obj)
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x90 || status == 0x98) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
}
}
if (status == 0x98) {
@ -807,6 +830,10 @@ static void i2c_irq(i2c_t *obj)
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
}
else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
else {
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
@ -815,6 +842,7 @@ static void i2c_irq(i2c_t *obj)
i2c_ctl &= ~I2C_CTL_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
}
}
else {

View File

@ -80,15 +80,15 @@ void lp_ticker_init(void)
}
ticker_inited = 1;
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset module
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Configure clock

View File

@ -28,10 +28,6 @@ extern "C" {
#endif
struct gpio_irq_s {
//IRQn_Type irq_n;
//uint32_t irq_index;
//uint32_t event;
PinName pin;
uint32_t irq_handler;
uint32_t irq_id;
@ -45,12 +41,16 @@ struct port_s {
struct analogin_s {
ADCName adc;
//PinName pin;
PinName pin;
};
struct serial_s {
UARTName uart;
PinName pin_tx;
PinName pin_rx;
PinName pin_rts;
PinName pin_cts;
uint32_t baudrate;
uint32_t databits;
uint32_t parity;
@ -78,21 +78,19 @@ struct spi_s {
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
//void (*vec)(void);
// Async transfer related fields
DMAUsage dma_usage;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
//void (*irq_handler_tx_async)(void);
//void (*irq_handler_rx_async)(void);
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
};
struct i2c_s {
I2CName i2c;
//void (*vec)(void);
PinName pin_sda;
PinName pin_scl;
int slaveaddr_state;
uint32_t tran_ctrl;
@ -111,7 +109,7 @@ struct i2c_s {
struct pwmout_s {
PWMName pwm;
//PinName pin;
PinName pin;
uint32_t period_us;
uint32_t pulsewidth_us;
};
@ -122,6 +120,8 @@ struct trng_s {
struct can_s {
CANName can;
PinName pin_rd;
PinName pin_td;
char index;
};
#ifdef __cplusplus

View File

@ -17,6 +17,7 @@
#include "mbed_assert.h"
#include "pinmap.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "mbed_error.h"
/**
@ -90,3 +91,18 @@ void pin_mode(PinName pin, PinMode mode)
* 2. PushPullOutput/PIN_INPUT
*/
}
/* List of peripherals excluded from testing */
const PeripheralList *pinmap_restricted_peripherals()
{
static const int perifs[] = {
STDIO_UART // Dedicated to USB VCOM
};
static const PeripheralList peripheral_list = {
sizeof(perifs) / sizeof(perifs[0]),
perifs
};
return &peripheral_list;
}

View File

@ -68,20 +68,19 @@ void pwmout_init(pwmout_t* obj, PinName pin)
const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->pwm);
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
}
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
// NOTE: Channels 0/1, 2/3, and 4/5 share a clock source.
if ((((struct nu_pwm_var *) modinit->var)->en_msk & (0x3 << (chn / 2 * 2))) == 0) {
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
@ -90,10 +89,15 @@ void pwmout_init(pwmout_t* obj, PinName pin)
CLK_EnableModuleClock(PWM1CH01_MODULE);
}
}
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
}
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
// Default: period = 10 ms, pulse width = 0 ms
obj->period_us = 1000 * 10;
obj->pulsewidth_us = 0;
@ -146,6 +150,10 @@ void pwmout_free(pwmout_t* obj)
// Mark this module to be deinited.
int i = modinit - pwm_modinit_tab;
pwm_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->pin);
obj->pin = NC;
}
void pwmout_write(pwmout_t* obj, float value)

View File

@ -85,9 +85,10 @@ static void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable);
static int serial_is_rx_complete(serial_t *obj);
static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch);
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
#endif
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
bool serial_can_deep_sleep(void);
static struct nu_uart_var uart0_var = {
@ -198,18 +199,24 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
MBED_ASSERT(modinit->modname == (int) obj->serial.uart);
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
if (! var->ref_cnt) {
// Reset this module
SYS_ResetModule(modinit->rsetidx);
obj->serial.pin_tx = tx;
obj->serial.pin_rx = rx;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
if (! var->ref_cnt) {
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Configure baudrate
int baudrate = 9600;
@ -300,6 +307,16 @@ void serial_free(serial_t *obj)
int i = modinit - uart_modinit_tab;
uart_modinit_mask &= ~(1 << i);
}
// Free up pins
gpio_set(obj->serial.pin_tx);
gpio_set(obj->serial.pin_rx);
gpio_set(obj->serial.pin_rts);
gpio_set(obj->serial.pin_cts);
obj->serial.pin_tx = NC;
obj->serial.pin_rx = NC;
obj->serial.pin_rts = NC;
obj->serial.pin_cts = NC;
}
void serial_baud(serial_t *obj, int baudrate) {
@ -344,6 +361,26 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
{
UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart);
// Free up old rts/cts pins when they are different from new ones
if (obj->serial.pin_rts != rxflow) {
gpio_set(obj->serial.pin_rts);
obj->serial.pin_rts = rxflow;
}
if (obj->serial.pin_cts != txflow) {
gpio_set(obj->serial.pin_cts);
obj->serial.pin_cts = txflow;
}
// Free up old rts/cts pins when they are different from new ones
if (obj->serial.pin_rts != rxflow) {
gpio_set(obj->serial.pin_rts);
obj->serial.pin_rts = rxflow;
}
if (obj->serial.pin_cts != txflow) {
gpio_set(obj->serial.pin_cts);
obj->serial.pin_cts = txflow;
}
if (rxflow != NC) {
// Check if RTS pin matches.
uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS);
@ -503,7 +540,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->INTSTS & (UART_INTSTS_RDAINT_Msk | UART_INTSTS_RXTOINT_Msk)) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next read.
UART_DISABLE_INT(uart_base, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, RxIrq)) {
// Call irq_handler() only when RxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, RxIrq);
}
}
@ -511,7 +549,8 @@ static void uart_irq(serial_t *obj)
if (uart_base->INTSTS & UART_INTSTS_THREINT_Msk) {
// Simulate clear of the interrupt flag. Temporarily disable the interrupt here and to be recovered on next write.
UART_DISABLE_INT(uart_base, UART_INTEN_THREIEN_Msk);
if (obj->serial.irq_handler) {
if (obj->serial.irq_handler && serial_is_irq_en(obj, TxIrq)) {
// Call irq_handler() only when TxIrq is enabled
((uart_irq_handler) obj->serial.irq_handler)(obj->serial.irq_id, TxIrq);
}
}
@ -1147,6 +1186,8 @@ static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch)
}
}
#endif // #if DEVICE_SERIAL_ASYNCH
static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
{
int inten_msk = 0;
@ -1163,8 +1204,6 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
return !! inten_msk;
}
#endif // #if DEVICE_SERIAL_ASYNCH
bool serial_can_deep_sleep(void)
{
bool sleep_allowed = 1;

View File

@ -138,22 +138,21 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->spi.pin_mosi = mosi;
obj->spi.pin_miso = miso;
obj->spi.pin_sclk = sclk;
obj->spi.pin_ssel = ssel;
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_SPI_ASYNCH
obj->spi.dma_usage = DMA_USAGE_NEVER;
@ -200,6 +199,16 @@ void spi_free(spi_t *obj)
// Mark this module to be deinited.
int i = modinit - spi_modinit_tab;
spi_modinit_mask &= ~(1 << i);
// Free up pins
gpio_set(obj->spi.pin_mosi);
gpio_set(obj->spi.pin_miso);
gpio_set(obj->spi.pin_sclk);
gpio_set(obj->spi.pin_ssel);
obj->spi.pin_mosi = NC;
obj->spi.pin_miso = NC;
obj->spi.pin_sclk = NC;
obj->spi.pin_ssel = NC;
}
void spi_format(spi_t *obj, int bits, int mode, int slave)
@ -387,6 +396,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
SPI_ENABLE_SYNC(spi_base);
// Initialize total SPI transfer frames
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
spi_master_write_asynch(obj, NU_SPI_FIFO_DEPTH / 2);
@ -645,16 +657,12 @@ static uint32_t spi_event_check(spi_t *obj)
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
max_tx = NU_MIN(max_tx, tx_limit);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while ((n_words < max_tx) && spi_writeable(obj)) {
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
if (spi_is_tx_complete(obj)) {
// Transmit dummy as transmit buffer is empty
SPI_WRITE_TX(spi_base, 0);
@ -678,6 +686,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
obj->tx_buff.pos ++;
}
n_words ++;
obj->spi.txrx_rmn --;
}
//Return the number of words that have been sent
@ -698,15 +707,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
static uint32_t spi_master_read_asynch(spi_t *obj)
{
uint32_t n_words = 0;
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
uint8_t data_width = spi_get_data_width(obj);
uint8_t bytes_per_word = (data_width + 7) / 8;
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while ((n_words < max_rx) && spi_readable(obj)) {
while (spi_readable(obj)) {
if (spi_is_rx_complete(obj)) {
// Disregard as receive buffer is full
SPI_READ_RX(spi_base);

View File

@ -63,15 +63,15 @@ void us_ticker_init(void)
}
ticker_inited = 1;
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
// Select IP clock source
CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
// Reset IP
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Timer for normal counter

View File

@ -7627,6 +7627,7 @@
"extra_labels": [
"NUVOTON",
"M451",
"M45xG_M45xE",
"NUMAKER_PFM_M453",
"FLASH_CMSIS_ALGO"
],