Official library for the FRDM-TFC shield

Dependents:   TFC-TEST TFC-RACING-DEMO TFC-RACING-DEMO TFC-RACING-FSLMENTORMATTERS ... more

Overview

This library is an example driver for the FRDM-TFC shield that can be used for with MBED compiler. Documentation for the hardware can be found here

https://community.freescale.com/docs/DOC-93914

Note that the current videos on that page pertain to the codewarrior example projects hosted on google code, not the library presented here. While the code is very similiar, there are some differences. New videos will be posted for the MBED libraries as the code bases will eventually merge

Also note that this is just the raw library. The example program that uses the code is here:

http://mbed.org/users/redxeth/code/TFC-TEST/

IMPORTANT

There is a bug with firmware "mbed_if_v2.0_frdm_kl25Z ". It seems to hold the I/O pin PORTC1 (FTM0 - Channel 0 on J10 Pin 12) high. This prevents the PWM signal for one of the motor drivers from working correctly.

Page 4 of the FRDM-LK25Z board shows the OpenSDA connected to this net via resistor R24. Remove this resistor on your freedom board.

This was verified to be in the SDA firmware as the debug firmware used for Codewarrior use (DEBUG-APP_Pemicro_v102.SDA) does not have this issue.

Example Main.cpp

#include "mbed.h"
#include "TFC.h"

 
//This macro is to maintain compatibility with Codewarrior version of the sample.   This version uses the MBED libraries for serial port access
Serial PC(USBTX,USBRX);

#define TERMINAL_PRINTF     PC.printf

 
 //This ticker code is used to maintain compability with the Codewarrior version of the sample.   This code uses an MBED Ticker for background timing.
 
#define NUM_TFC_TICKERS 4

Ticker TFC_TickerObj;
 
volatile uint32_t TFC_Ticker[NUM_TFC_TICKERS];
 
void TFC_TickerUpdate()
{
    int i;
 
    for(i=0; i<NUM_TFC_TICKERS; i++)
     {
        if(TFC_Ticker[i]<0xFFFFFFFF) 
        {
            TFC_Ticker[i]++;
        }
    }
}
 
 
int main()
{
    uint32_t i,t = 0;
  
    PC.baud(115200);
    TFC_TickerObj.attach_us(&TFC_TickerUpdate,2000);
   
    TFC_Init();
    
    for(;;)
    {      
        //TFC_Task must be called in your main loop.  This keeps certain processing happy (I.E. Serial port queue check)
         //   TFC_Task();

            //This Demo program will look at the middle 2 switch to select one of 4 demo modes.
            //Let's look at the middle 2 switches
            switch((TFC_GetDIP_Switch()>>1)&0x03)
            {
            default:
            case 0 :
                //Demo mode 0 just tests the switches and LED's
                if(TFC_PUSH_BUTTON_0_PRESSED)
                    TFC_BAT_LED0_ON;
                else
                    TFC_BAT_LED0_OFF;
                
                if(TFC_PUSH_BUTTON_1_PRESSED)
                    TFC_BAT_LED3_ON;
                else
                    TFC_BAT_LED3_OFF;
                
                
                if(TFC_GetDIP_Switch()&0x01)
                    TFC_BAT_LED1_ON;
                else
                    TFC_BAT_LED1_OFF;
                
                if(TFC_GetDIP_Switch()&0x08)
                    TFC_BAT_LED2_ON;
                else
                    TFC_BAT_LED2_OFF;
                
                break;
                    
            case 1:
                
                //Demo mode 1 will just move the servos with the on-board potentiometers
                if(TFC_Ticker[0]>=20)
                {
                    TFC_Ticker[0] = 0; //reset the Ticker
                    //Every 20 mSeconds, update the Servos
                    TFC_SetServo(0,TFC_ReadPot(0));
                    TFC_SetServo(1,TFC_ReadPot(1));
                }
                //Let's put a pattern on the LEDs
                if(TFC_Ticker[1] >= 125)
                {
                    TFC_Ticker[1] = 0;
                    t++;
                    if(t>4)
                    {
                        t=0;
                    }           
                    TFC_SetBatteryLED_Level(t);
                }
                
                TFC_SetMotorPWM(0,0); //Make sure motors are off
                TFC_HBRIDGE_DISABLE;
            

                break;
                
            case 2 :
                
                //Demo Mode 2 will use the Pots to make the motors move
                TFC_HBRIDGE_ENABLE;
               
                TFC_SetMotorPWM(TFC_ReadPot(0),TFC_ReadPot(1));
                
                        
                //Let's put a pattern on the LEDs
                if(TFC_Ticker[1] >= 125)
                    {
                        TFC_Ticker[1] = 0;
                            t++;
                            if(t>4)
                            {
                                t=0;
                            }           
                        TFC_SetBatteryLED_Level(t);
                    }
                break;
            
            case 3 :
            
         
                //Demo Mode 3 will be in Freescale Garage Mode.  It will beam data from the Camera to the 
                //Labview Application
                
                
                if(TFC_Ticker[0]>50 && TFC_LineScanImageReady>0)
                    {
                     TFC_Ticker[0] = 0;
                     TFC_LineScanImageReady=0;
                     TERMINAL_PRINTF("\r\n");
                     TERMINAL_PRINTF("L:");
                     
                        if(t==0)
                            t=4;
                        else
                            t--;
                        
                         TFC_SetBatteryLED_Level(t);
                        
                         // camera 1
                         for(i=0;i<128;i++)
                         {
                               TERMINAL_PRINTF("%X,",TFC_LineScanImage0[i]);
                         }
                        
                        // camera 2
                         for(i=0;i<128;i++)
                         {
                                 if(i==127)
                                     TERMINAL_PRINTF("%X\r\n",TFC_LineScanImage1[i]);
                                 else
                                     TERMINAL_PRINTF("%X,",TFC_LineScanImage1[i]);
                           
                         }
                    }
                 
                break;
            }
    }
    
 
}

Implementation Notes

The goal of the this library was to provide an easy to use API for the FRDM-TFC hardware that would give one a good start in getting a car working. There are only a couple of function calls needed to make the components on the care work. The library is implemented as a standard C API. While most of the MBED code is provided as a C++, the decision to use a C only API was done for the following reasons:

  • Some of the advantages of a C++ class really don't apply in this case. Since there would only be a single instance of the class library, there is no reason to wrap the functions in a class.
  • The library tightly integrated to synchronized different components in the interrupts routines. I.E. Camera acquisition is synced to the servo period. To accomplished this we had to write the code in raw C and write our own interrupt routines. Tieing these to a c++ class really didn't make sense.
  • Since many users also use an "offline" compiler, (I.E. Codewarrior) it was a design requirement that the the same code/API could be easy moved to the Codewarrior environment.
  • Even though the MBED libraries provide classes for PWM that could be used for the servos and drive motor controller, we had to write our own code for the internal TPM units as we needed some special features (Different switching frequency on certain channels) that could not be accomplished with the libraries. This is transparent to the end user.

The library uses a number of of resources on the Freedom board. The list below show what the library uses. The user should not use the MBED libraries to talk to those ports/peripherals.

I/O: -

  • PTB0 (Servo Channel 0 - TPM1)
  • PTB1 (Servo Channel 1 - TPM1)
  • PTB8 (Battery LED0)
  • PTB9 (Battery LED1)
  • PTB10 (Battery LED2)
  • PTB11 (Battery LED3)
  • PTD7 (Camera SI)
  • PTE0 (Camera CLK)
  • PTD5 (Camera A0 - ADC_SE6b)
  • PTD6 (Camera A1 - ADC_SE7b)
  • PTE2 DIP Switch 0
  • PTE3 DIP Switch 1
  • PTE4 DIP Switch 2
  • PTE5 DIP Switch 3
  • PTC13 Pushbutton SW1
  • PTC17 Pushbutton SW2
  • PTC3 H-Bridge A - 1 FTM0_CH3
  • PTC4 H-Bridge A - 2 FTM0_CH4
  • PTC1 H-Bridge B - 1 FTM0_CH1
  • PTC2 H-Bridge B - 2 FTM0_CH2
  • PTE21 H-Bridge Enable
  • PTE20 H-Bridge Fault
  • PTE23 H-Bridge A - IFB
  • PTE22 H-Bridge B - IFB

Files at this revision

API Documentation at this revision

Comitter:
emh203
Date:
Thu Feb 11 14:58:08 2016 +0000
Parent:
5:9fd02d06973b
Commit message:
removed the old mbed library and main.cpp to make integration easier

Changed in this revision

TFC.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show diff for this revision Revisions of this file
mbed.bld Show diff for this revision Revisions of this file
diff -r 9fd02d06973b -r 24430a0d7fd8 TFC.cpp
--- a/TFC.cpp	Mon Mar 17 14:10:28 2014 +0000
+++ b/TFC.cpp	Thu Feb 11 14:58:08 2016 +0000
@@ -4,8 +4,8 @@
 #define FTM1_CLK_PRESCALE                                                            6// Prescale Selector value - see comments in Status Control (SC) section for more details
 #define SERVO_DEFAULT_PERIOD                                                   (float)(.020)   // Desired Frequency of PWM Signal - Here 50Hz => 20ms period
 // use these to dial in servo steering to your particular servo
-#define SERVO_MIN_PULSE_WIDTH_DEFAULT                                          (float)(.0005)  // The number here should be be *pulse width* in seconds to move servo to its left limit
-#define SERVO_MAX_PULSE_WIDTH_DEFAULT                                          (float)(.002)  // The number here should be be *pulse width* in seconds to move servo to its left limit 
+#define SERVO_MIN_PULSE_WIDTH_DEFAULT                                          (float)(.00095)  // The number here should be be *pulse width* in seconds to move servo to its left limit
+#define SERVO_MAX_PULSE_WIDTH_DEFAULT                                          (float)(.00160)  // The number here should be be *pulse width* in seconds to move servo to its left limit 
 
 
 #define FTM0_CLOCK                                             (SystemCoreClock/2)
diff -r 9fd02d06973b -r 24430a0d7fd8 main.cpp
--- a/main.cpp	Mon Mar 17 14:10:28 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-#include "mbed.h"
-#include "TFC.h"
-
- 
-//This macro is to maintain compatibility with Codewarrior version of the sample.   This version uses the MBED libraries for serial port access
-Serial PC(USBTX,USBRX);
-
-#define TERMINAL_PRINTF     PC.printf
-
- 
- //This ticker code is used to maintain compability with the Codewarrior version of the sample.   This code uses an MBED Ticker for background timing.
- 
-#define NUM_TFC_TICKERS 4
-
-Ticker TFC_TickerObj;
- 
-volatile uint32_t TFC_Ticker[NUM_TFC_TICKERS];
- 
-void TFC_TickerUpdate()
-{
-    int i;
- 
-    for(i=0; i<NUM_TFC_TICKERS; i++)
-     {
-        if(TFC_Ticker[i]<0xFFFFFFFF) 
-        {
-            TFC_Ticker[i]++;
-        }
-    }
-}
- 
- 
- 
- 
-int main()
-{
-    uint32_t i,t = 0;
-  
-    PC.baud(115200);
-    TFC_TickerObj.attach_us(&TFC_TickerUpdate,2000);
-   
-    TFC_Init();
-    
-    for(;;)
-    {      
-        //TFC_Task must be called in your main loop.  This keeps certain processing happy (I.E. Serial port queue check)
-         //   TFC_Task();
-
-            //This Demo program will look at the middle 2 switch to select one of 4 demo modes.
-            //Let's look at the middle 2 switches
-            switch((TFC_GetDIP_Switch()>>1)&0x03)
-            {
-            default:
-            case 0 :
-                //Demo mode 0 just tests the switches and LED's
-                if(TFC_PUSH_BUTTON_0_PRESSED)
-                    TFC_BAT_LED0_ON;
-                else
-                    TFC_BAT_LED0_OFF;
-                
-                if(TFC_PUSH_BUTTON_1_PRESSED)
-                    TFC_BAT_LED3_ON;
-                else
-                    TFC_BAT_LED3_OFF;
-                
-                
-                if(TFC_GetDIP_Switch()&0x01)
-                    TFC_BAT_LED1_ON;
-                else
-                    TFC_BAT_LED1_OFF;
-                
-                if(TFC_GetDIP_Switch()&0x08)
-                    TFC_BAT_LED2_ON;
-                else
-                    TFC_BAT_LED2_OFF;
-                
-                break;
-                    
-            case 1:
-                
-                //Demo mode 1 will just move the servos with the on-board potentiometers
-                if(TFC_Ticker[0]>=20)
-                {
-                    TFC_Ticker[0] = 0; //reset the Ticker
-                    //Every 20 mSeconds, update the Servos
-                    TFC_SetServo(0,TFC_ReadPot(0));
-                    TFC_SetServo(1,TFC_ReadPot(1));
-                }
-                //Let's put a pattern on the LEDs
-                if(TFC_Ticker[1] >= 125)
-                {
-                    TFC_Ticker[1] = 0;
-                    t++;
-                    if(t>4)
-                    {
-                        t=0;
-                    }           
-                    TFC_SetBatteryLED_Level(t);
-                }
-                
-                TFC_SetMotorPWM(0,0); //Make sure motors are off
-                TFC_HBRIDGE_DISABLE;
-            
-
-                break;
-                
-            case 2 :
-                
-                //Demo Mode 2 will use the Pots to make the motors move
-                TFC_HBRIDGE_ENABLE;
-               
-                TFC_SetMotorPWM(TFC_ReadPot(0),TFC_ReadPot(1));
-                
-                        
-                //Let's put a pattern on the LEDs
-                if(TFC_Ticker[1] >= 125)
-                    {
-                        TFC_Ticker[1] = 0;
-                            t++;
-                            if(t>4)
-                            {
-                                t=0;
-                            }           
-                        TFC_SetBatteryLED_Level(t);
-                    }
-                break;
-            
-            case 3 :
-            
-         
-                //Demo Mode 3 will be in Freescale Garage Mode.  It will beam data from the Camera to the 
-                //Labview Application
-                
-                
-                if(TFC_Ticker[0]>50 && TFC_LineScanImageReady>0)
-                    {
-                     TFC_Ticker[0] = 0;
-                     TFC_LineScanImageReady=0;
-                     TERMINAL_PRINTF("\r\n");
-                     TERMINAL_PRINTF("L:");
-                     
-                        if(t==0)
-                            t=4;
-                        else
-                            t--;
-                        
-                         TFC_SetBatteryLED_Level(t);
-                        
-                         // camera 1
-                         for(i=0;i<128;i++)
-                         {
-                               TERMINAL_PRINTF("%X,",TFC_LineScanImage0[i]);
-                         }
-                        
-                        // camera 2
-                         for(i=0;i<128;i++)
-                         {
-                                 if(i==127)
-                                     TERMINAL_PRINTF("%X\r\n",TFC_LineScanImage1[i]);
-                                 else
-                                     TERMINAL_PRINTF("%X,",TFC_LineScanImage1[i]);
-                           
-                         }
-                    }
-                 
-                break;
-            }
-    }
-    
- 
-}
- 
diff -r 9fd02d06973b -r 24430a0d7fd8 mbed.bld
--- a/mbed.bld	Mon Mar 17 14:10:28 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/5798e58a58b1
\ No newline at end of file