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);
|
twi_init(1);
|
||||||
result = twi_switch_application(m_twi_address, BOOTTYPE_BOOTLOADER);
|
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 */
|
/* no response from target, do normal reset */
|
||||||
RESET_ACTIVE();
|
RESET_ACTIVE();
|
||||||
@ -641,6 +641,7 @@ static void cmd_handler_twi(uint8_t cmd)
|
|||||||
uint16_t write_pos = 0;
|
uint16_t write_pos = 0;
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
uint8_t result = TWI_SUCCESS;
|
||||||
|
|
||||||
m_led_mode = LED_FAST;
|
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);
|
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')
|
if (type == 'F')
|
||||||
{
|
{
|
||||||
twi_write_memory(m_twi_address, MEMTYPE_FLASH,
|
result = twi_write_memory(m_twi_address, MEMTYPE_FLASH,
|
||||||
(m_address << 1),
|
(m_address << 1),
|
||||||
m_page_buf + write_pos,
|
m_page_buf + write_pos,
|
||||||
m_twi_chipinfo.page_size);
|
m_twi_chipinfo.page_size);
|
||||||
|
|
||||||
/* when accessing flash, m_address is a word address */
|
/* when accessing flash, m_address is a word address */
|
||||||
m_address += (m_twi_chipinfo.page_size >> 1);
|
m_address += (m_twi_chipinfo.page_size >> 1);
|
||||||
@ -670,12 +673,13 @@ static void cmd_handler_twi(uint8_t cmd)
|
|||||||
{
|
{
|
||||||
uint8_t write_size;
|
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,
|
result = twi_write_memory(m_twi_address, MEMTYPE_EEPROM,
|
||||||
m_address,
|
m_address,
|
||||||
m_page_buf + write_pos,
|
m_page_buf + write_pos,
|
||||||
write_size);
|
write_size);
|
||||||
|
|
||||||
/* when accessing eeprom, m_address is a byte address */
|
/* when accessing eeprom, m_address is a byte address */
|
||||||
m_address += write_size;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,6 +894,7 @@ static void cmdloop(void)
|
|||||||
uart_send_buf(m_page_buf, read_size);
|
uart_send_buf(m_page_buf, read_size);
|
||||||
|
|
||||||
uart_send((result == TWI_SUCCESS) ? '\r' : '!');
|
uart_send((result == TWI_SUCCESS) ? '\r' : '!');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif /* (USE_TWI_SUPPORT) */
|
#endif /* (USE_TWI_SUPPORT) */
|
||||||
|
|
||||||
|
129
twi_master.c
129
twi_master.c
@ -22,6 +22,8 @@
|
|||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "twi_master.h"
|
#include "twi_master.h"
|
||||||
|
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
#if (USE_TWI_SUPPORT)
|
#if (USE_TWI_SUPPORT)
|
||||||
|
|
||||||
#define TWI_SLA_W(addr) (addr << 1)
|
#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 */
|
case 0x40: /* SLA+R transmitted, ACK received */
|
||||||
return TWI_SUCCESS;
|
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:
|
default:
|
||||||
return TWI_ERROR;
|
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)
|
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 result;
|
||||||
return TWI_ERROR;
|
} /* twi_master_tx_buf */
|
||||||
} /* twi_master_start */
|
|
||||||
|
|
||||||
|
/* ***********************************************************************
|
||||||
|
* 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));
|
result = twi_master_start(TWI_SLA_W(twi_addr));
|
||||||
if (result == TWI_SUCCESS)
|
if (result == TWI_SUCCESS)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
result = twi_master_tx_buf(p_wr_data, write_size);
|
||||||
|
|
||||||
for (i = 0; i < write_size; i++)
|
|
||||||
{
|
|
||||||
result = twi_master_tx(*p_wr_data++);
|
|
||||||
if (result != TWI_SUCCESS)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,19 +213,7 @@ uint8_t twi_generic(uint8_t twi_addr,
|
|||||||
result = twi_master_start(TWI_SLA_R(twi_addr));
|
result = twi_master_start(TWI_SLA_R(twi_addr));
|
||||||
if (result == TWI_SUCCESS)
|
if (result == TWI_SUCCESS)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
result = twi_master_rx_buf(p_rd_data, read_size);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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));
|
result = twi_master_start(TWI_SLA_W(twi_addr));
|
||||||
if (result == TWI_SUCCESS)
|
if (result == TWI_SUCCESS)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
result = twi_master_tx_buf(cmd, sizeof(cmd));
|
||||||
|
|
||||||
for (i = 0; i < sizeof(cmd); i++)
|
|
||||||
{
|
|
||||||
result = twi_master_tx(cmd[i]);
|
|
||||||
if (result != TWI_SUCCESS)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == TWI_SUCCESS)
|
if (result == TWI_SUCCESS)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
result = twi_master_tx_buf(p_data, data_length);
|
||||||
|
|
||||||
for (i = 0; i < data_length; i++)
|
|
||||||
{
|
|
||||||
result = twi_master_tx(*p_data++);
|
|
||||||
if (result != TWI_SUCCESS)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
twi_stop();
|
twi_stop();
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#define TWI_SUCCESS 0x00
|
#define TWI_SUCCESS 0x00
|
||||||
#define TWI_ERROR 0x01
|
#define TWI_ERROR 0x01
|
||||||
|
#define TWI_NACK_ADDR 0x02
|
||||||
|
#define TWI_NACK_DATA 0x03
|
||||||
|
|
||||||
typedef struct twi_chipinfo_s
|
typedef struct twi_chipinfo_s
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user