Skip to content

Commit 6702976

Browse files
Fix some M480 I2C issues causing test shield test failures (#461)
* Fix some M480 I2C issues causing test shield test failures * Fix pin validate failure * Remove redundant check
1 parent 6c216b9 commit 6702976

File tree

3 files changed

+72
-79
lines changed

3 files changed

+72
-79
lines changed

targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PinNames.h

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -43,42 +43,34 @@ typedef enum {
4343
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,
4444

4545
// Arduino UNO naming
46-
A0 = PB_6,
47-
A1 = PB_7,
48-
A2 = PB_8,
49-
A3 = PB_9,
50-
A4 = PB_0,
51-
A5 = PB_1,
52-
53-
D0 = PB_2,
54-
D1 = PB_3,
55-
D2 = PC_9,
56-
D3 = PC_10,
57-
D4 = PC_11,
58-
D5 = PC_12,
59-
D6 = PE_4,
60-
D7 = PE_5,
61-
D8 = PA_5,
62-
D9 = PA_4,
63-
D10 = PA_3,
64-
D11 = PA_0,
65-
D12 = PA_1,
66-
D13 = PA_2,
67-
D14 = PG_1,
68-
D15 = PG_0,
46+
ARDUINO_UNO_A0 = PB_6,
47+
ARDUINO_UNO_A1 = PB_7,
48+
ARDUINO_UNO_A2 = PB_8,
49+
ARDUINO_UNO_A3 = PB_9,
50+
ARDUINO_UNO_A4 = PB_0,
51+
ARDUINO_UNO_A5 = PB_1,
52+
53+
ARDUINO_UNO_D0 = PB_2,
54+
ARDUINO_UNO_D1 = PB_3,
55+
ARDUINO_UNO_D2 = PC_9,
56+
ARDUINO_UNO_D3 = PC_10,
57+
ARDUINO_UNO_D4 = PC_11,
58+
ARDUINO_UNO_D5 = PC_12,
59+
ARDUINO_UNO_D6 = PE_4,
60+
ARDUINO_UNO_D7 = PE_5,
61+
ARDUINO_UNO_D8 = PA_5,
62+
ARDUINO_UNO_D9 = PA_4,
63+
ARDUINO_UNO_D10 = PA_3,
64+
ARDUINO_UNO_D11 = PA_0,
65+
ARDUINO_UNO_D12 = PA_1,
66+
ARDUINO_UNO_D13 = PA_2,
67+
ARDUINO_UNO_D14 = PG_1,
68+
ARDUINO_UNO_D15 = PG_0,
6969

7070
// Note: board-specific
7171
// UART naming
72-
#if defined(MBED_CONF_TARGET_USB_UART_TX)
7372
CONSOLE_TX = MBED_CONF_TARGET_USB_UART_TX,
74-
#else
75-
CONSOLE_TX = NC,
76-
#endif
77-
#if defined(MBED_CONF_TARGET_USB_UART_RX)
7873
CONSOLE_RX = MBED_CONF_TARGET_USB_UART_RX,
79-
#else
80-
CONSOLE_RX = NC,
81-
#endif
8274
#if defined(MBED_CONF_TARGET_STDIO_UART_TX)
8375
STDIO_UART_TX = MBED_CONF_TARGET_STDIO_UART_TX,
8476
#else
@@ -89,33 +81,21 @@ typedef enum {
8981
#else
9082
STDIO_UART_RX = CONSOLE_RX,
9183
#endif
92-
SERIAL_TX = D10,
93-
SERIAL_RX = D13,
94-
95-
// I2C naming
96-
I2C_SCL = D15,
97-
I2C_SDA = D14,
98-
99-
// LED naming
100-
LED_RED = PH_0,
101-
LED_YELLOW = PH_1,
102-
LED_GREEN = PH_2,
103-
LED1 = LED_RED,
104-
LED2 = LED_YELLOW,
105-
LED3 = LED_GREEN,
106-
LED4 = LED1, // No real LED. Just for passing ATS.
107-
108-
// Button naming
109-
SW2 = PG_15,
110-
SW3 = PF_11,
111-
BUTTON1 = SW2,
112-
BUTTON2 = SW3,
11384

11485
// Force PinName to 32-bit required by NU_PINNAME_BIND(...)
11586
FORCE_ENUM_PINNAME_32BIT = 0x7FFFFFFF,
11687

11788
} PinName;
11889

90+
// LEDs
91+
#define LED1 PH_0 // Red LED
92+
#define LED2 PH_1 // Yellow LED
93+
#define LED3 PH_2 // Green LED
94+
95+
// Buttons
96+
#define BUTTON1 PG_15
97+
#define BUTTON2 PF_11
98+
11999
#ifdef __cplusplus
120100
}
121101
#endif

targets/TARGET_NUVOTON/TARGET_M480/i2c_api.c

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ int i2c_slave_receive(i2c_t *obj)
313313

314314
int i2c_slave_read(i2c_t *obj, char *data, int length)
315315
{
316-
return i2c_do_tran(obj, data, length, 1, 1);
316+
return i2c_do_tran(obj, data, length, 1, 0);
317317
}
318318

319319
int i2c_slave_write(i2c_t *obj, const char *data, int length)
@@ -691,7 +691,6 @@ static void i2c_irq(i2c_t *obj)
691691
}
692692
obj->i2c.slaveaddr_state = ReadAddressed;
693693
break;
694-
//case 0xA0: // Slave Transmit Repeat Start or Stop
695694
case 0xC0: // Slave Transmit Data NACK
696695
case 0xC8: // Slave Transmit Last Data ACK
697696
obj->i2c.slaveaddr_state = NoData;
@@ -705,40 +704,46 @@ static void i2c_irq(i2c_t *obj)
705704
case 0x68: // Slave Receive Arbitration Lost
706705
obj->i2c.slaveaddr_state = WriteAddressed;
707706
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
708-
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
709-
if (status == 0x80 || status == 0x88) {
710-
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
707+
// Did we receive any data? If so, receive it (if there is space in the buffer) and update tran_pos
708+
if (status == 0x80 || status == 0x88) {
709+
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
710+
if(obj->i2c.tran_pos < obj->i2c.tran_end)
711+
{
711712
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
712-
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
713713
}
714+
715+
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
714716
}
717+
}
715718

