Add new board: SAM3X-EK
[bertos.git] / boards / sam3x-ek / hw / hw_hx8347.h
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \brief HX8347 low-level hardware macros for Atmel SAM3X-EK board.
34  *
35  * The LCD controller is connected to the cpu static memory controller.
36  * LCD has 16 data lines and usual RS/WR/RD lines.  The data lines
37  * are connected to the SMC data bus (D0-15), while the SCM address bus
38  * (A1 only) is used to drive the RS pin.  WR/RD are connected to SMC's
39  * NWE and NRD respectively.
40  *
41  * \author Stefano Fedrigo <aleph@develer.com>
42  */
43
44 #ifndef HW_HX8347_H
45 #define HW_HX8347_H
46
47 #include "cfg/macros.h"
48 #include <io/sam3.h>
49
50
51 /*
52  * LCD I/O pins/ports and peripherals
53  */
54 #define LCD_DATABUS_PINS    (0xFFFF << 2)
55 #define LCD_DATABUS_PORT    PIOC_BASE
56 #define LCD_DATABUS_PERIPH  PIO_PERIPH_A
57
58 #define LCD_NRD_PIN         BV(29)
59 #define LCD_NRD_PORT        PIOA_BASE
60 #define LCD_NRD_PERIPH      PIO_PERIPH_B
61
62 #define LCD_NWE_PIN         BV(18)
63 #define LCD_NWE_PORT        PIOC_BASE
64 #define LCD_NWE_PERIPH      PIO_PERIPH_A
65
66 #define LCD_NCS2_PIN        BV(24)
67 #define LCD_NCS2_PORT       PIOB_BASE
68 #define LCD_NCS2_PERIPH     PIO_PERIPH_B
69
70 #define LCD_RS_PIN          BV(22)
71 #define LCD_RS_PORT         PIOC_BASE
72 #define LCD_RS_PERIPH       PIO_PERIPH_A
73
74
75 // How many cpu clocks per nanosecond.
76 #define CLOCKS_PER_NS(ns)  ((uint32_t)((ns * (CPU_FREQ/1000000)) / 1000) + 1)
77
78
79 // LCD Base Address, chip select 2
80 #define LCD_BASE  0x62000000
81
82 // LCD index register address
83 #define LCD_IR  (*(uint16_t *)(LCD_BASE))
84
85 // LCD data address (A1 drives RS signal)
86 #define LCD_D   (*(uint16_t *)(LCD_BASE + 2))
87
88 /**
89  * Send a command to LCD controller.
90  */
91 INLINE void hx8347_cmd(uint8_t cmd)
92 {
93     LCD_IR = cmd;
94 }
95
96 /**
97  * Send data to LCD controller.
98  */
99 INLINE void hx8347_write(uint16_t data)
100 {
101     LCD_D = data;
102 }
103
104 /**
105  * Read data from LCD controller.
106  */
107 INLINE uint16_t hx8347_read(void)
108 {
109     return LCD_D;
110 }
111
112 /**
113  * Bus initialization: on SAM3X-EK the display is wired
114  * on the static memory controller, chip select 2.
115  */
116 INLINE void hx8347_busInit(void)
117 {
118     // Configure pins: disable PIO...
119         HWREG(LCD_DATABUS_PORT + PIO_PDR_OFF) = LCD_DATABUS_PINS;
120         HWREG(LCD_NRD_PORT     + PIO_PDR_OFF) = LCD_NRD_PIN;
121         HWREG(LCD_NWE_PORT     + PIO_PDR_OFF) = LCD_NWE_PIN;
122         HWREG(LCD_NCS2_PORT    + PIO_PDR_OFF) = LCD_NCS2_PIN;
123         HWREG(LCD_RS_PORT      + PIO_PDR_OFF) = LCD_RS_PIN;
124
125         // ... enable pull-up...
126         HWREG(LCD_DATABUS_PORT + PIO_PUER_OFF) = LCD_DATABUS_PINS;
127         HWREG(LCD_NRD_PORT     + PIO_PUER_OFF) = LCD_NRD_PIN;
128         HWREG(LCD_NWE_PORT     + PIO_PUER_OFF) = LCD_NWE_PIN;
129         HWREG(LCD_NCS2_PORT    + PIO_PUER_OFF) = LCD_NCS2_PIN;
130         HWREG(LCD_RS_PORT      + PIO_PUER_OFF) = LCD_RS_PIN;
131
132         // ... and select appropriate peripheral.
133         PIO_PERIPH_SEL(LCD_DATABUS_PORT, LCD_DATABUS_PINS, LCD_DATABUS_PERIPH);
134         PIO_PERIPH_SEL(LCD_NRD_PORT, LCD_NRD_PIN, LCD_NRD_PERIPH);
135         PIO_PERIPH_SEL(LCD_NWE_PORT, LCD_NWE_PIN, LCD_NWE_PERIPH);
136         PIO_PERIPH_SEL(LCD_NCS2_PORT, LCD_NCS2_PIN, LCD_NCS2_PERIPH);
137         PIO_PERIPH_SEL(LCD_RS_PORT, LCD_RS_PIN, LCD_RS_PERIPH);
138
139     // Enable peripheral clock
140         PMC_PCER = SMC_SDRAMC_ID;
141
142     // Static memory controller configuration
143     SMC_SETUP2 =
144                 SMC_SETUP_NWE_SETUP(CLOCKS_PER_NS(10)) |
145                 SMC_SETUP_NCS_WR_SETUP(CLOCKS_PER_NS(10)) |
146                 SMC_SETUP_NRD_SETUP(CLOCKS_PER_NS(90)) |
147                 SMC_SETUP_NCS_RD_SETUP(CLOCKS_PER_NS(90));
148
149     SMC_PULSE2 =
150                 SMC_PULSE_NWE_PULSE(CLOCKS_PER_NS(35)) |
151                 SMC_PULSE_NCS_WR_PULSE(CLOCKS_PER_NS(35)) |
152                 SMC_PULSE_NRD_PULSE(CLOCKS_PER_NS(355)) |
153                 SMC_PULSE_NCS_RD_PULSE(CLOCKS_PER_NS(355));
154
155     SMC_CYCLE2 =
156                 SMC_CYCLE_NWE_CYCLE(CLOCKS_PER_NS(100)) |
157                 SMC_CYCLE_NRD_CYCLE(CLOCKS_PER_NS(460));
158
159     SMC_MODE2 =
160                 SMC_MODE_WRITE_MODE | SMC_MODE_READ_MODE | SMC_MODE_DBW;
161 }
162
163 #endif /* HW_HX8347_H */