Differentiate twi bus errors and address/data NACKs
This commit is contained in:
parent
afd7b92c1f
commit
2d9c71bb8b
29
ispprog.c
29
ispprog.c
@ -154,7 +154,7 @@ static void reset_statemachine(uint8_t events)
|
||||
|
||||
twi_init(1);
|
||||
result = twi_switch_application(m_twi_address, BOOTTYPE_BOOTLOADER);
|
||||
if (result == TWI_ERROR)
|
||||
if (result == TWI_NACK_ADDR)
|
||||
{
|
||||
/* no response from target, do normal reset */
|
||||
RESET_ACTIVE();
|
||||
@ -641,6 +641,7 @@ static void cmd_handler_twi(uint8_t cmd)
|
||||
uint16_t write_pos = 0;
|
||||
uint16_t size;
|
||||
uint8_t type;
|
||||
uint8_t result = TWI_SUCCESS;
|
||||
|
||||
m_led_mode = LED_FAST;
|
||||
|
||||
@ -653,14 +654,16 @@ static void cmd_handler_twi(uint8_t cmd)
|
||||
|
||||
memset(m_page_buf + size, 0xFF, sizeof(m_page_buf) - size);
|
||||
|
||||
while (write_pos < size)
|
||||
while ((write_pos < size) &&
|
||||
(result == TWI_SUCCESS)
|
||||
)
|
||||
{
|
||||
if (type == 'F')
|
||||
{
|
||||
twi_write_memory(m_twi_address, MEMTYPE_FLASH,
|
||||
(m_address << 1),
|
||||
m_page_buf + write_pos,
|
||||
m_twi_chipinfo.page_size);
|
||||
result = twi_write_memory(m_twi_address, MEMTYPE_FLASH,
|
||||
(m_address << 1),
|
||||
m_page_buf + write_pos,
|
||||
m_twi_chipinfo.page_size);
|
||||
|
||||
/* when accessing flash, m_address is a word address */
|
||||
m_address += (m_twi_chipinfo.page_size >> 1);
|
||||
@ -670,12 +673,13 @@ static void cmd_handler_twi(uint8_t cmd)
|
||||
{
|
||||
uint8_t write_size;
|
||||
|
||||
write_size = MIN(size, m_twi_chipinfo.page_size);
|
||||
/* one eeprom byte takes 3.5ms to programm */
|
||||
write_size = MIN(size, 4);
|
||||
|
||||
twi_write_memory(m_twi_address, MEMTYPE_EEPROM,
|
||||
m_address,
|
||||
m_page_buf + write_pos,
|
||||
write_size);
|
||||
result = twi_write_memory(m_twi_address, MEMTYPE_EEPROM,
|
||||
m_address,
|
||||
m_page_buf + write_pos,
|
||||
write_size);
|
||||
|
||||
/* when accessing eeprom, m_address is a byte address */
|
||||
m_address += write_size;
|
||||
@ -683,7 +687,7 @@ static void cmd_handler_twi(uint8_t cmd)
|
||||
}
|
||||
}
|
||||
|
||||
uart_send('\r');
|
||||
uart_send((result == TWI_SUCCESS) ? '\r' : '!');
|
||||
break;
|
||||
}
|
||||
|
||||
@ -890,6 +894,7 @@ static void cmdloop(void)
|
||||
uart_send_buf(m_page_buf, read_size);
|
||||
|
||||
uart_send((result == TWI_SUCCESS) ? '\r' : '!');
|
||||
break;
|
||||
}
|
||||
#endif /* (USE_TWI_SUPPORT) */
|
||||
|
||||
|
129
twi_master.c
129
twi_master.c
@ -22,6 +22,8 @@
|
||||
#include "target.h"
|
||||
#include "twi_master.h"
|
||||
|
||||
#include <util/delay.h>
|
||||
|
||||
#if (USE_TWI_SUPPORT)
|
||||
|
||||
#define TWI_SLA_W(addr) (addr << 1)
|
||||
@ -73,6 +75,13 @@ static uint8_t twi_master_tx(uint8_t value)
|
||||
case 0x40: /* SLA+R transmitted, ACK received */
|
||||
return TWI_SUCCESS;
|
||||
|
||||
case 0x20: /* SLA+W transmitted, NACK received */
|
||||
case 0x48: /* SLA+R transmitted, NACK received */
|
||||
return TWI_NACK_ADDR;
|
||||
|
||||
case 0x30: /* Data transmitted, NACK received */
|
||||
return TWI_NACK_DATA;
|
||||
|
||||
default:
|
||||
return TWI_ERROR;
|
||||
}
|
||||
@ -105,17 +114,78 @@ static uint8_t twi_master_rx(uint8_t * p_value, uint8_t ack)
|
||||
* *********************************************************************** */
|
||||
static uint8_t twi_master_start(uint8_t twi_addr)
|
||||
{
|
||||
if (twi_start() == TWI_SUCCESS)
|
||||
uint8_t result = TWI_NACK_ADDR;
|
||||
uint8_t retry = 10;
|
||||
|
||||
while ((result == TWI_NACK_ADDR) && (retry--))
|
||||
{
|
||||
if (twi_master_tx(twi_addr) == TWI_SUCCESS)
|
||||
result = twi_start();
|
||||
if (result == TWI_SUCCESS)
|
||||
{
|
||||
return TWI_SUCCESS;
|
||||
result = twi_master_tx(twi_addr);
|
||||
if (result == TWI_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
twi_stop();
|
||||
_delay_ms(2);
|
||||
}
|
||||
|
||||
return result;
|
||||
} /* twi_master_start */
|
||||
|
||||
|
||||
/* ***********************************************************************
|
||||
* twi_master_tx_buf
|
||||
* *********************************************************************** */
|
||||
static uint8_t twi_master_tx_buf(const uint8_t * p_data, uint16_t data_size)
|
||||
{
|
||||
uint8_t result = TWI_ERROR;
|
||||
|
||||
while (data_size--)
|
||||
{
|
||||
result = twi_master_tx(*p_data++);
|
||||
if (result != TWI_SUCCESS)
|
||||
{
|
||||
/* NACK for the last transmitted byte is OK */
|
||||
if ((result == TWI_NACK_DATA) && (data_size == 0))
|
||||
{
|
||||
result = TWI_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
twi_stop();
|
||||
return TWI_ERROR;
|
||||
} /* twi_master_start */
|
||||
return result;
|
||||
} /* twi_master_tx_buf */
|
||||
|
||||
|
||||
/* ***********************************************************************
|
||||
* twi_master_rx_buf
|
||||
* *********************************************************************** */
|
||||
static uint8_t twi_master_rx_buf(uint8_t * p_data, uint16_t data_size)
|
||||
{
|
||||
uint8_t result = TWI_ERROR;
|
||||
|
||||
while (data_size--)
|
||||
{
|
||||
uint8_t ack;
|
||||
|
||||
ack = (data_size > 0);
|
||||
result = twi_master_rx(p_data++, ack);
|
||||
if (result != TWI_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
} /* twi_master_rx_buf */
|
||||
|
||||
|
||||
/* ***********************************************************************
|
||||
@ -132,16 +202,7 @@ uint8_t twi_generic(uint8_t twi_addr,
|
||||
result = twi_master_start(TWI_SLA_W(twi_addr));
|
||||
if (result == TWI_SUCCESS)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < write_size; i++)
|
||||
{
|
||||
result = twi_master_tx(*p_wr_data++);
|
||||
if (result != TWI_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = twi_master_tx_buf(p_wr_data, write_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,19 +213,7 @@ uint8_t twi_generic(uint8_t twi_addr,
|
||||
result = twi_master_start(TWI_SLA_R(twi_addr));
|
||||
if (result == TWI_SUCCESS)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < read_size; i++)
|
||||
{
|
||||
uint8_t ack;
|
||||
|
||||
ack = (i != (read_size -1));
|
||||
result = twi_master_rx(p_rd_data++, ack);
|
||||
if (result != TWI_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = twi_master_rx_buf(p_rd_data, read_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,30 +286,12 @@ uint8_t twi_write_memory(uint8_t twi_addr, uint8_t memory_type, uint16_t memory_
|
||||
result = twi_master_start(TWI_SLA_W(twi_addr));
|
||||
if (result == TWI_SUCCESS)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < sizeof(cmd); i++)
|
||||
{
|
||||
result = twi_master_tx(cmd[i]);
|
||||
if (result != TWI_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = twi_master_tx_buf(cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
if (result == TWI_SUCCESS)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < data_length; i++)
|
||||
{
|
||||
result = twi_master_tx(*p_data++);
|
||||
if (result != TWI_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = twi_master_tx_buf(p_data, data_length);
|
||||
}
|
||||
|
||||
twi_stop();
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
#define TWI_SUCCESS 0x00
|
||||
#define TWI_ERROR 0x01
|
||||
#define TWI_NACK_ADDR 0x02
|
||||
#define TWI_NACK_DATA 0x03
|
||||
|
||||
typedef struct twi_chipinfo_s
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user