freeRTOS操作系统机器人实现
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

157 lines
3.5 KiB

#include "bsp_config.h"
#ifdef USE_LUA_ST_CAN
#include "lua_base.h"
#include "fdcan.h"
#include "bsp_can.h"
typedef struct
{
TComCtrl *m_ptComCtrl;
} stm32_can_t;
TComCtrl *g_ptCAN1;
int CAN1_Send(char *_pBuffer, uint32_t _iSize)
{
return CAN_TX_FIFOQ(g_ptCAN1, _pBuffer[0], &_pBuffer[4], _iSize);
}
void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs)
{
if (hfdcan->Instance == FDCAN1)
{
MX_FDCAN1_Init();
}
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if (hfdcan->Instance == FDCAN1)
{
CAN_RX_IRQHandler(g_ptCAN1);
}
}
// 构造函数: st.CAN(st.OUT)
static int l_can_new(lua_State *L)
{
int iIsLoop = luaL_optinteger(L, 1, 1);// 默认使用回环模式
// 创建 userdata
stm32_can_t *u = (stm32_can_t*)lua_newuserdata(L, sizeof(stm32_can_t));
TCANUserData *ptCANUserData = CAN_userdata_init(&hfdcan1, 8, iIsLoop);
g_ptCAN1 = rd_ComCreate(NULL, NULL, CAN1_Send, CONFIG_CAN_BUFFER_SIZE, ptCANUserData);
CAN_IT_init(g_ptCAN1);
u->m_ptComCtrl = g_ptCAN1;
// 设置 Metatable
luaL_getmetatable(L, "stm32.CANMT");
lua_setmetatable(L, -2);
return 1;
}
// 方法: CAN:write(FrameID, str)
static int l_can_write(lua_State *L)
{
stm32_can_t *u = (stm32_can_t*)luaL_checkudata(L, 1, "stm32.CANMT");
int iFrameID = luaL_optinteger(L, 2, 0xffff);// 默认FrameID为 0xffff
size_t len;
const char *str = luaL_checklstring(L, 3, &len); // 支持二进制数据
char *buf = (char*)RD_MALLOC(len + 4);
RD_MEMCPY(buf, &iFrameID, 4);
RD_MEMCPY(buf + 4, str, len);
rd_ComSend(u->m_ptComCtrl, (char *)buf, len);
lua_pushinteger(L, len); // 返回发送的字节数
RD_FREE(buf);
return 1;
}
// 方法: CAN:read(mode)
static int l_can_read(lua_State *L)
{
int iRet = 1;
char ch = 0;
stm32_can_t *u = (stm32_can_t*)luaL_checkudata(L, 1, "stm32.CANMT");
int mode = luaL_optinteger(L, 2, 0); // 默认不使用16进制
char *buf = (char*)RD_MALLOC(CONFIG_CAN_BUFFER_SIZE);
int iLen = 0;
if (!buf) return luaL_error(L, "Memory alloc failed");
while(iRet)
{
__disable_irq();
iRet = rd_ComRead(u->m_ptComCtrl, &ch, 1);
__enable_irq();
if (iRet > 0)
{
if (3 == mode)
{
lua_print("%02X ", ch);
}
else
{
lua_print("%c", ch);
}
if (iLen >= CONFIG_CAN_BUFFER_SIZE) break;
buf[iLen++] = ch;
}
}
if (iLen > 0)
{
lua_pushlstring(L, buf, iLen);
}
else
{
lua_pushstring(L, "");
}
RD_FREE(buf);
return 1;
}
// 模块注册
int luaopen_stm32_can(lua_State *L)
{
// 1. 注册 Metatable
if (luaL_newmetatable(L, "stm32.CANMT"))
{
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
const luaL_Reg uart_methods[] =
{
{"write", l_can_write},
{"read", l_can_read},
{NULL, NULL}
};
const luaL_Reg *l;
for (l = uart_methods; l->name != NULL; l++)
{
lua_pushcfunction(L, l->func);
lua_setfield(L, -2, l->name);
}
}
lua_pop(L, 1);
// 2. 创建模块表
lua_newtable(L);
// 3. 注册构造函数
lua_pushcfunction(L, l_can_new);
lua_setfield(L, -2, "new");
return 1;
}
#endif