diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PinNames.h b/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PinNames.h index 8b636f05c13..65eba1d2624 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PinNames.h +++ b/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PinNames.h @@ -43,42 +43,34 @@ typedef enum { PH_0 = NU_PINNAME(7, 0), PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7, PH_8, PH_9, PH_10, PH_11, // Arduino UNO naming - A0 = PB_6, - A1 = PB_7, - A2 = PB_8, - A3 = PB_9, - A4 = PB_0, - A5 = PB_1, - - D0 = PB_2, - D1 = PB_3, - D2 = PC_9, - D3 = PC_10, - D4 = PC_11, - D5 = PC_12, - D6 = PE_4, - D7 = PE_5, - D8 = PA_5, - D9 = PA_4, - D10 = PA_3, - D11 = PA_0, - D12 = PA_1, - D13 = PA_2, - D14 = PG_1, - D15 = PG_0, + ARDUINO_UNO_A0 = PB_6, + ARDUINO_UNO_A1 = PB_7, + ARDUINO_UNO_A2 = PB_8, + ARDUINO_UNO_A3 = PB_9, + ARDUINO_UNO_A4 = PB_0, + ARDUINO_UNO_A5 = PB_1, + + ARDUINO_UNO_D0 = PB_2, + ARDUINO_UNO_D1 = PB_3, + ARDUINO_UNO_D2 = PC_9, + ARDUINO_UNO_D3 = PC_10, + ARDUINO_UNO_D4 = PC_11, + ARDUINO_UNO_D5 = PC_12, + ARDUINO_UNO_D6 = PE_4, + ARDUINO_UNO_D7 = PE_5, + ARDUINO_UNO_D8 = PA_5, + ARDUINO_UNO_D9 = PA_4, + ARDUINO_UNO_D10 = PA_3, + ARDUINO_UNO_D11 = PA_0, + ARDUINO_UNO_D12 = PA_1, + ARDUINO_UNO_D13 = PA_2, + ARDUINO_UNO_D14 = PG_1, + ARDUINO_UNO_D15 = PG_0, // Note: board-specific // UART naming -#if defined(MBED_CONF_TARGET_USB_UART_TX) CONSOLE_TX = MBED_CONF_TARGET_USB_UART_TX, -#else - CONSOLE_TX = NC, -#endif -#if defined(MBED_CONF_TARGET_USB_UART_RX) CONSOLE_RX = MBED_CONF_TARGET_USB_UART_RX, -#else - CONSOLE_RX = NC, -#endif #if defined(MBED_CONF_TARGET_STDIO_UART_TX) STDIO_UART_TX = MBED_CONF_TARGET_STDIO_UART_TX, #else @@ -89,33 +81,21 @@ typedef enum { #else STDIO_UART_RX = CONSOLE_RX, #endif - SERIAL_TX = D10, - SERIAL_RX = D13, - - // I2C naming - I2C_SCL = D15, - I2C_SDA = D14, - - // LED naming - LED_RED = PH_0, - LED_YELLOW = PH_1, - LED_GREEN = PH_2, - LED1 = LED_RED, - LED2 = LED_YELLOW, - LED3 = LED_GREEN, - LED4 = LED1, // No real LED. Just for passing ATS. - - // Button naming - SW2 = PG_15, - SW3 = PF_11, - BUTTON1 = SW2, - BUTTON2 = SW3, // Force PinName to 32-bit required by NU_PINNAME_BIND(...) FORCE_ENUM_PINNAME_32BIT = 0x7FFFFFFF, } PinName; +// LEDs +#define LED1 PH_0 // Red LED +#define LED2 PH_1 // Yellow LED +#define LED3 PH_2 // Green LED + +// Buttons +#define BUTTON1 PG_15 +#define BUTTON2 PF_11 + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c b/targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c index 8fa211e190b..6d784ce6deb 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c @@ -313,7 +313,7 @@ int i2c_slave_receive(i2c_t *obj) int i2c_slave_read(i2c_t *obj, char *data, int length) { - return i2c_do_tran(obj, data, length, 1, 1); + return i2c_do_tran(obj, data, length, 1, 0); } int i2c_slave_write(i2c_t *obj, const char *data, int length) @@ -691,7 +691,6 @@ static void i2c_irq(i2c_t *obj) } obj->i2c.slaveaddr_state = ReadAddressed; break; - //case 0xA0: // Slave Transmit Repeat Start or Stop case 0xC0: // Slave Transmit Data NACK case 0xC8: // Slave Transmit Last Data ACK obj->i2c.slaveaddr_state = NoData; @@ -705,40 +704,46 @@ static void i2c_irq(i2c_t *obj) case 0x68: // Slave Receive Arbitration Lost obj->i2c.slaveaddr_state = WriteAddressed; 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) { - if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) { + // Did we receive any data? If so, receive it (if there is space in the buffer) and update tran_pos + if (status == 0x80 || status == 0x88) { + if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) { + if(obj->i2c.tran_pos < obj->i2c.tran_end) + { *obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base); - obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA; } + + 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 && - obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) { - // Last data - i2c_ctl &= ~I2C_CTL0_AA_Msk; - } - I2C_SET_CONTROL_REG(i2c_base, i2c_ctl); - obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA; + // Did we NACK this byte, ending the transaction? + if (status == 0x88) { + obj->i2c.slaveaddr_state = NoData; + i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk); + } + // Otherwise, tell the peripheral to receive the next byte + else { + uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk; + if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 && + obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) { + // Last data + i2c_ctl &= ~I2C_CTL0_AA_Msk; } - } else { - obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; - i2c_disable_int(obj); - break; + I2C_SET_CONTROL_REG(i2c_base, i2c_ctl); + obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA; } } else { i2c_disable_int(obj); } break; - //case 0xA0: // Slave Receive Repeat Start or Stop + + case 0xA0: // Slave Operation Complete + // Master sent STOP condition, go back to idle state and end the operation + obj->i2c.slaveaddr_state = NoData; + i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk); + obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; + i2c_disable_int(obj); + break; // GC mode //case 0xA0: // GC mode Repeat Start or Stop @@ -903,6 +908,7 @@ uint32_t i2c_irq_handler_asynch(i2c_t *obj) uint8_t *rx = (uint8_t *) obj->rx_buff.buffer; rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c))); } + // fall through case 0x40: // Master Receive Address ACK I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk | ((obj->rx_buff.pos != obj->rx_buff.length - 1) ? I2C_CTL0_AA_Msk : 0)); break; @@ -915,11 +921,15 @@ uint32_t i2c_irq_handler_asynch(i2c_t *obj) break; case 0x58: // Master Receive Data NACK + + // We get here after the last byte was transferred in an async read. Save it into the buffer + // and end the transaction. if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) { uint8_t *rx = (uint8_t *) obj->rx_buff.buffer; rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c))); } - I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk); + I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk); + event = I2C_EVENT_TRANSFER_COMPLETE; break; case 0x00: // Bus error diff --git a/targets/targets.json5 b/targets/targets.json5 index c524cbad9ee..12b92b7dc4f 100644 --- a/targets/targets.json5 +++ b/targets/targets.json5 @@ -8241,6 +8241,9 @@ mode is recommended for target MCUs with small amounts of flash and RAM.", "spim-ccm-enable": 1, "network-default-interface-type": "ETHERNET" }, + "supported_form_factors": [ + "ARDUINO_UNO" + ], "image_url": "https://os.mbed.com/media/cache/platforms/NuMaker-PFM-M487.png.250x250_q85.png" }, "NUMAKER_IOT_M487": {