Merge pull request #11379 from OpenNuvoton/nuvoton_m263_fpga-ci

M263: Fix FPGA CI testing failing
pull/11410/head
Martin Kojtal 2019-09-04 14:06:19 +02:00 committed by GitHub
commit ea54f126a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 219 additions and 115 deletions

View File

@ -43,7 +43,7 @@ const PinMap PinMap_GPIO[] = {
{PA_13, GPIO_A, SYS_GPA_MFPH_PA13MFP_GPIO},
{PA_14, GPIO_A, SYS_GPA_MFPH_PA14MFP_GPIO},
{PA_15, GPIO_A, SYS_GPA_MFPH_PA15MFP_GPIO},
// GPIO B MFP
{PB_0, GPIO_B, SYS_GPB_MFPL_PB0MFP_GPIO},
{PB_1, GPIO_B, SYS_GPB_MFPL_PB1MFP_GPIO},
@ -61,7 +61,7 @@ const PinMap PinMap_GPIO[] = {
{PB_13, GPIO_B, SYS_GPB_MFPH_PB13MFP_GPIO},
{PB_14, GPIO_B, SYS_GPB_MFPH_PB14MFP_GPIO},
{PB_15, GPIO_B, SYS_GPB_MFPH_PB15MFP_GPIO},
// GPIO C MFP
{PC_0, GPIO_C, SYS_GPC_MFPL_PC0MFP_GPIO},
{PC_1, GPIO_C, SYS_GPC_MFPL_PC1MFP_GPIO},
@ -77,7 +77,7 @@ const PinMap PinMap_GPIO[] = {
{PC_11, GPIO_C, SYS_GPC_MFPH_PC11MFP_GPIO},
{PC_12, GPIO_C, SYS_GPC_MFPH_PC12MFP_GPIO},
{PC_13, GPIO_C, SYS_GPC_MFPH_PC13MFP_GPIO},
// GPIO D MFP
{PD_0, GPIO_D, SYS_GPD_MFPL_PD0MFP_GPIO},
{PD_1, GPIO_D, SYS_GPD_MFPL_PD1MFP_GPIO},
@ -94,7 +94,7 @@ const PinMap PinMap_GPIO[] = {
{PD_12, GPIO_D, SYS_GPD_MFPH_PD12MFP_GPIO},
{PD_13, GPIO_D, SYS_GPD_MFPH_PD13MFP_GPIO},
{PD_14, GPIO_D, SYS_GPD_MFPH_PD14MFP_GPIO},
// GPIO E MFP
{PE_0, GPIO_E, SYS_GPE_MFPL_PE0MFP_GPIO},
{PE_1, GPIO_E, SYS_GPE_MFPL_PE1MFP_GPIO},
@ -146,6 +146,7 @@ const PinMap PinMap_GPIO[] = {
{PH_9, GPIO_H, SYS_GPH_MFPH_PH9MFP_GPIO},
{PH_10, GPIO_H, SYS_GPH_MFPH_PH10MFP_GPIO},
{PH_11, GPIO_H, SYS_GPH_MFPH_PH11MFP_GPIO},
{NC, NC, 0}
};
#endif
@ -169,7 +170,7 @@ const PinMap PinMap_ADC[] = {
{PB_13, ADC_0_13, SYS_GPB_MFPH_PB13MFP_EADC0_CH13},
{PB_14, ADC_0_14, SYS_GPB_MFPH_PB14MFP_EADC0_CH14},
{PB_15, ADC_0_15, SYS_GPB_MFPH_PB15MFP_EADC0_CH15},
{NC, NC, 0}
};
@ -209,7 +210,7 @@ const PinMap PinMap_I2C_SDA[] = {
{PF_2, I2C_0, SYS_GPF_MFPL_PF2MFP_I2C0_SDA},
{PG_3, I2C_1, SYS_GPG_MFPL_PG3MFP_I2C1_SDA},
{PH_9, I2C_2, SYS_GPH_MFPH_PH9MFP_I2C2_SDA},
{NC, NC, 0}
};
@ -238,7 +239,7 @@ const PinMap PinMap_I2C_SCL[] = {
{PF_3, I2C_0, SYS_GPF_MFPL_PF3MFP_I2C0_SCL},
{PG_2, I2C_1, SYS_GPG_MFPL_PG2MFP_I2C1_SCL},
{PH_8, I2C_2, SYS_GPH_MFPH_PH8MFP_I2C2_SCL},
{NC, NC, 0}
};
@ -355,7 +356,7 @@ const PinMap PinMap_UART_TX[] = {
{NU_PINNAME_BIND(PH_10, UART_0), UART_0, SYS_GPH_MFPH_PH10MFP_UART0_TXD},
{PH_10, UART_4, SYS_GPH_MFPH_PH10MFP_UART4_TXD},
{NU_PINNAME_BIND(PH_10, UART_4), UART_4, SYS_GPH_MFPH_PH10MFP_UART4_TXD},
{NC, NC, 0}
};
@ -407,7 +408,7 @@ const PinMap PinMap_UART_RX[] = {
{NU_PINNAME_BIND(PH_11, UART_0), UART_0, SYS_GPH_MFPH_PH11MFP_UART0_RXD},
{PH_11, UART_4, SYS_GPH_MFPH_PH11MFP_UART4_RXD},
{NU_PINNAME_BIND(PH_11, UART_4), UART_4, SYS_GPH_MFPH_PH11MFP_UART4_RXD},
{NC, NC, 0}
};
@ -428,7 +429,7 @@ const PinMap PinMap_UART_RTS[] = {
{PE_13, UART_4, SYS_GPE_MFPH_PE13MFP_UART4_nRTS},
{PF_4, UART_2, SYS_GPF_MFPL_PF4MFP_UART2_nRTS},
{PH_8, UART_3, SYS_GPH_MFPH_PH8MFP_UART3_nRTS},
{NC, NC, 0}
};
@ -449,7 +450,7 @@ const PinMap PinMap_UART_CTS[] = {
{PE_11, UART_1, SYS_GPE_MFPH_PE11MFP_UART1_nCTS},
{PF_5, UART_2, SYS_GPF_MFPL_PF5MFP_UART2_nCTS},
{PH_9, UART_3, SYS_GPH_MFPH_PH9MFP_UART3_nCTS},
{NC, NC, 0}
};
@ -474,7 +475,7 @@ const PinMap PinMap_SPI_MOSI[] = {
{PF_6, SPI_0, SYS_GPF_MFPL_PF6MFP_SPI0_MOSI},
{PF_11, SPI_2, SYS_GPF_MFPH_PF11MFP_SPI2_MOSI},
{PH_5, SPI_1, SYS_GPH_MFPL_PH5MFP_SPI1_MOSI},
{NC, NC, 0}
};
@ -497,54 +498,31 @@ const PinMap PinMap_SPI_MISO[] = {
{PF_7, SPI_0, SYS_GPF_MFPL_PF7MFP_SPI0_MISO},
{PG_4, SPI_2, SYS_GPG_MFPL_PG4MFP_SPI2_MISO},
{PH_4, SPI_1, SYS_GPH_MFPL_PH4MFP_SPI1_MISO},
{NC, NC, 0}
};
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_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_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},
{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}
};
@ -567,7 +545,7 @@ const PinMap PinMap_SPI_SSEL[] = {
{PG_2, SPI_2, SYS_GPG_MFPL_PG2MFP_SPI2_SS},
{PH_7, SPI_1, SYS_GPH_MFPL_PH7MFP_SPI1_SS},
{PH_9, SPI_1, SYS_GPH_MFPH_PH9MFP_SPI1_SS},
{NC, NC, 0}
};
@ -629,10 +607,10 @@ const PinMap PinMap_CAN_TD[] = {
{PC_5, CAN_0, SYS_GPC_MFPL_PC5MFP_CAN0_TXD},
{PD_11, CAN_0, SYS_GPD_MFPH_PD11MFP_CAN0_TXD},
{PE_14, CAN_0, SYS_GPE_MFPH_PE14MFP_CAN0_TXD},
{NC, NC, 0}
};
const PinMap PinMap_CAN_RD[] = {
{PA_4, CAN_0, SYS_GPA_MFPL_PA4MFP_CAN0_RXD},
{PA_13, CAN_0, SYS_GPA_MFPH_PA13MFP_CAN0_RXD},

View File

@ -135,6 +135,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

@ -54,28 +54,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 module
SYS_ResetModule(modinit->rsetidx);
// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
// Reset module
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 pins
gpio_set(obj->pin);
obj->pin = NC;
}
void analogout_write(dac_t *obj, float value)

View File

@ -54,12 +54,12 @@ void dma_init(void)
dma_chn_mask = ~NU_PDMA_CH_Msk;
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
// Reset module
SYS_ResetModule(dma_modinit.rsetidx);
// Enable IP clock
CLK_EnableModuleClock(dma_modinit.clkidx);
// Reset module
SYS_ResetModule(dma_modinit.rsetidx);
/* Check PDMA0. */
PDMA_T *pdma_base = dma_modbase();
if (((uint32_t) pdma_base) != PDMA0_BASE) {

View File

@ -63,10 +63,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;
@ -111,10 +124,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

@ -86,9 +86,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);
@ -103,14 +104,17 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->i2c.i2c);
// Reset 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);
// Select IP clock source
CLK_EnableModuleClock(modinit->clkidx);
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
// Reset module
SYS_ResetModule(modinit->rsetidx);
#if DEVICE_I2C_ASYNCH
obj->i2c.dma_usage = DMA_USAGE_NEVER;
@ -592,11 +596,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 &&
@ -605,6 +615,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;
@ -659,12 +670,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 &&
@ -673,6 +690,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;
@ -695,12 +713,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 &&
@ -709,6 +733,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

@ -82,12 +82,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(TIMER_MODINIT.rsetidx);
/* Select IP clock source
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
@ -100,6 +94,12 @@ void lp_ticker_init(void)
*/
CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
/* Reset module
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
SYS_ResetModule(TIMER_MODINIT.rsetidx);
TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
// Configure clock

View File

@ -43,15 +43,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,13 +91,15 @@ struct spi_s {
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
uint32_t hdlr_async;
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
};
struct i2c_s {
I2CName i2c;
PinName pin_sda;
PinName pin_scl;
int slaveaddr_state;
uint32_t tran_ctrl;
char * tran_beg;
char * tran_pos;
@ -108,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"
/**
@ -83,3 +84,17 @@ 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;
}

View File

@ -69,11 +69,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 this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
}
obj->pin = pin;
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
@ -85,8 +84,11 @@ void pwmout_init(pwmout_t* obj, PinName pin)
CLK_EnableModuleClock(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 this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
}
// Default: period = 10 ms, pulse width = 0 ms
obj->period_us = 1000 * 10;
@ -119,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

@ -86,9 +86,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 = {
@ -200,17 +201,22 @@ 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;
@ -303,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)
@ -349,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);
@ -519,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);
}
}
@ -527,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);
}
}
@ -1167,6 +1195,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;
@ -1183,8 +1213,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

@ -141,24 +141,23 @@ 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;
@ -205,6 +204,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)
@ -388,6 +397,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);
@ -658,16 +670,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);
@ -690,6 +698,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
@ -710,15 +719,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

@ -57,15 +57,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