HAL for MSP430 family with mspgcc compiler

This is the TiROS hardware abstraction layer for the Texas Instruments MSP430x family of embedded microcontrollers.

This microcontroller family can support software interrupts. These microcontrollers can be driven from a 32kHz crystal oscillator. The time functions have been written assuming such an oscillator drives the timer. If this is not the case, modify the functions in porttime.h and the timer initialization functions in tr_port.c.

Note that in the MSP430 architecture, the low-power state of the processor is stored in the status register. Since this is part of the context, per-task power control is automatic. To keep the processor in low-power state during idle time, simple define the idle task as

 void idle_task(void *dummy) 
 {
   while(1) {
       _BIS_SR(LPM3_bits);
   }
 }

Tested with TI MSP430x1611

Configuration Options:

TRPORT_MSP_OSTIMER [A | B] :
Options are A or B. The MSP430 family supports two timers, TimerA and TimerB. TimerA is available on the entire family line. TimerB is only available on some. By default, if this configuration option is not set, TimerA is used as source for the timer interrupt.
TIROS_KERNEL_TRAP_ENABLED [0|1]:
If this define is set to 1, OS kernel context switches from ISRs are made using a software trap (i.e.) by causing an interrupt under software control. This makes ISRs very efficient. The MSP430/GCC port supports kernel traps. So this is enabled as a default. To disable it, set TIROS_KERNEL_TRAP_ENABLED to 0 in proj_config.h.
USER_DEFINED_KERNEL_TRAP :
If TIROS_KERNEL_TRAP_ENABLED is set to 1, kernel traps are enabled. The default implementation uses Port 2, pins. By setting a specific pin, an interrupt is forced. The user can override this default and specify a different interrupt handler for this purpose. In this case, create user definitions for isr_kernel_trap and OS_KERNEL_TRAP, and hal_setup_kernel_trap() . Do not define or set these functions if TIROS_KERNEL_TRAP_ENABLED is set to 0.

Writing ISRs.

If no TiROS API functions will be called, interrupts will stay disabled, then the ISR can be written very simply. See the requirements in Usage with Interrupt Service Routines.

  interrupt (IVECTOR) ISR_function(void)
 {
  // do stuff
 }

If TiROS API calls have to be used, the form of the ISR depends on whether TIROS_KERNEL_TRAP_ENABLED is set (It is set as a default). If TIROS_KERNEL_TRAP_ENABLED is set to 1, the ISR is simple

 interrupt (IVECTOR) ISR_function(void) 
 {
   int x;
   OS_CRITICAL_ENABLE();   // Only needed if any critical sections
                           // will be used and interrupt nesting is enabled.

   OS_ISR_BEGIN();         // Mark the beginning of an ISR. Note
                           // that if OS_CRITICAL_ENABLE() is also
                           // present, then this comes after 
                           // that. 
  
  x = 3;
    Do more stuff ....
  
  OS_ISR_END();
 }

If TIROS_KERNEL_TRAP_ENABLED is set to 0, the ISR would look as below. Use the ISR implementation in tr_port.c as a reference.

 interrupt (IVECTOR) ISR_function(void) __attribute__ ( (naked))
 interrupt (IVECTOR) ISR_function(void) 
 {
    HALINT_ISR_ENTRY();
    OS_ISR_BEGIN();
    perform_actions();
    OS_ISR_END();
    HALINT_ISR_EXIT();
 }

TiROS User Manual: Last Updated on Fri Jul 20 10:52:24 2007