Zigbee Module Examples

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Macros | Functions | Variables
hal_mdb1.c File Reference

Hardware Abstraction Layer (HAL) for the Module Development Board (MDB1) More...

`#include "hal_mdb1.h"`
`#include "hal_msp430x2xxx_oscillators.h"`
`#include "hal_msp430x2xxx_usci.h"`

## Macros
#define | EXCLUDE_STATUS_LEDS 0x3F
#define | TIMER_MAX_SECONDS 4
#define | ADC_VREF_DELAY_MS 17
#define | ADC12_COUNT_TO_MILLIVOLT_MULTIPLIER_3V3 1.220703125
#define | ADC_COUNT_TO_VCC_UNREG_MULTIPLIER 6.715506715506716f

## Functions
__interrupt void | USCIAB0RX_ISR (void)
__interrupt void | USCI1RX_ISR (void)
unsigned char | getButtons ()
__interrupt void | PORT2_ISR (void)
__interrupt void | PORT1_ISR (void)
void | doNothing (int8_t a)
void | oscInit ()
void | halEnableAuxFlowControl ()
void | portInit ()
void | halInit ()
int | putchar (int c)
int | putcharAux (int c)
void | delayMs (unsigned int delay)
void | halSpiInitModule ()
void | spiWrite (unsigned char *bytes, unsigned char numBytes)
signed char | setStatusLed (unsigned char color)
void | setButtonLeds (unsigned char led)
signed int | setLed (unsigned char led)
void | clearLeds ()
void | clearButtonLeds ()
void | toggleLed (unsigned char whichLed)
unsigned char | getSwitches ()
void | stopTimer ()
__interrupt void | Timer_A0 (void)
int16_t | initTimer (uint8_t seconds)
signed int | calibrateVlo ()
unsigned int | getVcc3 ()
unsigned int | getVddUnregulated ()
void | halSetAllPinsToInputs ()

## Variables
void(* | debugConsoleIsr )(int8_t)
void(* | buttonIsr )(int8_t)
void(* | auxSerialPort )(char)
void(* | bitBangSerialIsr )(char)
uint16_t | wakeupFlags = 0
uint16_t | vloFrequency = 0
unsigned int | aClk = 0
void(* | timerIsr )(void)

## Detailed Description

Hardware Abstraction Layer (HAL) for the Module Development Board (MDB1)

This development board has an MSP430F248 and module and was the initial development platform for these examples. This file is included to show how easy it is to port the libraries to a different hardware platform.

Peripherals:

- Module Interface: Connects to the module via jumper-selectable SPI or UART
- LEDs: Six general purpose LEDs, one bi-color (Red/Yellow/Green) Status LED, and one power LED
- Buttons: Five general purpose buttons, one reset button
- Interfaces: MSP430 & module programming connectors, RS-232 on DB-9
- Crystals: External 32kHz and 16MHz crystal options
- I2C Serial EEPROM
- Other I/O: Two Opto-Isolated inputs, Four relay drivers, I/O pins on headers
- Configurability: All on-board peripherals may be disabled with cuttable jumpers

Module UART implementation configuration:

Note:
  CTS (Clear To Send) is an output of processor, input to Module
  - CTS = 0: CC2530 will transmit
  - CTS = 1: CC2530 will stop transmitting 1.0 Module CTS (if using serial), output 1.1 Module RTS (if using serial), input, no interrupt 1.2 Module Reset (used either Module interface is SPI or UART) 1.3 Module SRDY (only used if Module interface is SPI) 3.6 Second (Module/Aux) UART Tx (used if Module interface is UART) 3.7 Second (Module/Aux) UART Rx (used if Module interface is UART)

Rev:
  1642

Author:
  dsmith

Date:
  2012-10-31 11:17:04 -0700 (Wed, 31 Oct 2012)

# Support

Please refer to the wiki at www.anaren.com/air-wiki-zigbee for more information. Additional support is available via email at the following addresses:

- Questions on how to use the product: AIR@a.nosp@m.nare.nosp@m.n.com
- Feature requests, comments, and improvements: featu.nosp@m.rere.nosp@m.quest.nosp@m.s@te.nosp@m.slaco.nosp@m.ntro.nosp@m.ls.co.nosp@m.m
- Consulting engagements: sales.nosp@m.@tes.nosp@m.lacon.nosp@m.trol.nosp@m.s.com

# License

Copyright (c) 2012 Tesla Controls. All rights reserved. This Software may only be used with an Anaren A2530E24AZ1, A2530E24CZ1, A2530R24AZ1, or A2530R24CZ1 module. Redistribution and use in source and binary forms, with or without modification, are subject to the Software License Agreement in the file "anaren_eula.txt"

YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ANAREN MICROWAVE OR TESLA CONTROLS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSE INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.

## Function Documentation

signed int calibrateVlo | ( |  | ) |

Required for compatibility with MSP430 libraries

Calibrate VLO. Once this is done, the VLO can be used semi-accurately for timers etc. Once calibrated, VLO is within ~2% of actual when using a 1% calibrated DCO frequency and temperature and supply voltage remain unchanged.

