AVR, Atmega644 SPI im Bootloader kein output

OP #7405321
Lesenswert?

Hallo Ihr,

ich verwende schon länger den CAN-Bus Bootloader von Fabian Greif und hab ihn erweitert. Hauptsächlich verwende ich die ATMEGA328 und jetzt habe ich ihn auf den ATmega644 und 1282 erweitern wollen nur leider kommen keine Daten aus dem SPI raus (Oszi).

Ich habe mal die spi_putc ausgelagert in eine C-Funktion um mit LED auszugeben was sache ist. Habe auch die Register SPCR überprüft ob diese anderst stehen es ist aber so wie gewolt.

So schwer ist doch der SPI nicht ist doch super simple. Ach ich habe einen Externen 16 MHz Quarz, aber auch mit dem Internen funktioniert es nicht. Es wird einfach keine Daten rausgeschoben auf der SPI Schnitstelle, die LED und CS Funktionieren.

Das lustige an dem Ganzen ist ja das mein eigentliches Programm über CAN-Bus wie es soll kommuniziert und hier ist die Initalisierung auch nicht wirklich anderst.

Hier die Fuse Bits: (E:FF, H:12, L:F7)

Vielen dank schon mal für eure Hilfe und Zeit.

Hier mal der Code von mir:

1
void boot(void) \
2
    __attribute__((naked)) \
3
    __attribute__((section(".vectors")));
4

5
void boot(void)
6
{
7
  __asm__ __volatile__ ("rjmp  init" "\n\t");
8
}
9

10
// ----------------------------------------------------------------------------
11
void
12
init(void) \
13
    __attribute__((naked)) \
14
    __attribute__((section(".init3")));
15

16
void init(void)
17
{
18
    uint8_t status;
19
    uint16_t temp;
20
  // Clear r1 (__zero_reg__) and initialize the stack
21
  __asm__ __volatile__ (
22
      "eor  r1, r1"    "\n\t"
23
      "out  0x3f, r1"  "\n\t"
24
      "ldi  r28, 0xFF" "\n\t"
25
      "ldi  r29, 0x04" "\n\t"
26
      "out  0x3e, r29" "\n\t"
27
      "out  0x3d, r28" "\n\t");
28
  
29
#ifdef GPIOR0
30
  // Save MCUSR so that the main program can access if later
31
  GPIOR0 = MCUSR;
32
#endif
33

34
    status = MCUSR;                    // save MCUC(S)R reset status at very first
35
    MCUSR = status & 0xF0;             // then clear reset status, before touching the watchdog
36
  
37
  // Disable the watchdog timer
38
  // see http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html
39
  // 
40
  // The orignal implementation uses additional commands to disable
41
  // interrupts. As we never enable interrupts this is not needed here.
42
  __asm__ __volatile__ (  \
43
      "sts %0, %1" "\n\t" \
44
      "sts %0, __zero_reg__" "\n\t" \
45
       : /* no outputs */ \
46
       : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
47
         "r" ((uint8_t) ((1 << _WD_CHANGE_BIT) | (1 << WDE))) \
48
       : "r0");
49

50
    MCUCR = (1<<IVCE);                 // enable interruptvectors change
51
    MCUCR = (1<<IVSEL);                // move interruptvectors to the Boot-Sector
52
}
53

54
// ----------------------------------------------------------------------------
55
int main(void) __attribute__((naked)) \
56
    __attribute__((section(".init9")));
57

58
int main(void) 
59
....
60

61
uint8_t spi_putc_c(uint8_t data)
62
{
63
   // put byte in send-buffer
64
    SPDR = data;
65
    
66
    // wait until byte was send
67
    while( !( SPSR & (1 << SPIF) ) )
68
    {
69
        BOOT_LED2_TOGGLE;
70
        if( SPDR != data )
71
        {
72
            SPDR = data;
73
            BOOT_LED_OFF;
74
        }
75
        else
76
        {
77
            BOOT_LED_ON;
78
        }
79
        _delay_ms(100);
80
    }
81
    
82
    return SPDR;
83
}
84

85

