View previous topic :: View next topic |
Author |
Message |
David Pouzar
Joined: 20 Sep 2005 Posts: 27
|
Noritake GT800X480A-C903P SPI seems to not working |
Posted: Fri Aug 24, 2018 1:15 pm |
|
|
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: 19553
|
|
Posted: Fri Aug 24, 2018 1:54 pm |
|
|
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
|
The Fog is clearing a little bit |
Posted: Mon Aug 27, 2018 6:29 am |
|
|
Thank you Ttelmah. I will be starting that today. I just needed a refresher, love converting code. I still think this is the best approach? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Mon Aug 27, 2018 6:39 am |
|
|
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
|
|
Posted: Mon Aug 27, 2018 6:42 am |
|
|
Wonderful idea.. |
|
|
|