Returns:
  VLO frequency (number of VLO counts in 1sec), or -1 if out of range

Precondition:
  SMCLK is 4MHz
  MCLK is 8MHz
  ACLK sourced by VLO (BCSCTL3 = LFXT1S_2 in MSP430F2xxx)

Note:
  Calibration is only as good as MCLK source. Obviously, if using the internal DCO (+/- 1%) then this value will only be as good as +/- 1%. YMMV.
  On MSP430F248 or MSP430F22x2 or MSP430F22x4, must use TACCR2. On MSP430F20x2, must use TACCR0. On MSP430G2553, must use CCI0B on CCR0 Check device-specific datasheet to see which module block has ACLK as a compare input. Modify TACCTLx, TACCRx, and CCIS_x accordingly For example, see page 23 of the MSP430F24x datasheet or page 17 of the MSP430F20x2 datasheet, or page 18 of the MSP430F22x4 datasheet.
  If application will require accuracy over change in temperature or supply voltage, recommend calibrating VLO more often.

Postcondition:
  Timer A settings restored to what they were beforehand except for TACCR0 which is reset.

void clearButtonLeds | ( |  | ) |

    Turns off the button LEDs and leaves status LED unchanged.

Postcondition:
  button LEDs are all off. Status LED is in the same state as it was before the method was called.

void clearLeds | ( |  | ) |

    Turns OFF the specified LED. Required for Module examples.

Parameters:

  led | the LED to turn off, must be 0,1,2,3,4.

Returns:
  0 if success, -1 if invalid LED specified

void delayMs | ( | unsigned int | delay | ) |

    A fairly accurate blocking delay for waits in the millisecond range. Good for 1mSec to 1000mSec.

At 1MHz, error of zero for 100mSec or 1000mSec. For 10mSec, error of 100uSec. At 1mSec, error is 20uSec. At 8MHz, error of zero for 1000mSec. Note that accuracy will depend on the clock source. MSP430F2xx internal DCO is typically +/-1%. For better timing accuracy, use a timer, or a crystal.

Precondition:
  TICKS_IN_ONE_MS is defined correctly

Parameters:

  delay | number of milliseconds to delay

void doNothing | ( | int8_t | a | ) |

Simple placeholder to point the function pointers to so that they don't cause mischief

unsigned char getButtons | ( |  | ) |

    Reads the current status of the buttons

Returns:
  0x01 if button 1 is pressed, 0x02 if button 2 is pressed, 0x04 if button 3 is pressed, etc.

unsigned char getSwitches | ( |  | ) |

Read value of the two Dual In-Line Package (DIP) switches.

Returns:
  the state of the switches as a number from 0 to 3.

Precondition:
  DIP Switches (P2.6, P2.7) are configured as digital inputs with pull-DOWNs

unsigned int getVcc3 | ( |  | ) |

    Measures Vcc to the MSP430, nominally 3300mV

- ADC measures VCC/2 compared to 2.5V reference
- If Vcc = 3.3V, ADC output should be (1.65/2.5)*4095 = 2703
- (halfVcc/2.5)*4095 = ADC reading and (Vcc/2.5)*4095 = 2*ADC
- Vcc*4096 = 5*ADC –> and VCC=5*ADC/4095
  Returns:
    Vcc in millivolts

unsigned int getVddUnregulated | ( |  | ) |

    Measures Unregulated input voltage. This feeds a 10k/1k 1% resistor divider to the MSP430 ADC input A3.

- ADC measures VCC/11 compared to 2.5V reference
- If VddUnregulated = 8V, ADC output should be (0.727/2.5)*4095 = 1191
- (eleventh8V8/2.5)*4095 = ADC reading and (8V8/2.5)*4095 = 11*ADC
- Vcc*4096 = 27.5*ADC –> and VCC=27.5*ADC/4095
- V = 8 then Vccunreg/11 = 0.801, or 2187 adc counts if using 1.5V reference
  Returns:
    Vdd Unregulated in millivolts

void halEnableAuxFlowControl | ( |  | ) |

Enables flow control (makes the pin an output) and enables communications to occur.

void halInit | ( |  | ) |

Configures hardware for the particular board

- Initializes clocks
- Ports: including purpose, direction, pullup/pulldown resistors etc.
- Holds radio in reset (active-low)

void halSetAllPinsToInputs | ( | void |  | ) |

Configures all module interface signals as inputs to allow the module to be programmed. Toggles LED0 quickly to indicate application is running.

void halSpiInitModule | ( |  | ) |

Initializes the SPI interface to the Module.

Note:
  Module SPI clock speed < 4MHz. SPI port configured for clock polarity of 0, clock phase of 0, and MSB first.
  On MDB the RFIC SPI port is USCIB1
  Modify this method for other hardware implementations.

Precondition:
  SPI pins configured correctly: Clock, MOSI, MISO configured as SPI function; Chip Select configured as an output; SRDY configured as an input.

