# hal_mdb1.c File Reference

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

`#include "hal_mdb1.h"`

## Defines
#define | EXCLUDE_STATUS_LEDS 0x3F
#define | LED_TEST_DELAY 250
#define | TIMER_MAX_SECONDS 4
#define | ADC_VREF_DELAY_MS 17
#define | ADC_COUNT_TO_MILLIVOLT_MULTIPLIER 1.220703125
## Functions
signed int | oscInit (unsigned char mainOscConfiguration, unsigned char auxOscConfiguration)
__interrupt void | USCIAB0RX_ISR (void)
__interrupt void | USCI1RX_ISR (void)
unsigned char | getButtons ()
__interrupt void | PORT2_ISR (void)
__interrupt void | PORT1_ISR (void)
void | halInit ()
signed int | debugConsoleInit (unsigned char baudRate)
signed int | auxSerialPortInit (unsigned char baudRate)
int | putchar (int c)
int | putcharAux (int c)
void | halSpiInitZnp ()
void | spiWrite (unsigned char *bytes, unsigned char numBytes)
void | delayMs (unsigned int ms)
void | setStatusLed (unsigned char color)
void | setButtonLeds (unsigned char led)
signed int | setLed (unsigned char led)
void | clearLeds ()
void | clearButtonLeds ()
void | toggleLed (unsigned char whichLed)
void | testLEDs ()
unsigned char | getSwitches ()
void | halEnableInterrupts ()
void | setZnpInterfaceToInputs (void)
void | stopTimerA ()
signed int | initTimer (unsigned char seconds, unsigned char wakeOnTimer)
__interrupt void | Timer_A (void)
signed int | calibrateVlo ()
unsigned int | getAnalogInput (unsigned int adc12ctl0, unsigned int adc12ctl1, unsigned char adc12mctl0)
unsigned int | getVcc3 ()
## Variables
void(* | debugConsoleIsr )(char)
void(* | buttonIsr )(char)
void(* | timerIsr )(void)
void(* | auxSerialPort )(char)
void(* | bitBangSerialIsr )(char)
unsigned long | mclk
unsigned long | smclk
unsigned int | aClk = 0
unsigned char | wakeupAfterTimer = 0

## Detailed Description

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

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

Peripherals:

- ZNP Interface: Connects to the ZNP 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 & CC2530 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 See www.smith-electronics.com for more information.

Rev
  709

Author
  dsmith

Date
  2010-08-12 19:00:00 -0700 (Thu, 12 Aug 2010)

YOU 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 TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES 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 auxSerialPortInit | ( | unsigned char | baudRate | ) |

Configures the Auxilliary Serial Port UART (USCIA1) with the specified baud rate. Also enables the Rx interrupt for this UART.

Precondition:
  SMCLK = 4MHz

Returns:
  0 if success, -1 if invalid parameter

signed int calibrateVlo | ( |  | ) |

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. At room temperature, typical VLO frequencies seen are 9kHz (MSP430F248) and 12kHz (MSP430F2274)

Returns:
  VLO frequency (number of VLO counts in 1sec)

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. Check device-specific datasheet to see which module block has ACLK as a compare input. 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 changed
  ACLK divide by 8 bit cleared

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 ZNP examples.

Parameters:

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

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

signed int debugConsoleInit | ( | unsigned char | baudRate | ) |

Configures the debug console UART (USCIA0) for the specified baud rate, with oversampling Also enables the Rx interrupt for this UART.

Precondition:
  SMCLK is 4MHz

See also:
  Table 15-5 of MSP430F2xxx Family User's Guide, slau144

Returns:
  0 if success, -1 if invalid parameter

void delayMs | ( | unsigned int | ms | ) |

Blocking Delay in Milliseconds delays by at least the specified number of milliseconds (ms)

Precondition:
  TICKS_PER_MS set

Parameters:

  | ms | number of milliseconds to delay

