/*##############################################################*/ /* */ /* File : tft.c */ /* */ /* Project : TFT for Raspberry Pi Revision 2 */ /* */ /* Date : 2014-08-14 last update: 2014-08-14 */ /* */ /* Author : Hagen Ploog */ /* Kai Gillmann */ /* Timo Pfander */ /* */ /* IDE : Geany 1.22 */ /* Compiler : gcc (Debian 4.6.3-14+rpi1) 4.6.3 */ /* */ /* Copyright (C) 2013 admatec GmbH */ /* */ /* */ /* Description : */ /* */ /* This file controlls the communications between the */ /* Raspberry Pi and the TFT. The file initialized also the */ /* GPIO Pins of the Raspberry Pi. */ /* */ /* */ /* License: */ /* */ /* This program is free software; you can redistribute it */ /* and/or modify it under the terms of the GNU General */ /* Public License as published by the Free Software */ /* Foundation; either version 3 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will */ /* be useful, but WITHOUT ANY WARRANTY; without even the */ /* implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */ /* Public License for more details. */ /* */ /* You should have received a copy of the GNU General */ /* Public License along with this program; if not, */ /* see . */ /* */ /* */ /* Revision History: */ /* */ /* Version 1.0 - Initial release */ /* */ /* */ /* */ /*##############################################################*/ #include #include #include "RAIO8870.h" #include "tft.h" // initialization of GPIO and SPI // ---------------------------------------------------------- void TFT_init_board ( void ) { // *************** set the pins to be an output and turn them on bcm2835_gpio_fsel( OE, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_write( OE, HIGH ); bcm2835_gpio_fsel( RAIO_RST, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_write( RAIO_RST, HIGH ); bcm2835_gpio_fsel( RAIO_CS, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_write( RAIO_CS, HIGH ); bcm2835_gpio_fsel( RAIO_RS, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_write( RAIO_RS, HIGH ); bcm2835_gpio_fsel( RAIO_WR, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_write( RAIO_WR, HIGH ); bcm2835_gpio_fsel( RAIO_RD, BCM2835_GPIO_FSEL_OUTP ); bcm2835_gpio_write( RAIO_RD, HIGH ); // *************** now the inputs bcm2835_gpio_fsel( RAIO_WAIT, BCM2835_GPIO_FSEL_INPT ); bcm2835_gpio_set_pud( RAIO_WAIT, BCM2835_GPIO_PUD_UP); bcm2835_gpio_fsel( RAIO_INT, BCM2835_GPIO_FSEL_INPT ); bcm2835_gpio_set_pud( RAIO_INT, BCM2835_GPIO_PUD_UP); bcm2835_gpio_fsel( MISO, BCM2835_GPIO_FSEL_INPT ); bcm2835_gpio_set_pud( MISO, BCM2835_GPIO_PUD_UP); // *************** set pins for SPI //bcm2835_gpio_fsel(MISO, BCM2835_GPIO_FSEL_ALT0); bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_ALT0); bcm2835_gpio_fsel(SCLK, BCM2835_GPIO_FSEL_ALT0); bcm2835_gpio_fsel(SPI_CE1, BCM2835_GPIO_FSEL_ALT0); // set the SPI CS register to the some sensible defaults volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/8; bcm2835_peri_write( paddr, 0 ); // All 0s // clear TX and RX fifos bcm2835_peri_write_nb( paddr, BCM2835_SPI0_CS_CLEAR ); bcm2835_spi_setBitOrder( BCM2835_SPI_BIT_ORDER_MSBFIRST ); bcm2835_spi_setDataMode( BCM2835_SPI_MODE0 ); bcm2835_spi_setClockDivider( BCM2835_SPI_CLOCK_DIVIDER_2 ); bcm2835_spi_chipSelect( BCM2835_SPI_CS1 ); bcm2835_spi_setChipSelectPolarity( BCM2835_SPI_CS1, LOW ); } // hard reset of the graphic controller and the tft // ---------------------------------------------------------- void TFT_hard_reset( void ) { bcm2835_gpio_write( RAIO_RST, LOW ); bcm2835_delay( 10 ); bcm2835_gpio_write( RAIO_RST, HIGH ); bcm2835_delay( 1 ); } // wait during raio is busy // ---------------------------------------------------------- void TFT_wait_for_raio ( void ) { while ( !bcm2835_gpio_lev( RAIO_WAIT ) ); } // write data via SPI to tft // ---------------------------------------------------------- void TFT_SPI_data_out ( uint16_t data ) { union my_union number; char buffer[2]; number.value = data; buffer[0] = (char) number.split.high; buffer[1] = (char) number.split.low; bcm2835_spi_writenb( &buffer[0], 2 ); } uint32_t TFT_shift_data_in() { uint32_t i, data=0; //, data1, data2; // Das Umschalten ist der 1te Puls ... ups bcm2835_gpio_fsel( SCLK, BCM2835_GPIO_FSEL_OUTP ); for ( i=15; i>0; i-- ) { data <<= 1; data |= ( bcm2835_gpio_lev( MISO ) ? 0x00000001 : 0x00000000 ); //bcm2835_delayMicroseconds( 1 ); bcm2835_gpio_write( SCLK, LOW ); //bcm2835_delayMicroseconds( 1 ); bcm2835_gpio_write( SCLK, HIGH ); } //data = bcm2835_spi_transfer( 0 ); bcm2835_gpio_fsel(SCLK, BCM2835_GPIO_FSEL_ALT0); return ( data ); } // write byte to register // ---------------------------------------------------------- void TFT_RegWrite( uint16_t reg ) { bcm2835_gpio_write( RAIO_RS, HIGH ); bcm2835_gpio_write( RAIO_CS, LOW ); bcm2835_gpio_write( RAIO_WR, LOW ); bcm2835_gpio_write( OE, LOW ); TFT_SPI_data_out ( reg ); bcm2835_gpio_write( RAIO_WR, HIGH ); bcm2835_gpio_write( RAIO_CS, HIGH ); bcm2835_gpio_write( OE, HIGH ); } // write byte to tft // ---------------------------------------------------------- void TFT_DataWrite( uint16_t data ) { bcm2835_gpio_write( RAIO_RS, LOW ); bcm2835_gpio_write( RAIO_CS, LOW ); bcm2835_gpio_write( RAIO_WR, LOW ); bcm2835_gpio_write( OE, LOW ); TFT_SPI_data_out ( data ); bcm2835_gpio_write( RAIO_WR, HIGH ); bcm2835_gpio_write( RAIO_CS, HIGH ); bcm2835_gpio_write( OE, HIGH ); }; // read byte from register // ---------------------------------------------------------- uint16_t TFT_DataRead( ) { uint16_t data; bcm2835_gpio_write( RAIO_RS, LOW ); bcm2835_gpio_write( RAIO_CS, LOW ); bcm2835_gpio_write( RAIO_RD, LOW ); bcm2835_delayMicroseconds( 1 ); bcm2835_gpio_write( RAIO_RD, HIGH ); bcm2835_gpio_write( RAIO_CS, HIGH ); data = TFT_shift_data_in(); return ( data ); } // read byte from register // ---------------------------------------------------------- uint16_t TFT_StatusRead( ) { uint16_t data; bcm2835_gpio_write( RAIO_RS, HIGH ); bcm2835_gpio_write( RAIO_CS, LOW ); bcm2835_gpio_write( RAIO_RD, LOW ); bcm2835_delayMicroseconds( 1 ); bcm2835_gpio_write( RAIO_RD, HIGH ); bcm2835_gpio_write( RAIO_CS, HIGH ); data = TFT_shift_data_in(); return ( data ); } // write 'count'-bytes to tft // ---------------------------------------------------------- void TFT_DataMultiWrite( uint16_t *data, uint32_t count ) { volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; volatile uint32_t* gpio_set = bcm2835_gpio + BCM2835_GPSET0/4; volatile uint32_t* gpio_clear = bcm2835_gpio + BCM2835_GPCLR0/4; uint32_t i; bcm2835_gpio_write( RAIO_RS, LOW ); bcm2835_gpio_write( RAIO_CS, LOW ); bcm2835_gpio_write( OE, LOW ); for( i=0; i> 8); *fifo = (uint8_t)(data[i] & 0xFF); // write fifo data to SPI TX buffer while (!(*paddr & BCM2835_SPI0_CS_DONE)) { // clear SPI RX buffer *paddr |=BCM2835_SPI0_CS_CLEAR_RX; }; // deactivate SPI transfer *paddr &= ~BCM2835_SPI0_CS_TA; // WR = 1 *gpio_set = ( 1 << RAIO_WRpin ); } bcm2835_gpio_write( RAIO_CS, HIGH ); bcm2835_gpio_write( OE, HIGH ); }