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

📄 spp_dev_a_leds.c

📁 蓝牙虚拟串口程序1 设备A BLUELAB4.0
💻 C
字号:
/***************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2006-2008

	This file was auto-generated by the ledparse application from 
	BlueLab 4.0.1-release and provides simple LED indications.
*****************************************************************************/

#include "spp_dev_a_leds.h"

#include <pio.h>
#include <message.h>
#include <panic.h>

#define DEBUG_LEDSx

#ifdef DEBUG_LEDS
#define LED_DEBUG(x) {printf x;}
#else
#define LED_DEBUG(x) 
#endif

#define ON  (0x1)
#define OFF (0x0)
#define RPT (0x1)

#define LED_UPDATE_MSG (0x0)

typedef struct ledEntryTag
{
    uint16   PioMask;           /* mask of PIOs */
    unsigned On         :1;
    unsigned Time       :15;    /* ms */   
}ledEntry_t;

typedef struct ledHeaderTag
{
    unsigned     num_entries    :8;
    unsigned     reserved       :7;
    unsigned     repeat         :1;
} ledHeader_t;    

typedef struct ledbTag 
{
    ledHeader_t  header;
    ledEntry_t * entries;
} led_t;
    

/*START_OF_INSERTED_CODE*/



#define SPECIAL_LED_PINS

/*All of The LED pins used*/
static const int gLedPinsUsed = 0xC000 ; 

 /*BLUE_FLASH*/ 
static const ledEntry_t pattern_BLUE_FLASH [ 2 ] = 
{
    { 0xC000 , ON  , 500  }  , 
    { 0x8000 , OFF , 500  }  
}; 
/*RED_BLUE_ALT*/ 
static const ledEntry_t pattern_RED_BLUE_ALT [ 4 ] = 
{
    { 0x4000 , ON  , 50   }  , 
    { 0x4000 , OFF , 0    }  , 
    { 0x8000 , ON  , 50   }  , 
    { 0x8000 , OFF , 0    }  
}; 


#define LED_NUM_PATTERNS ( 2 )

/*The LED entries*/
static const led_t gLeds [ LED_NUM_PATTERNS ] = 
{
    {  { 2,  0x00 , RPT }, (ledEntry_t *) pattern_BLUE_FLASH } ,

    {  { 4,  0x00 , RPT }, (ledEntry_t *) pattern_RED_BLUE_ALT } 
};

/*END_OF_INSERTED_CODE*/


/* The LEDs task data. */
typedef struct
{
	TaskData task;
        
    /* Current pattern being played. */
    LedPattern_t gCurrentPattern;   
    /* Position in the sequence of playing the current pattern. */   
    uint16 gCurrentPatternPosition;
    /* Current repeating pattern being played */
    LedPattern_t gRepeatingPattern;
    /* Position in the sequence through that repeating pattern */
    uint16 gRepeatingPatternPosition;
    
} LedState_t;


/* This is the main LED state - initialised when used. */
LedState_t * LED = NULL;

/* Local Functions */
static void ledsInit ( void );
static void ledsSet ( uint16 pLedMask , bool pOnOrOff );
static void ledsSetPio ( uint16 pPIOMask , bool pOnOrOff  );
static void ledsHandler (Task task, MessageId id, Message data);
static bool ledsConfigPattern ( LedPattern_t  pNewPattern  ) ;


