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

📄 hal_digio.c

📁 裡面有許多cc2430的範例code
💻 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"

#include "hal_assert.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
*/

// 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();
    }
}


/***********************************************************************************
  Copyright 2007 Texas Instruments Incorporated. All rights reserved.

  IMPORTANT: Your use of this Software is limited to those specific rights
  granted under the terms of a software license agreement between the user
  who downloaded the software, his/her employer (which must be your employer)
  and Texas Instruments Incorporated (the "License").  You may not use this
  Software unless you agree to abide by the terms of the License. The License
  limits your use, and you acknowledge, that the Software may not be modified,
  copied or distributed unless embedded on a Texas Instruments microcontroller
  or used solely and exclusively in conjunction with a Texas Instruments radio
  frequency transceiver, which is integrated into your product.  Other than for
  the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  works of, modify, distribute, perform, display or sell this Software and/or
  its documentation for any purpose.

  YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  PROVIDED 揂S IS

⌨️ 快捷键说明

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