TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: groundman en 01 de Enero de 2012, 22:11:36

Título: caso extraño con LCD 16x2
Publicado por: groundman en 01 de Enero de 2012, 22:11:36
hola.estoy trabajando con una LCD en modo 4bit.y quiero testear el bit busy.dicen que no hace falta,y que con una temporizacion es mas que suficiente.
esto ya lo he probado y funciona bien.el caso es que estoy empeñado en testearlo.
para ello hay que leer los dos nibles de la LCD.priemero leo el nible alto y extraigo la informacion del bit7 (busy) y luego leo el nble bajo para la finlizacion de
la secuencia de lectura.esto funciona bien.

el caso es que cuando regresa del testado,la LCD deja de enviar caracteres.he estado desmenuzando el codigo hasta que di con un error.y es que aunque
en el proteus se ven las E/S de color azul/rojo segun el estado de cada pin.si no se ponen unas resistencias a positivo adecuadamente.el pic no lee el valor correcto.
esto lo he arreglado tambien.pero ahora hay algo que se me escapa de mi comprension.

resulta que programando la LCD para que mende un mensage con desplazamiento,este se ve perfectamente.pero si en medio del codigo pongo a 1 RS
y luego lo vuelvo a poner a 0.la LCD deja de enviar caracteres.
he mirado los nibles que le mando a la LCD y en los dos casos son exactamente los mismos.

es como si al poner RS a 1 y posteriormente  0.la LCD estubiera esperando a que hubiera hecho algo.se supone que solo es la conmutacion para
el envio/recepcion de datos o instrucciones.no se si sera un fallo del proteus.o las LCD funcionan de esta manera.
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 02 de Enero de 2012, 22:52:40
No comprendo exactamente a que te refieres cuando dices que la LCD deja de enviar caracteres. Supongo que te debes de referir a que la LCD ya no imprime o visualiza los datos que se envia.

Yo trabajo de la forma de la que estas haciendo tus pruebas, testeo el bit busy para poder saber si la LCD esta ocupada o no, y no ha habido porblemas de error de comunicaciòn ni necesidad de pull-ups en los pines de control del LCD. De repente la falla de comunicaciòn se da por que olvidadas reconfigurar los pines de datos (D7-D4 del LCD) de entrada a salida, como estabas en modo lectura, ahora tienen que ser salidas para poder estar em modo escritura.

Ahora, eso de cambiar el pin RS no tendrìa efecto, siempre y cuando, no realizes el pulso de enable en el LCD... saludos.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 06 de Enero de 2012, 16:25:21
gracias por la respuesta.exactamente es lo que quiero decir.
este es el codigo para el testeo del flag busy:

Código: [Seleccionar]
LCD_BUSYN               READ
LCD_BUSY2   ENABLE
call retardo1us
btfss   PORTB,3  
goto busy3
DISABLE
call retardo1us
ENABLE
call retardo1us
DISABLE
goto LCD_BUSY2
busy3 DISABLE
ENABLE
call retardo1us
DISABLE
frt WRITE
return


Código: [Seleccionar]
READ MACRO
movlw 0x0f
iorwf TRISB
bsf PORTA,1
ENDM
WRITE MACRO
movlw 0xf0
andwf TRISB
bcf PORTA,1
ENDM

#define ENABLE bsf PORTA,2 ;habilita LCD
#define DISABLE bcf PORTA,2 ;deshabilita LCD



la comunicacion con la LCD la hago por el nible bajo de portb.

RA0=RS
RA1=R/W
RA2=ENABLE
Título: Re: caso extraño con LCD 16x2
Publicado por: MGLSOFT en 07 de Enero de 2012, 08:26:58
Yo siempre la hice por el nible alto del LCD, nunca por el bajo. :lol: :lol:
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 07 de Enero de 2012, 14:15:57
al principio tambien lo hize asi.pero uso un teclado matricial de 4x4 en el mismo puerto.para aprobechar las resistencias pull-up y la interrupcion por cambio de estado de PB4 A PB7.
y tenia conflicto entre la LCD y el teclado.asi que tube que cambiar la configuracion del portb.


Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 08 de Enero de 2012, 03:38:23

Código: [Seleccionar]
LCD_BUSYN                READ
LCD_BUSY2   ENABLE
call retardo1us
btfss   PORTB,3 
goto busy3
DISABLE
call retardo1us
ENABLE
call retardo1us
DISABLE
goto LCD_BUSY2
busy3 DISABLE
ENABLE
call retardo1us
DISABLE
frt WRITE
return


Hola groundman... te comento que yo lo hago de forma diferente. En mi caso, yo leo el byte completo y lo guardo en un registro temporal, y recien en ese registro testeo el bit busy. Podrìas intentar de esa forma, y si obtienes mejores resultados, quizas ahi radicaba el problema; de todas maneras probare tu metodo (aprovechando que estoy actualizando mis librerias) y te comentare como me fue a mi,... saludos.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 08 de Enero de 2012, 13:07:36
gracias por tu atencion.probare de la forma que tu lo haces.aunque se supone que deberia funcionar de las dos maneras.ya sea testeando el flag en ese instante o despues.
creo que de la forma que yo lo hago es mas rapida.pero da paso a que por un evento indeterminado se produzca la lectura del nible equivocado.y esto conlleve
a un error.lo tendre que revisar muy bien.

aunque ya estoy mosqueado.no se si provar el programa en una LCD fisicamente.porque cuando se dejan de ver el mensage en la LCD es cuando le da la gana.
igual pasan 4 mensages que 25.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 09 de Enero de 2012, 10:55:31
he estado analizando el programa al milimetro y no veo ningun fallo.cada vez estoy mas seguro de que es un problema del proteus.
como aquella vez que no me funcionaba y tube que cambiar la frecuencia de la LCD.

ya solo me falta comprovarlo fisicamente.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 12 de Febrero de 2012, 18:05:56
ya consegui semanas atras que me funcionara el testeo del bit busy.pero como era de esperar,se tenia que solucionar el problema creando otro.
resulta que yo escribo los caracteres en los 40 byutes de la DDRAM para visualizarlos en la LCD para mensages largos y vuelvo a cargar la DDRAM con los caracteres que falten.y esto funciona muy bien si no paso por el subprograma de testeo del bit BUSY.
ya que cuando paso por este subprograma,al tener que habilitar y desabilitar dos veces la LCD para la lectura de los dos nibles,el contador de direcciones
se incrementa y al escribir el siguiente caracter,se intercalan espacios entre letra y letra.

se supone que este incremento solo se realiza al escribir un dato en la LCD pero no cuando se lee.almenos en los documentos que he leido.
que cosas mas raras.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 26 de Febrero de 2012, 16:12:14
 :5] ya estoy arto del testeo del bit busy de la LCD en el modo de 4bit.esto es imposible  :x 

algo no va bien en el proteus.tiene un fallo que no le veo explicacion.

como es posible que al configurar PA0 como salida y poniendolo a cero.y conectado a RS.la LCD visualiza los caracteres.y sin haberlo pasado a 1,lo vuelvo a poner a cero.y ya no visualiza los caracteres.
yo pensaba que estaba haciendo algo mal.pero esto no tiene ni pies ni cabeza.supongo que tiene algo que ver con la inicializacion interna de la LCD.
pero ya no pierdo mas tiempo.
pondre unas pausas para que le de tiempo a escribir en la memoria interna y a otra cosa.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 12 de Febrero de 2014, 20:11:17
hola.se me presento un proyecto basado en un termostato.y ahora he puesto a funcionar el proyecto con un mensage con desplazamieto.

por lo visto el proyecto funciona perfectamente en el isis.pero en la parte fisica el desplazamiento lo hace al reves.asi que el comando de izquierdas
la lcd rota a derecha y viceversa.

