Jump to content
CorB

SOLVED: SPI on C2000 launchpad

Recommended Posts

Hi,

 

 

I am trying to get the LCD that I am using on the 430Launchpad also to work on the C2000Launchpad (http://lars.roland.bz/lcd/) . This LCD works using a 3 wire SPI and I had the feeling connecting this and getting it running would be easy ... I have been trying to adopt the SPI Loopback code that comes with the CONTROLSUITE but unfortunately I have not seen any signs of life on the LCD.

 

Did anybody overhere allready get a simple LCD SPI device working ? The LCD I am using is a readonly device so I cannot "listen" to the device to understand where things go wrong.

 

regards

 

CorB

Share this post


Link to post
Share on other sites

Hi Bluehash,

 

I would not know if I did, where does that get specified ?

 

Here's my init code

 

void spi_init()

{

SpiaRegs.SPICCR.all =0x0008; // Reset on, rising edge, 8-bit char bits

SpiaRegs.SPICTL.all =0x0006; // Enable master mode, normal phase,

// enable talk, and SPI int disabled.

SpiaRegs.SPIPRI.bit.TRIWIRE =1; // CORB ADDED setup for 3 wire SPI

SpiaRegs.SPIBRR =0x007F;

SpiaRegs.SPICCR.all =0x009F; // Relinquish SPI from Reset

SpiaRegs.SPIPRI.bit.FREE = 1; // Set so breakpoints don't disturb xmission

}

 

The original transmission routine (had to comment the RX part out otherwise the module would hang)

 

void spi_xmit(char sdata)

{

SpiaRegs.SPICTL.bit.TALK = 1; // Enable Transmit path

SpiaRegs.SPITXBUF = sdata; // Master transmits data

// while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) {} // CORB COMMENTED OUT Waits until data rx’d

 

}

 

A translated copy of Lars Rolands routine to write to the ST7579, communication is done with 2 bytes first byte sets CMD(0x00) or DATA (0x01), the 2nd byte is the actual data.

 

 

void SPIWrite(char command, char data)

{

char first = (command << 7) | (data >> 1);

char second = (data << 7);

 

spi_xmit(first);

spi_xmit(second);

}

 

I then use this to send the initialisation sequence to the LCD

 

SPIWrite(CMD, 0x21); //Function set PD=0,H1=0,H0=1

SPIWrite(CMD, 0x10+0x03); //SET Bias system

SPIWrite(CMD, 0X80+0x20); //SET V0

SPIWrite(CMD, 0x20); //Function set PD=0 ,H1=0, H0=0

SPIWrite(CMD, 0x05); //Set VLCD Range(PRS) 0x04 = VLo-low, 0x05 VO-high

SPIWrite(CMD, 0x0C); //Display control D=1 E=0 (Normal) 0x0C = normal display 0x0D = reversed

SPIWrite(CMD, 0x40); //Set Y startingline BIT6 line0=0x40

SPIWrite(CMD, 0x80); //Set y startingline BIT5-0 line0=0x80

SPIWrite(CMD, 0x28); //Function set PD=0,H1=0,H0=0 reverse directions

 

And finally I write a few 0xffs into the LCD screen memory which should give me a few black lines

 

SPIWrite(DATA,0xff);

SPIWrite(DATA,0xff);

SPIWrite(DATA,0xff);

SPIWrite(DATA,0xff);

 

But nothing thusfar happens, unfortunately I do not have a buspirate or anything else to debug the hardware part of this story.

 

regards

CorB

Share this post


Link to post
Share on other sites

Hi Bluehash,

 

I am allready using SpiaRegs.SPIBRR =0x007F, and according to the specs that is the lowest baudrate I can use. Since the system runs on 60Mhz the baudrate will be 60Mhz/128 ~ 460kBaud. Maybe I should lower the systemclock ?

 

Further, just saw on code used by others that in order to use 8 bits you need to set

SpiaRegs.SPICCR.all =0x0007; // Reset on, rising edge, 16-bit char bits

 

Trying that now.

 

EDIT: lowering the SPICCR has not helped, next will be the systemclock probably

Share this post


Link to post
Share on other sites

CorB,

You're sooooo close! Turns out our SPI is a little different because of the 16 bit wide memory architecture. Data must be written to the transmit register LEFT justified (check the guide SPRUG71 page 30). The register is 16 bits wide so if you want to transmit 8 bit wide data you need to shift it up by 8.

 

Try changing your transmit function to something like this:

 

void spi_xmit(char sdata)
{
SpiaRegs.SPICTL.bit.TALK = 1; // Enable Transmit path
SpiaRegs.SPITXBUF = (sdata << 8); // Master transmits data
// while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) {} // CORB COMMENTED OUT Waits until data rx’d

}

 

Can't wait to see that LCD lit up! Cheers!

Share this post


Link to post
Share on other sites

Hello Trey,

 

Just tried that but ... no signs of life yet on the LCD. The code compiles fine and when I start the code it also seems to run but nothing happens with the LCD.

 

One more thing you might have an idea why this happens, if I physically disconnect the c2000 lauchpad from my laptop and reconnect ... the launchpad runs the default show temperature with leds application again ... Maybe my code does not get fully loaded onto the C2000???

 

regards

CorB

Share this post


Link to post
Share on other sites

Hrmmm...weird. Maybe you are linking your application to run from RAM and have not reprogrammed the flash yet. That would cause the behavior you're seeing.

 

All the example projects should have two build configurations: one for RAM and one for Flash. You ought to be able to easily switch between the two by right clicking on the project in CCS and going to the Build Configurations entry.

Share this post


Link to post
Share on other sites

Aha ... the differences between the C2000 and MSP430 are clearly on many fronts.

from the documentation of the SPI_loopback code I see the info below. I guess the boot to SARAM shows its RAMbased code. How do I change that to flashbased code ?

PS: the code I used did not come with 2 flavours for compilation, I only have the defaults Debug and Release (same coding)

 

FILE: Example_2802xSpi_FFDLB.c

//

// TITLE: DSP2802x Device Spi Digital Loop Back program.

//

// ASSUMPTIONS:

//

// This program requires the DSP2802x header files.

//

// This program uses the internal loop back test mode of the peripheral.

// Other then boot mode pin configuration, no other hardware configuration

// is required.

//

// As supplied, this project is configured for "boot to SARAM"

// operation. The 2802x Boot Mode table is shown below.

// For information on configuring the boot mode of an eZdsp,

// please refer to the documentation included with the eZdsp,

//

Share this post


Link to post
Share on other sites

For those interested, Ive added the full code I am using to this mail.

 

cheers

Cor

 

EDIT: code removed after solving the issues

Share this post


Link to post
Share on other sites

CorB,

Where did you get this sample code from? Specifically what directory in controlSUITE? This is a really old version of the example. The newer examples do in fact have the dual build configuration and use the new driver library.

 

FYI I'm gonna try to start doing some videos to help explain some of the quirks related to C2000. Hopefully that will help ya'll learn the chip a little easier.

Share this post


Link to post
Share on other sites

Trey,

 

Ive got the code from the V126 directory I think ... cant trace it back. The advantage of this code is that I can easily see which settings are used. The more recent examples of the SPI_loopback seemed less informative and more difficult to understand/change. But I guess this is currently not my main issue ... whether I compile in RAM or FLASH doesnt change the functionality I think.

Share this post


Link to post
Share on other sites

Gotcha, ya that's the older code that hasn't been touched in a few years. Those examples are nice for that reason, its very easy to see what bits in each register are set to. That beings said, we are trying to move away from the bitfield approach because it isn't standard and can potentially cause issues. They are fine to use for learning though.

 

Check it out

 

All you really should need to do to get it to run in flash it to switch out the linker command file for one of the Flash ones. If you are using any functions that are linked to RAM you'll need to make sure there is a call to memcpy in your main function so that these RAM functions get copied to RAM at run time.

Share this post


Link to post
Share on other sites

I understand your reasoning behind it ... but this code is supplied with the controlsuite so some people might be - like me - tricked into using it. The at least visual complexity of the newer coding system is really not helpfull for starting users. It seems I had deleted the latest V200 version of the SPI_Loopback, now trying to reinstall that and use all the lessons learned to try again and program it into the flash. Will report ASAP

Share this post


Link to post
Share on other sites

And the saga continous, ive grown up and now use the current SPI_loopback example as the base to get the LCD working but ... again no results.

 

Here's my code ... I am slowly moving in the direction to give up on this, maybe I just should wait and see if someone else can get an LCD working on this system. I am too much of a newbie it seems.


//#############################################################################
//
//  File:   f2802x_examples_ccsv4/spi_loopback/Example_F2802xSpi_FFDLB.c
//
//  Title:  F2802x Device Spi Digital Loop Back program.
//
//  Group:		  C2000
//  Target Device:  TMS320F2802x
//
//! \addtogroup example_list
//!  <h1>SPI Digital Loop Back</h1>
//!
//!   This program is a SPI example that uses the internal loopback of
//!   the peripheral.  Interrupts are not used.
//!
//!   A stream of data is sent and then compared to the recieved stream.
//!
//!   The sent data looks like this:
//!   0000 0001 0002 0003 0004 0005 0006 0007 .... FFFE FFFF
//!
//!   This pattern is repeated forever.
//!
//!   Watch Variables:
//!   - sdata - sent data
//!   - rdata - received data
//
//  © Copyright 2012, Texas Instruments, Inc.
//#############################################################################
// $TI Release: f2802x Support Library v200 $
// $Release Date: Tue Jul 24 10:01:39 CDT 2012 $
//#############################################################################
#include "DSP28x_Project.h"	 // Device Headerfile and Examples Include File
#include "f2802x_common/include/adc.h"
#include "f2802x_common/include/clk.h"
#include "f2802x_common/include/flash.h"
#include "f2802x_common/include/gpio.h"
#include "f2802x_common/include/pie.h"
#include "f2802x_common/include/pll.h"
#include "f2802x_common/include/spi.h"
#include "f2802x_common/include/wdog.h"
// Prototype statements for functions found within this file.
// interrupt void ISRTimer2(void);
void delay_loop(void);
void spi_xmit(uint16_t a);
void LCDSPI(uint16_t command, uint16_t data);
void spi_fifo_init(void);
void spi_init(void);
void error(void);
ADC_Handle myAdc;
CLK_Handle myClk;
FLASH_Handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
SPI_Handle mySpi;
#define DATA 0x01
#define CMD 0x00
void main(void)
{
   uint16_t sdata;  // send data
   uint16_t rdata;  // received data

   CPU_Handle myCpu;
   PLL_Handle myPll;
   WDOG_Handle myWDog;

   // Initialize all the handles needed for this application   
   myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj));
   myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));
   myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
   myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
   myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
   myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
   myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
   mySpi = SPI_init((void *)SPIA_BASE_ADDR, sizeof(SPI_Obj));
   myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));

   // Perform basic system initialization   
   WDOG_disable(myWDog);
   CLK_enableAdcClock(myClk);
   (*Device_cal)();

   //Select the internal oscillator 1 as the clock source
   CLK_setOscSrc(myClk, CLK_OscSrc_Internal);

   // Setup the PLL for x10 /2 which will yield 50Mhz = 10Mhz * 10 / 2
   PLL_setup(myPll, PLL_Multiplier_1, PLL_DivideSelect_ClkIn_by_2);

   // Disable the PIE and all interrupts
   PIE_disable(myPie);
   PIE_disableAllInts(myPie);
   CPU_disableGlobalInts(myCpu);
   CPU_clearIntFlags(myCpu);

   // If running from flash copy RAM only functions to RAM  
#ifdef _FLASH
   memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif  
   // Initalize GPIO
   GPIO_setPullUp(myGpio, GPIO_Number_16, GPIO_PullUp_Enable);
   GPIO_setPullUp(myGpio, GPIO_Number_17, GPIO_PullUp_Enable);
   GPIO_setPullUp(myGpio, GPIO_Number_18, GPIO_PullUp_Enable);
   GPIO_setPullUp(myGpio, GPIO_Number_19, GPIO_PullUp_Enable);
   GPIO_setQualification(myGpio, GPIO_Number_16, GPIO_Qual_ASync);
   GPIO_setQualification(myGpio, GPIO_Number_17, GPIO_Qual_ASync);
   GPIO_setQualification(myGpio, GPIO_Number_18, GPIO_Qual_ASync);
   GPIO_setQualification(myGpio, GPIO_Number_19, GPIO_Qual_ASync);
   GPIO_setMode(myGpio, GPIO_Number_16, GPIO_16_Mode_SPISIMOA);
   GPIO_setMode(myGpio, GPIO_Number_17, GPIO_17_Mode_SPISOMIA);
   GPIO_setMode(myGpio, GPIO_Number_18, GPIO_18_Mode_SPICLKA);
   GPIO_setMode(myGpio, GPIO_Number_19, GPIO_19_Mode_SPISTEA_NOT);
   // Setup a debug vector table and enable the PIE
   PIE_setDebugIntVectorTable(myPie);
   PIE_enable(myPie);
   spi_init();		 // Initialize SPI
   spi_fifo_init();    // Initialize the SPI FIFOs
   LCDSPI(CMD, 0x21);  //Function set PD=0,H1=0,H0=1
   LCDSPI(CMD, 0x10+0x03);  //SET Bias system
   //LCDSPI(CMD, 0X80+0x29);  //SET V0
   LCDSPI(CMD, 0X80+0x20);  //SET V0
   LCDSPI(CMD, 0x20);  //Function set PD=0 ,H1=0, H0=0
   LCDSPI(CMD, 0x05);  //Set VLCD Range(PRS) 0x04 = VLo-low, 0x05 VO-high
   LCDSPI(CMD, 0x0C);  //Display control D=1 E=0 (Normal) 0x0C = normal display 0x0D = reversed
   LCDSPI(CMD, 0x40);  //Set Y startingline BIT6    line0=0x40
   LCDSPI(CMD, 0x80);  //Set y startingline BIT5-0  line0=0x80
   LCDSPI(CMD, 0x28);  //Function set PD=0,H1=0,H0=0 reverse directions
   LCDSPI(DATA,0xff);
   LCDSPI(DATA,0xff);
   LCDSPI(DATA,0xff);
   LCDSPI(DATA,0xff);

   //sdata = 0x0000;

   for(; {

   /* // Transmit data
    SPI_write(mySpi, sdata);

    // Wait until data is received
    while(SPI_getRxFifoStatus(mySpi) == SPI_FifoStatus_Empty){
    }

    // Check against sent data
    rdata = SPI_read(mySpi);
    if(rdata != sdata)
	    error();

    sdata++;
    */
   }
}