/****************************************************************************
NAME	
	ledsPlay

DESCRIPTION
    Play an LED pattern. 
    
    If a repeating pattern is already playing 
    - then this will be interrupted and the new pattern (non repeating or 
      repeating) will be played. If the new pattern is non-repeating then 
      the interrupted pattern will be resumed after completion of the 
      non-repeating pattern.
    
    If a non-repeating pattern is currently playing    
    - if the new pattern is also a non-repeating pattern, then returns false 
      (caller is responsible for queuing LEDS).
    - if the new pattern is a repeating pattern, then this will be played on 
      completion of the non-repeating current pattern.
    
RETURNS
	void
*/
bool ledsPlay ( LedPattern_t pNewPattern  ) 
{
    bool lUpdate;
    
    /* Init the LED structure if required. */
    if ( ! LED )
    {
        ledsInit();
    }
    /* Ensure range is valid. */
    if (pNewPattern > (LED_NUM_PATTERNS-1) ) 
        return FALSE;
    
    /* Function which configures the requested pattern, if possible. */
    lUpdate = ledsConfigPattern ( pNewPattern  ) ;
    
    if (lUpdate)
    {
        MessageFlushTask ( &LED->task );
                       
        LED_DEBUG(("LED: Play [%d]\n", pNewPattern));
       
        ledsSet ( gLedPinsUsed , OFF );
                  
        MessageSend ( &LED->task , LED_UPDATE_MSG , 0 );
    }
    
    return lUpdate;
}

/****************************************************************************
NAME	
	ledsHandler

DESCRIPTION
    Update the LED playback.
    Turn the LEDs On or Off according to the next element in the pattern.
    If the pattern has completed and is non repeating, then restarts the 
    pattern.

RETURNS
	void
*/
static void ledsHandler(Task task, MessageId id, Message data) 
{
   LED_DEBUG(("LED: [%d][%d][%d]\n " , 
                    LED->gCurrentPattern , 
                    LED->gCurrentPatternPosition , 
                    gLeds[LED->gCurrentPattern].header.num_entries ));
          
    switch (id)
    {
        case ( LED_UPDATE_MSG ) :
        {

        LED_DEBUG(("LED Mask[%x] On[%d] Time[%d]\n" , 
                            gLeds[LED->gCurrentPattern]
                                .entries[LED->gCurrentPatternPosition]
                                    .PioMask , 
                            gLeds[LED->gCurrentPattern]
                                .entries[LED->gCurrentPatternPosition].On ,
                            gLeds[LED->gCurrentPattern]i
                                .entries[LED->gCurrentPatternPosition].Time));  

            /* The pattern has completed. */
            if (LED->gCurrentPatternPosition >= 
                            gLeds[LED->gCurrentPattern].header.num_entries)
            {  
                if (gLeds[LED->gCurrentPattern].header.repeat)
                {      
                    /* Reset the repeating pattern. */
                    LED_DEBUG(("LED: Repeat\n"));
                    LED->gCurrentPatternPosition = 0;
                }
                else
                {       
                    /* One shot pattern is complete. */
                    /* Return to playing the repeating pattern. */
                    LED->gCurrentPattern         = LED->gRepeatingPattern;
                    LED->gCurrentPatternPosition = 
                            LED->gRepeatingPatternPosition;       
                    
                    if (gLeds[LED->gCurrentPattern].header.repeat)
                    {   
                        /* Reset the repeating pattern. */
                        LED_DEBUG(("LED: Repeat 2\n"));
                        LED->gCurrentPatternPosition = 0;
                    }       
                }
            }               
            /* Cancel all pending LED update messages. */
            MessageFlushTask ( task );            

            ledsSet ( gLeds[LED->gCurrentPattern]
                            .entries[LED->gCurrentPatternPosition].PioMask, 
                      gLeds[LED->gCurrentPattern]
                            .entries[LED->gCurrentPatternPosition].On );
            
                    
            /* Only send a message if we are not a permanently on or off 
             * pattern.
             */   
            if ( ( gLeds[LED->gCurrentPattern].header.num_entries) != 1 ) 
            {
                MessageSendLater ( task, 
                                   LED_UPDATE_MSG, 
                                   0, 
                                   (gLeds[LED->gCurrentPattern]
                                        .entries[LED->gCurrentPatternPosition]
                                            .Time ) );
            }
            
            LED->gCurrentPatternPosition ++;                   
        }
        break;
        
        default:
        break;
    }  
}

/****************************************************************************
NAME	
	ledsInit

DESCRIPTION
    Initialise the LED Library.
    
RETURNS
	void
*/
static void ledsInit( void ) 
{   
    LED = PanicUnlessNew ( LedState_t );
    
	LED->task.handler              = ledsHandler;
	LED->gCurrentPatternPosition   = 0;
	LED->gCurrentPattern           = 0;
	LED->gCurrentPatternPosition   = 0;
	LED->gRepeatingPattern         = 0;
	LED->gRepeatingPatternPosition = 0;
}

