zweite SPI im SAM D mit Atmel Studio ASF hängt

Gast #5298288
Lesenswert?

Moin,

ich benötige mehrere SPIs im SAMD21.
Beim Einbinden der zweiten SPI hängt das Programm im
1
startup_samd21.c
2

3
void Dummy_Handler(void)
4
{  while (1) {}
5
}

Einen SPI habe ich mit der RadioHead-Library in Verwendung:
1
Sercom* H_spiNumber=SERCOM3;
2

3
HardwareSPI::HardwareSPI(uint32_t spiPortNumber) :_spiPortNumber(spiPortNumber)
4
{  switch (spiPortNumber)
5
  {
6
  case 0: H_spiNumber=SERCOM0; break;
7
...bla...
8
  }
9
}

Die zweite SPI soll ein externes Flash AT25DFx bedienen. Wurde mit dem 
ASF generiert:
1
void EM_configure_spi_master(void)
2
{   struct at25dfx_chip_config  vat25dfx_chip_config;
3
    struct spi_config vat25dfx_spi_config;
4

5
   at25dfx_spi_get_config_defaults(&vat25dfx_spi_config);
6
   vat25dfx_spi_config.mode_specific.master.baudrate = AT25DFX_CLOCK_SPEED;
7
   vat25dfx_spi_config.mux_setting = SPI_SIGNAL_MUX_SETTING_D;
8
   vat25dfx_spi_config.pinmux_pad0 = PINMUX_PB02D_SERCOM5_PAD0;
9
   vat25dfx_spi_config.pinmux_pad1 = PINMUX_PB03D_SERCOM5_PAD1;
10
   vat25dfx_spi_config.pinmux_pad2 = PINMUX_UNUSED;
11
   vat25dfx_spi_config.pinmux_pad3 = PINMUX_PB23D_SERCOM5_PAD3;
12
   spi_init(&at25dfx_spi, EM_spiNumber, &vat25dfx_spi_config);
13
   spi_enable(&at25dfx_spi);
14
   vat25dfx_chip_config.type = AT25DFX_512B;
15
   vat25dfx_chip_config.cs_pin = PINMUX_PB23D_SERCOM5_PAD3;
16
   at25dfx_chip_init(&at25dfx_chip, &at25dfx_spi, &vat25dfx_chip_config);
17
}

Wenn ich den Code in EM_configure_spi_master() auskommentiere, läuft die 
Kiste an. Sobald der Code aktiv ist, endet es im Dummy_Handler() (s.o.)

Hat jemand eine Idee?


Kann jemand erklären, wie die Logik der Funktion __libc_init_array() im 
Reset_Handler() ist?
Mit dem Debugger komme ich da im Single Step nicht rein.

Mit aktivem EM_configure_spi_master() springt das Programm vom 
__libc_init_array() direkt in den Dummy_Handler(). Warum?

1
startup_samd21.c
2

3
void Reset_Handler(void)
4
{
5
... bla ...
6
        __libc_init_array();        /* Initialize the C library */
7
        main();             /* Branch to main function */
8
        while (1);        /* Infinite loop */
9
}


Vielen Dank für eine Hilfe :o)
Gast #5299175
Lesenswert?

Hast du mal alle Fault-Handler, also UsageFault, BusFault etc., 
implementiert? Dann dürfte es etwas klarer werden, was für eine 
Exception auftritt, der Dummy-Handler ist nur eine Fallbacklösung und 
sagt relativ wenig aus. Die Fault-Handler müssen alle noch explizit 
aktiviert werden, das geschieht System Handler Control and State 
Register (SHCSR), welches (wenn ich mich recht erinner) im System 
Control Block (SCB) liegen dürfte.
#5300167
Lesenswert?

thomas schrieb:
> Kann jemand erklären, wie die Logik der Funktion __libc_init_array() im
> Reset_Handler() ist?

Die Funktion ruft statische Konstruktoren auf. Das du im Dummy-Handler 
landest kann verschiedene Gründe haben, z.B. einen Bus-Fault oder aber 
auch ganz einfach das du im SPI-IRQ-Handler landest, der aber nicht 
implementiert ist und damit landest du im Dummy-Handler. Um das Problem 
weiter eingrenzen zu können sind die Tips von Andi sicher hilfreich. 
Ansonsten kann bei sowas auch ein Assembler-Listing nicht schaden.
#5306043
Lesenswert?

Danke Christopher und Andi,

