7847c5e98d
* Microchip SAM MCU BSP update and add ethernet driver 1. Update Microchip SAM MCU BSP, add I2C, GMAC, ADC driver support. 2. Add ethernet driver support of SAM MCU for RT-Thread. * Add GMAC and I2C driver support 1. Update MCU BSP to support I2C/ADC/GMAC peripherals. 2. Add I2C and ethernet driver and LWIP support. 3. Update serial driver. * Add I2C driver and move some files to the common folder 1. Add I2C driver. 2. Move the same drivers and demo code to same folder to reduce duplicated code.
123 lines
3.1 KiB
C
123 lines
3.1 KiB
C
/*
|
|
* Copyright (c)
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Change Logs:
|
|
* Date Author Email Notes
|
|
* 2022-04-11 Kevin.Liu kevin.liu.mchp@gmail.com First Release
|
|
*/
|
|
|
|
#include <rtthread.h>
|
|
#include <rtdevice.h>
|
|
|
|
#include <atmel_start.h>
|
|
|
|
#ifdef SAM_I2C_EXAMPLE
|
|
|
|
struct sam_i2c_bus
|
|
{
|
|
struct rt_i2c_bus_device parent;
|
|
struct i2c_m_sync_desc *i2c_desc;
|
|
char *device_name;
|
|
};
|
|
|
|
#define I2CBUS_NAME "i2c0"
|
|
|
|
static struct sam_i2c_bus sam_i2c0 =
|
|
{
|
|
.i2c_desc = &I2C_0,
|
|
.device_name = I2CBUS_NAME,
|
|
};
|
|
|
|
static rt_size_t sam_i2c_master_xfer(struct rt_i2c_bus_device *bus,
|
|
struct rt_i2c_msg msgs[],
|
|
rt_uint32_t num);
|
|
static rt_size_t sam_i2c_slave_xfer(struct rt_i2c_bus_device *bus,
|
|
struct rt_i2c_msg msgs[],
|
|
rt_uint32_t num);
|
|
static rt_err_t sam_i2c_bus_control(struct rt_i2c_bus_device *bus,
|
|
rt_uint32_t, rt_uint32_t);
|
|
|
|
static const struct rt_i2c_bus_device_ops sam_i2c_ops =
|
|
{
|
|
.master_xfer = sam_i2c_master_xfer,
|
|
.slave_xfer = sam_i2c_slave_xfer,
|
|
.i2c_bus_control = sam_i2c_bus_control,
|
|
};
|
|
|
|
static inline void sam_i2c_update_control(struct rt_i2c_msg *src,
|
|
struct _i2c_m_msg *dest)
|
|
{
|
|
dest->len = (int32_t)src->len;
|
|
dest->addr = src->addr;
|
|
dest->buffer = src->buf;
|
|
|
|
/* Get I2C message R/W attribute first */
|
|
dest->flags = dest->flags & 0x0001;
|
|
|
|
if (dest->flags & RT_I2C_ADDR_10BIT)
|
|
dest->flags |= I2C_M_TEN;
|
|
else
|
|
dest->flags |= I2C_M_SEVEN;
|
|
}
|
|
|
|
static rt_size_t sam_i2c_master_xfer(struct rt_i2c_bus_device *bus,
|
|
struct rt_i2c_msg msgs[],
|
|
rt_uint32_t num)
|
|
{
|
|
struct sam_i2c_bus *sam_i2c = (struct sam_i2c_bus *)bus;
|
|
struct _i2c_m_msg i2c_msg;
|
|
rt_size_t i;
|
|
|
|
RT_ASSERT(bus != RT_NULL);
|
|
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
sam_i2c_update_control(&msgs[i], &i2c_msg);
|
|
if (i2c_m_sync_transfer(sam_i2c->i2c_desc, &i2c_msg) != 0)
|
|
break;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
static rt_size_t sam_i2c_slave_xfer(struct rt_i2c_bus_device *bus,
|
|
struct rt_i2c_msg msgs[],
|
|
rt_uint32_t num)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static rt_err_t sam_i2c_bus_control(struct rt_i2c_bus_device *bus,
|
|
rt_uint32_t cmd,
|
|
rt_uint32_t arg)
|
|
{
|
|
return RT_ERROR;
|
|
struct sam_i2c_bus *sam_i2c = (struct sam_i2c_bus *)bus;
|
|
|
|
RT_ASSERT(bus != RT_NULL);
|
|
|
|
switch (cmd)
|
|
{
|
|
case RT_I2C_DEV_CTRL_CLK:
|
|
i2c_m_sync_set_baudrate(sam_i2c->i2c_desc, 0, arg);
|
|
break;
|
|
default:
|
|
return -RT_EIO;
|
|
}
|
|
|
|
return RT_EOK;
|
|
}
|
|
|
|
int rt_hw_i2c_init(void)
|
|
{
|
|
rt_i2c_bus_device_register(&sam_i2c0.parent, sam_i2c0.device_name);
|
|
return 0;
|
|
}
|
|
#ifdef RT_USING_COMPONENTS_INIT
|
|
INIT_BOARD_EXPORT(rt_hw_i2c_init);
|
|
#endif
|
|
#endif
|
|
/*@}*/
|