86
void mcp2515_init(void)   _attribute__((naked))           __attribute__((section(".init5")));
87
void mcp2515_init(void)
88
{
89
        BOOT_LED2_SET_OUTPUT;
90
  BOOT_LED_SET_OUTPUT;
91
        BOOT_LED_ON;
92
        BOOT_LED2_ON;
93

94
        uart_puts( "Hallo\r\n" );
95

96
  // Aktivieren der Pins fuer das SPI Interface
97
  DDRB = _BV( DDB2 ) | _BV( DDB5 ) | _BV( DDB7 );
98
        
99
        SET(MCP2515_CS);
100

101
        BOOT_LED_OFF;
102
  
103
  // Aktivieren des SPI Master Interfaces
104
  SPCR = 0x91;//(1 << SPIE)  | (1 << SPE) | (1 << MSTR) |  ( 1 << SPR0 ) | (1 << CPHA); //R_SPCR;
105
  SPSR = 0; //R_SPSR;
106
  
107
  _delay_us(250);
108

109
  // MCP2515 per Software Reset zuruecksetzten,
110
  // danach ist er automatisch im Konfigurations Modus
111
  RESET(MCP2515_CS);
112
  spi_putc_c(SPI_RESET);
113
  _delay_us(10);
114
  SET(MCP2515_CS);
115
.......
#7405653
Lesenswert?

SPCR = 0x91;//(1 << SPIE) | (1 << SPE) | (1 << MSTR) | ( 1 << SPR0 ) | (1 << CPHA); //R_SPCR;

In der Konstanten stehen 3 Bits, im Kommentar jedoch 5? Und ja, SPE wird nicht gesetzt.

(Den ganzen Rest habe ich mir nicht näher angeschaut - zu ungewohnt, um es vorsichtig auszudrücken)

OP #7405891
Lesenswert?

Peter D. schrieb:

Wer macht denn solchen Blödsinn, lesbare Ausdrücke durch magische Nummern zu ersetzen? Da kannst Du keine Hilfe erwarten.

sehr schön, dann weis ich ja wer keine Fehler macht und wo ich was lernen kann. Danke für die Sachliche Antwort.

Hier handelt es sich um SPI Master und CS wird als erstes gesetzt. Wie ich geschrieben habe habe ich schon länger SPI im einsatz und der Bootloader lief auf dem Atmega328/168...

Danke für den Hinweis, ich habe das hard codiert, da es durch das setzen der einzelnen Bits auch nicht ging. Wie es auch immer noch nicht geht. In meiner eigentlichen Firmware funktioniert der SPI-CAN Chip wie er soll somit ist es nicht die Hardware.

Es wird das WCOL bit gesetzt und es gibt auf den SPI Pins auch kein Signal , das habe ich davor ausgetestet. Wie gesagt der Bootloader setzte ich schon lange ein bei einigen Modulen nur mit dem mega328/168.

Weiter man sieht wie der SPI die MOSI und SPI in anspruch nimmt (High-Low-High) je nachdem wie man es setzt war als test selbst high getrieben. Auf der SCK gibt es kein Signal.

Was mich wundert, dass es auf meiner FW ohne Probleme läuft nur im Bootloader gibt es mit dem 644 problme mit dem 328 geht es einwandfrei.

1
  SET_OUTPUT(MCP2515_CS);
2
  SET(MCP2515_CS);
3

4
  PORT_SPI &=  ~((1 << PIN_NUM(P_SCK)) | (1 << PIN_NUM(P_MOSI)));
5
  DDR_SPI |= (1 << PIN_NUM(P_SCK)) | (1 << PIN_NUM(P_MOSI));
6
       
7
  SET(MCP2515_CS);
8
        BOOT_LED_OFF;
9
  
10
  SPCR =  (1 << SPIE) | (1 << SPE) | (1 << MSTR); //R_SPCR;
11
  SPSR = _BV( SPI2X );
Beitrag #7405923 wurde von einem Moderator gelöscht.
Beitrag #7405931 wurde von einem Moderator gelöscht.
#7405970
Lesenswert?

15.3.2 Master Mode When the SPI is configured as a Master (MSTR in SPCR is set), the user can determine the direction of the SS pin. If SS is configured as an output, the pin is a general output pin which does not affect the SPI system. Typically, the pin will be driving the SS pin of the SPI Slave. If SS is configured as an input, it must be held high to ensure Master SPI operation. If the SS pin is driven low by peripheral circuitry when the SPI is configured as a Master with the SS pin defined as an input, the SPI system interprets this as another master selecting the SPI as a slave"

#7406059
Lesenswert?

Um es überdeutlich zu formulieren (Peter Dannegger möge entschuldigen):

Im eingangs gezeigten Programmausschnitt sieht es so aus, als sei vergessen worden, /SS von ATmega328.PB2 auf ATmega644.PB4 umzuziehen. Wenn nun PB4 auf der Reset-Einstellung 'Eingang' geblieben ist und, wie auch immer, von außen auf Low gezogen wird, dann führt ein Laden von SPDR direkt zu besagtem gesetzten WCOL.

OP #7407301
Lesenswert?

ja hab den fehler gefunden es war wirklich der SS den ich da nicht mit um gezogen habe. Offt sind die Offentlichsten dinge die am meisten Zeit kosten und wo man rein fällt.

@Peter D. man kann viel machen und sich überall verkünsteln und alles selbst Entwerfen, so dass man zu dem eigentlichen Thema kaum Zeit hat das alles möglich. Wie gesagt der Bootloader ist grundlegend bzw die Variante von Kreativen Chaos seite und bin ihm dankbar das er mir da Arbeit abgenommen hat.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren