24
Now we must send the correct signals over the MOSI line!!! Design and implementation details on the way to a valid SPI-LCD interface driver

Now we must send the correct signals over the MOSI line!!! Design and implementation details on the way to a valid SPI-LCD interface driver

  • View
    218

  • Download
    0

Embed Size (px)

Citation preview

Now we must send the correct signals over the

MOSI line!!!

Design and implementation details on the way to a valid

SPI-LCD interface driver

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

2 / 24

To be tackled today

All the new SPI stuff about “trying to get the code to work”• We want the code “to work in someway – even if very

slowly”

• Later we could “refactor the code for speed”Meaning if I can find the time to get the DMA to work (and it is easy to do) we will get that bit going in Lab. 4 as a bonus (or is very easy as part of Lab. 4

Look at first 3 tasks of Lab. 4

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

3 / 24

Review -- Master / Slave conceptSlave Select (Chip Select)We put a value into the Blackfin

SPI_TDBR register

Blackfin sends out active low chip select signal PF5

Blackfin sends out the “value-bits” on the MOSI signal.

Slave accepts signal as SS1 is connected to PF5

When PF5 line goes high then Slave will send values to the LCD display.

If we get the first step correct – then everything else should happen automatically – provided we have set up the SPI interface correctly

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

4 / 24

Review -- Blackfin transmits 16 bits using MSB-first format over the MOSI line

DB7, DB6, ………DB1, DB0

RS

1 – LCD data

0 – LCD instruction

R/W

1 – Read from LCD

0 – Write to LCD

E – Enable / Strobe

1 0 – When this line goes from high to the low, then the command is send to (latched into) LCD

To make LCD respond to command 0x4F0Then Blackfin must transmit 0x5F0 ( E High )0x4F0 ( E low )0x5F0 ( E high )

Now we care

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

5 / 24

LCD_Display (int, char*, char *);First attempt – may refactor later

#include <string.h>

LCD_Display (int lcd, char * type, char *operation) {

if (strcmp(type, “COMMAND”) == 0) { if (strcmp(operation, “CLEAR_SCREEN”) == 0) ClearScreen( );

if (strcmp(operation, “……..”) == 0) Do……..( );

}

if (strcmp(type, “DATA”) == 0) { if (strcmp(operation, “DISPLAY_TEMPERATURE”) == 0) DisplayTemperature( ); else WriteLetter(operation[0]); // First character

}}

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

6 / 24

We need to toggle that E-flag (and wait) to make “slow” LCD work

#define EN_LINE_HIGH 0x0100#define EN_LINE_LOW 0x0000#define ISDATA 0x400

ClearScreen( ) { WriteSPIASM(EN_LINE_HIGH | 0x0001); WaitABit(40 us); WriteSPIASM(EN_LINE_LOW | 0x0001); WaitABit(1.4 ms); WriteSPIASM(EN_LINE_HIGH | 0x0001); WaitABit(40 us); }

WriteLetter(char letter) { WriteSPIASM(EN_LINE_HIGH | ISDATA | letter); WaitABit(40 us);

WriteSPIASM(EN_LINE_HIGH | ISDATA | letter); WaitABit(40 us);WriteSPIASM(EN_LINE_LOW | ISDATA | letter); WaitABit(40 us);

CursorMove( ); ??????}// Just ONE routine to work -- to make Lab. 4 to work !!!!!!!!!!

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

7 / 24

SPI-Tests – InitializationSet_SPIregisters_ASM(ulong BAUD_SCALE)

#include <cdefsBF533.h>#define BAUD_SCALE 0x8000 // Make system slow so we can scope the data transfers

TEST(SET_SPI_Registers, ConfigureSPIregisters) {

WatchDataClass<unsigned short> spi_reg(4, pSPI_BAUD, pSPI_CTL, pSPI_FLG, pSPI_STAT);

WATCH_MEMORY_RANGE(spi_reg, (Set_SPIregisters_ASM(BAUD_SCALE)), READ_CHECK | WRITE_CHECK);

// Warning – many of the SPI_STAT bits are W1C – write 1 to clear – DON”T write 0’s

USHORTS_EQUAL(spi_reg.getFinalValue(0), BAUD_SCALE); USHORTS_EQUAL((spi_reg.getStartValue(1) | 0x01 | /* SPE | */ MSTR | CPOL | /* CPHA | */ SIZE),

spi_reg.getFinalValue(1)); USHORTS_EQUAL((spi_reg.getStartValue(2) | FLS5), spi_reg.getFinalValue(2)); USHORTS_EQUAL(spi_reg.getStartValue(3), 1); // Reset value is 1

CHECK(spi_reg.getReadsWrites() == 5); // May be a different number in your code

}

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

8 / 24

volatile bool transmit_empty; // FLAG / SEMAPHORE

volatile unsigned short transmit_value; // MESSAGE TO ISR

EX_INTERRUPT_HANDLER(SPI_ISR) {SPI_TDBR transmit_value;

transmit_empty = true; Clear the interrupt signal so don’t re-enter ISR}

void WriteSPI(unsigned short int value ) {while (transmit_empty = = false)

/* wait for a signal from the ISR to say ready for next */ ;transmit_empty = false;

transmit_value value; // Store the value as a message for ISR}

Not the “best solution” (that needs DMA stuff) – but would it work?????

WE KNOW WE DON’T NEED THIS LINE

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

9 / 24

Concept

We write 16-bits (0xFF0A) into SPI_TDBR Hardware transfers this to SHIFT register

• SPI_TDBR now empty – new interrupt occurs For next 16 ticks of SPI clock

• Hardware sends out 1 bit from shift register over MOSI line to SLAVE each clock tick – speeds up to 25 MHz per bit

• Hardware receives 1 bit over MISO line from the SLAVE and puts into shift register each clock tick – speeds up to 25 MHz per bit

Hardware transfers shift register value (from slave) into SPI_RDBR (receive DBR)• SPI_RDBR is now FULL

This transmission over a serial line (16-bits 1 at a time) is much slower than other internal Blackfin operation• Must be handled via interrupt control

0x F F 0 A

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

10 / 24

Can we write this sort of test to make things work on the SPI interface?

EX_INTERRUPT_HANDLER(spi_ISR);

TEST(WriteSPIValue, ConfigureSPIregisters) {

InitSPI_ASM(0x800); register_handler(?????, SPI_ISR); Set_SIC_IMASK_ASM(0x2000); // Set the SIC_IMASK as we needed to do // in Lab. 3 to make the general purpose timer interrupts work StartSPI( );

WriteSPI(0x0A); // Connect SPI interface to LED’s on logic station WriteSPI(0xFF05); // Values should be there WriteSPI(0x0F0F); // Look at values on MOSI line with scope // SOMETHING should be there EVEN IF INVALID // Need to look at both MOSI and PF5 }

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

11 / 24

Things we DO and DON’T want to happen

PF5 line

MOSI signal3 words

transmitted

WORD 1 RECEIVEDBY SLAVE BUT NOT

SENT ONTO LCD

PF HIGHSLAVE IGNORES

BLACKFIN

PF LOWSLAVE LISTENS

TO BLACKFIN

WORD 2 RECEIVEDBY SLAVE ANDSENT TO LCD

SLAVE SENDSCOMMAND TO LCD

WORD 3 IGNOREDBY SLAVE AND NOT

SENT ONTO LCD

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

12 / 24

SPI_registers Hardware Chap. 10-16

SPI Status register – Has SPI finished the transfer?

void WaitWhileSPIF_ASM(low / high)

Wait while SPI low (not finished)

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

13 / 24

volatile bool transmit_empty; // FLAG / SEMAPHORE

volatile unsigned short transmit_value; // MESSAGE TO ISR

EX_INTERRUPT_HANDLER(SPI_ISR) {SPI_TDBR transmit_value;

transmit_empty = true; Clear the interrupt signal so don’t re-enter ISR}

void WriteSPI(unsigned short int value ) {while (*transmit_empty = = false)

/* wait for a signal from the ISR to say ready for next */ ; WaitWhileSPIF(0x0); /* Wait for HARDWARE SIGNAL */ transmit_empty = false; transmit_value value; // Store the value as a message for ISR}

Not the “best solution” (that needs DMA stuff) – but would it work?????

Don’t need this lineLOOK FOR

SPIF bit instead(SPI_FINISHED)

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

14 / 24

Would that really work?void WriteSPI(unsigned short int value ) {

WaitWhileSPIF(0x0); /* Wait for HARDWARE SIGNAL */ transmit_value value; // Store the value as a message for ISR}

Possible RACE condition problem Might WriteSPI( ) put many values into the transmit buffer before

ANY are transmitted?

Does it depend on how fast Blackfin is compared to SPI interface

Answer: I don’t know till I try stuff and see if a problem.

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

15 / 24

PF5 line

MOSI signal3 words

transmitted

WORD 1 RECEIVEDBY SLAVE BUT NOT

SENT ONTO LCD

WORD 2 RECEIVEDBY SLAVE ANDSENT TO LCD

WORD 3 IGNOREDBY SLAVE AND NOT

SENT ONTO LCD

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

16 / 24

PF5 line

MOSI signal2 words

transmitted

WORD 1 RECEIVEDBY SLAVE BUT NOT

SENT ONTO LCD

WORD 2 RECEIVEDBY SLAVE ANDSENT TO LCD

If look at signal with an “ultra-high-speed”scope then can see PF line go high for“a very short period of time”. Blackfinis “too fast” for interface

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

17 / 24

Need to slow things down a bitor take different approach?void WriteSPI(unsigned short int value ) {

WaitWhileSPIF(0x0); /* Wait for HARDWARE SIGNAL */ transmit_value value; // Store the value as a message for ISR WaitAwhile(??? How-long is enough); // Is this the right location for the wait?

// DO we need this instead (or perhaps -- as well as) to solve race conditions? // WaitWhileSPIF(0x1); /* Wait for HARDWARE SIGNAL */}

This is beginning to sound like “epi-cycles – on epi-cycles” as we work out how the planets go around the sun.

It might (just work) for this laboratory but we should really be looking at letting the hardware worry about the timing

Put all the messages in a long array

Set DMA registers to point to start of array. Activate both SPI and DMA and let the Blackfin do the job. That is what it was designed for!!!!!!!!!!!!!

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

18 / 24

WORD 1 RECEIVEDBY SLAVE AND

SENT ONTO LCD

WORD 2 RECEIVEDBY SLAVE ANDSENT TO LCD

WORD 3 RECEIVEDBY SLAVE AND

SENT ONTO LCD

VALUES GOING TO LCD

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

19 / 24

So do we think we are in good shape to get Lab. 4 started?

Task 1 – same as Task 1 in Lab. 3

Set up the Lab4 and Lab4Test directories Make the Lab4.prj and Lab4Test projects Write a simple Lab4main to check that the Blackfin and

the 50-pin cable are still working Check that all the Lab1, Lab2 and Lab3 tests work. Select

“exclude from build” for Lab2 and Lab3 tests if you want. • Remove the _FCT_Lab3.cpp file

• Don’t forget to “Refresh connections” using the GUI interface

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

20 / 24

Lets not tackle too many things at once. Show ability to recognize commands and data -- Task 2extern volatile bool centigrade;extern volatile short int temperature;

char *LCDcommands[ ] = { "COMMAND", "INIT_LCD", "COMMAND", "CLEAR_SCREEN",

"COMMAND", "MOVE_TO_LINE_1", "COMMAND", "CLEAR_LINE_1", "DATA", "4", "DATA", "1", "DATA", "5",

"COMMAND", "MOVE_TO_LINE_2", "COMMAND", "CLEAR_LINE_2", "DATA_TEMPERATURE", "TEMPERATURE_DISPLAY", NULL, NULL};

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

21 / 24

Lab 4 main( ) – first attemptSimulate the LCD screen

int main( ) {

long int switch_result = 0; Initialize_ProgrammableFlagsASM( ); InitializeLEDInterfaceASM( );

char **pt = LCDcommands; // Point to the start of the commands char *type_of_operation = NULL; // what needs to be done char *which_operation = NULL;

centigrade = true; temperature = 40; while (*pt != NULL) { // While there are commands to do type_of_operation = *pt++; which_operation = *pt++; LCD_Display( LCD_SIMULATION, type_of_operation, which_operation); }}

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

22 / 24

First attempt to get the LCD_Display to work

void LCD_Display( int which_LCD_version, char *type_of_operation, char *which_operation) { char small_string[2]; small_string[1] = '\0'; // I used this when printing out the temperature if (strcmp(type_of_operation, "DATA_TEMPERATURE") == 0) { // Recursively use LCD_Display( ) to print out each digit of temperature // followed by a ‘C” or and “F” return; }

if (which_LCD_version == LCD_SIMULATION) { printf(“Group name here %s %s\n", type_of_operation, which_operation); return; }}

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

23 / 24

Task 3 – Test out the interface -- Lights Connect the special Blackfin interface (logic lab) CJ7 and

CJ8 lines to the logic lab lights – make sure that the bit order and wires are correct, otherwise you will be paying $2 into the Zoo Christmas “support a family fund”

Connect the MOSI, PF5 and CLK lines Download and run the program “SPILightstrial.dxe”

• The lights will flash from right-to-left if the wires are hooked up correctly

• If you press and release SW3, then the program will stop

Later, when the LCD needs testing we will use this program again

04/19/23 SPI and LCD , Copyright M. Smith, ECE, University of Calgary, Canada

24 / 24

Information taken from Analog Devices On-line Manuals with permission http://www.analog.com/processors/resources/technicalLibrary/manuals/

Information furnished by Analog Devices is believed to be accurate and reliable. However, Analog Devices assumes no responsibility for its use or for any infringement of any patent other rights of any third party which may result from its use. No license is granted by implication or otherwise under any patent or patent right of Analog Devices. Copyright Analog Devices, Inc. All rights reserved.