From 04fa77f90972e7194ac71c4faba9d8a378a4cdef Mon Sep 17 00:00:00 2001 From: mazgch Date: Tue, 6 May 2014 09:13:58 +0200 Subject: [PATCH 1/4] increase timeout for slow slaves that use clock extensive stretching --- .../mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c | 4 ++-- .../mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/i2c_api.c | 2 +- .../TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/i2c_api.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c index 4cbdb2d42f..55727807ad 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.00 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -103,7 +103,7 @@ int i2c_stop(i2c_t *obj) { } static int timeout_status_poll(i2c_t *obj, uint32_t mask) { - uint32_t i, timeout = 1000; + uint32_t i, timeout = 100000; for (i = 0; i < timeout; i++) { if (obj->i2c->S & mask) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/i2c_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/i2c_api.c index add00a6d7c..a1b6414e7c 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/i2c_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/i2c_api.c @@ -103,7 +103,7 @@ int i2c_stop(i2c_t *obj) { } static int timeout_status_poll(i2c_t *obj, uint32_t mask) { - uint32_t i, timeout = 1000; + uint32_t i, timeout = 100000; for (i = 0; i < timeout; i++) { if (obj->i2c->S & mask) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/i2c_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/i2c_api.c index b505813ec7..79165e54c2 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/i2c_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/i2c_api.c @@ -83,7 +83,7 @@ int i2c_stop(i2c_t *obj) { } static int timeout_status_poll(i2c_t *obj, uint32_t mask) { - uint32_t i, timeout = 1000; + uint32_t i, timeout = 100000; for (i = 0; i < timeout; i++) { if (HW_I2C_S_RD(obj->instance) & mask) From 850bb1164573f50c82f69434cfa56b451e90ff9b Mon Sep 17 00:00:00 2001 From: mazgch Date: Tue, 6 May 2014 09:18:06 +0200 Subject: [PATCH 2/4] undo typo --- .../mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c index 55727807ad..0db9323f20 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/i2c_api.c @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.00 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, From e61b2f1f88c4b4ef2caf3cf9510e130183ee20dc Mon Sep 17 00:00:00 2001 From: mazgch Date: Wed, 7 May 2014 09:38:26 +0200 Subject: [PATCH 3/4] make sure we remove any function from a physical pin so that we can assign a new function to it. --- .../TARGET_NXP/TARGET_LPC15XX/serial_api.c | 72 ++++++++----------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/serial_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/serial_api.c index 13667ff257..462b765f63 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/serial_api.c +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/serial_api.c @@ -42,13 +42,13 @@ static const SWM_Map SWM_UART_RX[] = { static const SWM_Map SWM_UART_RTS[] = { {0, 16}, {1, 24}, - {3, 0}, + {3, 0}, // not available }; static const SWM_Map SWM_UART_CTS[] = { {0, 24}, {2, 0}, - {3, 8} + {3, 8} // not available }; // bit flags for used UARTs @@ -82,9 +82,29 @@ static uart_irq_handler irq_handler; int stdio_uart_inited = 0; serial_t stdio_uart; +static void switch_pin(const SWM_Map *swm, PinName pn) +{ + uint32_t regVal; + if (pn != NC) + { + // check if we have any function mapped to this pin already and remove it + for (int n = 0; n < sizeof(LPC_SWM->PINASSIGN)/sizeof(*LPC_SWM->PINASSIGN); n ++) { + regVal = LPC_SWM->PINASSIGN[n]; + for (int j = 0; j <= 24; j += 8) { + if (((regVal >> j) & 0xFF) == pn) + regVal |= (0xFF << j); + } + LPC_SWM->PINASSIGN[n] = regVal; + } + } + // now map it + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (pn << swm->offset); +} + void serial_init(serial_t *obj, PinName tx, PinName rx) { int is_stdio_uart = 0; - + int uart_n = get_available_uart(); if (uart_n == -1) { error("No available UART"); @@ -93,16 +113,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) { obj->uart = (LPC_USART0_Type *)(LPC_USART0_BASE + (0x4000 * uart_n)); uart_used |= (1 << uart_n); - const SWM_Map *swm; - uint32_t regVal; - - swm = &SWM_UART_TX[uart_n]; - regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); - LPC_SWM->PINASSIGN[swm->n] = regVal | (tx << swm->offset); - - swm = &SWM_UART_RX[uart_n]; - regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); - LPC_SWM->PINASSIGN[swm->n] = regVal | (rx << swm->offset); + switch_pin(&SWM_UART_TX[uart_n], tx); + switch_pin(&SWM_UART_RX[uart_n], rx); /* uart clock divided by 6 */ LPC_SYSCON->UARTCLKDIV =6; @@ -296,33 +308,11 @@ void serial_break_clear(serial_t *obj) { } void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { - const SWM_Map *swm_rts, *swm_cts; - uint32_t regVal_rts, regVal_cts; - - swm_rts = &SWM_UART_RTS[obj->index]; - swm_cts = &SWM_UART_CTS[obj->index]; - regVal_rts = LPC_SWM->PINASSIGN[swm_rts->n] & ~(0xFF << swm_rts->offset); - regVal_cts = LPC_SWM->PINASSIGN[swm_cts->n] & ~(0xFF << swm_cts->offset); - - if (FlowControlNone == type) { - LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset); - LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset); - obj->uart->CFG &= ~CTSEN; - return; - } - if ((FlowControlRTS == type || FlowControlRTSCTS == type) && (rxflow != NC)) { - LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (rxflow << swm_rts->offset); - if (FlowControlRTS == type) { - LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset); - obj->uart->CFG &= ~CTSEN; - } - } - if ((FlowControlCTS == type || FlowControlRTSCTS == type) && (txflow != NC)) { - LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (txflow << swm_cts->offset); - obj->uart->CFG |= CTSEN; - if (FlowControlCTS == type) { - LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset); - } - } + if ((FlowControlNone == type || FlowControlRTS == type)) txflow = NC; + if ((FlowControlNone == type || FlowControlCTS == type)) rxflow = NC; + switch_pin(&SWM_UART_RTS[obj->index], rxflow); + switch_pin(&SWM_UART_CTS[obj->index], txflow); + if (txflow == NC) obj->uart->CFG &= ~CTSEN; + else obj->uart->CFG |= CTSEN; } From 94ac072267cc87e12c9ea6f7da58f663c2613ffa Mon Sep 17 00:00:00 2001 From: mazgch Date: Wed, 7 May 2014 13:39:27 +0200 Subject: [PATCH 4/4] fix multibyte reads (was polling wrong status value) --- libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c index 394b65ae89..09d7ec6b55 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c @@ -138,7 +138,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { LPC_I2C0->MSTCTL = (1 << 0); data[count] = (LPC_I2C0->MSTDAT & 0xFF); status = ((LPC_I2C0->STAT >> 1) & (0x07)); - if (status != 0x00) { + if (status != 0x01) { i2c_stop(obj); return count; }