forked from electronics/osmo-opencm3-projects
rfdsatt: add low-level EEPROM read/write support
This commit is contained in:
parent
3b39d671fe
commit
e63259baaa
|
@ -19,7 +19,7 @@
|
|||
|
||||
BINARY = rfdsatt
|
||||
|
||||
OBJS = attenuator.o board_rfdsatt_4ch.o
|
||||
OBJS = attenuator.o eeprom.o board_rfdsatt_4ch.o
|
||||
|
||||
# when building for M0
|
||||
#LDSCRIPT = ./stm32f051-openblt.ld
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
#include <libopencm3/stm32/i2c.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "eeprom.h"
|
||||
|
||||
/* wait for I2C status register flags to appear */
|
||||
static bool i2c_wait(uint32_t i2c, uint32_t sr1, uint32_t sr2)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 1000000; i++) {
|
||||
if (((I2C_SR1(i2c) & sr1) == sr1) &&
|
||||
((I2C_SR2(i2c) & sr2) == sr2))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int eeprom_read(uint8_t *buf_out, unsigned int num_bytes, uint16_t read_addr)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (num_bytes > 255)
|
||||
return -EINVAL; /* no reload cycles yet */
|
||||
|
||||
i2c_send_start(I2C1);
|
||||
|
||||
/* Wait for the end of the start condition, master mode selected, and BUSY bit set */
|
||||
if (!i2c_wait(I2C1, I2C_SR1_SB, I2C_SR2_MSL|I2C_SR2_BUSY))
|
||||
return -EIO;
|
||||
|
||||
/* Send Address, wait until it is transferred */
|
||||
i2c_send_7bit_address(I2C1, 0x50, I2C_WRITE);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_ADDR, 0))
|
||||
return -EIO;
|
||||
|
||||
/* Send memory address */
|
||||
#if 0 /* 16bit address */
|
||||
i2c_send_data(I2C1, read_addr >> 8);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_BTF, 0))
|
||||
return -EIO;
|
||||
#endif
|
||||
i2c_send_data(I2C1, read_addr & 0xff);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_BTF, 0))
|
||||
return -EIO;
|
||||
|
||||
/* re-start */
|
||||
i2c_send_start(I2C1);
|
||||
i2c_enable_ack(I2C1);
|
||||
|
||||
/* Wait for the end of the start condition, master mode selected, and BUSY bit set */
|
||||
if (!i2c_wait(I2C1, I2C_SR1_SB, I2C_SR2_MSL|I2C_SR2_BUSY))
|
||||
return -EIO;
|
||||
|
||||
/* Send Address, wait until it is transferred */
|
||||
i2c_send_7bit_address(I2C1, 0x50, I2C_READ);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_ADDR, 0))
|
||||
return -EIO;
|
||||
|
||||
for (i = 0; i < num_bytes; i++) {
|
||||
if (i == num_bytes - 1)
|
||||
i2c_disable_ack(I2C1);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_RxNE, 0))
|
||||
return -EIO;
|
||||
buf_out[i] = i2c_get_data(I2C1);
|
||||
}
|
||||
|
||||
i2c_send_stop(I2C1);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int wait_write_complete(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
i2c_send_start(I2C1);
|
||||
/* Wait for the end of the start condition, master mode selected, and BUSY bit set */
|
||||
if (!i2c_wait(I2C1, I2C_SR1_SB, I2C_SR2_MSL|I2C_SR2_BUSY))
|
||||
return -EIO;
|
||||
/* Send Address, wait until it is transferred */
|
||||
i2c_send_7bit_address(I2C1, 0x50, I2C_WRITE);
|
||||
if (i2c_wait(I2C1, I2C_SR1_ADDR, 0)) {
|
||||
/* slave has sent an ACK, we may proceed */
|
||||
return 0;
|
||||
}
|
||||
i2c_send_stop(I2C1);
|
||||
}
|
||||
}
|
||||
|
||||
int eeprom_write_byte(uint16_t write_addr, uint8_t byte)
|
||||
{
|
||||
i2c_send_start(I2C1);
|
||||
|
||||
/* Wait for the end of the start condition, master mode selected, and BUSY bit set */
|
||||
if (!i2c_wait(I2C1, I2C_SR1_SB, I2C_SR2_MSL|I2C_SR2_BUSY))
|
||||
return -EIO;
|
||||
|
||||
/* Send Address, wait until it is transferred */
|
||||
i2c_send_7bit_address(I2C1, 0x50, I2C_WRITE);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_ADDR, 0))
|
||||
return -EIO;
|
||||
|
||||
/* Send memory address */
|
||||
#if 0 /* 16bit address */
|
||||
i2c_send_data(I2C1, write_addr >> 8);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_BTF, 0))
|
||||
return -EIO;
|
||||
#endif
|
||||
i2c_send_data(I2C1, write_addr & 0xff);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_BTF, 0))
|
||||
return -EIO;
|
||||
|
||||
/* Send data to write */
|
||||
i2c_send_data(I2C1, byte);
|
||||
if (!i2c_wait(I2C1, I2C_SR1_BTF, 0))
|
||||
return -EIO;
|
||||
|
||||
i2c_send_stop(I2C1);
|
||||
|
||||
wait_write_complete();
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
int eeprom_read(uint8_t *buf_out, unsigned int num_bytes, uint16_t read_addr);
|
||||
int eeprom_write_byte(uint16_t write_addr, uint8_t byte);
|
|
@ -38,6 +38,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "attenuator.h"
|
||||
#include "eeprom.h"
|
||||
#include "misc.h"
|
||||
|
||||
static uint32_t last_reset_cause;
|
||||
|
@ -337,6 +338,36 @@ DEFUN(test, test_cmd, "test", "Enter interactive test-ramp mode")
|
|||
}
|
||||
|
||||
|
||||
DEFUN(i2c_read, i2c_read_cmd, "i2c-read", "Read from I2C EEPROM")
|
||||
{
|
||||
uint16_t mem_addr = 0;
|
||||
uint8_t rbuf[16];
|
||||
unsigned int i;
|
||||
|
||||
i = eeprom_read(rbuf, sizeof(rbuf), mem_addr);
|
||||
printf("Read result: %d\r\n", i);
|
||||
for (i = 0; i < sizeof(rbuf); i++)
|
||||
printf("%02x ", rbuf[i]);
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
DEFUN(i2c_write, i2c_write_cmd, "i2c-write", "write to I2C EEPROM")
|
||||
{
|
||||
int rc, addr, val;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("you have to specify address + value\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
addr = atoi(argv[1]);
|
||||
val = atoi(argv[2]);
|
||||
|
||||
printf("Writing 0x%02x to address 0x%02x\r\n", val, addr);
|
||||
rc = eeprom_write_byte(addr, val);
|
||||
printf("Write result: %d\r\n", rc);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* main
|
||||
***********************************************************************/
|
||||
|
@ -403,6 +434,8 @@ int main(void)
|
|||
microvty_register(&att_set_cmd);
|
||||
microvty_register(&interact_cmd);
|
||||
microvty_register(&test_cmd);
|
||||
microvty_register(&i2c_read_cmd);
|
||||
microvty_register(&i2c_write_cmd);
|
||||
|
||||
print_banner();
|
||||
microvty_print_prompt();
|
||||
|
|
Loading…
Reference in New Issue