Jeremy Dawkins / mbedWSEsbc

Dependents:   cts_matlab_interface

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbedWSEsbc.h Source File

mbedWSEsbc.h

00001 /* C Library for the WSE-PROJ-SBC
00002  J Bradshaw
00003  20140912
00004  20140918 J Bradshaw - Found CS mistake in Encoder routines
00005     Added comments in Init function, encoder functions
00006  20150210 J Bradshaw - Initialized DigitalOuts with pre-defined logic
00007    levels (CS's high, etc)
00008 */
00009 
00010 
00011 // LS7366 ENCODER IC DEFINITIONS
00012 //=============================================================================
00013 // Four commands for the Instruction Register (B7,B6) - LS7366
00014 //=============================================================================
00015 #define CLR     0x00    //Clear Instruction
00016 #define RD      0x01    //Read Instruction
00017 #define WR      0x02    //Write Instruction
00018 #define LOAD    0x03    //Load Instruction
00019 
00020 //=============================================================================
00021 // Register to Select from the Instruction Register (B5,B4,B3) - LS7366
00022 //=============================================================================
00023 #define NONE        0x00    //No Register Selected
00024 #define MDR0        0x01    //Mode Register 0
00025 #define MDR1        0x02    //Mode Register 1
00026 #define DTR         0x03    //Data Transfer Register
00027 #define CNTR        0x04    //Software Configurable Counter Register
00028 #define OTR         0x05    //Output Transfer Register
00029 #define STR         0x06    //Status Register
00030 #define NONE_REG    0x07    //No Register Selected
00031 
00032 // Set-up hardwired IO
00033 SPI spi_max1270(p5, p6, p7);
00034 SPI spi(p5, p6, p7);
00035 DigitalOut max1270_cs(p8, 1);  //CS for MAX1270 ADC (U3)
00036 DigitalOut max522_cs(p11, 1);  //CS for MAX522 DAC (U5)
00037 
00038 DigitalOut ls7166_cs1(p19, 1); //CS for LS7366-1 (U8)
00039 DigitalOut ls7166_cs2(p20, 1); //CS for LS7366-2 (U9)
00040 
00041 DigitalOut mot1_ph1(p21, 0);       
00042 DigitalOut mot1_ph2(p22, 0);
00043 PwmOut mot_en1(p23);
00044 
00045 DigitalOut mot2_ph1(p24, 0);
00046 DigitalOut mot2_ph2(p25, 0);
00047 PwmOut mot_en2(p26);
00048 
00049 DigitalOut led1(LED1, 0);
00050 DigitalOut led2(LED2, 0);
00051 DigitalOut led3(LED3, 0);
00052 DigitalOut led4(LED4, 0);
00053 
00054 Serial pc(USBTX, USBRX); // tx, rx for serial USB interface to pc
00055 Serial xbee(p13, p14); // tx, rx for Xbee
00056 Timer t; // create timer instance
00057 
00058 // ------ Prototypes -----------
00059 int read_max1270(int chan, int range, int bipol);
00060 float read_max1270_volts(int chan, int range, int bipol);
00061 void mot_control(int drv_num, float dc);
00062 void LS7366_cmd(int inst,  int reg);
00063 long LS7366_read_counter(int chan_num);
00064 void LS7366_quad_mode_x4(int chan_num);
00065 void LS7366_reset_counter(int chan_num);
00066 void LS7366_write_DTR(int chan_num,long enc_value);
00067 void write_max522(int chan, float volts);
00068 
00069 //---- Function Listing -------------------------------
00070 int read_max1270(int chan, int range, int bipol){
00071     int cword=0x80;     //set the start bit
00072     
00073     spi_max1270.frequency(10000000);
00074     spi_max1270.format(8, 0);   // 8 data bits, CPOL0, and CPHA0 (datasheet Digital Interface)
00075         
00076     cword |= (chan << 4);   //shift channel
00077     cword |= (range << 3);
00078     cword |= (bipol << 2);
00079             
00080     max1270_cs = 0;
00081            
00082     spi_max1270.write(cword);
00083     wait_us(15);    //15us
00084     spi_max1270.format(12, 3);
00085     
00086     int result = spi_max1270.write(0);
00087     
00088     max1270_cs = 1;
00089     spi_max1270.format(8, 0);
00090     return result;
00091 }
00092 
00093 float read_max1270_volts(int chan, int range, int bipol){
00094     float rangevolts=0.0;
00095     float volts=0.0;
00096     int adc_res;
00097 
00098     //read the ADC converter
00099     adc_res = read_max1270(chan, range, bipol) & 0xFFF;
00100         
00101    //Determine the voltage range
00102    if(range)  //RNG bit 
00103      rangevolts=10.0;
00104    else
00105      rangevolts=5.0;
00106              
00107    //bi-polar input range
00108    if(bipol){ //BIP is set, input is +/-
00109      if(adc_res < 0x800){ //if result was positive
00110       volts = ((float)adc_res/0x7FF) * rangevolts;      
00111      }       
00112      else{  //result was negative
00113       volts = -(-((float)adc_res/0x7FF) * rangevolts) - (rangevolts * 2.0); 
00114      }
00115    }
00116    else{  //input is positive polarity only
00117       volts = ((float)adc_res/0xFFF) * rangevolts;   
00118    }
00119    
00120    return volts;     
00121 }
00122     
00123 //Motor control routine for PWM on 5 pin motor driver header
00124 // drv_num is 1 or 2 (defaults to 1, anything but 2)
00125 // dc is signed duty cycle (+/-1.0)
00126 
00127 void mot_control(int drv_num, float dc){        
00128     if(dc>1.0)
00129         dc=1.0;
00130     if(dc<-1.0)
00131         dc=-1.0;
00132     
00133     if(drv_num != 2){           
00134         if(dc > 0.0){
00135             mot1_ph2 = 0;
00136             mot1_ph1 = 1;
00137             mot_en1 = dc;
00138         }
00139         else if(dc < -0.0){
00140             mot1_ph1 = 0;
00141             mot1_ph2 = 1;
00142             mot_en1 = abs(dc);
00143         }
00144         else{
00145             mot1_ph1 = 0;
00146             mot1_ph2 = 0;
00147             mot_en1 = 0.0;
00148         }
00149     }                
00150     else{
00151         if(dc > 0.0){
00152             mot2_ph2 = 0;
00153             mot2_ph1 = 1;
00154             mot_en2 = dc;
00155         }
00156         else if(dc < -0.0){
00157             mot2_ph1 = 0;
00158             mot2_ph2 = 1;
00159             mot_en2 = abs(dc);
00160         }
00161         else{
00162             mot2_ph1 = 0;
00163             mot2_ph2 = 0;
00164             mot_en2 = 0.0;
00165         }
00166     }                   
00167 }
00168 
00169 //----- LS7366 Encoder/Counter Routines --------------------
00170 void LS7366_cmd(int inst,  int reg){
00171     char cmd;
00172     
00173     spi.format(8, 0);
00174     spi.frequency(2000000);
00175     cmd = (inst << 6) | (reg << 3);
00176 //    printf("\r\ncmd=0X%2X", cmd);
00177     spi.write(cmd);
00178 }
00179 
00180 long LS7366_read_counter(int chan_num){
00181     union bytes{
00182         char byte_enc[4];
00183         long long_enc;
00184     }counter;
00185     
00186     counter.long_enc = 0;
00187     
00188     spi.format(8, 0);
00189     spi.frequency(2000000);
00190     
00191     if(chan_num!=2){
00192         ls7166_cs1 = 0;
00193         wait_us(1);
00194         LS7366_cmd(LOAD,OTR);//cmd = 0xe8, LOAD to OTR
00195         ls7166_cs1 = 1;
00196         wait_us(1);
00197         ls7166_cs1 = 0;
00198     }
00199     else{
00200         ls7166_cs2 = 0;    
00201         wait_us(1);
00202         LS7366_cmd(LOAD,OTR);//cmd = 0xe8, LOAD to OTR
00203         ls7166_cs2 = 1;
00204         wait_us(1);
00205         
00206         ls7166_cs2 = 0;        
00207     }
00208     wait_us(1);
00209     LS7366_cmd(RD,CNTR);  //cmd = 0x60, READ from CNTR
00210     counter.byte_enc[3] = spi.write(0x00);
00211     counter.byte_enc[2] = spi.write(0x00);
00212     counter.byte_enc[1] = spi.write(0x00);
00213     counter.byte_enc[0] = spi.write(0x00);
00214     
00215     if(chan_num!=2){
00216         ls7166_cs1 = 1;    
00217     }            
00218     else{
00219         ls7166_cs2 = 1;    
00220     }        
00221     
00222     return counter.long_enc;  //return count
00223 }
00224 
00225 void LS7366_quad_mode_x4(int chan_num){
00226     
00227     spi.format(8, 0);
00228     spi.frequency(2000000);
00229     
00230     if(chan_num!=2){
00231         ls7166_cs1 = 0;    
00232     }            
00233     else{
00234         ls7166_cs2 = 0;    
00235     }    
00236     wait_us(1);
00237     LS7366_cmd(WR,MDR0);// Write to the MDR0 register
00238     wait_us(1);
00239     spi.write(0x03); // X4 quadrature count mode
00240     if(chan_num!=2){
00241         ls7166_cs1 = 1;    
00242     }            
00243     else{
00244         ls7166_cs2 = 1;    
00245     }
00246 }
00247 
00248 void LS7366_reset_counter(int chan_num){    
00249     spi.format(8, 0);           // set up SPI for 8 data bits, mode 0
00250     spi.frequency(2000000);     // 2MHz SPI clock
00251     
00252     if(chan_num!=2){            // activate chip select
00253         ls7166_cs1 = 0;    
00254     }
00255     else{
00256         ls7166_cs2 = 0;    
00257     }    
00258     wait_us(1);                 // short delay
00259     LS7366_cmd(CLR,CNTR);       // Clear the counter register
00260     if(chan_num!=2){            // de-activate chip select
00261         ls7166_cs1 = 1;    
00262     }            
00263     else{
00264         ls7166_cs2 = 1;
00265     }
00266     wait_us(1);                 // short delay
00267     
00268     if(chan_num!=2){            // activate chip select
00269         ls7166_cs1 = 0;    
00270     }            
00271     else{
00272         ls7166_cs2 = 0;    
00273     }        
00274     wait_us(1);                 // short delay
00275     LS7366_cmd(LOAD,CNTR);      // load counter reg
00276     if(chan_num!=2){            // de-activate chip select
00277         ls7166_cs1 = 1;    
00278     }            
00279     else{
00280         ls7166_cs2 = 1;    
00281     }
00282 }
00283 
00284 void LS7366_write_DTR(int chan_num, long enc_value){
00285     union bytes                // Union to speed up byte writes
00286     {
00287         char byte_enc[4];
00288         long long_enc;
00289     }counter;
00290     
00291     spi.format(8, 0);           // set up SPI for 8 data bits, mode 0
00292     spi.frequency(2000000);     // 2MHz SPI clock
00293     
00294     counter.long_enc = enc_value; // pass enc_value to Union
00295     
00296     if(chan_num!=2){              // activate chip select
00297         ls7166_cs1 = 0;    
00298     }            
00299     else{
00300         ls7166_cs2 = 0;    
00301     }   
00302     wait_us(1);                 // short delay
00303     LS7366_cmd(WR,DTR);         // Write to the Data Transfer Register
00304     spi.write(counter.byte_enc[3]); // Write the 32-bit encoder value
00305     spi.write(counter.byte_enc[2]);
00306     spi.write(counter.byte_enc[1]);
00307     spi.write(counter.byte_enc[0]);
00308     if(chan_num!=2){            // de-activate the chip select
00309         ls7166_cs1 = 1;    
00310     }            
00311     else{
00312         ls7166_cs2 = 1;    
00313     }     
00314     
00315     wait_us(1);                 // short delay
00316     if(chan_num!=2){            // activate chip select
00317         ls7166_cs1 = 0;    
00318     }            
00319     else{
00320         ls7166_cs2 = 0;    
00321     }
00322     wait_us(1);                 // short delay
00323     LS7366_cmd(LOAD,CNTR);      // load command to the counter register from DTR
00324     if(chan_num!=2){            // de-activate chip select
00325         ls7166_cs1 = 1;    
00326     }            
00327     else{
00328         ls7166_cs2 = 1;    
00329     }
00330 }   
00331 
00332 //------- MAX522 routines ---------------------------------
00333 void write_max522(int chan, float volts){
00334     int cmd=0x20;   //set UB3
00335     int data_word = (int)((volts/5.0) * 256.0);
00336     if(chan != 2)
00337         cmd |= 0x01;    //set DAC A out
00338     else
00339         cmd |= 0x02;    //set DACB out        
00340     
00341  //   pc.printf("cmd=0x%4X  data_word=0x%4X \r\n", cmd, data_word);
00342     
00343     spi.format(8, 0);
00344     spi.frequency(2000000);
00345     max522_cs = 0;
00346     spi.write(cmd & 0xFF);
00347     spi.write(data_word & 0xFF);
00348     max522_cs = 1;    
00349 }
00350 
00351 void mbedWSEsbcInit(unsigned long pcbaud){
00352     led1 = 0;           //Initialize all LEDs as off
00353     led2 = 0;
00354     led3 = 0;
00355     led4 = 0;
00356     max1270_cs = 1;     //Initialize all chip selects as off
00357     max522_cs = 1;
00358     ls7166_cs1 = 1;
00359     ls7166_cs2 = 1;
00360     
00361     wait(.2);   //delay at beginning for voltage settle purposes
00362     
00363     mot_en1.period_us(50);   //20KHz for DC motor control PWM
00364     pc.baud(pcbaud); //Set up serial port baud rate
00365     pc.printf("\r\n");
00366     xbee.baud(115200);
00367     
00368     LS7366_reset_counter(1);
00369     LS7366_quad_mode_x4(1);       
00370     LS7366_write_DTR(1,0);
00371     
00372     LS7366_reset_counter(2);
00373     LS7366_quad_mode_x4(2);       
00374     LS7366_write_DTR(2,0);
00375           
00376     t.start();  // Set up timer    
00377 }//mbedWSEsbc_init()