/*
 * main.c
 *
 *  Created on: Jun 20, 2016
 *      Author: Holguer
 */
#include <stdio.h> 					// Libreria encargada de printf y scanf, comunicaci�n serial
#include <unistd.h>					// Libreria para realizar usleep (retardos)
#include <fcntl.h>					// Libreria para realizar escritura y lectura de la memoria
#include <sys/mman.h>				// Libreria para realizar mapeo de memoria
#include "socal.h"					// Funciones para escritura en palabras de GPIOs
#include "hps.h"					// Instancia las direcci�nes de GPIOs del HPS
#include "alt_gpio.h"				// Configuracion de GPIOs
#include "hwlib.h"					// Definici�n de hardware
#define HW_REGS_BASE ( ALT_STM_OFST ) // Define HW_REGS_BASE como
#define HW_REGS_SPAN ( 0x04000000 )   // Tama�o de la region de memoria
#define HW_REGS_MASK ( HW_REGS_SPAN - 1 ) // enmascaramiento del tama�o de la region de memoria
#define USER_IO_DIR     (0x01000000)
#define BIT_LED         (0x01000000)
#define BUTTON_MASK     (0x02000000)
int main(int argc, char **argv) { //
	void *virtual_base;
	int fd;
	uint32_t scan_input;
	int i;
	// map the address space for the LED registers into user space so we can interact with them.
	// we'll actually map in the entire CSR span of the HPS since we want to access various registers within that span
	if ((fd = open("/dev/mem", ( O_RDWR | O_SYNC))) == -1) { // open abre archivos abre la memoria RDWR de forma sincrona ir a consola cd dev -- ls aparece el mem el men contiene todo el elspacio qe el sistema operativo tiene acceso a travez del mmu que es el management memory unit
		printf("ERROR: could not open \"/dev/mem\"...\n"); // si es -1 el dev men no existe y sale un error
		return (1);
	} // de lo contrario en fd se guarda el puntero que apunta a la direccion de dev/mem en fd se guarda ese valor
	virtual_base = mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE),
	MAP_SHARED, fd, HW_REGS_BASE); // mapea el mapa de memoria  y se limita para que no tenga acceso a otro lugar con mmap cuyos argumentos se pueden ver en la funcion---vamos a escribir o leer, map_shared significa que es una memoria compartida, fd direccion de memoria, hw_regs_base empiezan registros de perifericos todos inician en fc
	if (virtual_base == MAP_FAILED) {  // si falla envia error
		printf("ERROR: mmap() failed...\n");
		close(fd);
		return (1);
	}
	// initialize the pio controller
	// led: set the direction of the HPS GPIO1 bits attached to LEDs to output
	alt_setbits_word(
			( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DDR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ),
			USER_IO_DIR);
	int numero_flashes = 0;
	int delay = 300;
	/*if (argc > 1) { // argumento del main
		if (argc > 2) {
			sscanf(argv[2], "%d", &delay);
		} else {
			sscanf(argv[1], "%d", &numero_flashes);
		}
	} else {
		printf("please use the next input style: ./ejemplo_gpio3 #flashes \n");
		printf("or input style: ./ejemplo_gpio3 #flashes #delay \n");
	}*/
	printf("led test\r\n");
	printf("the led flash 2 times\r\n");
	for (i = 0; i < 2; i++) {
		alt_setbits_word(
				( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ),
				BIT_LED);
		usleep(delay * 1000);
		alt_clrbits_word(
				( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ),
				BIT_LED);
		usleep(delay* 1000);
	}
	printf("user key test \r\n");
	printf("press key to control led\r\n");
	while (1) {
		scan_input =
				alt_read_word(
						( virtual_base + ( ( uint32_t )( ALT_GPIO1_EXT_PORTA_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ));
		//usleep(1000*1000);
		if (~scan_input & BUTTON_MASK)
			alt_setbits_word(
					( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ),
					BIT_LED);
		else
			alt_clrbits_word(
					( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ),
					BIT_LED);
	} */
	// clean up our memory mapping and exit
	if (munmap(virtual_base, HW_REGS_SPAN) != 0) {
		printf("ERROR: munmap() failed...\n");
		close(fd);
		return (1);
	}
	close(fd);
	return (0);
}