¿Alguien tiene código para emular un registro de desplazamiento de entrada de 16 bits con un ATtiny2313?

3

Me gustaría usar un ATtiny2313 para emular un controlador Super Nintendo porque tengo un ATtiny2313 pero no tengo un registro de cambios de entrada y no tengo ganas de soldar cables en una placa de controlador SNES existente.

Esta aplicación requiere 12 entradas (los bits 13-16 son siempre 1) y un pin de cierre, reloj y salida de datos.

¿Tienes este código por ahí? No puede haber más de 20 instrucciones.

    
pregunta joeforker

4 respuestas

6

Ya hay un registro de desplazamiento de 8 bits integrado en la Interfaz de serie universal (USI) . Todo lo que tienes que hacer es usarlo dos veces seguidas.

    
respondido por el Yann Vernier
3

No tengo este código, pero tengo las siguientes mejores cosas:

Podría decir que tengo el código, pero no está organizado y concatenado correctamente ...;)

    
respondido por el tyblu
3

Como dice @tyblu, todo está en el manual para el USI. En particular, lo que desea es utilizarlo en "Funcionamiento en modo maestro de tres cables". Eche un vistazo a la Figura 61 en la página 143 de la hoja de datos. La hoja de datos es lo suficientemente amable como para proporcionar una rutina de ensamblador optimizada (8 instrucciones) (SPITransfer) para este propósito exacto:

SPITransfer:
  out USIDR,r16
  ldi r16,(1<<USIOIF)
  out USISR,r16
  ldi r16,(1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC)
SPITransfer_loop:
  out USICR,r16
  sbis USISR,USIOIF
  rjmp SPITransfer_loop
  in r16,USIDR
  ret

Si lo cablea para que tenga un pin 2313 conectado al cable de "enganche" del controlador (naranja), el pin USCK se conecta al cable de "pulso" del controlador (rojo), y el pin DI se conecta al Cable de "datos" del controlador (amarillo): debería estar listo. Según la hoja de datos, el ejemplo del código supone que los pines DO y USCK están habilitados como salidas en el registro DDRB.

Una vez que se configura el hardware, todo lo que debe hacer es generar un impulso de 12us en el pin "latch", soltar el pin en 6us, luego llamar a la rutina de ensamblaje anterior dos veces (guardando el valor de retorno) después de cada llamada.

Encontré esta referencia muy informativa con respecto a la interfaz (S) NES.

    
respondido por el vicatcu
0

El siguiente código funciona muy bien. La señal de bloqueo está conectada a PB5 . El controlador SIG_PIN_CHANGE hace su trabajo en ambos bordes de la señal de retención, pero no importa, y la última vez que intenté agregar el cheque no funcionó.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

ISR(SIG_PIN_CHANGE)
{
    USIDR = PINA | (PIND & 0b01111100) | (PINB << 7);
    USISR = (1 << USIOIF); // clear overflow bit, set counter to 0
    USICR |= (1 << USIOIE); // enable overflow interrupt
}

ISR(SIG_USI_OVERFLOW)
{
    USIDR = (PINB << 3) | 0x0f;
    USISR |= (1 << USIOIF); // clear overflow bit
    USICR &= (0xff ^ (1 << USIOIE)); // disable overflow interrupt
}

int main() {

    USIDR = 0xff;
    USICR = (1 << USIWM0) | (1 << USICS1); // 3-wire mode; external, positive edge.

    DDRA = 0;
    DDRD = 0;
    DDRB = 1 << 6; // MISO

    // Enable pullups
    PORTA = 0x3;
    PORTB = 0b11111;
    PORTD = 0xfc;

    // USIDR is shifted out MSB first.

    // pin change interrupt for latch pin
    PCMSK = (1 << 5);
    GIMSK |= (1 << PCIE);

    sei();

    while (1) {
        sleep_mode();
    }
}
    
respondido por el joeforker

Lea otras preguntas en las etiquetas