Merge pull request #294 from mazgch/master

increase timeout for slow I2C slaves that make use of extensive clock stretching
pull/299/head
Bogdan Marinescu 2014-05-07 13:18:30 +01:00
commit 06edaf703a
5 changed files with 35 additions and 45 deletions

View File

@ -102,7 +102,7 @@ int i2c_stop(i2c_t *obj) {
} }
static int timeout_status_poll(i2c_t *obj, uint32_t mask) { 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++) { for (i = 0; i < timeout; i++) {
if (obj->i2c->S & mask) if (obj->i2c->S & mask)

View File

@ -97,7 +97,7 @@ int i2c_stop(i2c_t *obj) {
} }
static int timeout_status_poll(i2c_t *obj, uint32_t mask) { 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++) { for (i = 0; i < timeout; i++) {
if (obj->i2c->S & mask) if (obj->i2c->S & mask)

View File

@ -84,7 +84,7 @@ int i2c_stop(i2c_t *obj) {
} }
static int timeout_status_poll(i2c_t *obj, uint32_t mask) { 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++) { for (i = 0; i < timeout; i++) {
if (HW_I2C_S_RD(obj->instance) & mask) if (HW_I2C_S_RD(obj->instance) & mask)

View File

@ -138,7 +138,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
LPC_I2C0->MSTCTL = (1 << 0); LPC_I2C0->MSTCTL = (1 << 0);
data[count] = (LPC_I2C0->MSTDAT & 0xFF); data[count] = (LPC_I2C0->MSTDAT & 0xFF);
status = ((LPC_I2C0->STAT >> 1) & (0x07)); status = ((LPC_I2C0->STAT >> 1) & (0x07));
if (status != 0x00) { if (status != 0x01) {
i2c_stop(obj); i2c_stop(obj);
return count; return count;
} }

View File

@ -42,13 +42,13 @@ static const SWM_Map SWM_UART_RX[] = {
static const SWM_Map SWM_UART_RTS[] = { static const SWM_Map SWM_UART_RTS[] = {
{0, 16}, {0, 16},
{1, 24}, {1, 24},
{3, 0}, {3, 0}, // not available
}; };
static const SWM_Map SWM_UART_CTS[] = { static const SWM_Map SWM_UART_CTS[] = {
{0, 24}, {0, 24},
{2, 0}, {2, 0},
{3, 8} {3, 8} // not available
}; };
// bit flags for used UARTs // bit flags for used UARTs
@ -82,9 +82,29 @@ static uart_irq_handler irq_handler;
int stdio_uart_inited = 0; int stdio_uart_inited = 0;
serial_t stdio_uart; 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) { void serial_init(serial_t *obj, PinName tx, PinName rx) {
int is_stdio_uart = 0; int is_stdio_uart = 0;
int uart_n = get_available_uart(); int uart_n = get_available_uart();
if (uart_n == -1) { if (uart_n == -1) {
error("No available UART"); 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)); obj->uart = (LPC_USART0_Type *)(LPC_USART0_BASE + (0x4000 * uart_n));
uart_used |= (1 << uart_n); uart_used |= (1 << uart_n);
const SWM_Map *swm; switch_pin(&SWM_UART_TX[uart_n], tx);
uint32_t regVal; switch_pin(&SWM_UART_RX[uart_n], rx);
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);
/* uart clock divided by 6 */ /* uart clock divided by 6 */
LPC_SYSCON->UARTCLKDIV =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) { void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) {
const SWM_Map *swm_rts, *swm_cts; if ((FlowControlNone == type || FlowControlRTS == type)) txflow = NC;
uint32_t regVal_rts, regVal_cts; if ((FlowControlNone == type || FlowControlCTS == type)) rxflow = NC;
switch_pin(&SWM_UART_RTS[obj->index], rxflow);
swm_rts = &SWM_UART_RTS[obj->index]; switch_pin(&SWM_UART_CTS[obj->index], txflow);
swm_cts = &SWM_UART_CTS[obj->index]; if (txflow == NC) obj->uart->CFG &= ~CTSEN;
regVal_rts = LPC_SWM->PINASSIGN[swm_rts->n] & ~(0xFF << swm_rts->offset); else obj->uart->CFG |= CTSEN;
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);
}
}
} }