Postcondition:
  SPI port is configured for RFIC communications.

int16_t initTimer | ( | uint8_t | seconds | ) |

    Configures timer.

Precondition:
  ACLK sourced from VLO
  VLO has been calibrated; number of VLO counts in one second is in vloFrequency.

Parameters:

  seconds | period of the timer. Maximum is 0xFFFF / vloFrequency; or about 4 since VLO varies between 9kHz - 15kHz. Use a prescaler on timer (e.g. set IDx bits in TACTL register) for longer times. Maximum prescaling of Timer A is divide by 8. Even longer times can be obtained by prescaling ACLK if this doesn't affect other system peripherals.

Returns:
  0 if success; -1 if illegal parameter or -2 if VLO not calibrated

void oscInit | ( |  | ) |

    Initializes Oscillator

- turns off WDT
- Configures MCLK to 8MHz using internal DCO
- Sets SMCLK to 4MHz
- Configures ACLK to use external xtal.

__interrupt void PORT1_ISR | ( | void |  | ) |

    Port P1 interrupt service routine.

Precondition:
  Port 1 pins are configured as interrupts appropriately.

__interrupt void PORT2_ISR | ( | void |  | ) |

    Port P2 interrupt service routine.

Precondition:
  Port 2 pins are configured as interrupts appropriately.

void portInit | ( |  | ) |

Initializes Ports/Pins: sets direction, interrupts, pullup/pulldown resistors etc.

int putchar | ( | int | c | ) |

Send one byte via hardware UART. Called by printf() etc. in stdio.h

int putcharAux | ( | int | c | ) |

Send one byte via hardware UART to the auxilliary serial port. Aux Serial Port is USCIA1.

void setButtonLeds | ( | unsigned char | led | ) |

    Turns on the specified button LED. Leaves status LED unchanged.

Note:
  Button LEDs are active-LOW, Status LED is active-HIGH.

Parameters:

  whichLed | the LED to turn on.

signed int setLed | ( | unsigned char | led | ) |

    Turns ON the specified LED.

Parameters:

  led | the LED to turn on, must be 0,1,2,3,4.

Returns:
  0 if success, -1 if invalid LED specified

signed char setStatusLed | ( | unsigned char | color | ) |

LED Control Sets the status LED to a particular color. Leaves the other LEDs unchanged. The status LED is a two-element LED (red+green) that is capable of displaying red, green, or yellow.

Note:
  Button LEDs are active-LOW, Status LED is active-HIGH.

Parameters:

  color | the color to set, must be STATUS_LED_RED, STATUS_LED_GREEN, or STATUS_LED_YELLOW.

Returns:
  -1 if invalid color, 0 if success

void spiWrite | ( | unsigned char * | bytes,
|  | unsigned char | numBytes
| ) |  |

Used to communicate with Zigbee module

void stopTimer | ( |  | ) |

Halts the timer. Leaves period unchanged.

void toggleLed | ( | unsigned char | whichLed | ) |

    Toggles the specified button LED.

Parameters:

  whichLed | the LED to toggle, must be 0-4.

Postcondition:
  The specified button LED is toggled. Status LED is unchanged.

Todo:
  this should read from a globals file based on the type of device, how many LEDs, etc.

__interrupt void USCI1RX_ISR | ( | void |  | ) |

Auxilliary Serial Port interrupt service routine, called when a byte is received on USCIA1 or USCIB1.

__interrupt void USCIAB0RX_ISR | ( | void |  | ) |

Debug console interrupt service routine, called when a byte is received on USCIA0 or USCIB0.

## Variable Documentation

unsigned int aClk = 0

Clock speed of the auxilliary clock. Set in oscInit() if an external xtal is used or calibrateVlo() if using VLO.

void(* auxSerialPort)(char)

Function pointer for the ISR called when a byte is received on the aux. serial port

void(* bitBangSerialIsr)(char)

    Function pointer for the ISR called when a byte is received on the bit-bang

serial port. Parameter is which bit-bang interface (0 or 1)

void(* buttonIsr)(int8_t)

Function pointer for the ISR called when a button is pressed. Parameter is which button.

void(* debugConsoleIsr)(int8_t)

    This is a function pointer for the Interrupt Service Routine called when a debug console character is received.

To use it, declare it with `extern void (*debugConsoleIsr)(char);` and then point it to a function you created, e.g. `debugConsoleIsr =` and your function handleDebugConsoleInterrupt() will be called when a byte is received.

void(* timerIsr)(void)

Function pointer for the ISR called when a timer generates an interrupt

uint16_t vloFrequency = 0

    The post-calibrated frequency of the Very Low Oscillator (VLO). This MUST be

calibrated by calibrateVlo() prior to use. Set with calibrateVlo() and read by initTimer().

uint16_t wakeupFlags = 0

    Flags to indicate when to wake up the processor. These are read in the

various ISRs. If the flag is set then the processor will be woken up with HAL_WAKEUP() at the end of the ISR. This is required because HAL_WAKEUP() cannot be called anywhere except in an ISR.