• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

spi_if.c

Go to the documentation of this file.
00001 //****************************************************************************
00002 //THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
00003 //REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
00004 //INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
00005 //FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
00006 //COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
00007 //TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
00008 //POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
00009 //INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
00010 //YOUR USE OF THE PROGRAM.
00011 //
00012 //IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
00013 //CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
00014 //THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
00015 //OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
00016 //OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
00017 //EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
00018 //REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
00019 //OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
00020 //USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
00021 //AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
00022 //YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
00023 //(U.S.$500).
00024 //
00025 //Unless otherwise stated, the Program written and copyrighted
00026 //by Texas Instruments is distributed as "freeware".  You may,
00027 //only under TI's copyright in the Program, use and modify the
00028 //Program without any charge or restriction.  You may
00029 //distribute to third parties, provided that you transfer a
00030 //copy of this license to the third party and the third party
00031 //agrees to these terms by its first use of the Program. You
00032 //must reproduce the copyright notice and any other legend of
00033 //ownership on each copy or partial copy, of the Program.
00034 //
00035 //You acknowledge and agree that the Program contains
00036 //copyrighted material, trade secrets and other TI proprietary
00037 //information and is protected by copyright laws,
00038 //international copyright treaties, and trade secret laws, as
00039 //well as other intellectual property laws.  To protect TI's
00040 //rights in the Program, you agree not to decompile, reverse
00041 //engineer, disassemble or otherwise translate any object code
00042 //versions of the Program to a human-readable form.  You agree
00043 //that in no event will you alter, remove or destroy any
00044 //copyright notice included in the Program.  TI reserves all
00045 //rights not specifically granted under this license. Except
00046 //as specifically provided herein, nothing in this agreement
00047 //shall be construed as conferring by implication, estoppel,
00048 //or otherwise, upon you, any license or other right under any
00049 //TI patents, copyrights or trade secrets.
00050 // 
00051 //You may not use the Program in non-TI devices.
00052 //
00053 //This software has been submitted to export control regulations
00054 //The ECCN is EAR99 
00055 //****************************************************************************
00065 #include "msp430.h"
00066 #include "main.h"
00067 #include "spi_if.h"
00068 
00072 unsigned char calculate_crc(unsigned char* buffer, 
00073                             unsigned char buffer_lenght);
00074 
00078 //read write masks for the 'PL536 devices
00079 const unsigned char spi_regs_rw_mask[] = 
00080 {
00081   0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
00082   0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
00083   0x3,0x3,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
00084   0x3,0x3,0x3,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x2,0x3,0x0,0x3,
00085   0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0
00086 };
00087 
00088 //CRC lookup table
00089 const unsigned char CrcTable[] = {
00090   0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
00091   0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
00092   0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
00093   0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
00094   0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
00095   0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
00096   0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
00097   0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
00098   0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
00099   0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
00100   0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
00101   0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
00102   0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
00103   0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
00104   0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
00105   0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
00106   0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
00107   0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
00108   0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
00109   0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
00110   0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
00111   0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
00112   0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
00113   0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
00114   0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
00115   0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
00116   0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
00117   0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
00118   0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
00119   0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
00120   0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
00121   0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
00122 };
00123 
00134 void init_spi(void)
00135 {
00136   
00137   UCBxCTL1 |= UCSWRST;                     // Stop USCI state machine
00138   
00139   // SPI take control over the PINs
00140   CLK_PxSEL |= IO_SPI_SCLK;  
00141   SIMO_PxSEL |=  IO_SPI_SDI;
00142   SOMI_PxSEL  |= IO_SPI_SDO;
00143   
00144   STE_PxSEL &= ~(IO_SPI_CS); // SPI_CS needs to be output driven by SW 
00145   STE_PxREN &= ~(IO_SPI_CS); // Pullup/Pull down resistor disabled  
00146   STE_PxOUT |= IO_SPI_CS;    // Set CS to HIGH
00147   STE_PxDIR |= IO_SPI_CS;    // SPI_CS needs to be output driven by SW  
00148   
00149   UCBxCTL0 |= UCMSB + UCMST + UCSYNC;       // 3-pin, 8-bit SPI mstr, MSB 1st
00150   UCBxCTL1 |= UCSSEL_2;                     // SMCLK = 24.969M Hz
00151   UCBxBR0 = 0x17;                           // SMCLK/24 = 1.04 MHz
00152   UCBxBR1 = 0;
00153   UCBxCTL1 &= ~UCSWRST;                     // Start USCI state machine
00154 }
00155 
00156 
00163 short spi_write_reg(unsigned char dev_addr, 
00164                     unsigned char reg_addr, 
00165                     unsigned char data)
00166 {
00167   unsigned char package[4];
00168   unsigned char TimeOutCounter = 0;
00169   short i=0;
00170  
00171   if (spi_regs_rw_mask[reg_addr] & WRITE_ACCESS)
00172   {
00173     package[0] = (dev_addr<<1) | 0x01/*Write*/;
00174     package[1] = reg_addr;
00175     package[2] = data;
00176     package[3] = calculate_crc(package, 3);
00177     
00178     //Write 1 byte into the selected register
00179     STE_PxOUT &= ~IO_SPI_CS;                   // Enable BQ Pack, /CS asserted
00180     
00181    
00182     for (i=0; i<4; i++)
00183     {
00184       // USCI_A0 TX buffer ready?
00185       while (!(UCBxIFG & UCBxTXIFG)){
00186         __delay_cycles(1000);
00187         TimeOutCounter++;
00188         if(TimeOutCounter >= 200)
00189           return 0;    
00190                      
00191       }
00192         
00193 
00194        
00195       UCBxTXBUF = package[i];       // Write data to TX to start SPI transfer
00196        // Data in USCI_A0 RX buffer
00197       while (!(UCBxIFG & UCBxRXIFG)){
00198         __delay_cycles(1000);
00199         TimeOutCounter++;
00200         if(TimeOutCounter >= 200)
00201           return 0;    
00202                       
00203       }
00204                  
00205       package[0] = UCBxRXBUF;     // Dummy read to clean RX buffer
00206     }
00207     
00208     STE_PxOUT |= IO_SPI_CS;       // Disable BQ Pack, /CS deasserted
00209   }
00210   
00211   return i;  
00212 
00213 }
00214 
00224 short spi_read_reg(unsigned char dev_addr,
00225                    unsigned char reg_addr,
00226                    short elem_num,
00227                    unsigned char discard_crc,//*True, False*/
00228                    unsigned char* pData)
00229 {
00230   unsigned char package[3];
00231   short i=0;
00232   unsigned char TimeOutCounter = 0;
00233  
00234   if (spi_regs_rw_mask[reg_addr] & READ_ACCESS)
00235   {
00236     package[0] = (dev_addr<<1)/*Read*/;
00237     package[1] = reg_addr;
00238     package[2] = elem_num;
00239     
00240     //Write 1 byte into the selected register
00241     STE_PxOUT &= ~IO_SPI_CS;                    // Enable BQ Pack, /CS asserted
00242 
00243     if (UCBxIFG & UCBxRXIFG)
00244     {
00245       *pData = UCBxRXBUF;                   // Dummy read to clear RX buffer
00246     }
00247     
00248 
00249     for (i=0; i<3; i++)
00250     {
00251       // USCI_A0 TX buffer ready?
00252       while (!(UCBxIFG & UCBxTXIFG)){
00253         __delay_cycles(1000);
00254         TimeOutCounter++;
00255         if(TimeOutCounter >= 200)
00256           return 0;    
00257                        
00258       }
00259       
00260       
00261       UCBxTXBUF = package[i];       // Write data to TX to start SPI transfer
00262        // Data in USCI_A0 RX buffer
00263       while (!(UCBxIFG & UCBxRXIFG)){
00264         __delay_cycles(1000);
00265         TimeOutCounter++;
00266         if(TimeOutCounter >= 200)
00267           return 0;    
00268                      
00269       }    
00270       
00271       
00272       *pData = UCBxRXBUF;            // Dummy read to clear RX buffer
00273     }
00274       
00275     
00276     for (i=0; i<elem_num+1/*+1 to count CRC*/; i++)
00277     { // USCI_B0 TX buffer ready?
00278 
00279       while (!(UCBxIFG & UCBxTXIFG)){
00280         __delay_cycles(1000);
00281         TimeOutCounter++;
00282         if(TimeOutCounter >= 200)
00283           return 0;    
00284                           
00285       }        
00286       
00287       UCBxTXBUF = 0x00;               // Dummy write to keep clocking going
00288        // Data in USCI_A0 RX buffer
00289       while (!(UCBxIFG & UCBxRXIFG)){
00290         __delay_cycles(1000);
00291         TimeOutCounter++;
00292         if(TimeOutCounter >= 200)
00293           return 0;    
00294                       
00295       }  
00296       if (i==elem_num)
00297       {
00298         /*Read CRC*/
00299         if (discard_crc)
00300           package[0] = UCBxRXBUF;           // Read and discard CRC
00301         else
00302           *pData++ = UCBxRXBUF;             // R15 = 00|MSB
00303       }
00304       else
00305       {
00306         /*Read data*/
00307         *pData++ = UCBxRXBUF;               // R15 = 00|MSB
00308       }
00309     }
00310   
00311     STE_PxOUT |= IO_SPI_CS;                 // Disable BQ Pack, /CS deasserted
00312   }
00313   
00314   return i;
00315 }
00316 
00327 unsigned char calculate_crc(unsigned char* buffer, 
00328                             unsigned char buffer_lenght)
00329 {
00330   unsigned char crc = 0;
00331   unsigned short temp = 0;
00332   unsigned short i;
00333   for ( i = 0; i < buffer_lenght; i++)
00334   {
00335     temp = crc ^ buffer[i];
00336     crc = CrcTable[temp];
00337   }
00338   return crc;
00339 }
00340 
00341 /*EOF*/

Generated on Fri Dec 17 2010 12:08:30 for Multi-cell Lithium-Ion Battery Manager System using MSP430 and BQ76PL536 by  doxygen 1.7.1