ich habe den Dummy_Handler erweitert:
1
void Dummy_Handler(void)
2
{  volatile int i,j,p;
3
  
4
  HardFault_HandlerAsm();
5
    while (1) {
6
    i=__get_IPSR();
7
    j=__get_APSR();
8
    p=__get_xPSR();
9
  }
10
}
11
/**
12
 * HardFault_HandlerAsm:
13
 * Alternative Hard Fault handler to help debug the reason for a fault.
14
 * To use, edit the vector table to reference this function in the HardFault vector
15
 * This code is suitable for Cortex-M3 and Cortex-M0 cores
16
 */
17

18
// Use the 'naked' attribute so that C stacking is not used.
19
__attribute__((naked))
20
void HardFault_HandlerAsm(void)
21
{        /*
22
         * Get the appropriate stack pointer, depending on our mode,
23
         * and use it as the parameter to the C handler. This function
24
         * will never return
25
         */
26

27
        __asm(  ".syntax unified\n"
28
                        "MOVS   R0, #4  \n"
29
                        "MOV    R1, LR  \n"
30
                        "TST    R0, R1  \n"
31
                        "BEQ    _MSP    \n"
32
                        "MRS    R0, PSP \n"
33
                        "B      HardFault_HandlerC      \n"
34
                "_MSP:  \n"
35
                        "MRS    R0, MSP \n"
36
                        "B      HardFault_HandlerC      \n"
37
                ".syntax divided\n") ;
38
}
39

40
/**
41
 * HardFaultHandler_C:
42
 * This is called from the HardFault_HandlerAsm with a pointer the Fault stack
43
 * as the parameter. We can then read the values from the stack and place them
44
 * into local variables for ease of reading.
45
 * We then read the various Fault Status and Address Registers to help decode
46
 * cause of the fault.
47
 * The function ends with a BKPT instruction to force control back into the debugger
48
 */
49
void HardFault_HandlerC(unsigned long *hardfault_args){
50
        volatile unsigned long stacked_r0 ;
51
        volatile unsigned long stacked_r1 ;
52
        volatile unsigned long stacked_r2 ;
53
        volatile unsigned long stacked_r3 ;
54
        volatile unsigned long stacked_r12 ;
55
        volatile unsigned long stacked_lr ;
56
        volatile unsigned long stacked_pc ;
57
        volatile unsigned long stacked_psr ;
58
        volatile unsigned long _CFSR ;
59
        volatile unsigned long _HFSR ;
60
        volatile unsigned long _DFSR ;
61
        volatile unsigned long _AFSR ;
62
        volatile unsigned long _BFAR ;
63
        volatile unsigned long _MMAR ;
64

65
        stacked_r0 = ((unsigned long)hardfault_args[0]) ;
66
        stacked_r1 = ((unsigned long)hardfault_args[1]) ;
67
        stacked_r2 = ((unsigned long)hardfault_args[2]) ;
68
        stacked_r3 = ((unsigned long)hardfault_args[3]) ;
69
        stacked_r12 = ((unsigned long)hardfault_args[4]) ;
70
        stacked_lr = ((unsigned long)hardfault_args[5]) ;
71
        stacked_pc = ((unsigned long)hardfault_args[6]) ;
72
        stacked_psr = ((unsigned long)hardfault_args[7]) ;
73

74
        // Configurable Fault Status Register
75
        // Consists of MMSR, BFSR and UFSR
76
        _CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;   
77

78
        // Hard Fault Status Register
79
        _HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
80

81
        // Debug Fault Status Register
82
        _DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;
83

84
        // Auxiliary Fault Status Register
85
        _AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;
86

87
        // Read the Fault Address Registers. These may not contain valid values.
88
        // Check BFARVALID/MMARVALID to see if they are valid values
89
        // MemManage Fault Address Register
90
        _MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
91
        // Bus Fault Address Register
92
        _BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
93

94
        __asm("BKPT #0\n") ; // Break into the debugger
95

96
}
97
/**
98
 * \brief Default interrupt handler for unused IRQs.
99
  __get_IPSR();:
100
    ISR_NUMBER (IPSR[8:0])
101
        =0 Thread mode
102
        =1 Reserved
103
        =2 NMI
104
        =3 HardFault
105
        =4 MemManage
106
        =5 BusFault
107
        =6 UsageFault
108
        =7-10 Reserved
109
        =11 SVCall
110
        =12 Reserved for Debug
111
        =13 Reserved
112
        =14 PendSV
113
        =15 SysTick
114
        =16 IRQ0
115
        ...
116
        =n+15 IRQ(n-1)
117

118

119
 */

Beim Steppen fiel mir dann ein HardFault auf.
Nachdem ich den
1
//RHReliableDatagram  rf95reliable(rf95, rf95CLIENT_ADDRESS);
auskommentiert hatte, ging es.

Scheint eine Kollision zwischen RHReliableDatagram und ASF:AT25FFx zu 
sein. Das bedarf noch weitere Forschung.

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