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)
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)

View File

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

27
main.c
View File

@ -50,7 +50,7 @@ static uint32_t pitc_test(struct pitc_timer *timer)
printf("\r");
*/
static uint8_t data[4] = { 0x0f, 0x0f, 0x0f, 0x0f };
static uint8_t data[4] = { 0x00, 0x00, 0x00, 0x00 };
twi_setpwm(data);
return PITC_RESTART_TIMER;
@ -83,7 +83,7 @@ int main(void)
/* twi */
at91_twi_init();
at91_twi_test();
// at91_twi_test();
/* usb */
at91_udp_init();
@ -93,7 +93,28 @@ int main(void)
/* adc, need timer */
// 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);
}

View File

@ -22,7 +22,6 @@
#include "AT91SAM7S256.h"
#include "board.h"
#include "at91_twi.h"
#include "at91_pio.h"
/*
* 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) {
*AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK;
twi_state = TWI_ERROR;
// TODO: TWI_BLMC_UPDATE?
return;
}
@ -134,7 +131,7 @@ uint32_t twi_setpwm(uint8_t *values)
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)
twi_state = TWI_IDLE;
@ -146,7 +143,7 @@ uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
twi_state = TWI_GENERIC_CMD;
/* 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 */
*AT91C_TWI_MMR = (addr << 16) | (cmd->mode & 0xFF) << 8;
*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_count = 0;
if (cmd->mode & BLMC_CMD_READ) {
if (cmd->mode & TWI_MODE_READ) {
*AT91C_TWI_CR = AT91C_TWI_START;
*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;
}
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)
{
uint32_t i;
for (i = TWI_ADDR_BL1; i <= TWI_ADDR_BL4; i++) {
printf("twi[0x%02lx] ", i);
struct blmc_cmd cmd = {
struct twi_cmd cmd = {
.cmd = CMD_BOOT_LOADER,
.mode = BLMC_CMD_WRITE | BLMC_CMD_0_ARG,
.mode = TWI_MODE_WRITE | TWI_MODE_0_ARG,
};
twi_cmd(i, &cmd);
@ -206,7 +249,7 @@ void at91_twi_test(void)
uint8_t buf[16];
buf[0] = '\0';
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.data = buf;
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]);
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;
twi_cmd(i, &cmd);
@ -232,7 +275,7 @@ void at91_twi_test(void)
buf[0] = '\0';
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.data = buf;
twi_cmd(i, &cmd);
@ -240,7 +283,7 @@ void at91_twi_test(void)
struct blmc_param 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.data = (uint8_t *)&param;
twi_cmd(i, &cmd);