Autor Tema: modem + teclado + tv + interfaces = mini computador  (Leído 2696 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado uniqdom

  • PIC10
  • *
  • Mensajes: 7
modem + teclado + tv + interfaces = mini computador
« en: 14 de Octubre de 2011, 01:15:31 »
Hola amigos, tengo un  módem adsl que contiene un firmware basado en Linux. Llevo bastante tiempo con la idea de transformarlo en un pequeño computador ( casi 200mhz , 2mb de rom, 8 de ram, teclado y pantalla)

El módem en cuestión es un zxdsl 831 II


Uploaded with ImageShack.us



Buscando información acerca del módem, encontré esta pagina, que aunque no es el mismo modelo, es similar. El tipo ruso lo deshuesa a fondo.

el módem cuenta con un puerto rj45, un puerto rj11, un puerto serial UART, un led bicolor (rojo y verde), y tres leds verdes, un botón de encendido y otro para resetearlo. Además tiene los pines como para un puerto usb me imagino que debe de poderse soldar un puerto usb hembra tipo B, pero eso ya va por otro tema.


A grandes rasgos, mi idea es la siguiente:

   Teclado  -->  Interfaz KEYBOARD PC to RS232  -->   Router  --> generador de video ntsc  -->  TV


Siendo mas especifico, conectaré el teclado a una interfaz KEYBOARD PC to RS232 como la que desarrollo RedPic en un proyecto suyo (seguro que tendré que hacerle alguna modificación). A su vez, la interfaz estará conectada al puerto RX del serial UART del router.
Creo que hasta ahí es posible.
Ahora, por el otro lado, el TX estará conectado a algún generador de vídeo ntsc   y este a una TV. como generador de vídeo pensé en algo como este, pero la verdad no se si funcione.

¿Saben de algún proyecto similar? ¿Algún link de utilidad?
Cualquier comentario u orientación es bienvenido.

Saludos




« Última modificación: 18 de Octubre de 2011, 01:14:41 por uniqdom »

Desconectado uniqdom

  • PIC10
  • *
  • Mensajes: 7
Re: modem + teclado + tv + interfaces = mini computador
« Respuesta #1 en: 18 de Octubre de 2011, 00:51:15 »
Quería comentarles que ya tengo funcionando (faltan algunos detalles, pero como prueba de concepto, ya funciona) la conexión del teclado al módem. Para ello, pedí prestado el código hecho por XP8100 y que RedPic modificó. Traduje el código para ser compilado en SDCC y para que funcione en un pic16f877a.
Aquí un esquema del cableado entre el teclado, el 16f877a y el UART del modem








Y aquí el código (recordar que es solo un esbozo):
Código: [Seleccionar]
//-----------------------------------------------------------------------------
// Title:         KEYBOARD_PC_To_RS232.c
// Description:   Interfase entre un teclado convencional tipo AT y un puerto RS232C
// Date:          Abr-2005
// Ver.Rev.:      V01
// Author:        XP8100 (xp8100@gmail.com)
//
//                #Based on the AN AVR313: Interfacing the PC AT Keyboard from ATMEL#
//                #Adaptado para 16F628A por Redraven
//                #Readaptado para 16F877A y SDCC por uniqdom
//
// NOTA:     De momento este codigo es un esbozo. Falta arreglar unas cuantas cosas.
//  Pero como prueba de concepto, funciona.
//
//-----------------------------------------------------------------------------
//
// init_kb()      Inicializa rutina y contadores
//
// decode (char)  Decodifica la pulsación realizada, convirtiendola a un caracter de la tabla
//
// int_ext_isr    Rutina de gestión de interrupciones. Captura los diferentes bit's
//
//-----------------------------------------------------------------------------
// RB0 - Señal de reloj
// RB3 - Tren de impulsos (11 bit) Start+10101010+Paridad+Stop
//-----------------------------------------------------------------------------
//
// Commment   : Permite conectar un teclado convencional de PC a un entorno
//              gestionado por un PIC 16F877.
//              El actual sistema se define como un primer prototipo, en el que no se realizan
//              acciones concretas asociadas a teclas establecidas.
//              Tampoco se actua sobre los indicadores luminosos del teclado, repetición de teclas, ...
//
//
//
// THIS DOCUMENT IS PROVIDED TO THE USER 'AS IS'
//-----------------------------------------------------------------------------



/* Define processor and include header file. */
#define __16f677a
#include"/usr/local/share/sdcc/non-free/include/pic14/pic16f877a.h"
//#include"/usr/share/sdcc/non-free/include/pic/pic16f877a.h"

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

// If KHZ is not specified by the makefile, assume it to be 4 MHZ
#ifndef KHZ
#define KHZ 20000
#endif

// These are fixed.  The 16f628a can only use these as transmit and recieve.
#define TX_PORT 2
#define RX_PORT 1
#define TX_BIT (1<<TX_PORT)
#define RX_BIT (1<<RX_PORT)


// Twiddle these as you like BUT remember that not all values work right!
// See the datasheet for what values can work with what clock frequencies.
#define BAUD 115200
#define BAUD_HI 1

// This section calculates the proper value for SPBRG from the given
// values of BAUD and BAUD_HI.  Derived from Microchip's datasheet.
#if (BAUD_HI == 1)
#define BAUD_FACTOR (16L*BAUD)
#else
#define BAUD_FACTOR (64L*BAUD)
#endif
#define SPBRG_VALUE (unsigned char)(((KHZ*1000L)-BAUD_FACTOR)/BAUD_FACTOR)


//-----------------------------------------------------------------------------
// Definiciones globales
//-----------------------------------------------------------------------------

unsigned char edge, bitcount;

char got_interrupt;
char interrupt_count;
char status_b3;


//-------- Tabla de caracteres correspondientes a la pulsación de la tecla
//-------- en modalidad normal (sin pulsar SHIFT)

unsigned char const unshifted[68][2] = {
{0x0d,9},
{0x0e,'º'}, {0x15,'q'}, {0x16,'1'}, {0x1a,'z'}, {0x1b,'s'}, {0x1c,'a'}, {0x1d,'w'},
{0x1e,'2'}, {0x21,'c'}, {0x22,'x'}, {0x23,'d'}, {0x24,'e'}, {0x25,'4'}, {0x26,'3'},
{0x29,' '}, {0x2a,'v'}, {0x2b,'f'}, {0x2c,'t'}, {0x2d,'r'}, {0x2e,'5'}, {0x31,'n'},
{0x32,'b'}, {0x33,'h'}, {0x34,'g'}, {0x35,'y'}, {0x36,'6'}, {0x39,','}, {0x3a,'m'},
{0x3b,'j'}, {0x3c,'u'}, {0x3d,'7'}, {0x3e,'8'}, {0x41,','}, {0x42,'k'}, {0x43,'i'},
{0x44,'o'}, {0x45,'0'}, {0x46,'9'}, {0x49,'.'}, {0x4a,'-'}, {0x4b,'l'}, {0x4c,'ñ'},
{0x4d,'p'}, {0x4e,'\''},{ 0x52,'Ž'},{ 0x54,'`'},{ 0x55,'¡'},{ 0x5a,13}, { 0x5b,'+'},
{0x5d,'ç'}, {0x61,'<'}, {0x66,8},   {0x69,'1'}, {0x6b,'4'}, {0x6c,'7'}, {0x70,'0'},
{0x71,'.'}, {0x72,'2'}, {0x73,'5'}, {0x74,'6'}, {0x75,'8'}, {0x79,'+'}, {0x7a,'3'},
{0x7b,'-'}, {0x7c,'*'}, {0x7d,'9'},
{0,0}
};

//-------- Tabla de caracteres correspondientes a la pulsación de la tecla
//-------- en modalidad desplazamiento (pulsando SHIFT)

unsigned char const shifted[68][2] = {
{0x0d,9},
{0x0e,'ª'}, {0x15,'Q'}, {0x16,'!'}, {0x1a,'Z'}, {0x1b,'S'}, {0x1c,'A'}, {0x1d,'W'},
{0x1e,'"'}, {0x21,'C'}, {0x22,'X'}, {0x23,'D'}, {0x24,'E'}, {0x25,'$'}, {0x26,'·'},
{0x29,' '}, {0x2a,'V'}, {0x2b,'F'}, {0x2c,'T'}, {0x2d,'R'}, {0x2e,'%'}, {0x31,'N'},
{0x32,'B'}, {0x33,'H'}, {0x34,'G'}, {0x35,'Y'}, {0x36,'&'}, {0x39,'L'}, {0x3a,'M'},
{0x3b,'J'}, {0x3c,'U'}, {0x3d,'/'}, {0x3e,'('}, {0x41,';'}, {0x42,'K'}, {0x43,'I'},
{0x44,'O'}, {0x45,'='}, {0x46,')'}, {0x49,':'}, {0x4a,'_'}, {0x4b,'L'}, {0x4c,'Ñ'},
{0x4d,'P'}, {0x4e,'?'}, {0x52,'š'}, {0x54,'^'}, {0x55,'¿'}, {0x5a,13},  {0x5b,'*'},
{0x5d,'Ç'}, {0x61,'>'}, {0x66,8},   {0x69,'1'}, {0x6b,'4'}, {0x6c,'7'}, {0x70,'0'},
{0x71,'.'}, {0x72,'2'}, {0x73,'5'}, {0x74,'6'}, {0x75,'8'}, {0x79,'+'}, {0x7a,'3'},
{0x7b,'-'}, {0x7c,'*'}, {0x7d,'9'},
{0,0}
};


//-----------------------------------------------------------------------------
// Definición de protipos
//-----------------------------------------------------------------------------

void init_kb(void);
void decode(unsigned char sc);
void delay_ms(long ms)
{
long i;
while (ms--)
for(i=0;i!=330;i++)
;
}
//-----------------------------------------------------------------------------
// Rutina de gestión de interrupciones
//-----------------------------------------------------------------------------

static void int_ext_isr(void) __interrupt 0 {

unsigned char datos;
   //-------- Los bit 3 a 10 se consideran datos. Paridad, start y stop
   //-------- son ignorados
   if(bitcount < 11 && bitcount > 2){
      datos = (datos >> 1);
      //status_b3 = input(PIN_B3);
status_b3= RB3;
      if((status_b3) == 1){
          datos = datos | 0x80;
      }
   }
   //-------- Todos los bits se han recibido
   if(--bitcount == 0){
      decode(datos);
      datos = 0;
      bitcount = 11;
      got_interrupt = TRUE;
   }
   got_interrupt = TRUE;
   interrupt_count++;
   //disable_interrupts(INT_EXT);
INTE = 0;
}

//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------

void main(void)
{
TRISB|=TX_BIT|RX_BIT; // These need to be 1 for USART to work
//SPBRG=SPBRG_VALUE; // Baud Rate register, calculated by macro
SPBRG=10;  //el valor calculado por la macro da 9. Realicé los cálculos y en verdad da 9.850.
                               //en el lenguaje C, al realizar la operación división, el resultado es truncado.
                               //por lo tanto da 9. La cosa es que cuando realicé las pruebas, solo llegaban datos
                               //erróneos. Yo lo aproximé a 10 y funcionó (aunque algunos caracteres se los comía).

       BRGH=BAUD_HI;

SYNC=0; // Disable Synchronous/Enable Asynchronous
SPEN=1; // Enable serial port
TXEN=1; // Enable transmission mode
   delay_ms(100);

   init_kb();

   //B0 y B3 son configurados como entradas
   TRISB = 0x09; //  0x09 = 00001001

   //-------- Activa pullups sobre todos los pins del puerto B.
   OPTION_REG=0x7F;
  

   //-------- Espera a que se activen.
   //delay_us(5);
delay_ms(100);
   //--------
   //TODO: esta linea creo q no es necesaria
   //output_low(PIN_B5);

   //-------- Inicializa las variables usadas por la rutina de interrupción
   //-------- antes de activar las interrupciones
   interrupt_count = 0;
   got_interrupt = FALSE;
   status_b3 = 0;

   //-------- Desde que se activó el modo PULLUPS del puerto B, el estado
   //-------- normal del pin B0 es ALTO. La gestión de la interrupción externa
   //-------- se gestiona cuando se produce un cambio de nivel ALTO a BAJO.
   //ext_int_edge(H_TO_L);
INTEDG=0;

   //-------- Asegurarse de que el el bit de flag de la interrupción externa
   //-------- es borrado antes de activar la gestión de dicha interrupción
   //-------- externa.
   INTCON = 0;             /* clear interrupt flag bits */

   //-------- Configuramos las interrupciones
   INTE = 1;               /* external interrupt enabled in pin B0 */
   GIE = 1;                /* global interrupt enable */


   //-------- Bucle principal.
   //-------- Chequear si se produce alguna interrupción (got_interrupt). Si es así, contar, borrar
   //-------- el flag y esperar 50 ms, reactivando la gestión de las interrupciones
   while(1)

      {

      //-------- Chequear si se produce alguna interrupción (got_interrupt).
      if(got_interrupt == TRUE)

         {

            //-------- Borrar el flag global que se inicio en la rutina de servicio
            //-------- de interrupciones externas.
            got_interrupt = FALSE;

            //-------- Esperar 50 ms para evitar rebotes en los contactos de las teclas.
            //delay_ms(50);

            //-------- Borrar cualquier interrupción producida durante el periodo de espera.
            //INTF_BIT = 0;
INTF = 0; // ahi solo borramos el flag de interrupcion externa.
                                  //con INTCON=0 podriamos borrar todos los flags...
                                  //pero en verdad no lo necesitamos ya que no estamos
                                 // usando las otras interrupciones.
            
  //-------- Reactivar interrupciones

            //enable_interrupts(INT_EXT);
INTE = 1;

         } // --- End If ---

      } // --- End While ---

} // --- End MAIN ---


//-----------------------------------------------------------------------------
// Funciones
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Inicialización de teclado.
//-----------------------------------------------------------------------------
void init_kb(void)
{

   //-------- Longitud de la trama para cada pulsación y mensaje de bienvenida
   bitcount = 11;
   //printf("\n\rPC AT Keyboard Interface Ver 1.0 by XP8100");
   //printf("\n\rAdpapted for 16F628A by Redpic");
  //printf("\n\rDecoder and Monitoring for 16F628A connected ...\n\r\n\r");
}


//-----------------------------------------------------------------------------
// Decodificación de pulsaciones
//-----------------------------------------------------------------------------
void decode(unsigned char sc)
{
   static unsigned char is_up=0, shift = 0, mode = 0;
   unsigned char i;


   //printf("[%X]",sc);


   //-------- El último dato recibido fue el identificador de Up-Key
   if (!is_up){
         switch (sc){
               //-------- Identificador de Up-Key
               case 0xF0 :
                  is_up = 1;
                  break;
               //-------- SHIFT Izquierdo
               case 0x12 :
                  shift = 1;
                  break;
               //-------- SHIFT Derecho
               case 0x59 :
                  shift = 1;
                  break;
               //-------- ENTER
               case 0x5A :
                  shift = 0;
                  //printf("\n\r");
TXREG='\n'; // Add a character to the output buffer
while(!TXIF);
TXREG='\r'; // Add a character to the output buffer
while(!TXIF);
                  break;
               //-------- Si no es ninguno de los identificadores especiales, procesar
               //-------- pulsación, localizando caracter en tabla de caracteres.
               default:
                  //-------- Pulsación normal
                  if(!shift)
                     {
                        for(i = 0; unshifted[i][0]!=sc && unshifted[i][0]; i++);
                        if (unshifted[i][0] == sc)
                           {
                             // printf("<%c>", unshifted[i][1]);
   TXREG=unshifted[i][1]; // Add a character to the output buffer
   while(!TXIF);
                           }
                     }
                  else
                  //-------- Pulsación + SHIFT presionado
                     {
                        for(i = 0; shifted[i][0]!=sc && shifted[i][0]; i++);
                        if (shifted[i][0] == sc)
                           {
                             // printf("<%c>", shifted[i][1]);
                            TXREG=shifted[i][1]; // Add a character to the output buffer
   while(!TXIF);
  }
                     }
                     break;
               } // --- End Switch
         }
      else
         {
         //-------- No se permiten 2 0xF0 en una fila
         is_up = 0;
         switch (sc)
            {
               //-------- SHIFT Izquierdo
               case 0x12 :
                  shift = 0;
                  break;
               //-------- SHIFT Derecho
               case 0x59 :
                  shift = 0;
                  break;
            } // --- End Switch
         }
}


Quiero comentarles que hice pruebas entre mi PC, la interfaz y el teclado, a funcionando a 9600bps y no hubo problemas.
El módem funciona a 115200bps, así que modifique el código para que puedan establecer la comunicación a dicha velocidad. La cosa es que a veces pulso alguna tecla y esta no se alcanza a leer. 

leyendo en el datasheet del 16f877a (pagina 115) dice que para velocidad alta:
BRGH = 1 (High Speed), el baud rate está dado por:
Baud Rate = FOSC/(16 (X + 1)), donde X = value in SPBRG (0 to 255)

por lo tanto si quiero que el Baud Rate sea de 115200, despejando X:
X=9.850...

ahí en el código hay una macro que saca el calculo automáticamente
pero da 9 porque en lenguaje C, al realizarse la operación de división se trunca la parte fraccionaria.

Si hago funcionar el pic con  SPBRG=9 (aproximado hacia abajo), solo muestra un caracter erroneo por cada tecla pulsada.
Luego forcé el valor a 10. es decir SPBRG=10 (aproximado hacia arriba) con lo cual de 10 letras yo diría que 7 llegan bien y las otras no son leídas. ¿Algún tip para mejorar la comunicación?



Sé que este pic es demasiado grande para el propósito. Por lo mismo  lo tengo en una protoboard y no he hecho una PCB. Estoy en búsqueda de alguno mas pequeño. Si saben de alguno que tenga UART y interrupción externa me avisan.

Ahora avanzaré en el generador de imágenes NTSC.
Como el sistema en el módem es un Linux, y la interacción es mediante un terminal lo ideal sería generar vídeo en modo 80x25 lineas.
De generación de imágenes no se nada, así que comenzaré a leer.





« Última modificación: 18 de Octubre de 2011, 01:54:11 por uniqdom »

Desconectado gary_servin

  • PIC12
  • **
  • Mensajes: 65
Re: modem + teclado + tv + interfaces = mini computador
« Respuesta #2 en: 18 de Octubre de 2011, 12:06:17 »
Excelente proyecto, también quería hacer algo parecido pero con el módem adsl que tengo en desuso no lo puedo hacer! Para mejorar la comunicación serial puedes usar un cristal de 18.432 MHz por ejemplo, con este valor de cristal el calculo para el generador de baud rate debería salir exacto, eliminando el % de error de la comunicación.

Saludos!

Desconectado uniqdom

  • PIC10
  • *
  • Mensajes: 7
Re: modem + teclado + tv + interfaces = mini computador
« Respuesta #3 en: 18 de Octubre de 2011, 16:39:55 »
Excelente proyecto, también quería hacer algo parecido pero con el módem adsl que tengo en desuso no lo puedo hacer! Para mejorar la comunicación serial puedes usar un cristal de 18.432 MHz por ejemplo, con este valor de cristal el calculo para el generador de baud rate debería salir exacto, eliminando el % de error de la comunicación.

Saludos!

Gracias!! tendré que conseguirme uno por ahí...

Desconectado xp8100

  • PIC12
  • **
  • Mensajes: 71
Re: modem + teclado + tv + interfaces = mini computador
« Respuesta #4 en: 19 de Octubre de 2011, 14:50:32 »
Saludos amigo.

Leyendo una parte de la cabecera que escribí en su momento "Date:          Abr-2005" me doy cuenta de lo rápido que pasa el tiempo, jajajajajajaja.

Buen trabajo, sigue así.

Un abrazo,

Jc