Migrating to BoostC from mikroC

Discussion in 'Embedded Systems and Microcontrollers' started by T.Jackson, Dec 5, 2011.

  1. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    I am looking for some help with migrating from mikroC to BoostC. If some experts out there can help me translate the following code portion below into BoostC I would really appreciate it.

    Code ( (Unknown Language)):
    1.  
    2. /*
    3.  * PROJECT:
    4.       DIY Keypad-based car engine security system ...
    5.       Copyright ©2010 Trent Jackson all rights reserved
    6.  
    7.  * MCU:
    8.       PIC16F628a @4MHz
    9. */
    10.  
    11. // :: Global scope variables :: //
    12.  
    13. unsigned short scan = 0;
    14. unsigned short userCode[6];
    15. unsigned short user[6];
    16. unsigned short keyDown = 0;
    17. unsigned short active = 1;
    18. unsigned short tmrLED = 0;
    19. unsigned short progMode = 0;
    20. unsigned short codeCorrect = 0;
    21. unsigned short hashPressed = 0;
    22. unsigned short ukeyPointer = 0;
    23. unsigned short Pinattempts = 0;
    24. unsigned short i = 0;
    25. unsigned short j = 0;
    26.  
    27. unsigned int timeout = 0;
    28. unsigned int tmrIgnit = 0;
    29.  
    30. // :: Defines :: //
    31.  
    32. // Keypad rows ...
    33. #define rowA PORTB.F0
    34. #define rowB PORTB.F1
    35. #define rowC PORTB.F2
    36. #define rowD PORTB.F3
    37.  
    38. // Keypad columns
    39. #define colA PORTB.F4
    40. #define colB PORTB.F5
    41. #define colC PORTB.F6
    42.  
    43. // LEDs ...
    44. #define LEDa PORTA.F3
    45. #define LEDb PORTB.F7
    46.  
    47. // Relays
    48. #define relayA PORTA.F0
    49. #define relayB PORTA.F1
    50.  
    51. // Ignition
    52. #define ignit PORTA.F4
    53.  
    54. void interrupt()
    55. {
    56.   tmrLED++;
    57.   tmrIgnit++;
    58.   TMR0   = 96;
    59.   INTCON = 0x20;
    60. }
    61.  
    62. void flashLEDa()
    63. {
    64.    LEDa = ~LEDa;
    65. }
    66.  
    67. void flashLEDb()
    68. {
    69.    LEDb = ~LEDb;
    70. }
    71.  
    72. void playValidSND()
    73. {
    74.    for (i = 0; i < 5; i++)
    75.    {
    76.       Sound_Play(2000, 25);
    77.       Delay_ms(100);
    78.    }
    79. }
    80.  
    81. void playErrorSND()
    82. {
    83.    for (i = 0; i < 5; i++)
    84.    {
    85.       Sound_Play(250, 50);
    86.       Delay_ms(100);
    87.    }
    88. }
    89.  
    90. void rstUser()
    91. {
    92.    ukeyPointer = 0;
    93.    codeCorrect = 0;
    94.    hashPressed = 0;
    95.  
    96.    for (i = 0; i < 5; i++)
    97.    {
    98.       user[i] = 255;
    99.    }
    100. }
    101.  
    102. unsigned short getKey()
    103. {
    104. /*
    105.                       :: Multiplex 4x3 keypad function ::
    106.  
    107.    1. Cycle through rows and check for corresponding column being set ...
    108.    2. Return the key if col is set (active high)
    109.    3. Protocol implementation(s) / limitation(s):
    110.  
    111.                                     a. No simultaneous key sequences
    112.                                     b. Key detect on release ...
    113.                                     c. Very responsive with zero bounce
    114. */
    115.       switch (scan)
    116.       {
    117.          case 0: // :: First col (1, 4, 7, *) :: //
    118.  
    119.             // Set cols
    120.             colA = 1;
    121.             colB = 0;
    122.             colC = 0;
    123.  
    124.             // 5mS delay allow port to settle
    125.             Delay_ms(5);
    126.  
    127.             // Check for button press ...
    128.             if (rowA == 1)
    129.             {
    130.                return  1;
    131.             }
    132.             else if (rowB == 1)
    133.             {
    134.                return  4;
    135.             }
    136.             else if (rowC == 1)
    137.             {
    138.                return  7;
    139.             }
    140.             else if (rowD == 1)
    141.             {
    142.                return  54;
    143.             }
    144.             break;
    145.  
    146.          case 1:
    147.  
    148.             // Set cols
    149.             colA = 0;
    150.             colB = 1;
    151.             colC = 0;
    152.  
    153.             // 5mS delay allow port to settle
    154.             Delay_ms(5);
    155.  
    156.             // Check for button press ...
    157.             if (rowA == 1)
    158.             {
    159.                return  2;
    160.             }
    161.             else if (rowB == 1)
    162.             {
    163.                return  5;
    164.             }
    165.             else if (rowC == 1)
    166.             {
    167.                return  8;
    168.             }
    169.             else if (rowD == 1)
    170.             {
    171.                return  0;
    172.             }
    173.             break;
    174.  
    175.          case 2:
    176.  
    177.             // Set cols
    178.             colA = 0;
    179.             colB = 0;
    180.             colC = 1;
    181.  
    182.             // 5mS delay allow port to settle
    183.             Delay_ms(5);
    184.  
    185.             // Check for button press ...
    186.             if (rowA == 1)
    187.             {
    188.                return  3;
    189.             }
    190.             else if (rowB == 1)
    191.             {
    192.                return  6;
    193.             }
    194.             else if (rowC == 1)
    195.             {
    196.                return  9;
    197.             }
    198.             else if (rowD == 1)
    199.             {
    200.                return  55;
    201.             }
    202.             break;
    203.  
    204.  
    205.       }
    206.  
    207.    // Inc to next col ...
    208.    scan ++;
    209.  
    210.    // Reset after last row
    211.    if (scan == 3)
    212.    {
    213.       scan = 0;
    214.    }
    215.  
    216.    // Nothing pressed, 255 denotes this
    217.    return 255;
    218. }
    219. [/i]


    Cont ...
     
  2. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    Code ( (Unknown Language)):
    1.  
    2.  
    3. void main()
    4. {
    5.   CMCON = 7;          // Disable analog comparators
    6.   OPTION_REG = 0x84;  // Assign prescaler to TMR0
    7.   TMR0  = 96;         // Timer0 initial value
    8.   INTCON = 0xA0;      // Enable TMRO interrupt
    9.   TRISA = 0x10;       // PortA as output ...
    10.   PORTA = 0x00;       // Init port, all pins low
    11.   TRISB = 0x0F;       // 4 inputs & 4 outputs
    12.  
    13.   // Using snd lib for short beep on key press
    14.   //Sound_Init(&PORTA, 2);
    15.  
    16.   // Leds both off
    17.   LEDa = 0;
    18.   LEDb = 0;
    19.  
    20.   // Relays off
    21.   relayA = 0;
    22.   relayB = 0;
    23.  
    24.   // Cols off ...
    25.   colA = 0;
    26.   colB = 0;
    27.   colC = 0;
    28.  
    29.   // Null user vars
    30.   rstUser();
    31.  
    32.   // Fetch 4-digit code from EEPROM
    33.   for (i = 0; i < 4; i++)
    34.   {
    35.      Delay_ms(50);
    36.      userCode[i] = EEPROM_Read(i);
    37.   }
    38.  
    39.   // Load default code
    40.   if(userCode[0] == 0xFF)
    41.   {
    42.      userCode[0] = 1;
    43.      userCode[1] = 2;
    44.      userCode[2] = 4;
    45.      userCode[3] = 8;
    46.   }
    47.  
    48.   // :: Infinite program loop :: //
    49.  
    50.   while(1)
    51.   {
    52.       // :: Armed flash red deterrent led @~2Hz :: //
    53.      
    54.       if (pinAttempts < 3)
    55.       {
    56.          if (active == 1)
    57.          {
    58.             if (tmrLED >= 100)
    59.             {
    60.                flashLEDa();
    61.                tmrLED = 0;
    62.             }
    63.          }
    64.          else // Not armed
    65.          {
    66.             if (progMode == 1)
    67.             {
    68.                if (tmrLED >= 100)
    69.                {
    70.                   flashLEDb();
    71.                   tmrLED = 0;
    72.                }
    73.             }
    74.             else if (ignit == 1)
    75.             {
    76.                LEDb = 1;
    77.                relayA = 1;
    78.                relayB = 1;
    79.                tmrIgnit = 0;
    80.             }
    81.             else // Grn led + rlys off when no ignition
    82.             {
    83.                if (tmrIgnit == 1000)
    84.                {
    85.                   LEDb = 0;
    86.                   relayA = 0;
    87.                   relayB = 0;
    88.                   tmrIgnit = 0;
    89.                }
    90.             }
    91.          }
    92.      
    93.          // :: Fetch keys :: //
    94.    
    95.          if (keyDown != 1)
    96.          {
    97.             user[ukeyPointer] = getKey();
    98.  
    99.             if(user[ukeyPointer] != 255)
    100.             {
    101.                // Flag set ...
    102.                keyDown = 1;
    103.            
    104.                // Play tone
    105.                Sound_Play(888, 25);
    106.            
    107.                // 50mS debounce
    108.                Delay_ms(50);
    109.            
    110.                // Inc pos in array
    111.                ukeyPointer++;
    112.  
    113.                // Reset after 5 keys
    114.                if (ukeyPointer == 5)
    115.                {
    116.                   ukeyPointer = 0;
    117.                }
    118.             }
    119.          }
    120.          else // Wait for key release
    121.          {
    122.             if (rowA == 0)
    123.             {
    124.                if (rowB == 0)
    125.                {
    126.                   if (rowC == 0)
    127.                   {
    128.                      if (rowD == 0)
    129.                      {
    130.                         // Flag off ...
    131.                         keyDown = 0;
    132.                      }
    133.                   }
    134.                }
    135.             }
    136.          }
    137.      
    138.          // :: See if user has entered in the right pin :: //
    139.      
    140.          if(user[0] == userCode[0])
    141.          {
    142.             if(user[1] == userCode[1])
    143.             {
    144.                if(user[2] == userCode[2])
    145.                {
    146.                   if(user[3] == userCode[3])
    147.                   {
    148.                      codeCorrect = 1;
    149.                      pinAttempts = 0;
    150.                   }
    151.                }
    152.             }
    153.          }
    154.  
    155.          // :: Detect if hash key has been pressed :: //
    156.  
    157.          for (i = 0; i < 5; i++)
    158.          {
    159.             if (user[i] == 55)
    160.             {
    161.                hashPressed = 1;
    162.                break;
    163.             }
    164.          }
    165.      
    166.          // :: Hash to arm / disarm system :: //
    167.      
    168.          if (progMode == 0)
    169.          {
    170.             if (hashPressed == 1)
    171.             {
    172.                if (active == 1)
    173.                {
    174.                   if (codeCorrect == 1)
    175.                   {
    176.                      LEDa = 0;
    177.                      active = 0;
    178.                      playValidSND();
    179.                   }
    180.                   else
    181.                   {
    182.                      playErrorSND();
    183.                      pinAttempts ++;
    184.                   }
    185.                }
    186.                else // ARM if vehicle ignition is off
    187.                {
    188.                   if (ignit != 1)
    189.                   {
    190.                      LEDb = 0;
    191.                      active = 1;
    192.                      relayA = 0;
    193.                      relayB = 0;
    194.                   }
    195.                }
    196.                rstUser();
    197.             }
    198.  
    199.             // :: Star key after entering in pin to set new pin :: //
    200.      
    201.             else if (user[4] == 54)
    202.             {
    203.                if (codeCorrect == 1)
    204.                {
    205.                   if (active == 0)
    206.                   {
    207.                      if (ignit == 1)
    208.                      {
    209.                         progMode = 1;
    210.                      }
    211.                   }
    212.                }
    213.                else
    214.                {
    215.                   pinAttempts ++;
    216.                }
    217.                rstUser();
    218.             }
    219.          }
    220.          else  // :: User is programming in an new pin code :: //
    221.          {
    222.             if (ukeyPointer == 4)
    223.             {
    224.          
    225.                // Save code to eeprom ...
    226.                for (i = 0; i < 4; i++)
    227.                {
    228.                   userCode[i] = user[i];
    229.                   EEPROM_Write(i, userCode[i]);
    230.                   Delay_ms(20);
    231.                }
    232.            
    233.                // Reset & bail
    234.                progMode = 0;
    235.                rstUser();
    236.             }
    237.          }
    238.       }
    239.       else // 3 incorrect pin attempts in a row (lock out system for a few mins)
    240.       {
    241.      
    242.          if (timeout == 0)
    243.          {
    244.             LEDa = 0;
    245.             LEDb = 0;
    246.          }
    247.          
    248.          if (timeout < 50)
    249.          {
    250.             playErrorSND();
    251.             flashLEDa();
    252.             flashLEDb();
    253.             timeout ++;
    254.          }
    255.          else
    256.          {
    257.             timeout = 0;
    258.             pinAttempts = 0;
    259.             LEDa = 0;
    260.             LEDb = 0;
    261.          }
    262.       }
    263.    }
    264. }
    265. [/i][/i][/i][/i][/i]
     
  3. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Change your PORTA.3 to porta.3 (basically all ports are lowercase) for all your port aliases. All the port names and special names are lower case.

    delay_ms() is lowercase, only accepts up to 255 mS delay, differs on capitalized first letter in Mikro

    Unsure on EEPROM Read/Setup, that's a bit different, but the rest is ANSI C, so it ports over well.

    The PDF Manual and examples that come with it cover just about everything, i2c, LCD, EEPROM, etc.

    example:
    Code ( (Unknown Language)):
    1.  
    2.     //Configure port B
    3.     trisb = 0x0F;
    4.     //Configure port C
    5.     trisc = 0x00;
    6.    
    7.     //Initialize port B
    8.     portb = 0x00;
    9.     //Initialize port C
    10.     portc = 0x00;
    11.    
    12.     osccon=0x70;  // 8Mhz Internal Oscillator
    13.     cm1con0 = 0x70; //disable comparators
    14.     cm2con0 = 0x70; // both of em
    15.     ansel=0x0; // Disable ADC
    16.     anselh=0x0; // All 12 of them
    17.  
     
  4. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    Much appreciated.

    Can you check one more for me?
     
  5. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    post the code, though I can tell you ahead of time that most functions are the same, just with lower case, and the special function/port names are the same, just lower case

    LCD and EEPROM commands are slightly different.

    I do wish they'd come up with "standard" standard libraries for uC compilers.
     
  6. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    Any tips that you can offer with BoostC?

    Can I time code in it like I can do with mikroC, which has a stopwatch with a uS readout?
     
  7. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    There is a profiler in the debugger that lets you see what takes how many ticks after writing, as well as how much time each function takes, etc.

    The time a function can take varies based on what the inputs are. For fastest running use unsigned char for values 0-255 instead of unsigned int.

    Avoid using signed math anywhere (negative numbers) if you can avoid it. (declare everything unsigned, and as short as possible)

    Don't do much inside interrupts other than set variables that will be worked on in the main loop, only do high priority stuff in the interrupt() routine.
     
  8. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    Thanks for the advice.

    Question: I just changed all of my variables to unsigned char in my composite video program and did a time test. I am still getting the same times from point a to point b.
     
  9. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Compilers with optimization turned on will switch for you, but in the eval versions of some (HiTech is one), they disable all optimizations.

    Boost C and Mikro C only disable advanced optimizations, they just put a code limit in. For the price, BoostC can't be beat at $50 for a full compiler with RealTimeOS libraries, which might be useful in your project, assign the redraw to the highest priority task, and in another task do your other stuff. Goto http://www.sourceboost.com/Products/NovoRtos/Overview.html for an idea. You get a limited version of the RTOS with the $49 Full/no limit license of the compiler (assuming you don't use it for commercial gain). If used for commercial gain, then the full price applies, which you should be able to afford if using it commercially.

    Use a PIC that can have INTOSC PLL'd to 32 or 48Mhz, and you'd have plenty of power for a pong game and maybe even an NTSC color test at low res.
     
  10. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    Is HiTech C worth the money? Like as in the enterprise Ed @ USD 3K.
     
  11. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Not right now. It doesn't really offer much of anything over Boost C dollar for dollar.

    Microchip has acquired them, so the new compiler coming out may be a good deal cheaper, they may be realizing they are losing a lot in the marketplace due to Arduino and actually make a decent compiler for low cost, but who knows.
     
  12. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    I came close to laying down a deposit on one that I saw on ebay. Two grand with a few hundred deposit would have put it on hold for me.

    My gut told me no though.
     
  13. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    There is a gcc for PICs, but it doesn't support many controllers, has limited libraries, and the rest of the issues that go with early projects.

    gcc for AVR was built up by the huge user group the Arduino brought in. Hopefully, the PIC gcc will get more of a boost, it has at least on the 16/32/dsp side, just not the 8 bit side.

    All the major companies that use PIC in the business have pretty much already purchased their compilers, so now it is down to hobbyists, which is a numerically large group, provided the price point is right. Boost C is at the limit of the price point for most, even the free version isn't very limited, not many people make projects that need over 2k of code, a good number of common PICs don't even have 2k of storage.

    The simulator with plugin pack is very good, not ISIS level, but very good and accurate, meaning, if it doesn't work in the sim, it isn't going to work on the board.
     
  14. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    I agree that 2K is a lot if you half know what you're doing and have a valid project. Of course 2K of flash memory won't last long if all you're set out to do is display different texts on an LCD.
     
  15. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    How slow is it to read in data that is stored in flash and load it into an array that's in ram?

    I figure that with my monochrome video project I will have at least 1K of memory remaining, so wondering about the possibility of storing some ascii characters in flash.
     
  16. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Reading Flash/Program Memory is very quick, basically standard clock speed to print out a block of data declared in code, move character to w, print w, repeat, so it will go fairly quickly. On Enhanced Midrange PIC16 series(16F1827, 16F690) and the 18F series, the process is single cycle, as the data doesn't need to traverse through w.

    If you are storing it in EEPROM onbaord, it's a bit slower, but not crippling slow. Fetching data from on-chip EEPROM is single instruction after 5 instruction setup (8 instructions per word/2 bytes of EEPROM to RAM)

    Writing back to program memory (PIC18 series and Enhanced Midrange PIC16 series) is slower. But if you wanted to change what the strings in firm coded memory were, it's possible.

    Enhanced Mid Range PIC16 and PIC18 have:
    • C Compiler Optimized Architecture
    • Up to 8 Kbytes Linear Program Memory Addressing
    • Linear Data Random Access Memory Addressing
    • Interrupt Capability with Automatic Context Saving
    • Direct, Indirect and Relative Addressing modes:
    - Two full 16-bit File Select Registers (FSRs)
    - FSRs can read program and data memory
     
    Last edited: Dec 6, 2011
  17. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    Can you elaborate on this one?

    You're a salesman working for Microchip right?
     
  18. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    I just copied and pasted from a datasheet

    But that one is detailed in the next few.

    Pointers allowed, "flat" memory access, etc. All are inherent methods of C programs to handle data, passing by reference, reading until NULL from pointer with destination RAM or another indirect pointer.

    No excessive bank switching to read more data like the other PIC10/12/16 series, and w can contain a pointer to another memory address that is to be used, rather than needing to contain the value itself.
     
  19. T.Jackson

    Thread Starter New Member

    Nov 22, 2011
    328
    14
    So it's not just a sale's pitch like everything else?

    It's genuine?
     
  20. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Three of the major hardware improvements/peripherals that weren't brought "back down" from PIC18 to PIC16E are the 8x8 hardware multiply, 12 bit ADC, or USB, though it's made up for by ECCP PWM, programmable Bandgap Vref, and the other features listed above.

    Otherwise, the major differences between PIC18 and PIC16 were the "Sticking points" of memory access listed above, so Microchip added them and made the PIC16E Enhanced Mid Range Microcontroller. The PIC 16F1827 is a great example of an 18 pin PIC with more peripherals than pins. Great "general purpose" uC, as long as you don't need USB, it has everything but the kitchen sink built in. Sample some now, 3 for free through microchipdirect.com if you have a business, or are a dedicated hobbyist with a business name and address. Samples take about a month to arrive, and most are SMD, but there are through hole available on their newer releases, such as the 1827

    The complete compare Checklist for PIC10 Baseline to PIC18 High performance 8 bit uCs, including what "Enhanced Mid-Range" is is on Page 3 of the Summer 2010 8 Bit Microcontroller Brochure
     
    Last edited: Dec 6, 2011
Loading...