void delay_loop()
{
   long	  i;

   for (i = 0; i < 1000000; i++) {
   }

   return;
}


void error(void)
{
   asm(" ESTOP0");	 // Test failed!! Stop!
   for (;{
   }
}
void spi_init()
{
   CLK_enableSpiaClock(myClk);

   // Reset on, rising edge, 8-bit char bits
   SPI_setCharLength(mySpi, SPI_CharLength_8_Bits);
   // Enable master mode, normal phase,
   // enable talk, and SPI int disabled.
   SPI_setMode(mySpi, SPI_Mode_Master);
   SPI_enableTx(mySpi);

   SPI_setBaudRate(mySpi, SPI_BaudRate_500_KBaud);

   // Relinquish SPI from Reset
   SPI_enableLoopBack(mySpi);
   SPI_enable(mySpi);
   // Set so breakpoints don't disturb xmission
   SPI_setPriority(mySpi, SPI_Priority_FreeRun);

   return;
}
void LCDSPI(uint16_t command, uint16_t data)
{
char first = (command << 7) | (data >> 1);
char second = (data << 7);
SPI_write(mySpi, command<<8);
SPI_write(mySpi, data<<8 );
}

void spi_fifo_init()
{

   // Initialize SPI FIFO registers
   SPI_enableChannels(mySpi);
   SPI_enableFifoEnh(mySpi);
   SPI_resetTxFifo(mySpi);
   SPI_clearTxFifoInt(mySpi);   
   SPI_resetRxFifo(mySpi);
   SPI_clearRxFifoInt(mySpi);
   SPI_setRxFifoIntLevel(mySpi, SPI_FifoLevel_4_Words);

   return;
}
//===========================================================================
// No more.
//===========================================================================

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...