Merge pull request #38 from inmarket/master

Add PWM backlight control to Nokia6610GE8
ugfx_release_2.6
Tectu 2013-03-04 02:06:42 -08:00
commit fa2f4b0f19
1 changed files with 238 additions and 196 deletions

View File

@ -1,196 +1,238 @@
/* /*
ChibiOS/GFX - Copyright (C) 2012 ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX. This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* @file drivers/gdisp/Nokia6610GE8/gdisp_lld_board_olimexsam7ex256.h * @file drivers/gdisp/Nokia6610GE8/gdisp_lld_board_olimexsam7ex256.h
* @brief GDISP Graphic Driver subsystem board interface for the Olimex SAM7-EX256 board. * @brief GDISP Graphic Driver subsystem board interface for the Olimex SAM7-EX256 board.
* *
* @addtogroup GDISP * @addtogroup GDISP
* @{ * @{
*/ */
#ifndef _GDISP_LLD_BOARD_H #ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H
// ****************************************************** // ******************************************************
// Pointers to AT91SAM7X256 peripheral data structures // Pointers to AT91SAM7X256 peripheral data structures
// ****************************************************** // ******************************************************
volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA; static volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
volatile AT91PS_PIO pPIOB = AT91C_BASE_PIOB; static volatile AT91PS_PIO pPIOB = AT91C_BASE_PIOB;
volatile AT91PS_SPI pSPI = AT91C_BASE_SPI0; static volatile AT91PS_SPI pSPI = AT91C_BASE_SPI0;
volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; static volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_SPI0; static volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_SPI0;
/** /* The PWM backlight control is non-linear on this board.
* @brief Initialise the board for the display. * We pick values here that make it look a bit more linear.
* @notes Performs the following functions: */
* 1. initialise the spi port used by your display #define PWM_TOP_VALUE 500
* 2. initialise the reset pin (initial state not-in-reset) #define PWM_BOTTOM_VALUE 200
* 3. initialise the chip select pin (initial state not-active)
* 4. initialise the backlight pin (initial state back-light off) #define PWM_VALUE(x) (PWM_BOTTOM_VALUE+(PWM_TOP_VALUE-PWM_BOTTOM_VALUE)*(x)/100)
*
* @notapi /* PWM configuration structure. The LCD Backlight is on PWM1/PB20 ie PWM2/PIN1 in ChibiOS speak */
*/ static const PWMConfig pwmcfg = {
static __inline void init_board(void) { 1000000, /* 1 MHz PWM clock frequency. Ignored as we are using PWM_MCK_DIV_n */
// ********************************************************************************************* 1000, /* PWM period is 1000 cycles. */
// InitSpi( ) NULL,
// {
// Sets up SPI channel 0 for communications to Nokia 6610 LCD Display {PWM_MCK_DIV_1 | PWM_OUTPUT_ACTIVE_HIGH | PWM_OUTPUT_PIN1 | PWM_DISABLEPULLUP_PIN1, NULL},
// },
// I/O ports used: PA2 = LCD Reset (set to low to reset) };
// PA12 = LCD chip select (set to low to select the LCD chip)
// PA16 = SPI0_MISO Master In - Slave Out (not used in LCD interface) static bool_t pwmRunning = FALSE;
// PA17 = SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
// PA18 = SPI0_SPCK Serial Clock (to LCD slave) /**
// PB20 = backlight control (normally PWM control, 1 = full on) * @brief Initialise the board for the display.
// * @notes Performs the following functions:
// *********************************************************************************************} * 1. initialise the spi port used by your display
* 2. initialise the reset pin (initial state not-in-reset)
/* This code should really use the ChibiOS driver for these functions */ * 3. initialise the chip select pin (initial state not-active)
* 4. initialise the backlight pin (initial state back-light off)
// Pin for backlight *
pPIOB->PIO_CODR = PIOB_LCD_BL_MASK; // Set PB20 to LOW * @notapi
pPIOB->PIO_OER = PIOB_LCD_BL_MASK; // Configure PB20 as output */
static __inline void init_board(void) {
// Reset pin // *********************************************************************************************
pPIOA->PIO_SODR = PIOA_LCD_RESET_MASK; // Set PA2 to HIGH // InitSpi( )
pPIOA->PIO_OER = PIOA_LCD_RESET_MASK; // Configure PA2 as output //
// Sets up SPI channel 0 for communications to Nokia 6610 LCD Display
// CS pin - this seems to be ignored //
// pPIOA->PIO_SODR = 1<<12; // Set PA2 to HIGH // I/O ports used: PA2 = LCD Reset (set to low to reset)
// pPIOA->PIO_OER = 1<<12; // Configure PA2 as output // PA12 = LCD chip select (set to low to select the LCD chip)
// PA16 = SPI0_MISO Master In - Slave Out (not used in LCD interface)
// Init SPI0 // PA17 = SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
// Disable the following pins from PIO control (will be used instead by the SPI0 peripheral) // PA18 = SPI0_SPCK Serial Clock (to LCD slave)
// BIT12 = PA12 -> SPI0_NPCS0 chip select // PB20 = backlight control (normally PWM control, 1 = full on)
// BIT16 = PA16 -> SPI0_MISO Master In - Slave Out (not used in LCD interface) //
// BIT17 = PA17 -> SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave) // *********************************************************************************************}
// BIT18 = PA18 -> SPI0_SPCK Serial Clock (to LCD slave)
pPIOA->PIO_PDR = (1<<12) | (1<<16) | (1<<17) | (1<<18); /* This code should really use the ChibiOS driver for these functions */
pPIOA->PIO_ASR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
pPIOA->PIO_BSR = 0; // Pin for backlight
pPIOB->PIO_CODR = PIOB_LCD_BL_MASK; // Set PB20 to LOW
//enable the clock of SPI pPIOB->PIO_OER = PIOB_LCD_BL_MASK; // Configure PB20 as output
pPMC->PMC_PCER = 1 << AT91C_ID_SPI0;
// Reset pin
// Fixed mode pPIOA->PIO_SODR = PIOA_LCD_RESET_MASK; // Set PA2 to HIGH
pSPI->SPI_CR = 0x81; //SPI Enable, Sowtware reset pPIOA->PIO_OER = PIOA_LCD_RESET_MASK; // Configure PA2 as output
pSPI->SPI_CR = 0x01; //SPI Enable
// CS pin - this seems to be ignored
//pSPI->SPI_MR = 0xE0019; //Master mode, fixed select, disable decoder, FDIV=1 (MCK), PCS=1110 // pPIOA->PIO_SODR = 1<<12; // Set PA2 to HIGH
pSPI->SPI_MR = 0xE0011; //Master mode, fixed select, disable decoder, FDIV=0 (MCK), PCS=1110 // pPIOA->PIO_OER = 1<<12; // Configure PA2 as output
//pSPI->SPI_CSR[0] = 0x01010C11; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/32*12 = 125kHz // Init SPI0
pSPI->SPI_CSR[0] = 0x01010311; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/8 = 6MHz if using commented MR line above // Disable the following pins from PIO control (will be used instead by the SPI0 peripheral)
} // BIT12 = PA12 -> SPI0_NPCS0 chip select
// BIT16 = PA16 -> SPI0_MISO Master In - Slave Out (not used in LCD interface)
/** // BIT17 = PA17 -> SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
* @brief Set or clear the lcd reset pin. // BIT18 = PA18 -> SPI0_SPCK Serial Clock (to LCD slave)
* pPIOA->PIO_PDR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
* @param[in] state TRUE = lcd in reset, FALSE = normal operation pPIOA->PIO_ASR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
* pPIOA->PIO_BSR = 0;
* @notapi
*/ //enable the clock of SPI
static __inline void setpin_reset(bool_t state) { pPMC->PMC_PCER = 1 << AT91C_ID_SPI0;
if (state)
palClearPad(IOPORT1, PIOA_LCD_RESET); // Fixed mode
else pSPI->SPI_CR = 0x81; //SPI Enable, Sowtware reset
palSetPad(IOPORT1, PIOA_LCD_RESET); pSPI->SPI_CR = 0x01; //SPI Enable
}
//pSPI->SPI_MR = 0xE0019; //Master mode, fixed select, disable decoder, FDIV=1 (MCK), PCS=1110
/** pSPI->SPI_MR = 0xE0011; //Master mode, fixed select, disable decoder, FDIV=0 (MCK), PCS=1110
* @brief Set the lcd back-light level.
* @note For now 0% turns the backlight off, anything else the backlight is on. //pSPI->SPI_CSR[0] = 0x01010C11; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/32*12 = 125kHz
* While the hardware supports PWM backlight control, we are not using it pSPI->SPI_CSR[0] = 0x01010311; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/8 = 6MHz if using commented MR line above
* yet.
* /* Display backlight control at 100% */
* @param[in] percent 0 to 100% pwmRunning = FALSE;
* palSetPad(IOPORT2, PIOB_LCD_BL);
* @notapi }
*/
static __inline void set_backlight(uint8_t percent) { /**
if (percent) * @brief Set or clear the lcd reset pin.
palSetPad(IOPORT2, PIOB_LCD_BL); *
else * @param[in] state TRUE = lcd in reset, FALSE = normal operation
palClearPad(IOPORT2, PIOB_LCD_BL); *
} * @notapi
*/
/** static __inline void setpin_reset(bool_t state) {
* @brief Take exclusive control of the bus if (state)
* palClearPad(IOPORT1, PIOA_LCD_RESET);
* @notapi else
*/ palSetPad(IOPORT1, PIOA_LCD_RESET);
static __inline void acquire_bus(void) { }
/* Nothing to do for this board as the LCD is the only device on the SPI port */
} /**
* @brief Set the lcd back-light level.
/** * @note For now 0% turns the backlight off, anything else the backlight is on.
* @brief Release exclusive control of the bus * While the hardware supports PWM backlight control, we are not using it
* * yet.
* @notapi *
*/ * @param[in] percent 0 to 100%
static __inline void release_bus(void) { *
// Nothing to do for this board as the LCD is the only device on the SPI port * @notapi
} */
static __inline void set_backlight(uint8_t percent) {
/** if (percent == 100) {
* @brief Send an 8 bit command to the lcd. /* Turn the pin on - No PWM */
* if (pwmRunning) {
* @param[in] cmd The command to send pwmStop(&PWMD2);
* pwmRunning = FALSE;
* @notapi }
*/ palSetPad(IOPORT2, PIOB_LCD_BL);
static __inline void write_cmd(uint16_t cmd) { } else if (percent == 0) {
// wait for the previous transfer to complete /* Turn the pin off - No PWM */
while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); if (pwmRunning) {
// send the command pwmStop(&PWMD2);
pSPI->SPI_TDR = cmd & 0xFF; pwmRunning = FALSE;
} }
palClearPad(IOPORT2, PIOB_LCD_BL);
/** } else {
* @brief Send an 8 bit data to the lcd. /* Use the PWM */
* if (!pwmRunning) {
* @param[in] data The data to send pwmStart(&PWMD2, &pwmcfg);
* pwmRunning = TRUE;
* @notapi }
*/ pwmEnableChannel(&PWMD2, 0, PWM_VALUE(percent));
static __inline void write_data(uint16_t data) { }
// wait for the previous transfer to complete }
while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
// send the data /**
pSPI->SPI_TDR = data | 0x0100; * @brief Take exclusive control of the bus
} *
* @notapi
#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__) */
/** static __inline void acquire_bus(void) {
* @brief Read data from the lcd. /* Nothing to do for this board as the LCD is the only device on the SPI port */
* }
* @return The data from the lcd
* /**
* @notapi * @brief Release exclusive control of the bus
*/ *
static __inline uint16_t read_data(void) { * @notapi
#error "gdispNokia6610GE8: GDISP_HARDWARE_READPIXEL and GDISP_HARDWARE_SCROLL are not supported on this board" */
return 0; static __inline void release_bus(void) {
} // Nothing to do for this board as the LCD is the only device on the SPI port
#endif }
#endif /* _GDISP_LLD_BOARD_H */ /**
/** @} */ * @brief Send an 8 bit command to the lcd.
*
* @param[in] cmd The command to send
*
* @notapi
*/
static __inline void write_cmd(uint16_t cmd) {
// wait for the previous transfer to complete
while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
// send the command
pSPI->SPI_TDR = cmd & 0xFF;
}
/**
* @brief Send an 8 bit data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static __inline void write_data(uint16_t data) {
// wait for the previous transfer to complete
while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
// send the data
pSPI->SPI_TDR = data | 0x0100;
}
#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
/**
* @brief Read data from the lcd.
*
* @return The data from the lcd
*
* @notapi
*/
static __inline uint16_t read_data(void) {
#error "gdispNokia6610GE8: GDISP_HARDWARE_READPIXEL and GDISP_HARDWARE_SCROLL are not supported on this board"
return 0;
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */