Hallo Forum,
ich verzweifle seit einiger Zeit daran, 2 STM8S per SPI miteinander im 
Full-Duplex-Modus und per Hardware-NSS/CS kommunizieren zu lassen.
Mein Ziel ist es dabei, das der Master einen Frame von 2 Byte an den 
Slave sendet und dabei CS entsprechend 'aktiviert' (LOW). Daraufhin soll 
CS 'idle' (HIGH) werden bis das Spielchen wieder von vorn beginnnt.
Das was der Slave an den Master sendet soll irrelevant sein.
Meinem Verständnis nach habe ich dies für den einfachst möglichen 
SPI-Master, unter Beachtung von "5. Set the MSTR and SPE bits ([!]they 
remain set only if the NSS pin is connected to a high-level signal[/!])" 
[RM0016, Reference manual, Doc ID 14587 Rev 8, S.258] für dessen 
Initialisierung, bereits erreicht (OpenBench LogicSniffer zeigt das 
gewünschte Bild; ausgenommen CS, welches dauerhaft HIGH ist):
1  | void SPI_Config(void)
  | 
2  | {
 | 
3  |   SPI_DeInit();
  | 
4  |   SPI_Init(SPI_FIRSTBIT_MSB,
  | 
5  |            SPI_BAUDRATEPRESCALER_128,
  | 
6  |            SPI_MODE_MASTER,          
  | 
7  |            SPI_CLOCKPOLARITY_HIGH,   
  | 
8  |            SPI_CLOCKPHASE_2EDGE,     
  | 
9  |            SPI_DATADIRECTION_2LINES_FULLDUPLEX, 
  | 
10  |            SPI_NSS_HARD,                        
  | 
11  |            0x00                                 
  | 
12  |           );
  | 
13  |   SPI_Cmd(ENABLE);
  | 
14  | }
  | 
15  | 
  | 
16  | int main( void )
  | 
17  | {
 | 
18  |   u16 wait = 0x00;
  | 
19  |  
  | 
20  |   CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); /* Fmaster = 16MHz */
  | 
21  | 
  | 
22  |   do
  | 
23  |   {
 | 
24  |     wait = 0x00;
  | 
25  |     do{wait++;}while(wait<150);
 | 
26  | 
  | 
27  |     SPI_Config();
  | 
28  |   }
  | 
29  |   while ( ((SPI->CR1 & SPI_CR1_MSTR) == 0) &&
  | 
30  |           ((SPI->CR1 & SPI_CR1_SPE ) == 0)
  | 
31  |         );
  | 
32  | 
  | 
33  |   for (;;)
  | 
34  |   {
 | 
35  |     (void) SPI_SendData(0xAA);
  | 
36  |     do{}while( (SPI->SR & SPI_SR_TXE) == 0x00 );
 | 
37  | 
  | 
38  |     (void) SPI_SendData(0x55);
  | 
39  |     do{}while( (SPI->SR & SPI_SR_TXE) == 0x00 );
 | 
40  | 
  | 
41  |     wait = 0x00;
  | 
42  |     do{wait++;}while(wait<150);
 | 
43  |   }
  | 
44  | 
  | 
45  |   return 0;
  | 
46  | }
  | 
Nun weiss ich aber beim Slave nicht so recht weiter.
Wie oben durch [!]...[/!] gekennzeichnet, erwartet ein STM8S-SPI-Master 
ein HIGH auf CS um sich überhaupt zu initialisieren.
Ein STM8S-SPI-Slave gibt ein solches HIGH aber scheinbar per Default 
nicht aus.
Dieser erwartet statt dessen ein LOW während eines Datentransfers:
"3. In Hardware mode (refer to Slave select (NSS) pin management on page 
255), the NSS pin must be connected to a low level signal during the 
complete data transmit sequence." [RM0016, Reference manual, Doc ID 
14587 Rev 8, S.258]
1  | void SPI_Config(void)
  | 
2  | {
 | 
3  |   SPI_DeInit();
  | 
4  |   SPI_Init(SPI_FIRSTBIT_MSB,
  | 
5  |            SPI_BAUDRATEPRESCALER_8,
  | 
6  |            SPI_MODE_SLAVE,        
  | 
7  |            SPI_CLOCKPOLARITY_HIGH,
  | 
8  |            SPI_CLOCKPHASE_2EDGE,  
  | 
9  |            SPI_DATADIRECTION_2LINES_FULLDUPLEX, 
  | 
10  |            SPI_NSS_HARD,                        
  | 
11  |            0x00                                 
  | 
12  |           );
  | 
13  |   SPI_ITConfig(SPI_IT_RXNE, ENABLE);
  | 
14  |   SPI_ITConfig(SPI_IT_TXE,  ENABLE);
  | 
15  |   SPI_Cmd(ENABLE);
  | 
16  | }
  | 
17  | 
  | 
18  | #pragma vector = (SPI_TXE_vector & SPI_RXNE_vector)
  | 
19  | __interrupt void SPI_RX_IRQHandler(void)
  | 
20  | {
 | 
21  |   if ( SET == SPI_GetITStatus(SPI_IT_TXE) )
  | 
22  |   {
 | 
23  |     return;
  | 
24  |   }
  | 
25  |   if ( SET == SPI_GetITStatus(SPI_IT_RXNE) )
  | 
26  |   {
 | 
27  |     u8 spi_tx_data = SPI_ReceiveData();
  | 
28  |     return;
  | 
29  |   }
  | 
30  | }
  | 
31  | 
  | 
32  | int main( void )
  | 
33  | {
 | 
34  |   CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); /* Fmaster = 16MHz */
  | 
35  | 
  | 
36  |   SPI_Config();
  | 
37  | 
  | 
38  |   enableInterrupts();
  | 
39  | 
  | 
40  |   for (;;)
  | 
41  |   {
 | 
42  |   }
  | 
43  | 
  | 
44  |   return 0;
  | 
45  | }
  | 
Der Versuch für den Slave NSS zusätzlich per GPIO als Pull-Up-Input zu 
konfigurieren hat leider auch nicht das gewünschte Ergebnis erzielt.
Siehe hierzu:
"Note: In applications with a parallel multi-slave structure, with 
separate NSS signals and the slave MISO outputs connected together, the 
corresponding GPIO registers must be configured correctly. [...]  When 
the NSS signal is released, the pin is driven by GPIO register settings 
only. To function correctly, the GPIO has to be configured in input 
pull-up mode with no interrupt." [RM0016, Reference manual, Doc ID 14587 
Rev 8, S.258]
Hat jemand von Euch Erfahrungen hierzu?
Kann mir jemand einen Tipp geben der mich weiterbringt?
Ist ggf. eine externe Beschaltung für NSS/CS erforderlich?
Ich bin für jede Hilfe dankbar.
Grüße,
Daniel