20240909-DXSPX-emb/Src/Usr/BSP/BSPI2C.c

202 lines
5.4 KiB
C
Raw Permalink Normal View History

#include "BSPI2C.h"
#include <cpu.h>
#include <os.h>
#include <bsp_int.h>
#include <bsp_sys.h>
#include <lib_def.h>
#include <os_cpu.h>
#include "BSPSys.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/i2c.h"
#include "driverlib/interrupt.h"
#include "inc/hw_memmap.h"
#include "inc/hw_i2c.h"
#include "inc/hw_ints.h"
// 使能外设和配置引脚
static void configurePins(uint8_t i2c_id) {
if (i2c_id == USR_I2C_NUM0) {
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinConfigure(GPIO_PB2_I2C0SCL);
GPIOPinConfigure(GPIO_PB3_I2C0SDA);
GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
} else if (i2c_id == USR_I2C_NUM1) {
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
GPIOPinConfigure(GPIO_PG0_I2C1SCL);
GPIOPinConfigure(GPIO_PG1_I2C1SDA);
GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);
GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);
}
}
// 主设备初始化
static void masterInit(uint32_t base, int32_t speed) {
if (speed == USR_I2C_SPEED400000) {
I2CMasterInitExpClk(base, BspGetSysClock(), true);
} else if (speed == USR_I2C_SPEED100000) {
I2CMasterInitExpClk(base, BspGetSysClock(), false);
}
}
// 从设备初始化
static void slaveInit(uint32_t base, uint8_t slave_address) {
I2CSlaveInit(base, slave_address);
}
// 初始化
int8_t BspI2CInit(uint8_t i2c_id, int32_t i2c_speed, uint8_t i2c_mode, uint8_t slave_address) {
if (i2c_mode == USR_I2C_MASTER) {
configurePins(i2c_id);
if (i2c_id == USR_I2C_NUM0) {
masterInit(I2C0_BASE, i2c_speed);
} else if (i2c_id == USR_I2C_NUM1) {
masterInit(I2C1_BASE, i2c_speed);
}
return 0;
} else if (i2c_mode == USR_I2C_SLAVE) {
configurePins(i2c_id);
if (i2c_id == USR_I2C_NUM0) {
slaveInit(I2C0_BASE, slave_address);
} else if (i2c_id == USR_I2C_NUM1) {
slaveInit(I2C1_BASE, slave_address);
}
return 0;
} else {
return -1;
}
}
int8_t BspMasterSend(uint8_t i2c_id, uint8_t slave_address,
uint8_t *send_data, uint32_t send_len)
{
uint32_t i;
uint32_t base;
CPU_SR_ALLOC();
OS_ENTER_CRITICAL();
// 错误检测
if (send_len < 1 || (i2c_id != USR_I2C_NUM0 && i2c_id != USR_I2C_NUM1)) {
OS_EXIT_CRITICAL();
return -1;
}
// 基地址转换
base = (i2c_id == USR_I2C_NUM0) ? I2C0_BASE : I2C1_BASE;
while (I2CMasterBusy(base)) { }
I2CMasterSlaveAddrSet(base, slave_address, false);
for (i = 0; i < send_len; ++i) {
I2CMasterDataPut(base, send_data[i]);
if (i == 0) {
I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_START);
} else if (i == send_len - 1) {
I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_FINISH);
} else {
I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_CONT);
}
if (I2CMasterErr(base) != I2C_MASTER_ERR_NONE) {
if (i != send_len - 1) {
I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
}
OS_EXIT_CRITICAL();
return -1;
}
while (I2CMasterBusy(base)) { }
}
OS_EXIT_CRITICAL();
return 0;
}
int8_t BspMasterRecv(uint8_t i2c_id, uint8_t slave_address,
uint8_t *recv_data, uint32_t recv_len)
{
uint32_t i;
uint32_t base;
CPU_SR_ALLOC();
OS_ENTER_CRITICAL();
if (recv_len < 1) {
OS_EXIT_CRITICAL();
return -1;
}
// 根据 i2c_id 选择基地址
if (i2c_id == USR_I2C_NUM0) {
base = I2C0_BASE;
} else if (i2c_id == USR_I2C_NUM1) {
base = I2C1_BASE;
} else {
OS_EXIT_CRITICAL();
return -1;
}
while(I2CMasterBusy(base)) {}
I2CMasterSlaveAddrSet(base, slave_address, true);
// 单字节接收
if (recv_len == 1) {
I2CMasterControl(base, I2C_MASTER_CMD_SINGLE_RECEIVE);
if (I2C_MASTER_ERR_NONE != I2CMasterErr(base)) {
OS_EXIT_CRITICAL();
return -1;
}
while(I2CMasterBusy(base)) {}
*recv_data = I2CMasterDataGet(base);
OS_EXIT_CRITICAL();
return 0;
}
// 多字节接收
for (i = 0; i < recv_len; i++) {
if (i == 0) {
I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_START);
} else if (i == recv_len - 1) {
I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
} else {
I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
}
if (I2C_MASTER_ERR_NONE != I2CMasterErr(base)) {
if (i != recv_len - 1) {
if ((I2C_MCS_ARBLST & I2CMasterErr(base)) != I2C_MCS_ARBLST) {
I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP);
}
}
OS_EXIT_CRITICAL();
return -1;
}
while(I2CMasterBusy(base)) {}
recv_data[i] = I2CMasterDataGet(base);
}
OS_EXIT_CRITICAL();
return 0;
}
int8_t BspSalveRecv(uint8_t i2c_id, uint8_t *recv_data, uint32_t recv_len)
{
return 0;
}
int8_t BspSalveSend(uint8_t i2c_id, uint8_t *send_data, uint32_t send_len)
{
return 0;
}