unsigned int getAnalogInput | ( | unsigned int | adc12ctl0,
|  | unsigned int | adc12ctl1,
|  | unsigned char | adc12mctl0 |
| ) |  |  |

Private helper method to setup ADC for one-shot conversion and read out value according to registers. Inserts a delay before beginning conversion if REFON

Returns:
  the raw ADC value with the specified commands.

Todo:
  move the VREF warmup to startup and leave on to avoid 17mSec blocking delay each time?

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

void halEnableInterrupts | ( |  | ) |

Enable interrupts on the processor

void halInit | ( |  | ) |

Configures hardware for the particular board

- Oscillator: turns off WDT, configures MCLK & SMCLK
- Ports: including purpose, direction, pullup/pulldown resistors etc.
- Holds radio in reset (active-low)

void halSpiInitZnp | ( |  | ) |

Initializes the SPI interface to the ZNP.

Note:
  CC2530 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.

signed int initTimer | ( | unsigned char | seconds,
|  | unsigned char | wakeOnTimer |
| ) |  |  |

Configures timer for source = ACLK

Precondition:
  ACLK configured
  VLO has been calibrated if using VLO; number of VLO counts in one second is in vloFrequency.

Parameters:

  | seconds | period of the timer. Maximum is 0xFFFF / aClk; about 2 if using 32kHz xtal or about 4 if using VLO 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 aClk not set

signed int oscInit | ( | unsigned char | mainOscConfiguration,
|  | unsigned char | auxOscConfiguration |
| ) |  |  |

Stops the Watchdog timer and starts Oscillator based on the selected option. Halts if calibration constants erased.

Parameters:

  | mainOscConfiguration | the main oscillator (MCLK) configuration - must be MCLK_1_DCO or MCLK_8_DCO or MCLK_8_XTAL
  | auxOscConfiguration | the aux oscillator (ACLK) configuration - must be ACLK_VLO or ACLK_32_XTAL or ACLK_32_EXT

Returns:
  0 if success, else error code if invalid parameter.

__interrupt void PORT2_ISR | ( | void |  | ) |

Port P2 interrupt service routine.

Precondition:
  Port 2 pins are configured as interrupts appropriately.

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, must be 0-4.

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

Turns ON the specified LED. Required for ZNP examples.

Parameters:

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

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

void setStatusLed | ( | unsigned char | color | ) |

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.

void setZnpInterfaceToInputs | ( | void |  | ) |

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

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

Sends a message over SPI to the radio IC on USCI_B1. Based on hal_board.c in CC2480 example application ZASA. The ZNP uses a "write-to-read" approach to read data out, you must write data in. This is a private method that gets wrapped by other methods, e.g. spiSreq(), spiAreq, etc. To Write, set *bytes, numBytes. To Read, set *bytes only. Don't need to set numBytes because CC2530ZNP will stop when no more bytes read.

Parameters:

  | bytes | the data to be sent or received.
  | numBytes | the number of bytes to be sent. This same buffer will be overwritten with the received data.

Note:
  Modify this method for other hardware implementations.

Precondition:
  SPI port configured for writing
  CC2530ZNP has been initialized

Postcondition:
  bytes contains received data, if any

void testLEDs | ( |  | ) |

Simple test of all LEDs

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.

__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

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. Param is which bit-bang interface (0 or 1)

void(* buttonIsr)(char)

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

void(* debugConsoleIsr)(char)

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.

unsigned long mclk

For total code + CONST size of 29k, (as of 1/28/10) flash up to 0x5669 is in use. time for segment erase = 4819/fFTG, or about 12mSec time for block program is about 1.73mSec per Block, so total per segment is approx. 15mSec. If writing entire 30kB firmware image (60segments) then total time is ~900mSec. Total time spent programming each block must be less than 4mSec. (i.e. don't include much stuff inbetween writing bytes)

void(* timerIsr)(void)

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

All Files Functions Variables