⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_digio.c

📁 cc2x30_sw_examples: 适用于SmartRF05EB 支持CC2430、CC2530 提供Light_Switch及perTest例程。
💻 C
字号:

/*******************************************************************************
  Filename:     hal_digio.c

  Description:  HAL digital IO functionality

*******************************************************************************/

/*******************************************************************************
* INCLUDES
*/
#include "hal_types.h"
#include "hal_defs.h"
#include "hal_board.h"
#include "hal_int.h"
#include "hal_digio.h"


/*******************************************************************************
* LOCAL VARIABLES
*/
static ISR_FUNC_PTR port0_isr_tbl[8] = {0};
static ISR_FUNC_PTR port1_isr_tbl[8] = {0};
static ISR_FUNC_PTR port2_isr_tbl[5] = {0};


/* Find a better place for this! */
#if chip==2430 || chip==2431
#define PICTL_PADSC_BM 0x40
#define PICTL_P2IEN_BM 0x20
#define PICTL_P0IENH_BM 0x10
#define PICTL_P0IENL_BM 0x08
#define PICTL_P2ICON_BM 0x04
#define PICTL_P1ICON_BM 0x02
#define PICTL_P0ICON_BM 0x01
#elif chip==2530 || chip==2531
#define PICTL_PADSC_BM 0x80
#define PICTL_P2IEN_BM 0x40
#define PICTL_P0IENH_BM 0x20
#define PICTL_P0IENL_BM 0x10
#define PICTL_P2ICON_BM 0x08
#define PICTL_P1ICONH_BM 0x04
#define PICTL_P1ICONL_BM 0x02
#define PICTL_P1ICON_BM 0x06 // Combined - for compatibility
#define PICTL_P0ICON_BM 0x01
#endif

/*******************************************************************************
* GLOBAL FUNCTIONS
*/

