CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Noritake GT800X480A-C903P SPI seems to not working

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

Noritake GT800X480A-C903P SPI seems to not working
PostPosted: Fri Aug 24, 2018 1:15 pm     Reply with quote

Has anyone worked with this display in an i2c or spi interface? I am using dsPIC33FJ128GP708A. I have an 2 SPI temperature sensors that work ok. I am using one of the their inputs to interface with the display. I download their libraries but could not make sense of them. They were not written in CCS. It could be that it is Friday and my brain is toasted?
GTCP_SPI_Interface.c
Code:

/**
@author Cody Johnson
@email [email protected]
@website noritake-elec.com
@version v1.1 (ME-N59-1)
@ide IAR
@brief SPI library for MSP430 (MSP-EXP430F5529LP) and Noritake GT-CP modules.

@verbatim
Provide the SPI interface between MSP430 (MSP-EXP430F5529LP) and Noritake GT-CP modules.
@endverbatim
*/

#include "GTCP_SPI_Interface.h"
#include "stdint.h"
#include <stddef.h>

int dataRead;
int statusRead;
int bytesToRead;

/**
Initializes the SPI interface for MSP430 to communicate with a Noritake
GTCP series module.

Wiring reference:
  CS -> P8.1
  MBUSY -> P4.0
  MOSI -> P3.0
  MISO -> P3.1
  SCK -> P3.2

@return none
*/
void initSPI(){
  interface = 1; // interface identifier set to SPI
  WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
 
  P1DIR |= 0x01; //Set P1.0 for LED1 (DEBUG)
 
  P2DIR |= BIT6; //Set P2.6 to an output for CS
  P2OUT |= BIT6; // Set CS
 
  P4DIR &= ~0x01; //Set P4.0 for MBUSY input
  P3SEL |= BIT0 + BIT1 + BIT2; // Select P3.0 (MOSI), P3.1(MISO), P3.2(SCLK) for SPI
 
  UCB0CTL1 |= UCSWRST; // Hold USCI logic in reset state
 
  UCB0CTL0 |= UCMST; // Master mode
  UCB0CTL0 |= UCSYNC; // Synchronous mode
  UCB0CTL0 |= UCCKPL; // High clock polarity
  UCB0CTL0 |= UCMSB; // MSB first
 
  UCB0CTL1 |= UCSSEL_3; // Use the SMCLK
 
  UCB0BR0 = 0x00; // Bit clock prescaler low byte
  UCB0BR1 = 0x00; // Bit clock prescaler high byte
  UCB0CTL1 &= ~UCSWRST; //Release USCI logic for use
  //UCB0IE |= UCRXIE; //Enable RX interrupt
  //UCB0IE |= UCTXIE; //Enable TX interrupt
  P1OUT &= ~0x01;
}

/**
Starts SPI write communication.

@return none
*/
void beginWriteSPI(){
  P2OUT &= ~BIT6; // Lower CS
 
  while(P4IN & 0x01); //Check MBUSY
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = 0x44; // Send write identifier
}

/**
Ends SPI communication

@return none
*/
void endSPI(){
  __delay_cycles(1);
  P2OUT |= BIT6; // Set CS
}

/**
Writes a character to the destination device.
This method must be used after the SPI interface has started.

@param  data The character to be transmitted.
@return none
*/
void writeSPI(char data){
  while(P4IN & 0x01); //Check MBUSY
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = data;
  while(!(UCB0IFG & UCRXIFG)); // Check to see if transmit buffer is empty

}

/**
Writes a string of characters to the destination device.
This method must be used after the SPI interface has started.

@param  data The data to be transmitted.
@return none
*/
void writeStringSPI(char* data){
  for(int i = 0; i < arraySize(data); i++){
    while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
    UCB0TXBUF = data[i];
  }
}

/**
Initialize the GTCP series display.
This method must be used after the SPI interface has started.

@return none
*/
void initGTCP(){

  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = 0x1b;
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = 0x40;
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
}

/**
Start the read sequence for SPI.

@return none
*/
void startSPIRead(){
  P2OUT &= ~BIT6; // Lower CS
  while(P4IN & 0x01); //Check MBUSY
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = 0x54; // Send data read identifier
}

/**
Reads in a single byte from the connected device.
This method must be used after the SPI interface has started.

@return The data read from the device.
*/
uint8_t singleSPIRead(){
  uint8_t rxdata;
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = 0x00; // Send dummy byte
  while(!(UCB0IFG & UCRXIFG)); // think i need this check or else i get garbage
  rxdata = UCB0RXBUF;
  return rxdata;
}

/**
*/
void readSPI(char* data){ // break into startRead, Read and endRead

  uint8_t rxdata;
  if(bytesToRead <= 63){
    P2OUT &= ~BIT6; // Lower CS
    while(P4IN & 0x01); //Check MBUSY
    while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
    UCB0TXBUF = 0x54; // Send data read identifier
    for(int i = 0; i < bytesToRead + 1; i++){
        while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
        UCB0TXBUF = 0x00;
        while(!(UCB0IFG & UCRXIFG)); // think i need this check or else I get garbage
        rxdata = UCB0RXBUF;
        if(rxdata == 0x11){
          dataRead = 0;
        }
        data[i] = rxdata;
    }
    P2OUT |= BIT6; // Release CS
  }
}