/****************************************************************************
NAME	
	ledsSet

DESCRIPTION
    Set / Clear the LED pins or PIOs.
    
RETURNS
	void
*/
static void ledsSet (uint16 pLedMask , bool pOnOrOff ) 
{	
    uint16 lMask = 0xffff;
    
#ifdef SPECIAL_LED_PINS    

  /* LED pins are special cases. */
    if ( pLedMask & 0x8000 )        
        PioSetLed0 ( pOnOrOff );
    if ( pLedMask & 0x4000 )
        PioSetLed1 ( pOnOrOff );

    /* Set the remaining PIOs. */    
    lMask = 0x3fff;
#endif

    /* set the PIOs. */    
    ledsSetPio ( ( pLedMask & lMask ) , pOnOrOff );
    
}

/****************************************************************************
NAME	
	ledsSetPio

DESCRIPTION
    Function to set / clear the mask of PIOs required.
    
RETURNS
	void
*/
static void ledsSetPio ( uint16 pPioMask , bool pOnOrOff  ) 
{
    uint16 lPinVals = 0;
    
    if ( pOnOrOff == TRUE )    
    {
        lPinVals = pPioMask ;
    }
    else
    {
        /* Clear the corresponding bit. */
        lPinVals = 0x0000;
    }
    /* (mask, bits) setting bit to a '1' sets the corresponding PIO for 
     * output.
     */
    PioSetDir( pPioMask , pPioMask );   
    /* Set the value of the pin to the corresponding value. */         
    PioSet ( pPioMask , lPinVals );     
}

/****************************************************************************
NAME	
	ledsConfigPattern

DESCRIPTION
    Function to configure the led that has been requested, returns false if
    the led cannot be played at this time.
    
RETURNS
	bool (if an update to the LEDS required)
*/
static bool ledsConfigPattern ( LedPattern_t  pNewPattern  ) 
{
    bool lUpdate = TRUE;

    LED_DEBUG(("LED: Play Curr[%x] New [%x]\n", 
                            gLeds[LED->gCurrentPattern].header.repeat, 
                            gLeds[pNewPattern].header.repeat ));    

    /* If current pattern is repeating */
    if ( gLeds[LED->gCurrentPattern].header.repeat )
    {       
        LED_DEBUG(("1\n"));

        /*If new pattern is repeating */
        if ( gLeds[pNewPattern].header.repeat )
        {
            /* then interrupt the pattern with the new repeating pattern. */
            LED_DEBUG(("2\n"));            
            LED->gCurrentPatternPosition   = 0;
            LED->gCurrentPattern           = pNewPattern;
            
            LED->gRepeatingPattern         = pNewPattern;
            LED->gRepeatingPatternPosition = 0;            
        }
        /* Interrupt the current pattern with a repeating pattern. */
        else 
        {
            LED_DEBUG(("3\n"));
            /* Then store the current pattern to be resumed */
            LED->gRepeatingPattern         = LED->gCurrentPattern;
            LED->gRepeatingPatternPosition = LED->gCurrentPatternPosition; 
            /* and start the requested pattern. */
            LED->gCurrentPattern = pNewPattern;
            LED->gCurrentPatternPosition = 0;            
        }
    }
    /* Current pattern is non repeating. */
    else 
    {
        /*if the new pattern is repeating */
        if ( gLeds[pNewPattern].header.repeat ) 
        {       
            /* then store this to be resumed. */
            LED_DEBUG(("4\n"));            
            LED->gRepeatingPattern         = pNewPattern;
            LED->gRepeatingPatternPosition = 0;            
        }
        /* The new pattern is also non-repeating and can't be currently 
         * played. 
         */
        else 
        {
            LED_DEBUG(("5\n"));                
            lUpdate = FALSE;
        }
    }       
    return lUpdate;
}


⌨️ 快捷键说明

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