he simulado con el ICD2 y las señales son correctas.almenos los bits de datos.en el modo de 4 bit.

las palabras fijas se visualizan correctamente.asi que supongo que todos los cables estan correctamnte puestos.yo creo que estos comandos
son compatibles para la LCD PC1602 1c7.he probado con dos LCDs y hacen lo mismo.
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 13 de Febrero de 2014, 09:16:00
que comando estas usando para hacer rotar el display del lcd, "entry mode display" o " Display shift"...
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 13 de Febrero de 2014, 16:55:47
uso Display shift.ya que guardo el mensage en memoria y luego lo desplazo. el valor es: movlw   B'00011100'    rotacion a izquierdas.
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 13 de Febrero de 2014, 23:39:49
tu dices que el comando de izquierda hace rotar hacia la derecha, pero la instruccion movlw   B'00011100', lo que hace es desplazar el display una posicion hacia la derecha. Parece que tienes ahi un error de conceptos, nada mas.

Por cierto, se que es algo tarde, pero como veo que no lo solucionastes te lo comento por si acaso. para leer el bit busy flag de la forma en testeo como tenias planeado, es necesario hacer un constante enable al lcd. Esto por que los datos a leer o escrobir en el lcd, se hacen en el flanco de bajada del enable.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 14 de Febrero de 2014, 20:19:38
muchas gracias por tu informacion.tienes razon el comando es de rotacion a derechas.no me di cuenta.asi que tengo que descartar el fallo en la LCD fisica.
y hecharle la culpa al isis.ya que en este si que se produce el fallo de la rotacion al reves.lo comprobare mejor.vaya a ser un error de tiempos.

respecto a lo del busy volvere a intentar hacerlo funcionar.
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 14 de Febrero de 2014, 20:59:27
yo no le echaria tan rápido la culpa al proteus isis; en este caso referente al manejo del lcd, me ha resultado ser fiel a lo que dicen los manuales.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 14 de Febrero de 2014, 22:33:32
podrias poner un trozo de codigo referente al envio de los dos nibbles con la comprobacion del busy?

a mi no me sale.o si sabes donde esta la libreria en cuestion?
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 15 de Febrero de 2014, 03:42:54
esta es una libreria mia de una version anterior, es de una conexcion de 4 bits por el nibble bajo, ya que por ahi lei que estabas usando el nibble bajo.

FLAG_ADDRES_LCD_4LBITS es un registro donde guardo el dato leido en el lcd. en este caso, la addres del pc del lcd, junto con el busy flag.


Código: [Seleccionar]

         ;Lee el bus del LCD;
         ;******************;
BF_4L
LCD_4LBITS_LEE ;R/W = 1, modo lectura
  nop
LCD_4LBITS_COMANDO ;RS = 0, modo comando
nop
LCD_4LBITS_E_ON ;E = 1, habilita bus del LCD
nop
LCD_4LBITS_E_OFF ;E = 0, deshabilita el bus del LCD
nop

        movf PORT_LCD_4LBITS,W ;Lee el LCD los 4 bits MSB
andlw 0x0F
banksel FLAG_ADDRES_LCD_4LBITS
movwf FLAG_ADDRES_LCD_4LBITS
swapf FLAG_ADDRES_LCD_4LBITS,F

banksel PORT_LCD_4LBITS
LCD_4LBITS_LEE ;R/W = 1, modo lectura
nop
LCD_4LBITS_COMANDO ;RS = 0, modo comando
nop
LCD_4LBITS_E_ON ;E = 1, habilita bus del LCD
nop
LCD_4LBITS_E_OFF ;E = 0, deshabilita el bus del LCD
nop

movf PORT_LCD_4LBITS,W ;Lee el LCD los 4 bits LSB
andlw 0x0F
banksel FLAG_ADDRES_LCD_4LBITS
addwf FLAG_ADDRES_LCD_4LBITS,F


         ;LCD ocupado o listo?; ;Si el bit 7 del FLAG_ADDRES_LCD_4LBITS
         ;********************; ;esta a cero, el LCD se encuentra
;         banksel FLAG_ADDRES_LCD_4LBITS ;listo, si esta a uno, el LCD se
; movwf FLAG_ADDRES_LCD_4LBITS ;encuentra ocupado. Los otros bits
btfsc FLAG_ADDRES_LCD_4LBITS,7 ;indican direccion actual del LCD
goto BF_4L ;


hay dos cosas que quizas deba de aclarar. la seccion donde leo el bus del lcd y lo guardo en el registro FLAG_ADDRES_LCD_4LBITS, lo hago mediante un arreglo rudimentario (es una version desfasada) ya que lo que deseo es tener el dato en un solo registro. Lo otro, es el desorden, como los tabs no funcionan y solo hice un copy paste del mplab a la web, se ve asi. trate de arreglarlo un poco, pero no queda bien.

Como te decia, en esta version, leo el lcd, y lo guardo en un registro, y ahi testeo el bit busy flag del lcd. La nueva version ya no la hace asi, lo testea directamente.
Como te decia, el dato se actualiza en el flanco de bajada, y por ser una conexion de 4 bits, se tiene que leer 2 veces.

Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 15 de Febrero de 2014, 14:38:42
ya me funciona lo de la comprobacion del busy.lo he hecho de las dos formas.guardando el bit busy en un registro.y tambien directamente.
guardandolo en un registro.la rutina funciona bien en el isis y no da ningun error.

pero si lo hago directamnte.de vez en cuando sale algun error en el isis.

referente a lo de la rotacion.sigue igual.tengo que invertir el sentido de desplazamiento segun use el isis o en circuito.


estoy pensando en usar entry mode set.incluso me parece que es mas efectivo.ya que se emplea menos tiempo en la visualizacion de mensages en movimiento.





Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 15 de Febrero de 2014, 14:50:54
entry mode set no te sirve, para la forma como estas escribiendo tus mensajes en el lcd y los estas visualizando.

realiza pruebas aparte de los comandos que estas usando; puede ser algún error de firmware.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 15 de Febrero de 2014, 19:13:58
jejeje.estoy realizando el codigo para el entry mode set.y la cosa no es tan facil como creia.hacerse si que se pude hacer.e incluso utilizaria menos
codigo que con el CURSOR OR DISPLAY SHIFT.pero teniendo hecho ya el codigo para DISPLAY SHIFT.no voy a perder mas tiempo.

en entry mode set.solo tendria que empezar a visualizar los caracteres en l parte izquierda de la pantalla.y conforme los imprimo,se irian
desplazando.pero no tube en cuenta de que la DDRAM tambien se desplaza.y cuando llegara al final de la DDRAM los caracteres se visualizarian
en la otra linea.o ni eso si estamos en diferente linea.
tendria que mapear parte del mensage en la zona visible y luego seguir el desplazamiento.y ni eso se si serviria.porque los primeros caracteres
podrian aparecer por otro sitio. y tendria que ir borrandolos.

asi que me quedo con CURSOR OR DISPLAY SHIFT.que no funciona correctamente en el isis.pues ya no se si es porque tengo mal mi version
o porque es.asi que ya posteare mi proyecto y que alguien lo pruebe por su cuenta.

muchas gracias JBQ me ha venido muy bien tu ayuda.por lo menos solucione lo del busy
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 16 de Febrero de 2014, 18:02:02
aqui pongo la rutina para el envio de los bytes a la LCD.con la comprobacion del flag busy.para el modo de 4bit.

Código: [Seleccionar]
;********************************************** ENVIO DE NIBLES  A LA LCD MODO 4bit******************************************************
;PULSO MACRO ;pulso en terminal E de la LCD
; bsf PORTA,3 ;habilita LCD (activa E de la LCD)
; nop ;retardo 1us
;   bcf PORTA,3 ;deshabilita LCD (desactiva E de la LCD)
; ENDM