/**
Reads the status byte from the device.

@return The number of bytes to be read from the device.
*/
int readSPIStatus(){
  int incomingByte = 0;
  bytesToRead = 0;
  while(P4IN & 0x01); //Check MBUSY
 
  //P8OUT &= ~BIT1; // Lower CS
  P2OUT &= ~BIT6;
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = 0x58; // Send status read identifier
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = 0x00;
  while(!(UCB0IFG & UCRXIFG)); // Check to see if receive buffer has a byte of data
  incomingByte = UCB0RXBUF; // Read data from receive buffer
  __delay_cycles(10); // Avoids a screen clear soft lock error but breaks reading
  if((incomingByte & 0x40) == 0){
    bytesToRead = incomingByte & 0x3F;
  }
  P8OUT |= BIT1; // Release CS
  P2OUT |= BIT6;
  return bytesToRead;
}

#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void){
  switch(__even_in_range(UCB0IV, 4)){
  case 0: //Vector 0 - No Interrupt
    break;
  case 2: //Vector 2 - RXIFG
    //__disable_interrupt();
    if(statusRead){
      while(!(UCB0IFG & UCRXIFG));
      bytesToRead = UCB0RXBUF;
      statusRead = 0;
    }
    if(dataRead){
      for(int i = 0; i < bytesToRead; i++){
        while(!(UCB0IFG & UCRXIFG));
        //RxDataArray[i] = UCB0RXBUF;
      }
      dataRead = 0;
    }
    __disable_interrupt();
    P8OUT |= BIT1;
    break;
  case 4:
    break;
  default:
    break;
  }
}

GTCP_SPI_Interface.h
Code:

/**
@author Cody Johnson
@email [email protected]
@website noritake-elec.com
@version v1.1 (ME-N59-1)
@ide IAR
@brief SPI library for MSP430 (MSP-EXP430F5529LP) and Noritake GT-CP modules.

@verbatim
Provide the SPI interface between MSP430 (MSP-EXP430F5529LP) and Noritake GT-CP modules.
@endverbatim
*/

#ifndef GTCP_SPI_INTERFACE_H
#define GTCP_SPI_INTERFACE_H

#include "io430.h"
#include "stdint.h"

extern int interface;

void initSPI();
void beginWriteSPI();
void endSPI();
void writeSPI(char data);
void writeStringSPI(char* data);
void initGTCP();
void startSPIRead();
uint8_t singleSPIRead();
void readSPI();
int readSPIStatus();

__interrupt void USCI_A0_ISR(void);

#endif
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Fri Aug 24, 2018 1:54 pm     Reply with quote

That is written for a different processor, so you are going to have to flow chart what it actually does, and then translate this to match the ports you want to use on the PIC. So:
Code:

void initSPI(){
  interface = 1; // interface identifier set to SPI
  WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
 
  P1DIR |= 0x01; //Set P1.0 for LED1 (DEBUG)
 
  P2DIR |= BIT6; //Set P2.6 to an output for CS
  P2OUT |= BIT6; // Set CS
 
  P4DIR &= ~0x01; //Set P4.0 for MBUSY input
  P3SEL |= BIT0 + BIT1 + BIT2; // Select P3.0 (MOSI), P3.1(MISO), P3.2(SCLK) for SPI
 
  UCB0CTL1 |= UCSWRST; // Hold USCI logic in reset state
 
  UCB0CTL0 |= UCMST; // Master mode
  UCB0CTL0 |= UCSYNC; // Synchronous mode
  UCB0CTL0 |= UCCKPL; // High clock polarity
  UCB0CTL0 |= UCMSB; // MSB first
 
  UCB0CTL1 |= UCSSEL_3; // Use the SMCLK
 
  UCB0BR0 = 0x00; // Bit clock prescaler low byte
  UCB0BR1 = 0x00; // Bit clock prescaler high byte
  UCB0CTL1 &= ~UCSWRST; //Release USCI logic for use
  //UCB0IE |= UCRXIE; //Enable RX interrupt
  //UCB0IE |= UCTXIE; //Enable TX interrupt
  P1OUT &= ~0x01;
}

1) Disable watchdog.
2)
#define LED_OUT PIN_xx //whatever pin you are using
#define CHIP_CS PIN_yy //whatever pin you are using.
3)
#USE SPI (SPI1, MODE=3, BAUD=4000000)
//The clock supports up to 8MHz max SPI, all transfer on rising edge
//clock idles high = MODE3
4)
enable_interrupts(INT_SPI1);

This is the equivalent to this paragraph.

Then for example:
Code:

void writeSPI(char data){
  while(P4IN & 0x01); //Check MBUSY
  while(!(UCB0IFG & UCTXIFG)); // Check to see if transmit buffer is empty
  UCB0TXBUF = data;
  while(!(UCB0IFG & UCRXIFG)); // Check to see if transmit buffer is empty



If simply:

val=spi_xfer(data);

Reading the return value here ensure the transfer waits to complete (which is what their function does).

etc. etc..
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

The Fog is clearing a little bit
PostPosted: Mon Aug 27, 2018 6:29 am     Reply with quote

Thank you Ttelmah. I will be starting that today. I just needed a refresher, love converting code. Shocked I still think this is the best approach? Shocked Shocked
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Mon Aug 27, 2018 6:39 am     Reply with quote

I'd sit down and work out the basic pin equivalences 'first'. So, it has:

CS -> P8.1
MBUSY -> P4.0
MOSI -> P3.0
MISO -> P3.1
SCK -> P3.2

and

P1.0 for an LED

So draw a table:

P8.1 = PIN_A0 (for example).

Then you can type these equivalents into the code, and perhaps a third of the changes are already done!...
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

PostPosted: Mon Aug 27, 2018 6:42 am     Reply with quote

Wonderful idea..
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group