Browse Source

twi eeprom handling

master
Olaf Rempel 12 years ago
parent
commit
580d8369fa
4 changed files with 89 additions and 24 deletions
  1. +2
    -1
      Makefile
  2. +8
    -8
      include/at91_twi.h
  3. +24
    -3
      main.c
  4. +55
    -12
      src/at91_twi.c

+ 2
- 1
Makefile 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)

+ 8
- 8
include/at91_twi.h 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);


+ 24
- 3
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);
}

+ 55
- 12
src/at91_twi.c 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);


Loading…
Cancel
Save