User Tools

Site Tools


programming_the_wisp_under_linux

Programming the WISP under Linux

This page is a tutorial for setting up your Ubuntu environment for compiling and debugging the WISP firmware using the USB key debugger.
Questions? - melsabagh melsabagh maintains this page.

Step1: Installing MSPGCC and MSPDebug


First, we need to install required build prerequisites. Open Terminal, and paste the following:

sudo apt-get install subversion gcc-4.4 texinfo patch libncurses5-dev zlibc zlib1g-dev libx11-dev libusb-dev libreadline6-dev

Now, we will checkout the MSPGCC source code from the repository, and then build and install it

svn checkout https://mspgcc4.svn.sourceforge.net/svnroot/mspgcc4
cd mspgcc4
sudo sh buildgcc.sh

To make MSPGCC accessible by other tools, we need to add it to the environment path variables by editing the /etc/environment file:

sudo nano /etc/environment

Append “:/opt/msp430-gcc-4.4.3/bin” to the end of the PATH variable, and reload the environment file by executing:

source /etc/environment

Next, we need to download and install MSPDebug. Land here and download the latest version (mspdebug-0.13.tar.gz is used here), then execute the following:

tar xvfz mspdebug-0.13.tar.gz
cd mspdebug-0.13
make
sudo make install

Now, our environment is ready to communicate with the USB key. Just one final step which is to allow user access to the USB interface. To do so, we need to first get the vendor and product IDs of the USB key. So, attach it, and execute 'lsusb'. This should list all available USB interfaces. Note the ID <vendor>:<product> of the USB key down (the default is 0451:f430, but yours might be different). Now, make a new udev rule:

sudo nano /etc/udev/rules.d/wisp_usb_key_debugger.rules

Add the following to the new rule file, after changing PRODUCT_ID to match that of your USB key

ATTRS{idVendor}=="0451", ATTRS{idProduct}=="PRODUCT_ID", MODE="0660", GROUP="plugdev"

And then restart udev

sudo restart udev

Finally, check if MSPDebug can detect the usb key correctly by running:

mspdebug uif -d /dev/ttyUSB0

If all went okay, proceed to the next step. Otherwise, revise the steps carefully and make sure you are using the correct PRODUCT_ID in your udev rule.




Step2: Installing and configuring Eclipse-CDT


To install Eclipse CDT, use the following command:

sudo apt-get install eclipse-cdt

**Step2 (a) : Configuring Eclipse to use MSPGCC**

  1. Create a new C++ project (we will give it the name 'wisp_41_mspgcc').
  2. Click on 'Project→Properties' menu item, and expand the 'C/C++ Build' node in the left panel.
  3. Select 'Discovery Options' from the left panel.
  4. For each of the compilers in the 'Tools' list, type 'msp430-gcc' in the 'Compiler invocation command' field.
  5. Select the 'Settings' node from the left panel.
  6. For each of the 'GCC C++ Compiler', 'GCC C Compiler' and 'GCC C++ Linker', type 'msp430-gcc -mmcu=msp430x2132' in the 'command' field.
  7. For the 'GCC Assembler' type 'msp430-as' in the 'command' field.
  8. Under the 'GCC C++ Linker', select 'Libraries' and add the following to the 'Library search path':
  • /opt/msp430-gcc-4.4.3/lib
  • /opt/msp430-gcc-4.4.3/msp430/lib
  1. Select the 'Build Artifact' tab, and type 'elf' in the 'Artifact extension' field.
  2. Select 'Binary Parser' tab, and make sure the 'ELF parser' is checked.
  3. Apply all, press Okay, and close the project properties window.


**Step2 (b) : Configuring Eclipse to work with MSPDebug**

  1. Open 'Run→External Tools→External Tools Configurations'
  2. Click on 'New launch configuration', and use the following parameters
  • Name: mspdebug gdb loop
  • Location: /usr/local/bin/mspdebug
  • Working Directory: ${project_loc}/Debug
  • Arguments: uif -d /dev/ttyUSB0 gdb
  1. Apply, press Okay, and close the wizard.
  2. Open 'Run→Debug Configurations', and click on 'New launch configuration'.
  3. In the 'Arguments' tab, deselect 'Use default' and change the 'Working directory' to:
  • ${workspace_loc:project_name/Debug}
  1. In the debugger tab, select 'gdbserver Debugger' from the 'Debugger' dropbox.
  2. In the 'Debugger Options' section, use the following parameters for the 'Main' options:
  • GDB debugger: msp430-gdb
  • GDB command file: .gdbinit
  • GDB command set: standard
  • Protocol: mi
  1. For the 'Connection' options, use the following parameters:
  • Type: TCP
  • Host name or IP address: localhost
  • Port number: 2000
  1. Now, add the firmware source and headers to your project, and change the file extension of hw41_D41 from .c to .cpp.
  2. Finally, go to the root directory of your project, create a new file called '.gdbinit' with the following content:

set remotetimeout 999999

load Debug/wisp_41_mspgcc.elf




**Step3: Patching the firmware source**


MSPGCC requires some specific style of inline asm, pragmas, and interrupt handlers. To modify the firmware source code to work with MSPGCC, you can save and apply the following patch:

  1. – hw41_D41.cpp 2009-03-06 12:31:16.000000000 +0200

+++ hw41_D41_mspgcc.cpp 2011-01-01 16:04:58.246979000 +0200

@@ -139,6 +139,12 @@
 #define TID_DESIGNER_ID_AND_MODEL_NUMBER  0xFF, 0xF0, 0x01
 ////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __MSP430__// TODO: REMOVE IF NOT mspgcc compiler
+  #define __MSP430__
+  #include <signal.h>
+#endif
+
 #if(WISP_VERSION == BLUE_WISP)
   #include <msp430x21x2.h>
   #include "pinDefWISP4.1DL.h"
@@ -194,8 +200,6 @@
 #define SEND_CLOCK  \
   BCSCTL1 = XT2OFF + RSEL3 + RSEL0 ; \
     DCOCTL = DCO2 + DCO1 ;
-  //BCSCTL1 = XT2OFF + RSEL3 + RSEL1 ; \
-  //DCOCTL = 0;
 #define RECEIVE_CLOCK \
   BCSCTL1 = XT2OFF + RSEL3 + RSEL1 + RSEL0; \
   DCOCTL = 0; \
@@ -211,9 +215,9 @@
 // #pragma data_alignment=2 is important in sendResponse() when the words are copied into arrays.
 // Sometimes the compiler puts reply[0] on an
 // odd address, which cannot be copied as a word and thus screws everything up.
-#pragma data_alignment=2
+///#pragma data_alignment=2
  1. volatile unsigned char queryReply[]= { 0x00, 0x03, 0x00, 0x00};

+volatile unsigned char queryReply[] attribute 1)) = { 0x00, 0x03, 0x00, 0x00};

 // ackReply:  First two bytes are the preamble.  Last two bytes are the crc.
 volatile unsigned char ackReply[]  = { 0x30, 0x00, EPC, 0x00, 0x00};
@@ -236,11 +240,21 @@
 // compiler uses working register 4 as a global variable
 // Pointer to &cmd[bits]
+#ifdef __MSP430__
+volatile register unsigned char* dest __asm__("4");
+#else
 extern volatile __no_init __regvar unsigned char* dest @ 4;
+#endif // __MSP430__
+
 // compiler uses working register 5 as a global variable
 // count of bits received from reader
+#ifdef __MSP430__
+volatile register unsigned short bits __asm__("5");
+#else
 extern volatile __no_init __regvar unsigned short bits @ 5;
+#endif // __MSP430__
+
 unsigned short TRcal=0;
 #define STATE_READY               0
@@ -423,7 +437,7 @@
 //  P1IES &= ~BIT2; // initial state is POS edge to find start of CW
 //  P1IFG = 0x00;       // clear interrupt flag after changing edge trigger
  1. asm(“MOV #0000h, R9”);

+ asm(“MOV #llo(0), R9”);

   // dest = destorig;
 #if READ_SENSOR
@@ -433,7 +447,7 @@
 #if !(ENABLE_SLOTS)
   queryReplyCRC = crc16_ccitt(&queryReply[0],2);
   queryReply[3] = (unsigned char)queryReplyCRC;
-  queryReply[2] = (unsigned char)__swap_bytes(queryReplyCRC);
+  queryReply[2] = (unsigned char) queryReplyCRC >> 8;
 #endif
 #if SENSOR_DATA_IN_ID
@@ -444,7 +458,7 @@
 #else
   ackReplyCRC = crc16_ccitt(&ackReply[0], 14);
   ackReply[15] = (unsigned char)ackReplyCRC;
-  ackReply[14] = (unsigned char)__swap_bytes(ackReplyCRC);
+  ackReply[14] = (unsigned char) ackReplyCRC >> 8;
 #endif
 #if ENABLE_SESSIONS
@@ -1827,7 +1841,7 @@
   P1IFG = 0;  // Clear interrupt flag
   P1IE  |= RX_PIN; // Enable Port1 interrupt
-  _BIS_SR(LPM4_bits | GIE);
+  _BIS_SR((LPM4_bits) | (GIE));
   return;
 }
@@ -1857,7 +1871,7 @@
   if (is_power_good())
     P2IFG = VOLTAGE_SV_PIN;
  1. _BIS_SR(LPM4_bits | GIE);

+ _BIS_SR2);

 //  P1OUT |= RX_EN_PIN;
   return;
