twi eeprom handling

This commit is contained in:
Olaf Rempel 2008-03-05 19:35:00 +01:00
parent c4227fbabb
commit 580d8369fa
4 changed files with 89 additions and 24 deletions

View File

@ -73,6 +73,7 @@ openocd:
$(shell $(OPENOCD) -f scripts/openocd.cfg) $(shell $(OPENOCD) -f scripts/openocd.cfg)
install: all install: all
./scripts/download.sh # ./scripts/download.sh
$(TOOLCHAIN)/dfu-util -i 0 -D $(BUILD)/$(TARGET).elf.bin
-include $(shell find $(BUILD) -name *.d 2> /dev/null) -include $(shell find $(BUILD) -name *.d 2> /dev/null)

View File

@ -8,7 +8,7 @@
#define TWI_ADDR_BL2 0x22 #define TWI_ADDR_BL2 0x22
#define TWI_ADDR_BL3 0x23 #define TWI_ADDR_BL3 0x23
#define TWI_ADDR_BL4 0x24 #define TWI_ADDR_BL4 0x24
#define TWI_ADDR_EEPROM 0x40 #define TWI_ADDR_EEPROM 0x50
/* TWIBOOT commands */ /* TWIBOOT commands */
#define CMD_WAIT 0x00 #define CMD_WAIT 0x00
@ -58,7 +58,7 @@ struct blmc_param {
uint16_t crc16; uint16_t crc16;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct blmc_cmd { struct twi_cmd {
uint32_t cmd; /* cmd byte(s) */ uint32_t cmd; /* cmd byte(s) */
uint8_t mode; /* read/write, cmdlen (1-3 bytes) */ uint8_t mode; /* read/write, cmdlen (1-3 bytes) */
uint16_t size; /* data size */ uint16_t size; /* data size */
@ -66,18 +66,18 @@ struct blmc_cmd {
}; };
/* same bits as TWI_MMR[8..15] */ /* same bits as TWI_MMR[8..15] */
#define BLMC_CMD_READ 0x10 #define TWI_MODE_READ 0x10
#define BLMC_CMD_WRITE 0x00 #define TWI_MODE_WRITE 0x00
#define BLMC_CMD_0_ARG 0x01 #define TWI_MODE_0_ARG 0x01
#define BLMC_CMD_1_ARG 0x02 #define TWI_MODE_1_ARG 0x02
#define BLMC_CMD_2_ARG 0x03 #define TWI_MODE_2_ARG 0x03
uint32_t twi_read_eeprom(uint32_t addr, uint8_t *buf, uint32_t size); uint32_t twi_read_eeprom(uint32_t addr, uint8_t *buf, uint32_t size);
uint32_t twi_write_eeprom(uint32_t addr, uint8_t *buf, uint32_t size); uint32_t twi_write_eeprom(uint32_t addr, uint8_t *buf, uint32_t size);
uint32_t twi_setpwm(uint8_t *values); uint32_t twi_setpwm(uint8_t *values);
uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd); uint32_t twi_cmd(uint8_t addr, struct twi_cmd *cmd);
void at91_twi_init(void); void at91_twi_init(void);
void at91_twi_test(void); void at91_twi_test(void);

27
main.c
View File

@ -50,7 +50,7 @@ static uint32_t pitc_test(struct pitc_timer *timer)
printf("\r"); printf("\r");
*/ */
static uint8_t data[4] = { 0x0f, 0x0f, 0x0f, 0x0f }; static uint8_t data[4] = { 0x00, 0x00, 0x00, 0x00 };
twi_setpwm(data); twi_setpwm(data);
return PITC_RESTART_TIMER; return PITC_RESTART_TIMER;
@ -83,7 +83,7 @@ int main(void)
/* twi */ /* twi */
at91_twi_init(); at91_twi_init();
at91_twi_test(); // at91_twi_test();
/* usb */ /* usb */
at91_udp_init(); at91_udp_init();
@ -93,7 +93,28 @@ int main(void)
/* adc, need timer */ /* adc, need timer */
// at91_adc_test_init(); // at91_adc_test_init();
pitc_schedule_timer(&pitc_test_timer); uint8_t buf[0x80];
memset(buf, 0xAA, sizeof(buf));
uint32_t ret = twi_read_eeprom(0x1234, buf, sizeof(buf));
printf("read:%ld\n\r", ret);
uint32_t i;
for (i = 0; i < sizeof(buf); i += 16) {
uint32_t j;
for (j = 0; j < 16; j++)
printf("0x%02x ", buf[i +j]);
printf("\n\r");
}
for (i = 0; i < sizeof(buf); i++)
buf[i] ^= 0xFF;
ret = twi_write_eeprom(0x1234, buf, sizeof(buf));
printf("write:%ld\n\r", ret);
// pitc_schedule_timer(&pitc_test_timer);
while (1); while (1);
} }

