SWE-350 TOTP Generator Milestone 5
The DE-10 board has six 7-segment displays, this can be used to display and generate a time based one-time pin (TOTP).
Loading...
Searching...
No Matches
LCD_Hw.c
Go to the documentation of this file.
1// ============================================================================
2// Copyright (c) 2013 by Terasic Technologies Inc.
3// ============================================================================
4//
5// Permission:
6//
7// Terasic grants permission to use and modify this code for use
8// in synthesis for all Terasic Development Boards and Altera Development
9// Kits made by Terasic. Other use of this code, including the selling
10// ,duplication, or modification of any portion is strictly prohibited.
11//
12// Disclaimer:
13//
14// This VHDL/Verilog or C/C++ source code is intended as a design reference
15// which illustrates how these types of functions can be implemented.
16// It is the user's responsibility to verify their design for
17// consistency and functionality through the use of formal
18// verification methods. Terasic provides no warranty regarding the use
19// or functionality of this code.
20//
21// ============================================================================
22//
23// Terasic Technologies Inc
24// 9F., No.176, Sec.2, Gongdao 5th Rd, East Dist, Hsinchu City, 30070. Taiwan
25//
26//
27// web: http://www.terasic.com/
28// email: support@terasic.com
29//
30// ============================================================================
31
32
33
34
35#include <stdio.h>
36#include <unistd.h>
37#include <fcntl.h>
38#include <sys/mman.h>
39#include <stdarg.h>
40#include "LCD_Hw.h"
41#include "hwlib.h"
42#include "socal/socal.h"
43#include "socal/hps.h"
44#include "socal/alt_gpio.h"
45#include "socal/alt_spim.h"
46#include "socal/alt_rstmgr.h"
47
48//#define USE_SPI_DRIVER
49
50#ifdef USE_SPI_DRIVER
51 #include <sys/ioctl.h>
52 #include <linux/spi/spidev.h>
53 static int lcd_spi_file = 0;
54 struct spi_ioc_transfer spi_xfer;
55#endif
56
57static void *lcd_virtual_base=NULL;
58
59
60 // internal fucniton
61//#define MY_DEBUG(msg, arg...) printf("%s:%s(%d): " msg, __FILE__, __FUNCTION__, __LINE__, ##arg)
62#define MY_DEBUG(msg, arg...)
63void PIO_DC_Set(bool bIsData);
65void SPIM_WriteTxData(uint8_t Data);
66
67
71
72
73#define HW_REGS_BASE ( ALT_STM_OFST )
74#define HW_REGS_SPAN ( 0x04000000 )
75#define HW_REGS_MASK ( HW_REGS_SPAN - 1 )
76
77#define HPS_LCM_D_C_BIT_GPIObit41_GPIOreg1 ( 0x00001000 )
78#define HPS_LCM_RESETn_BIT_GPIObit44_GPIOreg1 ( 0x00008000 )
79#define HPS_LCM_BACKLIHGT_BIT_GPIObit37_GPIOreg1 ( 0x00000100 )
80
81
82
83
85
86 lcd_virtual_base = virtual_base;
87
88
89 //
90 MY_DEBUG("virtual_base = %xh\r\n", (uint32_t)virtual_base);
91
92
97 // set the direction of the HPS GPIO1 bits attached to LCD RESETn to output
98 alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DDR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_RESETn_BIT_GPIObit44_GPIOreg1 );
99 // set the value of the HPS GPIO1 bits attached to LCD RESETn to zero
100 alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_RESETn_BIT_GPIObit44_GPIOreg1 );
101 usleep( 1000000 / 16 );
102 // set the value of the HPS GPIO1 bits attached to LCD RESETn to one
103 alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_RESETn_BIT_GPIObit44_GPIOreg1 );
104 usleep( 1000000 / 16 );
105
110 // set the direction of the HPS GPIO1 bits attached to LCD Backlight to output
111 alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DDR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_BACKLIHGT_BIT_GPIObit37_GPIOreg1 );
112 // set the value of the HPS GPIO1 bits attached to LCD Backlight to ZERO, turn OFF the Backlight
113 alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_BACKLIHGT_BIT_GPIObit37_GPIOreg1 );
114
115
116
120 // set LCD-A0 pin as output pin
121
122 alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DDR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_D_C_BIT_GPIObit41_GPIOreg1 );
123 // set HPS_LCM_D_C to 0
124 alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_D_C_BIT_GPIObit41_GPIOreg1 );
125
126
130 // SPIM0 Init
131#ifdef USE_SPI_DRIVER
132 char *filename = "/dev/spidev32766.0";
133
134 MY_DEBUG("use spi driver = %s\r\n", filename);
135
136 lcd_spi_file = open(filename,O_RDWR);
137 if (lcd_spi_file > 0){
138 uint8_t mode, lsb, bits;
139 uint32_t speed=2500000, max_speed;
140
141 if (ioctl(lcd_spi_file, SPI_IOC_RD_MODE, &mode) < 0)
142 {
143 MY_DEBUG("SPI rd_mode");
144 return;
145 }
146 if (ioctl(lcd_spi_file, SPI_IOC_RD_LSB_FIRST, &lsb) < 0)
147 {
148 MY_DEBUG("SPI rd_lsb_fist");
149 return;
150 }
151 if (ioctl(lcd_spi_file, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
152 {
153 MY_DEBUG("SPI bits_per_word");
154 return;
155 }
156 if (ioctl(lcd_spi_file, SPI_IOC_RD_MAX_SPEED_HZ, &max_speed) < 0)
157 {
158 MY_DEBUG("SPI max_speed_hz");
159 return;
160 }
161 MY_DEBUG("%s: spi mode %d, %d bits %sper word, %d Hz max\n",filename, mode, bits, lsb ? "(lsb first) " : "", max_speed);
162
163 spi_xfer.len = 3; /* Length of command to write*/
164 spi_xfer.cs_change = 0; /* Keep CS activated */
165 spi_xfer.delay_usecs = 0; //delay in us
166 spi_xfer.speed_hz = (speed > max_speed)?max_speed: speed;//2500000, //speed
167 spi_xfer.bits_per_word = bits;//8, // bites per word 8
168 }else{
169 MY_DEBUG("failed to open file = %s(lcd_spi_file=%d)\r\n", filename, lcd_spi_file);
170 }
171
172#else
173
174 usleep( 1000000 / 16 );
175
176 MY_DEBUG("[SPIM0]enable SPIM0 interface\r\n");
177 // initialize the peripheral to talk to the LCM
178 alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_RSTMGR_PERMODRST_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK );
179
180 //===================
181 // step 1: disable SPI
182 // writing 0 to the SSI Enable register (SSIENR).
183 //
184
185 MY_DEBUG("[SPIM0]SPIM0.spi_en = 0 # disable the SPI master\r\n");
186 // [0] = 0, to disalbe SPI
187 alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_SPIENR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_SPIENR_SPI_EN_SET_MSK );
188
189 //===================
190 // step 2: setup
191 // Write Control Register 0 (CTRLLR0).
192 // Write the Baud Rate Select Register (BAUDR)
193 // Write the Transmit and Receive FIFO Threshold Level registers (TXFTLR and RXFTLR) to set FIFO buffer threshold levels.
194 // Write the IMR register to set up interrupt masks.
195 // Write the Slave Enable Register (SER) register here to enable the target slave for selection......
196
197
198 // Transmit Only: Transfer Mode [9:8], TXONLY = 0x01
199 MY_DEBUG("[SPIM0]SPIM0_ctrlr0.tmod = 1 # TX only mode\r\n");
200 alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_CTLR0_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_CTLR0_TMOD_SET_MSK );
201 alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_CTLR0_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_CTLR0_TMOD_SET( ALT_SPIM_CTLR0_TMOD_E_TXONLY ) );
202
203
204 // 200MHz / 64 = 3.125MHz: [15:0] = 64
205 MY_DEBUG("[SPIM0]SPIM0_baudr.sckdv = 64 # 200MHz / 64 = 3.125MHz\r\n");
206 alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_BAUDR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_BAUDR_SCKDV_SET_MSK );
207 alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_BAUDR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_BAUDR_SCKDV_SET( 64 ) );
208
209
210
211 // ss_n0 = 1, [3:0]
212 MY_DEBUG("[SPIM0]SPIM0_ser.ser = 1 #ss_n0 = 1\r\n");
213 alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_SER_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_SER_SER_SET_MSK );
214 alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_SER_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_SER_SER_SET( 1 ) );
215
216
217
218 //===================
219 // step 3: Enable the SPI master by writing 1 to the SSIENR register.
220 // ALT_SPIM0_SPIENR_ADDR
221 MY_DEBUG("[SPIM0]spim0_spienr.spi_en = 1 # ensable the SPI master\r\n");
222 alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_SPIENR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_SPIENR_SPI_EN_SET_MSK );
223
224 // step 4: Write data for transmission to the target slave into the transmit FIFO buffer (write DR)
225 //alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_SPIM0_DR_ADDR ) & ( uint32_t )( ALT_SPIM1_SPIENR_ADDR ) ) ), data16 );
226
227#endif
228
229 MY_DEBUG("[SPIM0]LCD_Init done\r\n");
230
231}
232
233
234
235void LCDHW_BackLight(bool bON){
236 if (bON)
237 alt_setbits_word( ( lcd_virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_BACKLIHGT_BIT_GPIObit37_GPIOreg1 );
238 else
239 alt_clrbits_word( ( lcd_virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_BACKLIHGT_BIT_GPIObit37_GPIOreg1 );
240}
241
242
243
244void LCDHW_Write8(uint8_t bIsData, uint8_t Data){
245
246 static uint8_t bPreIsData=0xFF;
247
248 // set A0
249 if (bPreIsData != bIsData){
250 // Note. cannot change D_C until all tx dara(or command) are sent. i.e. fifo is empty
251 // while(!SPIM_IsTxEmpty()); // wait if buffer is not empty
252
253 PIO_DC_Set(bIsData);
254 bPreIsData = bIsData;
255 }else{
256 // wait buffer is not full
257 // while(SPIM_IsTxFull()); // wait if buffer is full
258 }
259
260
261 SPIM_WriteTxData(Data);
262}
263
264
265
267// internal funciton
269
270void PIO_DC_Set(bool bIsData){
271 // D_C = "H": Data
272 // D_C = "L": CMD
273
274
275 if (bIsData) // A0 = "H": Data
276 alt_setbits_word( ( lcd_virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_D_C_BIT_GPIObit41_GPIOreg1 );
277 else
278 alt_clrbits_word( ( lcd_virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), HPS_LCM_D_C_BIT_GPIObit41_GPIOreg1 );
279}
280
281
282#ifdef USE_SPI_DRIVER
283
285// Write n bytes int the 2 bytes address add1 add2
287void spi_write8(int file, uint8_t Data)
288 {
289 int status;
290
291 spi_xfer.tx_buf = (unsigned long)&Data;
292 spi_xfer.len = 1; /* Length of command to write*/
293 status = ioctl(file, SPI_IOC_MESSAGE(1), &spi_xfer);
294 if (status < 0)
295 {
296 MY_DEBUG("SPI_IOC_MESSAGE");
297 return;
298 }
299 //printf("env: %02x %02x %02x\n", buf[0], buf[1], buf[2]);
300 //printf("ret: %02x %02x %02x %02x\n", buf2[0], buf2[1], buf2[2], buf2[3]);
301
302 //com_serial=1;
303 //failcount=0;
304 }
305
306 #endif
307
308
309
310void SPIM_WriteTxData(uint8_t Data){
311
312#ifdef USE_SPI_DRIVER
313 if (lcd_spi_file > 0)
314 spi_write8(lcd_spi_file, Data);
315#else
316 while( ALT_SPIM_SR_TFE_GET( alt_read_word( ( lcd_virtual_base + ( ( uint32_t )( ALT_SPIM0_SR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ) ) ) != ALT_SPIM_SR_TFE_E_EMPTY );
317 alt_write_word( ( lcd_virtual_base + ( ( uint32_t )( ALT_SPIM0_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), ALT_SPIM_DR_DR_SET( Data ) );
318 while( ALT_SPIM_SR_TFE_GET( alt_read_word( ( lcd_virtual_base + ( ( uint32_t )( ALT_SPIM0_SR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ) ) ) != ALT_SPIM_SR_TFE_E_EMPTY );
319 while( ALT_SPIM_SR_BUSY_GET( alt_read_word( ( lcd_virtual_base + ( ( uint32_t )( ALT_SPIM0_SR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ) ) ) != ALT_SPIM_SR_BUSY_E_INACT );
320#endif
321}
322
323
void * virtual_base
Base for the LCD Used to define the address of the LCD.
Definition 7seg.c:25
#define MY_DEBUG(msg, arg...)
Definition LCD_Hw.c:62
void LCDHW_Init(void *virtual_base)
Definition LCD_Hw.c:84
void LCDHW_Write8(uint8_t bIsData, uint8_t Data)
Definition LCD_Hw.c:244
bool SPIM_IsTxFifoEmpty(void)
#define HW_REGS_MASK
Definition LCD_Hw.c:75
#define HPS_LCM_BACKLIHGT_BIT_GPIObit37_GPIOreg1
Definition LCD_Hw.c:79
#define HPS_LCM_D_C_BIT_GPIObit41_GPIOreg1
Definition LCD_Hw.c:77
void PIO_DC_Set(bool bIsData)
Definition LCD_Hw.c:270
#define HPS_LCM_RESETn_BIT_GPIObit44_GPIOreg1
Definition LCD_Hw.c:78
void LCDHW_BackLight(bool bON)
Definition LCD_Hw.c:235
void SPIM_WriteTxData(uint8_t Data)
Definition LCD_Hw.c:310