716-
if (status == 0x88) {
717-
obj->i2c.slaveaddr_state = NoData;
718-
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
719-
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
720-
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
721-
i2c_disable_int(obj);
722-
} else {
723-
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
724-
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
725-
obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
726-
// Last data
727-
i2c_ctl &= ~I2C_CTL0_AA_Msk;
728-
}
729-
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
730-
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
719+
// Did we NACK this byte, ending the transaction?
720+
if (status == 0x88) {
721+
obj->i2c.slaveaddr_state = NoData;
722+
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
723+
}
724+
// Otherwise, tell the peripheral to receive the next byte
725+
else {
726+
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
727+
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
728+
obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
729+
// Last data
730+
i2c_ctl &= ~I2C_CTL0_AA_Msk;
731731
}
732-
} else {
733-
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
734-
i2c_disable_int(obj);
735-
break;
732+
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
733+
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
736734
}
737735
} else {
738736
i2c_disable_int(obj);
739737
}
740738
break;
741-
//case 0xA0: // Slave Receive Repeat Start or Stop
739+
740+
case 0xA0: // Slave Operation Complete
741+
// Master sent STOP condition, go back to idle state and end the operation
742+
obj->i2c.slaveaddr_state = NoData;
743+
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
744+
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
745+
i2c_disable_int(obj);
746+
break;
742747

743748
// GC mode
744749
//case 0xA0: // GC mode Repeat Start or Stop
@@ -903,6 +908,7 @@ uint32_t i2c_irq_handler_asynch(i2c_t *obj)
903908
uint8_t *rx = (uint8_t *) obj->rx_buff.buffer;
904909
rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c)));
905910
}
911+
// fall through
906912
case 0x40: // Master Receive Address ACK
907913
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk | ((obj->rx_buff.pos != obj->rx_buff.length - 1) ? I2C_CTL0_AA_Msk : 0));
908914
break;
@@ -915,11 +921,15 @@ uint32_t i2c_irq_handler_asynch(i2c_t *obj)
915921
break;
916922

917923
case 0x58: // Master Receive Data NACK
924+
925+
// We get here after the last byte was transferred in an async read. Save it into the buffer
926+
// and end the transaction.
918927
if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
919928
uint8_t *rx = (uint8_t *) obj->rx_buff.buffer;
920929
rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c)));
921930
}
922-
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk);
931+
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
932+
event = I2C_EVENT_TRANSFER_COMPLETE;
923933
break;
924934

925935
case 0x00: // Bus error

targets/targets.json5

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8300,6 +8300,9 @@ mode is recommended for target MCUs with small amounts of flash and RAM.",
83008300
"spim-ccm-enable": 1,
83018301
"network-default-interface-type": "ETHERNET"
83028302
},
8303+
"supported_form_factors": [
8304+
"ARDUINO_UNO"
8305+
],
83038306
"image_url": "https://os.mbed.com/media/cache/platforms/NuMaker-PFM-M487.png.250x250_q85.png"
83048307
},
83058308
"NUMAKER_IOT_M487": {

0 commit comments

Comments
 (0)