View File

@ -22,7 +22,6 @@
#include "AT91SAM7S256.h" #include "AT91SAM7S256.h"
#include "board.h" #include "board.h"
#include "at91_twi.h" #include "at91_twi.h"
#include "at91_pio.h"
/* /*
* undocumented TWI_SR flags, at least OVRE seems to be present on a sam7s256 * undocumented TWI_SR flags, at least OVRE seems to be present on a sam7s256
@ -61,8 +60,6 @@ static void twi_isr(void)
if (status & AT91C_TWI_NACK) { if (status & AT91C_TWI_NACK) {
*AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK; *AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK;
twi_state = TWI_ERROR; twi_state = TWI_ERROR;
// TODO: TWI_BLMC_UPDATE?
return; return;
} }
@ -134,7 +131,7 @@ uint32_t twi_setpwm(uint8_t *values)
return 0; return 0;
} }
uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd) uint32_t twi_cmd(uint8_t addr, struct twi_cmd *cmd)
{ {
if (twi_state == TWI_ERROR) if (twi_state == TWI_ERROR)
twi_state = TWI_IDLE; twi_state = TWI_IDLE;
@ -146,7 +143,7 @@ uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
twi_state = TWI_GENERIC_CMD; twi_state = TWI_GENERIC_CMD;
/* read transfer, or write transfer with payload */ /* read transfer, or write transfer with payload */
if (cmd->mode & BLMC_CMD_READ || cmd->size != 0) { if (cmd->mode & TWI_MODE_READ || cmd->size != 0) {
/* set address, direction, argument count and command bytes */ /* set address, direction, argument count and command bytes */
*AT91C_TWI_MMR = (addr << 16) | (cmd->mode & 0xFF) << 8; *AT91C_TWI_MMR = (addr << 16) | (cmd->mode & 0xFF) << 8;
*AT91C_TWI_IADR = cmd->cmd; *AT91C_TWI_IADR = cmd->cmd;
@ -164,7 +161,7 @@ uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
twi_size = cmd->size; twi_size = cmd->size;
twi_count = 0; twi_count = 0;
if (cmd->mode & BLMC_CMD_READ) { if (cmd->mode & TWI_MODE_READ) {
*AT91C_TWI_CR = AT91C_TWI_START; *AT91C_TWI_CR = AT91C_TWI_START;
*AT91C_TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK; *AT91C_TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK;
@ -187,15 +184,61 @@ uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
return 0; return 0;
} }
uint32_t twi_read_eeprom(uint32_t addr, uint8_t *buf, uint32_t size)
{
struct twi_cmd cmd = {
.cmd = (addr & 0x7FFF),
.mode = TWI_MODE_READ | TWI_MODE_1_ARG,
.size = (size & 0x7FFF),
.data = buf,
};
if (twi_cmd(TWI_ADDR_EEPROM, &cmd) != 0)
size = 0;
return size;
}
uint32_t twi_write_eeprom(uint32_t addr, uint8_t *buf, uint32_t size)
{
uint32_t len = size;
while (len > 0) {
uint32_t count = 0x40 - (addr & 0x3F);
if (count > len)
count = len;
/* TODO: write complete polling */
volatile uint32_t x;
for (x = 0; x < 200000; x++);
struct twi_cmd cmd = {
.cmd = (addr & 0x7FFF),
.mode = TWI_MODE_WRITE | TWI_MODE_1_ARG,
.size = count,
.data = buf,
};
if (twi_cmd(TWI_ADDR_EEPROM, &cmd) != 0)
break;
addr += count;
buf += count;
len -= count;
}
return size - len;
}
void at91_twi_test(void) void at91_twi_test(void)
{ {
uint32_t i; uint32_t i;
for (i = TWI_ADDR_BL1; i <= TWI_ADDR_BL4; i++) { for (i = TWI_ADDR_BL1; i <= TWI_ADDR_BL4; i++) {
printf("twi[0x%02lx] ", i); printf("twi[0x%02lx] ", i);
struct blmc_cmd cmd = { struct twi_cmd cmd = {
.cmd = CMD_BOOT_LOADER, .cmd = CMD_BOOT_LOADER,
.mode = BLMC_CMD_WRITE | BLMC_CMD_0_ARG, .mode = TWI_MODE_WRITE | TWI_MODE_0_ARG,
}; };
twi_cmd(i, &cmd); twi_cmd(i, &cmd);
@ -206,7 +249,7 @@ void at91_twi_test(void)
uint8_t buf[16]; uint8_t buf[16];
buf[0] = '\0'; buf[0] = '\0';
cmd.cmd = CMD_GET_INFO; cmd.cmd = CMD_GET_INFO;
cmd.mode = BLMC_CMD_READ | BLMC_CMD_0_ARG; cmd.mode = TWI_MODE_READ | TWI_MODE_0_ARG;
cmd.size = sizeof(buf); cmd.size = sizeof(buf);
cmd.data = buf; cmd.data = buf;
twi_cmd(i, &cmd); twi_cmd(i, &cmd);
@ -223,7 +266,7 @@ void at91_twi_test(void)
printf("sig:0x%02x%02x%02x\n\r", buf[0], buf[1], buf[2]); printf("sig:0x%02x%02x%02x\n\r", buf[0], buf[1], buf[2]);
cmd.cmd = CMD_BOOT_APPLICATION; cmd.cmd = CMD_BOOT_APPLICATION;
cmd.mode = BLMC_CMD_WRITE | BLMC_CMD_0_ARG; cmd.mode = TWI_MODE_WRITE | TWI_MODE_0_ARG;
cmd.size = 0; cmd.size = 0;
twi_cmd(i, &cmd); twi_cmd(i, &cmd);
@ -232,7 +275,7 @@ void at91_twi_test(void)
buf[0] = '\0'; buf[0] = '\0';
cmd.cmd = CMD_GET_INFO; cmd.cmd = CMD_GET_INFO;
cmd.mode = BLMC_CMD_READ | BLMC_CMD_0_ARG; cmd.mode = TWI_MODE_READ | TWI_MODE_0_ARG;
cmd.size = sizeof(buf); cmd.size = sizeof(buf);
cmd.data = buf; cmd.data = buf;
twi_cmd(i, &cmd); twi_cmd(i, &cmd);
@ -240,7 +283,7 @@ void at91_twi_test(void)
struct blmc_param param; struct blmc_param param;
cmd.cmd = CMD_GET_PARAM; cmd.cmd = CMD_GET_PARAM;
cmd.mode = BLMC_CMD_READ | BLMC_CMD_0_ARG; cmd.mode = TWI_MODE_READ | TWI_MODE_0_ARG;
cmd.size = sizeof(param); cmd.size = sizeof(param);
cmd.data = (uint8_t *)&param; cmd.data = (uint8_t *)&param;
twi_cmd(i, &cmd); twi_cmd(i, &cmd);