This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5529: [MSP430F5529 + ili9341 screen] command instruction work step by step only

Part Number: MSP430F5529

Hi,

Since few days i'm working on a screen project with my MSP430F5529 and one ili9341 screen.
I have take an exemple (from arduino, can't find on MSP) and adapt it to know how use the screen. (don't want any lib for speed and space purpose)

After few try, i can fill the screen with colors but can't draw a simple line or rectangle at a special position.
When i run the program step by step, all instruction command work and on the screen i have all the program what have to do.

Between the debug mode and run mode : no code change nether compil option.

I have try to change all wire but no change.

Thank you so much if you can help me.

//This application does not rely on any libraries and it is for ILI9341

//This program is a demo of clearing screen to display black,white,red,green,blue.

//when using the BREAKOUT BOARD only and using these hardware spi lines to the LCD,
//the SDA pin and SCK pin is defined by the system and can't be modified.
//if you don't need to control the LED pin,you can set it to 3.3V and set the pin definition to -1.
//other pins can be defined by youself,for example
//pin usage as follow:
//             CS  DC/RS  RESET  SDI/MOSI  SCK   LED    VCC     GND
//                                                              GND

//Remember to set the pins to suit your display module!

#include <msp430.h> 

#define FPROC 25000000

/*
P3.0 : MOSI
P3.1 : MISO
P3.2 : CLK
*/

#define RSUP        P6OUT|=BIT0    // DC/RS
#define RSDOWN      P6OUT&=~BIT0
#define LEDUP       P6OUT|=BIT1
#define LEDDOWN     P6OUT&=~BIT1
#define CSUP        P6OUT|=BIT2
#define CSDOWN      P6OUT&=~BIT2
#define RESETUP     P6OUT|=BIT3
#define RESETDOWN   P6OUT&=~BIT3

unsigned long oldrand = 5468;


void SetVcoreUp (unsigned int level)
{
  // Open PMM registers for write
  PMMCTL0_H = PMMPW_H;
  // Set SVS/SVM high side new level
  SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
  // Set SVM low side to new level
  SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
  // Wait till SVM is settled
  while ((PMMIFG & SVSMLDLYIFG) == 0);
  // Clear already set flags
  PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
  // Set VCore to new level
  PMMCTL0_L = PMMCOREV0 * level;
  // Wait till new level reached
  if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);
  // Set SVS/SVM low side to new level
  SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
  // Lock PMM registers for write access
  PMMCTL0_H = 0x00;
}


// fonction aleatoire
unsigned int random(unsigned int n) {
    unsigned long nn = oldrand;
    oldrand = (unsigned int)((859*nn)%6823);
    return oldrand % n;
}

void delay(unsigned int i){
    while(i--)
        __delay_cycles(FPROC/1000);  // 1000 for 1MHz
}

// envoyer sur le SPI la donnée
void Lcd_Writ_Bus(unsigned char d)
{
    while(UCB0STAT&BIT0) {} // si la communication n'est pas finie on attend
    UCB0TXBUF = d;
}

// écrire la commande
void Lcd_Write_Com(unsigned char VH)
{
  RSDOWN; //LCD_RS=0;
  Lcd_Writ_Bus(VH);
}

// écrire la donnée
void Lcd_Write_Data(unsigned char VH)
{
  RSUP; //LCD_RS=1;
  Lcd_Writ_Bus(VH);
}

void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
    Lcd_Write_Com(0x2a);
Lcd_Write_Data(x1>>8);
Lcd_Write_Data(x1);
Lcd_Write_Data(x2>>8);
Lcd_Write_Data(x2);
    Lcd_Write_Com(0x2b);
Lcd_Write_Data(y1>>8);
Lcd_Write_Data(y1);
Lcd_Write_Data(y2>>8);
Lcd_Write_Data(y2);
    Lcd_Write_Com(0x2c);
}

void draw_pixel (unsigned char cr,unsigned char cv,unsigned char cb) {
    Lcd_Write_Data(cr);
    Lcd_Write_Data(cv);
    Lcd_Write_Data(cb);
}

void SPI_Init(void)
{
    UCB0CTL0 = BIT7 | BIT5 | BIT3; // Master + MSBfirst + front montant + CLK inactif 0
    UCB0CTL1 = BIT7 | BIT6; // SMCLK
    P3SEL |= 0x07; // on utilise le SPI (CLK, MOSI et MISO)
}

void Lcd_Init(void)
{
    RESETUP;
    delay(5);
    RESETDOWN;
    delay(15);
    RESETUP;
    delay(15);

    CSDOWN;  //CS

    Lcd_Write_Com(0xCB);
    Lcd_Write_Data(0x39);
    Lcd_Write_Data(0x2C);
    Lcd_Write_Data(0x00);
    Lcd_Write_Data(0x34);
    Lcd_Write_Data(0x02);

    Lcd_Write_Com(0xCF);
    Lcd_Write_Data(0x00);
    Lcd_Write_Data(0XC1);
    Lcd_Write_Data(0X30);

    Lcd_Write_Com(0xE8);
    Lcd_Write_Data(0x85);
    Lcd_Write_Data(0x00);
    Lcd_Write_Data(0x78);

    Lcd_Write_Com(0xEA);
    Lcd_Write_Data(0x00);
    Lcd_Write_Data(0x00);

    Lcd_Write_Com(0xED);
    Lcd_Write_Data(0x64);
    Lcd_Write_Data(0x03);
    Lcd_Write_Data(0X12);
    Lcd_Write_Data(0X81);

    Lcd_Write_Com(0xF7);
    Lcd_Write_Data(0x20);

    Lcd_Write_Com(0xC0);    //Power control
    Lcd_Write_Data(0x23);   // 23 VRH[5:0]

    Lcd_Write_Com(0xC1);    //Power control
    Lcd_Write_Data(0x10);   //SAP[2:0];BT[3:0]

    Lcd_Write_Com(0xC5);    //VCM control
    Lcd_Write_Data(0x3e);   //Contrast
    Lcd_Write_Data(0x28);

    Lcd_Write_Com(0xC7);    //VCM control2
    Lcd_Write_Data(0x86);   //--

    Lcd_Write_Com(0x36);    // Memory Access Control
    Lcd_Write_Data(0x48);   // 48    (28 -> mode paysage, 48 -> mode portrait)

    Lcd_Write_Com(0x3A);  // Pixel format set
    Lcd_Write_Data(0x66); // 55

    Lcd_Write_Com(0xB1);
    Lcd_Write_Data(0x00);
    Lcd_Write_Data(0x18); // 18

    Lcd_Write_Com(0xB6);    // Display Function Control
    Lcd_Write_Data(0x08);
    Lcd_Write_Data(0x82); // 82
    Lcd_Write_Data(0x27);

    Lcd_Write_Com(0x11);    //Exit Sleep
    delay(120);

    Lcd_Write_Com(0x29);    //Display on
    Lcd_Write_Com(0x2c);

    CSUP;
}

void H_line(unsigned int x, unsigned int y, unsigned int l,unsigned char cr,unsigned char cv,unsigned char cb)
{
    unsigned int i;
    CSDOWN;
    Lcd_Write_Com(0x02c); //write_memory_start
    Address_set(x,y,l+x,y);
    for(i=1;i<=l;i++)
    {
        draw_pixel(cr, cv, cb);
    }
    CSUP;
}

void V_line(unsigned int x, unsigned int y, unsigned int l,unsigned char cr,unsigned char cv,unsigned char cb)
{
  unsigned int i;
  CSDOWN;
  Lcd_Write_Com(0x02c); //write_memory_start
  Address_set(x,y,x,l+y);
  for(i=1;i<=l;i++)
  {
      draw_pixel(cr, cv, cb);
  }
  CSUP;
}

void Rect(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned char cr,unsigned char cv,unsigned char cb)
{
  H_line(x  , y  , w, cr, cv, cb);
  H_line(x  , y+h, w, cr, cv, cb);
  V_line(x  , y  , h, cr, cv, cb);
  V_line(x+w, y  , h, cr, cv, cb);
}

void Rectf(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned char cr,unsigned char cv,unsigned char cb)
{
  unsigned int i;
  for(i=0;i<h;i++)
  {
    H_line(x  , y  , w, cr, cv, cb);
    H_line(x  , y+i, w, cr, cv, cb);
  }
}

void LCD_Clear(unsigned char cr,unsigned char cv,unsigned char cb)
{
  unsigned int ii,mm;
  CSDOWN;
  Address_set(0,0,240,320);
  for(ii=0;ii<240;ii++)
    for(mm=0;mm<320;mm++)
    {
        draw_pixel(cr, cv, cb);
    }
  CSUP;
}

void LCD_Arc()
{
    unsigned int ii,mm;
    unsigned char cb = 0, cv = 0, cr = 0;
    CSDOWN;
    Address_set(0,0,240,320);
    for(ii=0;ii<320;ii++) {
        if (ii<80) cr=3*(ii%80);
        else if (ii<160) cr=3*(80-(ii-80)%80);
        else if (ii<240) cb=3*((ii-160)%80);
        else cb=3*(80-(ii-240)%80);
        for(mm=0;mm<240;mm++)
        {
            cv = mm%240;
            draw_pixel(cr, cv, cb);
        }
    }
    CSUP;
}

void LCD_Carre()
{
    unsigned int ii;
    CSDOWN;
    Address_set(10,10,20,20);
    for(ii=0;ii<100;ii++) {
      draw_pixel(0xff, 0xff, 0xff);
    }
    CSUP;
}

/**
 * main.c
 */
void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer

    SetVcoreUp(1);
    SetVcoreUp(2);
    SetVcoreUp(3);

    UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO (32 768)
    __bis_SR_register(SCG0);                  // Disable the FLL control loop
    UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5;                      // Select DCO range 25MHz operation
    UCSCTL2 = FLLD_0 + (FPROC/32768 - 1);     // Set DCO Multiplier for 25MHz (487 pour 16MHz) (761 pour 25MHz)
                                              // (N + 1) * FLLRef = Fdco
                                              // (761 + 1) * 32768 = 25MHz
                                              // Set FLL Div = fDCOCLK
    __bic_SR_register(SCG0);                  // Enable the FLL control loopthen select clock source by write SPI control register (UCSSELx)

    UCSCTL4 |= SELA_3;                  // présence de MCLK/1024 sur P1.0
    UCSCTL5 |= DIVPA_5 | DIVA_5;
    P1DIR |= BIT0;
    P1SEL |= BIT0;

    SPI_Init();
    P6DIR |= 0x0F; // bit0 à 3 en sortie

    RSUP;
    LEDUP;
    CSUP;
    RESETUP;

    Lcd_Init();

    while (1) {
        LCD_Clear(0xff, 0xff, 0xff);
        delay(1000);
        LCD_Clear(0xff, 0x00, 0x00);
        delay(1000);
        LCD_Clear(0x00, 0xff, 0x00);
        delay(1000);
        LCD_Clear(0x00, 0x00, 0xff);
        delay(1000);
        LCD_Arc();
        delay(3000);
        LCD_Carre();
        delay(5000);
        LCD_Clear(0x00, 0x00, 0x00);
        Rect(10,10,100,50,random(256),random(256),random(256));
        /*for(i=0;i<100;i++)
        {
            Rect(random(239),random(319),random(239),random(319),random(256),random(256),random(256)); // rectangle at x, y, width, hight, color
        }*/
        delay(5000);
    }

	__bis_SR_register(LPM4_bits);
}

  • 1) As I read ILI9341 data sheet (ILI9341_DS_V1.02) Sec 19.3.4, the maximum SPI speed is 1/Twc=10MHz. Since you haven't set a divisor, the SPI is running at 25MHz. Add something like this to SPI_Init():

    >  UCB0BR0 = 5;   // SCK=25/5=5MHz

    (You can speed it up gradually later)

    2) You aren't waiting for the SPI to complete before de-asserting /CS. Try changing CSUP to something like:

    > #define CSUP     do {while(UCB0STAT&UCBUSY)/*EMPTY*/; P6OUT|=BIT2; } while(0)

  • Hi, Thank you for reply.

    Sorry for my late answer, i had not check yesterday.

    Yesterday too, i have find the problem. I had set --opt_level 4 on optimisation.

    Since i use level 2 max, i have no problem.

    i keep your solution 2 in mind. I had forgot this issue.

    ILI9341 can take 30MHz SPI too. (my MSP430F5529 is currently running at 30MHz on 3.3V with same program)

    Thank's for all.

**Attention** This is a public forum