/*******************************************************************************
* @fn      halDigioConfig
*
* @brief   Configure the pin as specified by p.
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/

//comment: find better way of doing this. SFR registers can not be accessed by pointers, therefore code is different from MSP430 code
// comment: currently support only P0 and P1
uint8 halDigioConfig(const digioConfig* p)
{
  //  register volatile uint8* dir;
    register const uint8 bitmask = p->pin_bm;

    // Sanity check
    if ((bitmask == 0) || (bitmask != (uint8)BV(p->pin)))
    {
        return(HAL_DIGIO_ERROR);
    }

    switch(p->port)
    {
    case 0: P0SEL &= ~bitmask; 
            if (p->dir == HAL_DIGIO_OUTPUT)
            {
                if (p->initval == 1)
                {
                  P0 |= bitmask;  
                }
                else
                {
                  P0 &= ~bitmask;
                }
                P0DIR |= bitmask;
             }
             else // input
             {
                P0DIR &= ~bitmask;
             }
            break;
     case 1: P1SEL &= ~bitmask; 
            if (p->dir == HAL_DIGIO_OUTPUT)
            {
                if (p->initval == 1)
                {
                  P1 |= bitmask;  
                }
                else
                {
                  P1 &= ~bitmask;
                }
                P1DIR |= bitmask;
             }
             else // input
             {
                P1DIR &= ~bitmask;
             }
            break;
     case 2: P2SEL &= ~bitmask; 
            if (p->dir == HAL_DIGIO_OUTPUT)
            {
                if (p->initval == 1)
                {
                  P2 |= bitmask;  
                }
                else
                {
                  P2 &= ~bitmask;
                }
                P2DIR |= bitmask;
             }
             else // input
             {
                P2DIR &= ~bitmask;
             }
            break;
    //case 1: P1SEL &= ~bitmask; out = &P1OUT; dir = &P1DIR; break;
    //case 2: P2SEL &= ~bitmask; out = &P2OUT; dir = &P2DIR; break;
    default: return(HAL_DIGIO_ERROR);
    }
    return(HAL_DIGIO_OK);
}


/*******************************************************************************
* @fn      halDigioSet
*
* @brief   Set output pin
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/
uint8 halDigioSet(const digioConfig* p)
{
   if (p->dir == HAL_DIGIO_OUTPUT)
    {
        switch (p->port)
        {
        case 0: P0 |= p->pin_bm; break;
        case 1: P1 |= p->pin_bm; break;
        case 2: P2 |= p->pin_bm; break;
        default: return(HAL_DIGIO_ERROR);
        }
        return(HAL_DIGIO_OK);
    }
    return(HAL_DIGIO_ERROR);
}


/*******************************************************************************
* @fn      halDigioClear
*
* @brief   Clear output pin
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/
uint8 halDigioClear(const digioConfig* p)
{
   if (p->dir == HAL_DIGIO_OUTPUT)
    {
        switch (p->port)
        {
        case 0: P0 &= ~p->pin_bm; break;
        case 1: P1 &= ~p->pin_bm; break;
        case 2: P2 &= ~p->pin_bm; break;
        default: return(HAL_DIGIO_ERROR);
        }
        return(HAL_DIGIO_OK);
    }
    return(HAL_DIGIO_ERROR);
}


/*******************************************************************************
* @fn      halDigioToggle
*
* @brief   Toggle output pin
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/
uint8 halDigioToggle(const digioConfig* p)
{
  if (p->dir == HAL_DIGIO_OUTPUT)
    {
        switch (p->port)
        {
        case 0: P0 ^= p->pin_bm; break;
        case 1: P1 ^= p->pin_bm; break;
        case 2: P2 ^= p->pin_bm; break;
        default: return(HAL_DIGIO_ERROR);
        }
        return(HAL_DIGIO_OK);
    }
    return(HAL_DIGIO_ERROR);
}


/*******************************************************************************
* @fn      halDigioGet
*
* @brief   Get value on input pin
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/
uint8 halDigioGet(const digioConfig* p)
{
    if (p->dir == HAL_DIGIO_INPUT)
    {
        switch (p->port)
        {
        case 0: return (P0 & p->pin_bm ? 1 : 0);
        case 1: return (P1 & p->pin_bm ? 1 : 0);
        case 2: return (P2 & p->pin_bm ? 1 : 0);
        default: break;
        }
    }
    return(HAL_DIGIO_ERROR);
}


/*******************************************************************************
* @fn      halDigioIntConnect
*
* @brief   Connect function to IO interrupt
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*          ISR_FUNC_PTR func - pointer to function
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/
uint8 halDigioIntConnect(const digioConfig *p, ISR_FUNC_PTR func)
{
  istate_t key;
    HAL_INT_LOCK(key);
    switch (p->port)
    {
    case 0: port0_isr_tbl[p->pin] = func; break;
    case 1: port1_isr_tbl[p->pin] = func; break;
    case 2: port2_isr_tbl[p->pin] = func; break;
    default: HAL_INT_UNLOCK(key); return(HAL_DIGIO_ERROR);
    }
    halDigioIntClear(p);
    HAL_INT_UNLOCK(key);
    return(HAL_DIGIO_OK);
}


/*******************************************************************************
* @fn      halDigioIntEnable
*
* @brief   Enable interrupt on IO pin
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/
uint8 halDigioIntEnable(const digioConfig *p)
{
     switch (p->port)
    {
    case 0: 
      P0IE = 1;    // set P0IE bit
      if (p->pin < 4) {
        PICTL |= PICTL_P0IENL_BM; // set P0IENL
      }
      else {
        PICTL |= PICTL_P0IENH_BM; // set P0IENH
      }
            break;
    case 1:
      IEN2 |= 0x10;    // set P1IE bit
      P1IEN |= p->pin_bm;
      break;
    case 2:
      IEN2 |= 0x02;
      PICTL |= PICTL_P2IEN_BM; // Set P2IEN
      break;
    default: 
      return(HAL_DIGIO_ERROR);
    }
    return(HAL_DIGIO_OK);
}


/*******************************************************************************
* @fn      halDigioIntDisable
*
* @brief   Disable interrupt on IO pin
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/
uint8 halDigioIntDisable(const digioConfig *p)
{
   switch (p->port)
    {
    case 0: 
      if (p->pin  < 4) {
        PICTL &= ~PICTL_P0IENL_BM; // clear P0IENL
      }
      else {
        PICTL &= ~PICTL_P0IENH_BM;    // clear P0IENH
      }
            break;
    case 1:
      P1IEN &= ~p->pin_bm;
      break;
    case 2:
      PICTL &= ~PICTL_P2IEN_BM; // Clear P2IEN
      break;
    default: 
      return(HAL_DIGIO_ERROR);
    }
    return(HAL_DIGIO_OK);
}


/*******************************************************************************
* @fn      halDigioIntClear
*
* @brief   Clear interrupt flag
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/
uint8 halDigioIntClear(const digioConfig *p)
{
    switch (p->port)
    {
    case 0: P0IFG &= ~p->pin_bm; break;
    case 1: P1IFG &= ~p->pin_bm; break;
    case 2: P2IFG &= ~p->pin_bm; break;
    default: return(HAL_DIGIO_ERROR);
    }
    return(HAL_DIGIO_OK);
}


/*******************************************************************************
* @fn      halDigioIntSetEdge
*
* @brief   Set edge for IO interrupt
*
* @param   digioConfig* p - pointer to configuration structure for IO pin
*          edge - HAL_DIGIO_INT_FALLING_EDGE or HAL_DIGIO_INT_RISING_EDGE
*
* @return  uint8 - HAL_DIGIO_ERROR or HAL_DIGIO_OK
*/

