// Built with BFTC Rev. 1.0.0, lun 25 agosto 2014 09:37:35

 

/*

    Copyright 2014 Digital Technology Art SRL

    This file is part of Blackfin Toolchain (BFTC) project.

 

    BFTC is free software: you can redistribute it and/or modify

    it under the terms of the GNU General Public License as published by

    the Free Software Foundation, either version 3 of the License, or

    (at your option) any later version.

 

    BFTC is distributed in the hope that it will be useful,

    but WITHOUT ANY WARRANTY; without even the implied warranty of

    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

    GNU General Public License for more details.

 

    You should have received a copy of the GNU General Public License

    along with Nome-Programma.  If not, see <http://www.gnu.org/licenses/>.

*/

 

// In this very little example we show how to implement a servo controller

// with 8 outputs.

// Each output have a minimum step of 10us

// With this step a range of 10000 positions is settable, also for the servo?

//

#include "main.h"

 

#include <string.h>

 

// Default PWM values for each output

unsigned pwm[8];

// With the value of 1.0ms = 100 * 10us, The servo is positioned to the extreme left.

// With the value of 2.0ms = 200 * 10us, The servo is positioned to the extreme right.

// With the value of 1.5ms = 150 * 10us, The servo is centered.

unsigned pwmPreset[8] = { 150, 150, 150, 150, 150, 150, 150, 150 };

unsigned char portMask[8] = { PG0, PG1, PG2, PG3, PG4, PG5, PG6, PG7 };

 

// This procedure is called every 20ms and start PWM activity

// on each output

void callBack20ms()

{

    *pPORTGIO = 0xFF;

    memcpy(pwm, pwmPreset, sizeof(unsigned) * 8);

   // Enable PWM countdown

   Set_TimerEnable(TIMER_1, true);

}

 

void callBackPwm()

{

   int     i, a = 0;

   for(i = 0; i < 8; i++)

   {

       if(pwm[i])

           pwm[i]--;

       // Clear related bit if countdown is 0

       else *pPORTGIO_CLEAR = portMask[i];

       // Check the end of all counts

       a += pwm[i];

   }

   // If no more countdown disable the interrupt

   if(!a) Set_TimerEnable(TIMER_1, false);

}

 

unsigned char CommandMenu()

{

   printf("\n");

   printf("COMMANDS ******************\n");

   printf("1-8 Select PWM output\n");

   printf("+   Increment the value of the selected output (100us)\n");

   printf("-   Increment the value of the selected output (100us)\n");

   printf("> ");

   return GetChar_Uart0();;

}

int main(void)

{

   int     pwmSel = 0, com;

    Set_PLL(16, 4);     // CORE: 25MHz * 16 = 400MHz, SCLK: 400MHz / 4 = 100MHz

    Set_Port();         // Set the port according to project set

    Set_Uart0(115200);  // printf is redirected to UART0

   

    // Timer generate an interrupt every 20ms

    Set_TimerInterruptService(TIMER_0, &callBack20ms, 20000);

    Set_TimerEnable(TIMER_0, true);

   // Timer generate an interrupt every 10us

   Set_TimerInterruptService(TIMER_1, &callBackPwm, 10);

   

    while(1)            // Main loop

    {

       com = CommandMenu();

       switch(com)

       {

           // Change the output to be controlled

           case '1': case '2': case '3': case '4':

           case '5': case '6': case '7': case '8':

               pwmSel = com - '1';

               break;

           case '+':

               // Add an increment of 100us

               pwmPreset[pwmSel] += 10;

               break;

           case '-':

               // Decrement by 100us

               pwmPreset[pwmSel] -= 10;

               break;

       }

    }

    return 0;

}