259 lines
7.9 KiB
C
259 lines
7.9 KiB
C
#include "hal_io.h"
|
||
#include "OSAL.h"
|
||
#include <string.h>
|
||
|
||
static struct {
|
||
uint8 ioIntTskId;
|
||
uint8 intInUse[MAX_IOGROUP + 1];
|
||
uint8 endPointMap[MAX_IOPORT + 1];
|
||
void *endPointArgMap[MAX_IOPORT + 1];
|
||
} ioIntResMap;
|
||
void HalIOInit(uint8 taskId)
|
||
{
|
||
memset(&ioIntResMap, 0, sizeof(ioIntResMap));
|
||
ioIntResMap.ioIntTskId = taskId;
|
||
}
|
||
/***********************************************************
|
||
** 函数名称: HalIOSetInput
|
||
** 实现功能: 设置端口为普通输入IO
|
||
** 入口参数: group:Port;
|
||
** bit:Bit;
|
||
** pull:(Pull_None:无上下拉; Pull_Up:上拉; Pull_Down:下拉;);
|
||
** 返回结果: IOInt_None
|
||
** 注意事项: CC2530的通用IO上下拉电阻是对整个端口的设置,
|
||
** 不能实现将同一端口的不同位配置为上下拉不同
|
||
***********************************************************/
|
||
void HalIOSetInput(uint8 group, uint8 bit, PullSet_t pull)
|
||
{
|
||
switch(group)
|
||
{
|
||
case 0:
|
||
//设置为通用输入IO
|
||
CLRBIT(P0DIR, bit);
|
||
CLRBIT(P0SEL, bit);
|
||
//设置内部上下拉电阻状态
|
||
if(Pull_None == pull)
|
||
SETBIT(P0INP, bit); //P0INP[7-0]:(0:上下拉有效; 1:无效;)
|
||
else if(Pull_Up == pull)
|
||
{
|
||
CLRBIT(P0INP, bit); //P0INP[7-0]:(0:上下拉有效; 1:无效;)
|
||
CLRBIT(P2INP, 5); //P2INP[5 ]:(0:Port0 上拉; 1:Port0 下拉;)
|
||
}
|
||
else if(Pull_Down == pull)
|
||
{
|
||
CLRBIT(P0INP, bit); //P0INP[7-0]:(0:上下拉有效; 1:无效;)
|
||
SETBIT(P2INP, 5); //P2INP[5 ]:(0:Port0 上拉; 1:Port0 下拉;)
|
||
}
|
||
break;
|
||
case 1:
|
||
//设置为通用输入IO
|
||
CLRBIT(P1DIR, bit);
|
||
CLRBIT(P1SEL, bit);
|
||
//设置内部上下拉电阻状态
|
||
if(Pull_None == pull)
|
||
SETBIT(P1INP, bit); //P1INP[7-2]:(0:上下拉有效; 1:无效;) P[1-0] 写无效,读为0.
|
||
else if(Pull_Up == pull)
|
||
{
|
||
CLRBIT(P1INP, bit); //P1INP[7-2]:(0:上下拉有效; 1:无效;) P[1-0] 写无效,读为0.
|
||
CLRBIT(P2INP, 6); //P2INP[6 ]:(0:Port1 上拉; 1:Port1 下拉;)
|
||
}
|
||
else if(Pull_Down == pull)
|
||
{
|
||
CLRBIT(P1INP, bit); //P1INP[7-2]:(0:上下拉有效; 1:无效;) P[1-0] 写无效,读为0.
|
||
SETBIT(P2INP, 6); //P2INP[6 ]:(0:Port1 上拉; 1:Port1 下拉;)
|
||
}
|
||
break;
|
||
case 2:
|
||
//设置为通用输入IO
|
||
CLRBIT(P2DIR, bit);
|
||
CLRBIT(P2SEL, bit);
|
||
//设置内部上下拉电阻状态
|
||
if(Pull_None == pull)
|
||
SETBIT(P2INP, bit); //P2INP[4-0]:(0:上下拉有效; 1:无效;)
|
||
else if(Pull_Up == pull)
|
||
{
|
||
CLRBIT(P2INP, bit); //P2INP[4-0]:(0:上下拉有效; 1:无效;)
|
||
CLRBIT(P2INP, 7); //P2INP[7 ]:(0:Port2 上拉; 1:Port2 下拉;)
|
||
}
|
||
else if(Pull_Down == pull)
|
||
{
|
||
CLRBIT(P2INP, bit); //P2INP[4-0]:(0:上下拉有效; 1:无效;)
|
||
SETBIT(P2INP, 7); //P2INP[7 ]:(0:Port2 上拉; 1:Port2 下拉;)
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void HalIOSetOutput(uint8 group, uint8 bit)
|
||
{
|
||
switch(group)
|
||
{
|
||
case 0: P0DIR |= (1 << bit); P0SEL &= ~(1 << bit); break;
|
||
case 1: P1DIR |= (1 << bit); P1SEL &= ~(1 << bit); break;
|
||
case 2: P2DIR |= (1 << bit); P2SEL &= ~(1 << bit); break;
|
||
}
|
||
}
|
||
uint8 HalIOGetLevel(uint8 group, uint8 bit)
|
||
{
|
||
switch(group)
|
||
{
|
||
case 0: return !!(P0 & (1 << bit));
|
||
case 1: return !!(P1 & (1 << bit));
|
||
case 2: return !!(P2 & (1 << bit));
|
||
}
|
||
return 0;
|
||
}
|
||
void HalIOSetLevel(uint8 group, uint8 bit, uint8 value)
|
||
{
|
||
switch(group)
|
||
{
|
||
case 0:
|
||
if(value)
|
||
SETBIT(P0, bit);
|
||
else
|
||
CLRBIT(P0, bit);
|
||
break;
|
||
case 1:
|
||
if(value)
|
||
SETBIT(P1, bit);
|
||
else
|
||
CLRBIT(P1, bit);
|
||
break;
|
||
case 2:
|
||
if(value)
|
||
SETBIT(P2, bit);
|
||
else
|
||
CLRBIT(P2, bit);
|
||
break;
|
||
}
|
||
}
|
||
/***********************************************************
|
||
** 函数名称: IOIntteruptSet
|
||
** 实现功能: 设置端口中断触发方式
|
||
** 入口参数: group:Port;
|
||
** bit:Bit;
|
||
** trigger:(IOInt_Rising:上升沿触发; IOInt_Falling:下降沿触发;)
|
||
** 返回结果: IOInt_None
|
||
** 注意事项: CC2530的通用IO中断触发方式是对整个端口的设置,
|
||
** 只有P1口的高四位和第四位触发方式可以设置为不同
|
||
** P0端口和P2端口的所有端口触发方式以最后一次设置为准。
|
||
***********************************************************/
|
||
void HalIOIntSet(uint8 endPoint, uint8 group, uint8 bit, IntSel_t trigger, void *arg)
|
||
{
|
||
if(HAL_IOPORT(group, bit) > MAX_IOPORT)
|
||
return;
|
||
if(trigger == IOInt_None)
|
||
{
|
||
CLRBIT(ioIntResMap.intInUse[group], bit);
|
||
}
|
||
else
|
||
{
|
||
SETBIT(ioIntResMap.intInUse[group], bit);
|
||
ioIntResMap.endPointMap[HAL_IOPORT(group, bit)] = endPoint;
|
||
ioIntResMap.endPointArgMap[HAL_IOPORT(group, bit)] = arg;
|
||
}
|
||
switch(group)
|
||
{
|
||
case 0:
|
||
if(trigger == IOInt_None)
|
||
CLRBIT(P0IEN, bit);
|
||
else
|
||
{
|
||
SETBIT(P0IEN, bit);
|
||
if(trigger == IOInt_Rising)
|
||
CLRBIT(PICTL, 0);
|
||
else
|
||
SETBIT(PICTL, 0);
|
||
}
|
||
P0IFG = 0x00; //清除P0相应位中断标志
|
||
P0IF = 0; //清除P0端口总中断标志
|
||
//SETBIT(IEN1, 5); //P0总中断允许
|
||
CLRBIT(IEN1, 5); //P0总中断禁止
|
||
break;
|
||
case 1:
|
||
if(trigger == IOInt_None)
|
||
CLRBIT(P1IEN, bit);
|
||
else
|
||
{
|
||
uint8 ctlBit = (bit <= 3) ? 1 : 2;
|
||
SETBIT(P1IEN, bit);
|
||
if(trigger == IOInt_Rising)
|
||
CLRBIT(PICTL, ctlBit);
|
||
else
|
||
SETBIT(PICTL, ctlBit);
|
||
}
|
||
P1IFG = 0X00; //清除P0相应位中断标志
|
||
P1IF = 0; //清除P0端口总中断标志
|
||
//SETBIT(IEN2, 4); //P1总中断允许
|
||
CLRBIT(IEN2, 4); //P1总中断禁止
|
||
break;
|
||
case 2:
|
||
if(trigger == IOInt_None)
|
||
CLRBIT(P2IEN, bit);
|
||
else
|
||
{
|
||
SETBIT(P2IEN, bit);
|
||
if(trigger == IOInt_Rising)
|
||
CLRBIT(PICTL, 3);
|
||
else
|
||
SETBIT(PICTL, 3);
|
||
}
|
||
P2IFG = 0X00; //清除P0相应位中断标志
|
||
P2IF = 0; //清除P0端口总中断标志
|
||
//SETBIT(IEN2, 1); //P2总中断允许
|
||
CLRBIT(IEN2, 1); //P2总中断禁止
|
||
break;
|
||
default :
|
||
break;
|
||
}
|
||
}
|
||
|
||
void HalIOPortPoll()
|
||
{
|
||
OSALIOIntData_t* IOIntData;
|
||
|
||
uint8 idx;
|
||
uint8 flag = ioIntResMap.intInUse[0] & P0IFG;
|
||
for(idx = 0; flag && (idx < 8); idx++)
|
||
{
|
||
if(BV(idx) & flag)
|
||
{
|
||
IOIntData = (OSALIOIntData_t *)osal_msg_allocate(sizeof(OSALIOIntData_t));
|
||
IOIntData->hdr.event = IOPORT_INT_EVENT;
|
||
IOIntData->endPoint = ioIntResMap.endPointMap[HAL_IOPORT(0, idx)];
|
||
IOIntData->arg = ioIntResMap.endPointArgMap[HAL_IOPORT(0, idx)];
|
||
osal_msg_send(ioIntResMap.ioIntTskId, (uint8*)(IOIntData));
|
||
}
|
||
}
|
||
flag = ioIntResMap.intInUse[1] & P1IFG;
|
||
for(idx = 0; flag && (idx < 8); idx++)
|
||
{
|
||
if(BV(idx) & flag)
|
||
{
|
||
IOIntData = (OSALIOIntData_t *)osal_msg_allocate(sizeof(OSALIOIntData_t));
|
||
IOIntData->hdr.event = IOPORT_INT_EVENT;
|
||
IOIntData->endPoint = ioIntResMap.endPointMap[HAL_IOPORT(1, idx)];
|
||
IOIntData->arg = ioIntResMap.endPointArgMap[HAL_IOPORT(1, idx)];
|
||
osal_msg_send(ioIntResMap.ioIntTskId, (uint8*)(IOIntData));
|
||
}
|
||
}
|
||
flag = ioIntResMap.intInUse[2] & P2IFG;
|
||
for(idx = 0; flag && (idx < 5); idx++)
|
||
{
|
||
if(BV(idx) & flag)
|
||
{
|
||
IOIntData = (OSALIOIntData_t *)osal_msg_allocate(sizeof(OSALIOIntData_t));
|
||
IOIntData->hdr.event = IOPORT_INT_EVENT;
|
||
IOIntData->endPoint = ioIntResMap.endPointMap[HAL_IOPORT(2, idx)];
|
||
IOIntData->arg = ioIntResMap.endPointArgMap[HAL_IOPORT(2, idx)];
|
||
osal_msg_send(ioIntResMap.ioIntTskId, (uint8*)(IOIntData));
|
||
}
|
||
}
|
||
// 中断事件处理完毕,清除硬件中断标志位。
|
||
P0IFG = 0;
|
||
P1IFG = 0;
|
||
P2IFG = 0;
|
||
}
|