// Comment: all pins on port are configured at same time
uint8 halDigioIntSetEdge(const digioConfig *p, uint8 edge)
{
  switch(edge)
    {
    case HAL_DIGIO_INT_FALLING_EDGE:
        switch(p->port)
        {
        case 0: PICTL |= PICTL_P0ICON_BM; // set P0ICON high
                break;
        case 1: PICTL |= PICTL_P1ICON_BM; // set P1ICON high
                break;
        case 2: PICTL |= PICTL_P2ICON_BM; // set P2ICON high
                break;
        default: return(HAL_DIGIO_ERROR);
        }
        break;

    case HAL_DIGIO_INT_RISING_EDGE:
        switch(p->port)
        {
        case 0: PICTL &= ~PICTL_P0ICON_BM; // set P0ICON low
                break;
        case 1: PICTL &= ~PICTL_P1ICON_BM; // set P0ICON low
                break;
        case 2: PICTL &= ~PICTL_P2ICON_BM; // set P0ICON low
                break;
        default: return(HAL_DIGIO_ERROR);
        }
        break;

    default:
        return(HAL_DIGIO_ERROR);
    }
    return(HAL_DIGIO_OK);
}


/*******************************************************************************
* @fn      port0_ISR
*
* @brief   ISR framework for P0 digio interrupt
*
* @param   none
*
* @return  none
*/
HAL_ISR_FUNCTION(port0_ISR,P0INT_VECTOR)
{
    register uint8 i;
    P0IF = 0;
    if (P0IFG)
    {
        for (i = 0; i < 8; i++)
        {
            register const uint8 pinmask = 1 << i;
            if (P0IFG & pinmask) {
                if (port0_isr_tbl[i] != 0) {
                (*port0_isr_tbl[i])();
                }
                P0IFG &= ~pinmask;
            }
        }
        //__low_power_mode_off_on_exit();
    }
}

/*******************************************************************************
* @fn      port1_ISR
*
* @brief   ISR framework for P0 digio interrupt
*
* @param   none
*
* @return  none
*/
HAL_ISR_FUNCTION(port1_ISR,P1INT_VECTOR)
{
    register uint8 i;
    P1IF = 0;
    if (P1IFG)
    {
        for (i = 0; i < 8; i++)
        {
            register const uint8 pinmask = 1 << i;
            if (P1IFG & pinmask) {
                if (port1_isr_tbl[i] != 0) {
                    (*port1_isr_tbl[i])();
                }
                P1IFG &= ~pinmask;
            }
        }
        //__low_power_mode_off_on_exit();
    }
}

/*******************************************************************************
* @fn      port2_ISR
*
* @brief   ISR framework for P2 digio interrupt
*
* @param   none
*
* @return  none
*/
HAL_ISR_FUNCTION(port2_ISR,P2INT_VECTOR)
{
    register uint8 i;
    P2IF = 0;
    if (P2IFG)
    {
        for (i = 0; i < 5; i++)
        {
            register const uint8 pinmask = 1 << i;
            if (P2IFG & pinmask) {
                if (port2_isr_tbl[i] != 0) {
                    (*port2_isr_tbl[i])();
                }
                P2IFG &= ~pinmask;
            }
        }
        //__low_power_mode_off_on_exit();
    }
}

/*------------------------------------------------------------------------------
										  0ooo                                     
								ooo0	 (	 )                                     
								(	)	  ) /                                      
								 \ (	 (_/                                       
								  \_)		 Modify By:cuiqingwei [gary]                  
------------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -