SPI no funciona en ATtiny441

Me he estado tirando de los pelos por un tiempo con esto. Solo estoy tratando de hacer una transacción SPI básica, enviando un byte, en el ATtiny441 , pero no obtengo nada en las líneas SCK y MOSI. Primero, aquí están mis configuraciones de fusibles y pinout (en rojo): Probablemente la información más útil aquí es que estoy usando el oscilador interno de 8 MHz y no dividiendo por 8. Tenga en cuenta que estoy reasignando los pines SPI para que pueda deje mi analizador lógico encendido mientras programo con los pines predeterminados.Puntas de fusible extendidas Puntas de fusible alto Bits de fusibles bajos asignación de pines

Aquí está mi main.carchivo:

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>

#define SCK         3
#define MOSI        1
#define CSN         2

uint8_t data = 0;
uint8_t reg = 0;


int main(void)
{
    PRR = 0; // turn off power reduction
    REMAP |= (1<<SPIMAP); // remap SPI pins
    // set SCK, MOSI, CSN as outputs:
    DDRA = (1<<SCK) | (1<<MOSI) | (1<<CSN); 
    // enable SPI, set as master, use f_clkIO/16 (500kHz):
    SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
    reg = SPSR;
    reg = SPDR;

    while(1)
    {
        PORTA &= ~(1 << CSN); // clear CSN
        SPDR = data++; // send byte
        while( !(SPSR & (1<<SPIF)) ); // wait for flag to set
        PORTA |= (1 << CSN); // set CSN
        _delay_ms(10);
    }

    return 0;
}

Estoy leyendo los registros SPSRy SPDRantes del whilebucle por recomendación de la nota de la aplicación AVR151 de Atmel (página 11).

Cuando ejecuto el código, la CSNlínea permanece baja, junto con SCKy MOSI, lo que sugiere que se está atascando en la while( !(SPSR & (1<<SPIF)) );sección esperando que se SPIFestablezca. Cuando comento esta línea, la CSNlínea baja por ~ 25us y luego vuelve a subir, lo que se espera. Intenté configurar manualmente las salidas en alto SCKy MOSI, también, para asegurarme de que no se trata de un problema de conexión de clavijas y funcionaron bien.

Pregunta: ¿Alguien ve el error en mis caminos? Siento que hay un pequeño y estúpido error en alguna parte.

Editar: también quiero mencionar que lo probé con y sin el conjunto de bits de fusible del divisor de reloj (por 8), y con y sin reasignar los pines SPI desde la ubicación predeterminada (es decir, programar, quitar cables de programación, conectar cables de sonda lógica) .

Desafortunadamente, no veo ningún error obvio en su código. Pero alguna sugerencia para la prueba: verifique si el módulo SPI está activado y toma el control de los pines, ya sea en un modo SPI diferente con un reloj inactivo alto, o establezca un pin alto antes de habilitar SPI y verifique que se caiga. Verificar el código compilado también es una buena idea (es lo suficientemente corto como para desmontarlo y verificarlo "a mano"), ¿tal vez alguna optimización extraña o con errores o un error en sus encabezados, por ejemplo? Por cierto. Supongo que no ve actividad en las líneas data y clk ni con la línea while comentada, ¿verdad?
@Martin Tenía miedo de eso, ¡pero gracias por los buenos consejos para la solución de problemas! Sin duda probaré esos. Y eso es correcto: no hay actividad en SCK o MOSI con esa whilelínea comentada.
@Martin ¡Lo descubrí! Mira mi respuesta si estás interesado. ¡Gracias de nuevo!

Respuestas (1)

¡Eureka! ¡Resulta que el SPIMAPbit está mapeado incorrectamente!

/usr/local/CrossPack-AVR-20131216/avr/include/avr/iotn441.h:377:0: note: this is the
location of the previous definition
 #define SPIMAP 0
 ^

(Debería ser el bit 1). Por lo tanto, ¡la línea que reasignaba los pines SPI estaba fallando! Esto se corrige colocando un #define SPIMAP 1en la #definesección.

EDITAR: Como señaló Martin, de hecho estoy usando una versión anterior de avr-libc. Estaba usando la última versión de CrossPack , que data de hace casi 4 años a partir de hoy. La versión más reciente tiene este error solucionado.

Que bueno que lo solucionaste. Solo para su información, este error no parece estar presente en (al menos) las bibliotecas más recientes de Atmel, es decir, la versión 3.6.0 de finales de 2016 está bien ( distribuir.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain/ … ). La cadena de fecha en esta salida que ha copiado aquí es un poco extraña de todos modos, ya que, de acuerdo con el registro de cambios de Atmel, la compatibilidad con ATtiny441 se agregó solo en 2016. bicho ...?