I2C

Examples

#include "abov/system.h"
#include "abov/hal/uart.h"
#include "abov/hal/gpio.h"
#include "abov/irq.h"
#include "abov/delay.h"

#include "abov/ll/clk.h"

#define UART0_RX_PIN			(GPIOC + 8)
#define UART0_TX_PIN			(GPIOC + 9)

static uart_handle_t uart0_handle;

#include "printf.h"
void _putchar(char character)
{
	uart_write(PERI_UART0, &character, 1);
}

#include "libmcu/shell.h"
static size_t shell_read(void *buf, size_t bufsize)
{
	size_t result = uart_read(PERI_UART0, buf, bufsize);
	return result;
}

static size_t shell_write(const void *data, size_t datasize)
{
	size_t result = uart_write(PERI_UART0, data, datasize);
	return result;
}

#include "abov/hal/i2c.h"
#include "abov/ll/pwr.h"
#define I2C_SCL				(GPIOB + 14)
#define I2C_SDA				(GPIOB + 15)
static void myi2c_gpio_init(void)
{
	gpio_open(I2C_SCL, GPIO_MODE_OPENDRAIN);
	gpio_open(I2C_SDA, GPIO_MODE_OPENDRAIN);
	gpio_set_altfunc(I2C_SCL, 1);
	gpio_set_altfunc(I2C_SDA, 1);
}
static void myi2c_init(void)
{
	myi2c_gpio_init();
}

uint32_t bccr,ccr, mr, wdt, pcsr;
static void system_clock_init(void)
{
	bccr = *(volatile uint32_t *)0x4000003c;
	ccr = *(volatile uint32_t *)0x40000030;
	mr = *(volatile uint32_t *)0x40000004;
	wdt = *(volatile uint32_t *)0x40000408;
	pcsr = *(volatile uint32_t *)0x40000040;

#if 1
	clk_enable_source(CLK_HSI);
#if 1
	clk_set_pll_frequency(CLK_PLL, CLK_HSI, 16000000);
#else
	gpio_open(GPIOC + 14, GPIO_MODE_ANALOG); // XTALO
	gpio_set_altfunc(GPIOC + 14, 1);
	gpio_open(GPIOC + 15, GPIO_MODE_ANALOG); // XTALI
	gpio_set_altfunc(GPIOC + 15, 1);
	clk_enable_source(CLK_HSE);
	clk_set_pll_frequency(CLK_PLL, CLK_HSE, 16000000);
#endif
	clk_enable_pll();
	clk_set_source(CLK_PLL);
	while (!clk_is_pll_locked()) ;
#endif
}

static void system_init(void)
{
	system_clock_init();
}

static void uart_gpio_init(void)
{
	gpio_open(UART0_RX_PIN, GPIO_MODE_INPUT_PULLUP);
	gpio_open(UART0_TX_PIN, GPIO_MODE_PUSHPULL);
	gpio_set_altfunc(UART0_RX_PIN, 1);
	gpio_set_altfunc(UART0_TX_PIN, 1);
}

int _sbrk_r;
int main(void)
{
	system_init();

	uart_gpio_init();
	uart_init(PERI_UART0, &(struct uart_cfg) {
			.wordsize = UART_WORDSIZE_8,
			.stopbit = UART_STOPBIT_1,
			.parity = UART_PARITY_NONE,
			.baudrate = 115200, },
			&uart0_handle);

	uart_write(PERI_UART0, "Hello, World!\r\n", 15);
	printf("hclk %u, pclk %u\r\n", clk_get_hclk_frequency(), clk_get_pclk_frequency());

	myi2c_init();

	pwr_enable_peripheral(PERI_I2C0);
	clk_enable_peripheral(PERI_I2C0);
	i2c_reset(PERI_I2C0);
	i2c_set_frequency(PERI_I2C0, 100000, clk_get_pclk_frequency());

	//i2c_enable_irq(PERI_I2C0);
	//irq_enable(PERI_TO_IRQ(PERI_I2C0));

	i2c_start(PERI_I2C0, 0x69, 0);
	i2c_write_byte(PERI_I2C0, 0xf);
	i2c_start(PERI_I2C0, 0x69, 1);
	int rxd = i2c_read_byte(PERI_I2C0, false);
	i2c_stop(PERI_I2C0);

#if 0
	i2c_start(PERI_I2C0, 0x69, 0);
	i2c_write_byte(PERI_I2C0, 0x20);
	i2c_write_byte(PERI_I2C0, 0xf);
	i2c_stop(PERI_I2C0);
#endif

	i2c_start(PERI_I2C0, 0x69, 0);
	i2c_write_byte(PERI_I2C0, 0x20);
	i2c_start(PERI_I2C0, 0x69, 1);
	//int rxdata = i2c_read_byte(PERI_I2C0, false);
	int rxdata = i2c_read_byte(PERI_I2C0, true);
	rxdata = i2c_read_byte(PERI_I2C0, true);
	rxdata = i2c_read_byte(PERI_I2C0, false);
	i2c_stop(PERI_I2C0);

	printf("Recieved : %x\r\n", rxd);
	printf("Recieved : %x\r\n", rxdata);

	const shell_io_t io = {
		.read = shell_read,
		.write = shell_write,
	};
	shell_run(&io);

	while (1) {
		uint8_t ch;
		size_t received = uart_read(PERI_UART0, &ch, sizeof(ch));
		if (received > 0) {
			uart_write(PERI_UART0, &ch, sizeof(ch));
		}
	}

	return 0;
}

void ISR_I2C0(void)
{
	printf("INT\r\n");
#if 0
	switch (i2c_run_fsm()) {
	case I2C_FSM_ERROR:
		i2c_stop(PERI_I2C0);
		break;
	case I2C_FSM_START_SEND:
		i2c_set_txd(PERI_I2C0, 0xf);
		break;
	case I2C_FSM_START_RECV:
		break;
	case I2C_FSM_SENDING:
		i2c_set_txd(PERI_I2C0, 0xd3);
		i2c_disable_ack(PERI_I2C0);
		i2c_set_start(PERI_I2C0);
		break;
	case I2C_FSM_RECEIVING:
		printf("@gcall>tend|receiving: %x\r\n", i2c_read_byte(PERI_I2C0));
		i2c_stop(PERI_I2C0);
		break;
	default:
		break;
	}
#endif
#if 0
	uint32_t event = i2c_get_event(PERI_I2C0);
	if (event & 0x80) { //GCALL
		if (!(event & 1)) {
			printf("@gcall>noack\r\n");
			i2c_stop(PERI_I2C0);
		} else if (event & 2) { //송신모드
			printf("@gcall>tmode\r\n");
i2c_set_txd(PERI_I2C0, 0xf);
		} else { // 수신모드
		}
	} else if (event & 0x40) { //TEND
		if (event & 0x2) { //송신모드
			// if no ack, stop
			printf("@gcall>tend|tmode\r\n");
i2c_set_txd(PERI_I2C0, 0xd3);
//i2c_enable_ack(PERI_I2C0);
i2c_set_start(PERI_I2C0);
		} else { //수신모드
			// 마지막 바이트면 nak
			printf("@gcall>tend|receiving: %x\r\n", i2c_read_byte(PERI_I2C0));
i2c_stop(PERI_I2C0);
		}
	}
#endif

	volatile uint32_t *sr = (volatile uint32_t *)0x40000a08;
	*sr = 0xff;
}

HAL

Warning

doxygenfile: Cannot find file “halmcu/hal/i2c.h

LL

Enums

enum i2c_event_t

Values:

enumerator I2C_EVENT_NONE
enumerator I2C_EVENT_STOP
enumerator I2C_EVENT_BUSY
enumerator I2C_EVENT_RX
enumerator I2C_EVENT_TX
enumerator I2C_EVENT_SLAVE
enumerator I2C_EVENT_COLLISION
enumerator I2C_EVENT_MASK

Functions

void i2c_reset(periph_t i2c)
void i2c_enable(periph_t i2c)
void i2c_disable(periph_t i2c)
void i2c_set_frequency(periph_t i2c, uint32_t hz, uint32_t pclk)
void i2c_send_start(periph_t i2c)
void i2c_send_stop(periph_t i2c)
void i2c_enable_ack(periph_t i2c)
void i2c_disable_ack(periph_t i2c)
void i2c_write_byte(periph_t i2c, uint8_t value)
uint8_t i2c_read_byte(periph_t i2c)
bool i2c_is_busy(periph_t i2c)
bool i2c_has_started(periph_t i2c)
bool i2c_has_address_set(periph_t i2c)
bool i2c_has_transfer_completed(periph_t i2c)
bool i2c_has_received(periph_t i2c)
void i2c_enable_interrupt(periph_t i2c, i2c_event_t events)
void i2c_disable_interrupt(periph_t i2c, i2c_event_t events)
void i2c_start(periph_t i2c)
void i2c_stop(periph_t i2c)
void i2c_set_slave_address(periph_t i2c, uint16_t slave_addr)
void i2c_enable_irq(periph_t i2c)
void i2c_disable_irq(periph_t i2c)
i2c_event_t i2c_get_event(periph_t i2c)
void i2c_clear_event(periph_t i2c, i2c_event_t events)