@@ -1875,8 +1889,12 @@
 // Pin Setup :
 // Description : Port 2 interrupt wakes on power good signal from supervisor.
+#ifdef __MSP430__
+interrupt(PORT2_VECTOR) Port2_ISR (void)
+#else
 #pragma vector=PORT2_VECTOR
 __interrupt void Port2_ISR(void)   // (5-6 cycles) to enter interrupt
+#endif
 {
   P2IFG = 0x00;
   P2IE = 0;       // Interrupt disable
@@ -1890,12 +1908,16 @@
   LPM4_EXIT;
 }
  1. #if USE_2132
  2. #pragma vector=TIMER0_A0_VECTOR

+#ifdef MSP430

+interrupt (TIMER0_A0_VECTOR) TimerA0_ISR (void)
 #else
-#pragma vector=TIMERA0_VECTOR
-#endif
+# if USE_2132
+#  pragma vector=TIMER0_A0_VECTOR
+# else
+#  pragma vector=TIMERA0_VECTOR
+# endif
 __interrupt void TimerA0_ISR(void)   // (5-6 cycles) to enter interrupt
+#endif
 {
   TACTL = 0;    // have to manually clear interrupt flag
   TACCTL0 = 0;  // have to manually clear interrupt flag
@@ -1910,13 +1932,17 @@
 // Pin Setup :  P1.2
 // Description : Port 1 interrupt is used as finding delimeter.
+#ifdef __MSP430__
+interrupt (PORT1_VECTOR) Port1_ISR (void)
+#else
 #pragma vector=PORT1_VECTOR
 __interrupt void Port1_ISR(void)   // (5-6 cycles) to enter interrupt
+#endif
 {
 #if USE_2132
-  asm("MOV TA0R, R7");  // move TAR to R7(count) register (3 CYCLES)
+  asm("MOV %0, R7 ":: "r" (TA0R));
 #else
   asm("MOV TAR, R7");  // move TAR to R7(count) register (3 CYCLES)
 #endif
@@ -1924,37 +1950,37 @@
   TAR = 0;            // 4 cycles
   LPM4_EXIT;
  1. asm(“CMP #0000h, R5\n”); if (bits == 0) (1 cycle) + asm(“CMP #llo(0), R5\n”); if (bits == 0) (1 cycle)

asm(“JEQ bit_Is_Zero_In_Port_Int\n”); 2 cycles bits != 0:

  1. asm(“MOV #0000h, R5\n”); bits = 0 (1 cycles) + asm(“MOV #llo(0), R5\n”); bits = 0 (1 cycles)
  1. asm(“CMP #0010h, R7\n”); this is finding delimeter (12.5us) (2 cycles)*/ 2d → 14 + asm(“CMP #llo(0x10), R7\n”); this is finding delimeter (12.5us) (2 cycles)*/ 2d → 14

asm(“JNC delimiter_Value_Is_wrong\n”); (2 cycles) - asm(“CMP #0040h, R7”); this is finding delimeter (12.5us) (2 cycles)* 43H

+  asm("CMP #llo(0x40), R7");             //************ this is finding delimeter (12.5us)  (2 cycles)*********  43H
   asm("JC  delimiter_Value_Is_wrong\n");
-  asm("CLR P1IE");
+  asm("CLR %0" : "=r" (P1IE));
 #if USE_2132
-  asm("BIS #8010h, TA0CCTL1\n");     // (5 cycles)   TACCTL1 |= CM1 + CCIE
+  asm("BIS #llo(0x8010), %0\n" : "=r" (TA0CCTL1));
 #else
-  asm("BIS #8010h, TACCTL1\n");     // (5 cycles)   TACCTL1 |= CM1 + CCIE
+  asm("BIS #llo(0x8010), TACCTL1\n");     // (5 cycles)   TACCTL1 |= CM1 + CCIE
 #endif
-  asm("MOV #0004h, P1SEL\n");       // enable TimerA1    (4 cycles)
+  asm("MOV #llo(0x04), %0\n" : "=r" (P1SEL));
   asm("RETI\n");
   asm("delimiter_Value_Is_wrong:\n");
-  asm("BIC #0004h, P1IES\n");
-  asm("MOV #0000h, R5\n");          // bits = 0  (1 cycles)
+  asm("BIC #llo(0x04), %0\n" : "=r" (P1IES));
+  asm("MOV #llo(0), R5\n");          // bits = 0  (1 cycles)
   delimiterNotFound = 1;
   asm("RETI");
   asm("bit_Is_Zero_In_Port_Int:\n");                 // bits == 0
 #if USE_2132
-  asm("MOV #0000h, TA0R\n");     // reset timer (4 cycles)
+  asm("MOV #llo(0), %0\n" : "=r" (TA0R));     // reset timer (4 cycles)
 #else
-  asm("MOV #0000h, TAR\n");     // reset timer (4 cycles)
+  asm("MOV #llo(0), TAR\n");     // reset timer (4 cycles)
 #endif
-  asm("BIS #0004h, P1IES\n");   // 4 cycles  change port interrupt edge to neg
+  asm("BIS #llo(0x04), %0\n" : "=r" (P1IES));   // 4 cycles  change port interrupt edge to neg
   asm("INC R5\n");            // 1 cycle
   asm("RETI\n");
@@ -1965,27 +1991,30 @@
 // Pin Setup :  P1.2
 // Description :
  1. #if USE_2132
  2. #pragma vector=TIMER0_A1_VECTOR

+#ifdef MSP430

+interrupt (TIMER0_A1_VECTOR) TimerA1_ISR (void)
 #else
-#pragma vector=TIMERA1_VECTOR
-#endif
+# if USE_2132
+#  pragma vector=TIMER0_A1_VECTOR
+# else
+#  pragma vector=TIMERA1_VECTOR
+# endif
 __interrupt void TimerA1_ISR(void)   // (6 cycles) to enter interrupt
+#endif
 {
-
-    asm("MOV 0174h, R7");  // move TACCR1 to R7(count) register (3 CYCLES)
+    asm("MOV #llo(0x0174), R7");  // move TACCR1 to R7(count) register (3 CYCLES)
     TAR = 0;               // reset timer (4 cycles)
     TACCTL1 &= ~CCIFG;      // must manually clear interrupt flag (4 cycles)
     //<--------------up to here 26 cycles + 6 cyles of Interrupt == 32 cycles ---------------->
-    asm("CMP #0003h, R5\n");      // if (bits >= 3).  it will do store bits
+    asm("CMP #llo(0x03), R5\n");      // if (bits >= 3).  it will do store bits
     asm("JGE bit_Is_Over_Three\n");
     // bit is not 3
-    asm("CMP #0002h, R5\n");   // if ( bits == 2)
+    asm("CMP #llo(0x02), R5\n");   // if ( bits == 2)
     asm("JEQ bit_Is_Two\n");         // if (bits == 2).
     // <----------------- bit is not 2 ------------------------------->
-    asm("CMP #0001h, R5\n");      // if ( bits == 1). it will measure RTcal value.
+    asm("CMP #llo(0x01), R5\n");      // if ( bits == 1). it will measure RTcal value.
     asm("JEQ bit_Is_One\n");          // bits == 1
     // <-------------------- this is bit == 0 case --------------------->
@@ -1999,7 +2028,7 @@
     asm("bit_Is_One:\n");         // bits == 1.  calculate RTcal value
     asm("MOV R7, R9\n");       // 1 cycle
     asm("RRA R7\n");    // R7(count) is divided by 2.   1 cycle
-    asm("MOV #0FFFFh, R8\n");   // R8(pivot) is set to max value    1 cycle
+    asm("MOV #llo(0xffff), R8\n");   // R8(pivot) is set to max value    1 cycle
     asm("SUB R7, R8\n");        // R8(pivot) = R8(pivot) -R7(count/2) make new R8(pivot) value     1 cycle
     asm("INC R5\n");        // bits++
     asm("CLR R6\n");
@@ -2017,11 +2046,12 @@
     asm("ADDC.b @R4+,-1(R4)\n"); // roll left (emulated by adding to itself == multiply by 2 + carry)
     // R6 lets us know when we have 8 bits, at which point we INC dest*            // (1 cycle)
     asm("INC R6\n");
-    asm("CMP #0008,R6\n\n");   // undo increment of dest* (R4) until we have 8 bits
+    asm("CMP #llo(0x08),R6\n\n");   // undo increment of dest* (R4) until we have 8 bits
+
     asm("JGE out_p\n");
     asm("DEC R4\n");
     asm("out_p:\n");           // decrement R4 if we haven't gotten 16 bits yet  (3 or 4 cycles)
-    asm("BIC #0008h,R6\n");   // when R6=8, this will set R6=0   (1 cycle)
+    asm("BIC #llo(0x08),R6\n");   // when R6=8, this will set R6=0   (1 cycle)
     asm("INC R5\n");
     asm("RETI");
     // <------------------ end of bit 2 ------------------------------>
@@ -2029,7 +2059,7 @@
     asm("this_Is_TRcal:\n");
     asm("MOV R7, R5\n");    // bits = count. use bits(R5) to assign new value of TRcal
     TRcal = bits;       // assign new value     (4 cycles)
-    asm("MOV #0003h, R5\n");      // bits = 3..assign 3 to bits, so it will keep track of current bits    (2 cycles)
+    asm("MOV #llo(0x03), R5\n");      // bits = 3..assign 3 to bits, so it will keep track of current bits    (2 cycles)
     asm("CLR R6\n"); // (1 cycle)
     asm("RETI");
@@ -2040,11 +2070,11 @@
     asm("ADDC.b @R4+,-1(R4)\n"); // roll left (emulated by adding to itself == multiply by 2 + carry)
     // R6 lets us know when we have 8 bits, at which point we INC dest*            // (1 cycle)
     asm("INC R6\n");
-    asm("CMP #0008,R6\n");   // undo increment of dest* (R4) until we have 8 bits
+    asm("CMP #llo(0x08),R6\n");   // undo increment of dest* (R4) until we have 8 bits
     asm("JGE out_p1\n");
     asm("DEC R4\n");
     asm("out_p1:\n");           // decrement R4 if we haven't gotten 16 bits yet  (3 or 4 cycles)
-    asm("BIC #0008h,R6\n");   // when R6=8, this will set R6=0   (1 cycle)
+    asm("BIC #llo(0x08),R6\n");   // when R6=8, this will set R6=0   (1 cycle)
     asm("INC R5\n");              // bits++
     asm("RETI\n");
     // <------------------ end of bit is over 3 ------------------------------>
@@ -2103,23 +2133,23 @@
     //asm("MOV #05h, R14");
     //asm("MOV #02h, R15");
     bits = TRext;       // 6 cycles
-    asm("CMP #0001h, R5");  // 1 cycles
+    asm("CMP #llo(0x01), R5");  // 1 cycles
     asm("JEQ TRextIs_1");   // 2 cycles
-    asm("MOV #0004h, R9");   // 1 cycles
+    asm("MOV #llo(0x04), R9");   // 1 cycles
     asm("JMP otherSetup");   // 2 cycles
     // initialize loop for 16 M/LF
     asm("TRextIs_1:");
-    asm("MOV #000fh, R9");    // 2 cycles    *** this will chagne to right value
+    asm("MOV #llo(0x0f), R9");    // 2 cycles    *** this will chagne to right value
     asm("NOP");
     //
     asm("otherSetup:");
     bits = numOfBits;                // (3 cycles).  This value will be adjusted. if numOfBit is constant, it takes 2 cycles
-    asm("MOV #0bh, R14");     // (2 cycles) R14 is used as timer value 11, it will be 2 us in 6 MHz
-    asm("MOV #05h, R15");      // (2 cycles) R15 is used as tiemr value 5, it will be 1 us in 6 MHz
+    asm("MOV #llo(0x0b), R14");     // (2 cycles) R14 is used as timer value 11, it will be 2 us in 6 MHz
+    asm("MOV #llo(0x05), R15");      // (2 cycles) R15 is used as tiemr value 5, it will be 1 us in 6 MHz
     asm("MOV @R4+, R7");      // (2 cycles) Assign data to R7
-    asm("MOV #0010h, R13");   // (2 cycles) Assign decimal 16 to R13, so it will reduce the 1 cycle from below code
+    asm("MOV #llo(0x10), R13");   // (2 cycles) Assign decimal 16 to R13, so it will reduce the 1 cycle from below code
     asm("MOV R13, R6");       // (1 cycle)
     asm("SWPB R7");           // (1 cycle)    Swap Hi-byte and Low byte
     asm("NOP");
@@ -2142,7 +2172,7 @@
     // if the TRext is 0, there are 4 M/LF.  If the TRext is 1, there are 16 M/LF
     // The upper code executed 1 M/LF, so the count(R9) should be number of M/LF - 1
     //asm("MOV #000fh, R9");    // 2 cycles    *** this will chagne to right value
-    asm("MOV #0001h, R10");   // 1 cycles
+    asm("MOV #llo(0x01), R10");   // 1 cycles
     // The below code will create the number base encoding waveform., so the number of count(R9) should be times of M
     // For example, if M = 2 and TRext are 1(16, the number of count should be 32.
     asm("M_LF_Count:");
@@ -2172,8 +2202,8 @@
     asm("M_LF_Count_End:");
     // this code is preamble for 010111 , but for the loop, it will only send 01011
-    asm("MOV #5c00h, R9");      // 2 cycles
-    asm("MOV #0006h, R10");     // 2 cycles
+    asm("MOV #llo(0x5c00), R9");      // 2 cycles
+    asm("MOV #llo(0x06), R10");     // 2 cycles
     // this should be counted as 0. Therefore, Assembly DEC line should be 1 after executing
     asm("Preamble_Loop:");
     asm("DEC R10");               // 1 cycle
@@ -2183,7 +2213,7 @@
     // this is 1 case for preamble
     asm("NOP");
 #if USE_2132
-    asm("MOV R14, TA0CCR0");       // 4 cycle      .. 10
+    asm("MOV R14, %0" : "=r" (TA0CCR0));       // 4 cycle      .. 10
 #else
     asm("MOV R14, TACCR0");       // 4 cycle      .. 10
 #endif
@@ -2191,7 +2221,7 @@
     asm("NOP");
     asm("NOP");
 #if USE_2132
-    asm("MOV R15, TA0CCR0");       // 4 cycle      .. 19
+    asm("MOV R15, %0" : "=r" (TA0CCR0));       // 4 cycle      .. 19
 #else
     asm("MOV R15, TACCR0");       // 4 cycle      .. 19
 #endif
@@ -2229,7 +2259,7 @@
     asm("NOP");    // TURN ON
     asm("NOP");
 #if USE_2132
-    asm("MOV.B R14, TA0CCR0");// 4 cycles
+    asm("MOV.B R14, %0" : "=r" (TA0CCR0));// 4 cycles
 #else
     asm("MOV.B R14, TACCR0");// 4 cycles
 #endif
@@ -2237,7 +2267,7 @@
     asm("NOP");
     asm("NOP");
 #if USE_2132
-    asm("MOV.B R15, TA0CCR0");
+    asm("MOV.B R15, %0" : "=r" (TA0CCR0));
 #else
     asm("MOV.B R15, TACCR0");
 #endif
@@ -2267,7 +2297,7 @@
     // bit is 1
     asm("bit_is_one:");
 #if USE_2132
-    asm("MOV R14, TA0CCR0");                   // 4 cycles   ..11
+    asm("MOV R14, %0" : "=r" (TA0CCR0));                   // 4 cycles   ..11
 #else
     asm("MOV R14, TACCR0");                   // 4 cycles   ..11
 #endif                // 4 cycles   ..11
@@ -2276,7 +2306,7 @@
     // This code will assign new data from reply and then swap bytes.  After that, update R6 with 16 bits
     //asm("MOV @R4+, R7");
 #if USE_2132
-    asm("MOV R15, TA0CCR0");                   // 4 cycles   .. 20
+    asm("MOV R15, %0" : "=r" (TA0CCR0));                   // 4 cycles   .. 20
 #else
     asm("MOV R15, TACCR0");                   // 4 cycles   .. 20
 #endif
@@ -2292,7 +2322,7 @@
     asm("seq_zero:");
     asm("NOP");                         // 1 cycle   .. 3
 #if USE_2132
-    asm("MOV R15, TA0CCR0");         // 4 cycles       ..7
+    asm("MOV R15, %0" : "=r" (TA0CCR0));         // 4 cycles       ..7
 #else
     asm("MOV R15, TACCR0");         // 4 cycles       ..7
 #endif
@@ -2313,7 +2343,7 @@
     asm("JC nextBitIs1");            // 2 cycles  .. 20
     // bit is 0
 #if USE_2132
-    asm("MOV R14, TA0CCR0");             // 4 cycles  .. 24
+    asm("MOV R14, %0" : "=r" (TA0CCR0));             // 4 cycles  .. 24
 #else
     asm("MOV R14, TACCR0");             // 4 cycles  .. 24
 #endif
@@ -2331,7 +2361,7 @@
     asm("RLC R7");                        // 1 cycle     .. 18
     asm("JC nextBitIs1");                // 2 cycles    ..20
 #if USE_2132
-    asm("MOV R14, TA0CCR0");               // 4 cycles   .. 24
+    asm("MOV R14, %0" : "=r" (TA0CCR0));               // 4 cycles   .. 24
 #else
     asm("MOV R14, TACCR0");               // 4 cycles   .. 24
 #endif
@@ -2354,7 +2384,7 @@
     asm("bit_Count_Is_Not_16:");       // up to here 14
     asm("NOP");
 #if USE_2132
-    asm("MOV R15, TA0CCR0");             // 4 cycles   .. 20
+    asm("MOV R15, %0" : "=r" (TA0CCR0));             // 4 cycles   .. 20
 #else
     asm("MOV R15, TACCR0");             // 4 cycles   .. 20
 #endif
@@ -2391,7 +2421,7 @@
     asm("NOP");
     asm("NOP");
 #if USE_2132
-    asm("MOV.B R14, TA0CCR0");// 4 cycles
+    asm("MOV.B R14, %0" : "=r" (TA0CCR0));// 4 cycles
 #else
     asm("MOV.B R14, TACCR0");// 4 cycles
 #endif
@@ -2399,7 +2429,7 @@
     asm("NOP");
     asm("NOP");
 #if USE_2132
-    asm("MOV.B R15, TA0CCR0");
+    asm("MOV.B R15, %0" : "=r" (TA0CCR0));
 #else
     asm("MOV.B R15, TACCR0");
 #endif
@@ -2480,11 +2510,11 @@
   readReplyCRC = crc16_ccitt(&readReply[0], numDataBytes + 2);
   readReply[numDataBytes + 4] = readReply[numDataBytes + 2];
   // XOR the MSB of CRC with loner bit.
-  readReply[numDataBytes + 4] ^= __swap_bytes(readReplyCRC); // XOR happens with MSB of lower nibble
+  readReply[numDataBytes + 4] ^= (readReplyCRC >> 8); // XOR happens with MSB of lower nibble
   // Just take the resulting bit, not the whole byte
   readReply[numDataBytes + 4] &= 0x80;
  1. unsigned short mask = swap_bytes(readReply[numDataBytes + 4]); + unsigned short mask = (readReply[numDataBytes + 4] » 8); mask »= 3; mask |= (mask » 7); mask ^= 0x1020; @@ -2493,7 +2523,7 @@ readReplyCRC ^= mask; readReply[numDataBytes + 3] = (unsigned char) readReplyCRC; - readReply[numDataBytes + 2] |= (unsigned char) (swap_bytes(readReplyCRC) & 0x7F);

+ readReply[numDataBytes + 2] |= (unsigned char) ((readReplyCRC » 8) & 0x7F);

 }
 #if 0



**Step4: Debugging**


After applying the patch, everything should compile and build successfully! You are now ready to download the firmware to the WISP and start debugging. To do so, simply proceed as follows:

  1. Run the 'mspdebug gdb loop' external tool
  2. Then, press the 'Debug' button in the eclipse toolbar, and it will start a debug session where you can break, step in/out, etc.





Other Resources

1)
aligned(2
2)
LPM4_bits) | (GIE
programming_the_wisp_under_linux.txt · Last modified: 2018/07/11 08:25 (external edit)