; #define COMANDOS     bcf PORTA,1 ;Desactiva RS (modo comando)
; #define READ bsf PORTA,2 ;Activa RW (modo lectura de la lcd)
; #define WRITE bcf PORTA,2 ;Desactiva RW (modo escritura de la lcd)
; #define ENABLE_LCD bsf PORTA,3 ;habilita LCD
; #define DISABLE_LCD bcf PORTA,3 ;deshabilita LCD




BYTE       movwf   TEMPLCD ;guarda el contenido de W en registro temporal TEMPLCD

andlw 0xf0 ;nible bajo de PORTB como salida
         movwf   TRISB       ;
BYTE2       movlw   0xF0 ;pon a 0 el nible bajo de W
            andwf   LATB,F ;borra el nible bajo de portb sin tocar el nible alto.
            swapf   TEMPLCD,W ;invierte los nibles del registro TEMPLCD
            andlw   0x0F ;seleccionar el nible bajo de W
   iorwf   LATB,F ;manda nible bajo de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
   movlw   0xF0 ;pon a 0 el nible bajo de W
            andwf   LATB,F ;borra el nible bajo de portb sin tocar el nible alto.
            movf   TEMPLCD,W ;carga el contenido de TEMPLCD en W
            andlw   0x0F;f0 ;seleccionar el nible bajo de W
            iorwf   LATB,F ;manda nible bajo de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
call LCD_BUSY
return ;retorna


LCD_BUSY   movff PORTA,TEMP_PORTA;salva el registro PORTA
COMANDOS ;selecciona el modo comandos
iorlw 0x0F ;nible bajo de PORTB como entrada
         movwf    TRISB       ;PORT B como entrada
READ           ;Pone el LCD en Modo RD "lectura"
P_BUSY ENABLE_LCD ;activa LCD
nop ;retardo 1us
movff PORTB,TEMP_BUSY ;guarda el estado del busy
       DISABLE_LCD         ;Desactiva LCD
PULSO ;pulso Enable
btfsc   TEMP_BUSY,3 ;comprueba si el flag de ocupado de la LCD esta activo
   goto P_BUSY ;si es asi,espera a que la LCD este libre
L_BUSY DISABLE_LCD ;Desactiva LCD
WRITE         ;Pone LCD en modo WR
movff TEMP_PORTA,LATA ;restaura el registro LATA
return ;retorna
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 16 de Febrero de 2014, 20:08:19
bueno.aqui pongo el proyecto que visualiza mensages en la lcd.esta en proteus.debe de funcionar correctamente.pero con el comando invertido.
es decir a derechas para que funcione a izquierda en el isis.en el circuito fisico hay que modificarlo al valor correcto.

en la libreria Mensages.inc  al final del codigo esta el comando en binario.y esta comentado para poner el sentido de desplazamiento correcto.

por si alguien es capaz de encontrar el fallo.
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 17 de Febrero de 2014, 01:07:57
creo que ya comprendi tu confusión.

Mira, el LCD tiene.. digamnos, una tabla, letrero, cartel, donde se escribe el mensaje. Este consta de 64x2 caracteres, de los cuales solo son visibles 16x2 a traves de un display, ventana, pantalla.

Lo que tu haces desplazar, no es el objeto que contiene el mensaje, sino el display por donde se visualiza el mensaje. Por eso cuando crees que estas enviando un comando  de desplazanmiento a la derecha para que tu mensaje se mueva hacia la izquierda, lo que estas haciendo en realidad, es desplazar hacia la derecha el display por donde se visualiza el mensaje. El lugar donde se escribio el mensaje no se pude hacer desplazar.

No se si me deje entender.

te adjunto un archivo. en la pagina 8 esta mejor explicado lo que te comento,  aver si te ayuda.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 17 de Febrero de 2014, 10:57:34
si.eso lo entiendo.son 40 caracteres por linea.y lo que hace es desplazar la ddram.lo que no entiendo es que enviando los mismos nibles a la lcd,cunfiguracion de
escritura,modo comando,y pulso.aparte de comprobar el flag...etc.

porque funciona de forma diferente en el simulador con repecto al circuito fisico.
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 17 de Febrero de 2014, 11:40:04
no, no desplaza la ddram, desplaza el display. Ese es el error de concepto.

Bueno, lo otro podría ser como te dije  a un error en tu firmware. Con un rápido vistazo pude ver varios errores. uno que me llamo la atención es como cargas una cte en W; opr que no usas la instrcción movlw en ves de andlw?

Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 17 de Febrero de 2014, 19:04:06
comprendo.entoces movlw   B'00011100' es el comando de rotacion a derechas.que nos da la impresion de que el mensage va hacia la izquierda.
asi que el proteus funciona correctamente.algo tendre mal hecho en el codigo que si funciona en isis pero no en el circuito real.

PD. no entiendo que quieres decir con : cargas una cte en W   y encuanto a andlw.es una instruccion que debe de realizar su cometido.o puede fallar en un determinado funcionamiento?
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 17 de Febrero de 2014, 19:34:25
no es que falle la instrucción, es que me parece raro su uso en la subrutina donde la usas, se llama byte.
Ahi veo que guardas el valor de un registro en otro registro temporal, y de ahi configuras el puerto del lcd. esto es en el archivo mensajes.inc
 no pasa nada con los pines del  lcd, pero si afecta a los otros pines que pueden estar conectadso a algo, los desconfiguras.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 18 de Febrero de 2014, 11:13:05
te refieres a esta linea: andlw   0xf0         ;nible bajo de PORTB como salida

precisamente usar andlw o iorlw en determinados casos.lo que hace es prebenir el cambio de bits.

por ejemplo: andlw 0xf0  lo que hace es poner a cero los 4 bit menos significativos de w.pero no toca el nible alto.esten a 0 como a 1.
y tambien se puede hacer con bits independientes.  andlw b'11110000'  o andlw b'11010010'

iorlw hace la operacion inversa.pone a 1 los bits.

iorlw 0xf0   pone a 1 el nible alto independientemente del valor que tengan los bits. y no toca el nible bajo.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 18 de Febrero de 2014, 17:52:40
bueno.pues ya no pierdo mas tiempo. :5]

he utilizado el simulador por hardware ICD2. y paso por paso he comprobado los voltages a los pin D4,D5,D6 Y D7.

respectivamente los estados son 1000 para el primer nible enviado que es el nible alto.
y posteriormente el valor  0011 para el segundo nible que sera el nible bajo.

asi que el comando b'00011100' rotacion a derechas,en la lcd se traduce a una rotacion a izquierdas en el circuito real.almenos en el modo a 4bit.
no se como se comportara en el modo 8bit.

igual algun dia alguien me confirma que tengo un error en mi software.pero con un simulador en circuito y comprobandolo insitu.no veo que esto tenga solucion.

y no es problema de la LCD ya que he probado con dos de diferente marca.

asi que el comando b'00111000' rotacion a derechas,en la lcd se traduce a una rotacion a izquierdas.
Título: Re: caso extraño con LCD 16x2
Publicado por: JBQ en 18 de Febrero de 2014, 18:13:27
 :D bueno hombre,  tampoco te exasperes, suerte con el proyecto.
Título: Re: caso extraño con LCD 16x2
Publicado por: groundman en 18 de Febrero de 2014, 19:46:18
 :D  es que soy muy perfeccionista.y cuando algo no funciona como deberia de funcionar,me desconcierta.
pero todo tiene solucion.asi que hare algo parecido a lo que se hace cuando se programa en android.y es poner una etiqueta DEBUG para activar/desactivar
determinadas funciones cuando estamos simulando mediante software o hardware.