Forum: Mikrocontroller und Digitale Elektronik Sam 3x SPI / USART


von ech0 (Gast)


Lesenswert?

Hallo ihr lieben.

Erstmal: Tolles Forum. Ich lese immer ab und an mal mit.

Aber nun muss ich mal eure Hilfe erbitten...

Ich hab ein Projekt mit einem Sam 3xe ( arduino due board ).
Diesen programmiere ich im Atmel Studio mit ASF.
Ziel ist es einen Winzer per SPI und einen ESP8266 per USART 
anzusteuern.

Nun verzweifle ich bereits bei SPI und USART. Ich habe mir die Beispiele 
angesehen und mehr oder weniger nachgebaut. ABER es kommt nichts raus.
Ich verstehe einfach nicht warum...
Vielleicht könnt ihr mir helfen...

Ich bin mir grad nicht sicher, ob ich den Code als Datei anhängen darf, 
daher will ich ihn mal hier einbetten. Sorry das der Text dann relativ 
lang wird.

mySPI.h


#define USED_SPI  SPI0

/* SPI clock configuration. */
static const uint32_t gs_ul_clock_configurations[] =
{ 1, 500000, 1000000, 2000000, 5000000 };



typedef enum
{
  SPICLK_1Hz,
  SPICLK_500kHz,
  SPICLK_1MHz,
  SPICLK_2MHz,
  SPICLK_5MHz,

}eSPIClockConfig;

#define SPI_MASTER_BASE    USED_SPI


 /* Chip select. */
 #define SPI_CHIP_SEL 0
 #define SPI_CHIP_PCS spi_get_pcs(SPI_CHIP_SEL)

 /* Delay before SPCK. */
 #define SPI_DLYBS 0x40

 /* Delay between consecutive transfers. */
 #define SPI_DLYBCT 0x10


 /* Clock polarity. */
 #define SPI_CLK_POLARITY 0
 /* Clock phase. */
 #define SPI_CLK_PHASE 0


 void SPIMaster_Init(eSPIClockConfig clockConfig );

 void SPIMaster_Transfer(void *inOutBuffer, uint32_t size );

 void SPIMaster_WriteByte( uint8_t inBuf );
 uint8_t SPIMaster_ReadByte( void );

 void SPIMaster_SelectCS( void );
 void SPIMaster_DeselectCS( void );






mySPI.c

void SPIMaster_Init( eSPIClockConfig clockConfig )
{
  uint32_t spi_clock = gs_ul_clock_configurations[clockConfig];

  #if (SAMG55)
  /* Enable the peripheral and set SPI mode. */
  flexcom_enable(BOARD_FLEXCOM_SPI);
  flexcom_set_opmode(BOARD_FLEXCOM_SPI, FLEXCOM_SPI);
  #else
  /* Configure an SPI peripheral. */
  spi_enable_clock(SPI_MASTER_BASE);
  #endif
  spi_disable(SPI_MASTER_BASE);
  spi_reset(SPI_MASTER_BASE);
  spi_set_lastxfer(SPI_MASTER_BASE);
  spi_set_master_mode(SPI_MASTER_BASE);
  spi_disable_mode_fault_detect(SPI_MASTER_BASE);
  spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_PCS);
  spi_set_clock_polarity(SPI_MASTER_BASE, SPI_CHIP_SEL, 
SPI_CLK_POLARITY);
  spi_set_clock_phase(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
  spi_set_bits_per_transfer(SPI_MASTER_BASE, SPI_CHIP_SEL,
  SPI_CSR_BITS_8_BIT);
  spi_set_baudrate_div(SPI_MASTER_BASE, SPI_CHIP_SEL,
  (sysclk_get_cpu_hz() / spi_clock));
  spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS,
  SPI_DLYBCT);
  spi_enable(SPI_MASTER_BASE);

}


void SPIMaster_Transfer(void *inOutBuffer, uint32_t size)
{
  uint32_t i;
  uint8_t uc_pcs;
  static uint16_t data;

  uint8_t *p_buffer;

  p_buffer = inOutBuffer;

  for (i = 0; i < size; i++) {
    spi_write(SPI_MASTER_BASE, p_buffer[i], 0, 0);
    p_buffer[i] = 0xFF;
    /* Wait transfer done. */
    while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0);
    spi_read(SPI_MASTER_BASE, &data, &uc_pcs);
    p_buffer[i] = data;
  }
}

void SPIMaster_WriteByte( uint8_t inBuf )
{
  uint16_t bufAs16Bit = inBuf;
  spi_write(SPI_MASTER_BASE, bufAs16Bit, 0, 0);
  while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0);
}

uint8_t SPIMaster_ReadByte( void )
{
  uint16_t bufAs16Bit;
  uint8_t uc_pcs;
  spi_read(SPI_MASTER_BASE, &bufAs16Bit, &uc_pcs);
  return (uint8_t)(bufAs16Bit & 0xFF);
}

void SPIMaster_SelectCS( void )
{
  ioport_set_port_level( IOPORT_PIOD, PIO_PD10, IOPORT_PIN_LEVEL_LOW );
}

void SPIMaster_DeselectCS( void )
{
  ioport_set_port_level( IOPORT_PIOD, PIO_PD10, IOPORT_PIN_LEVEL_LOW );
}




Vielen Dank für eure Hilfe!

Lg ech0

von Wolfgang (Gast)


Lesenswert?

ech0 schrieb:
> Vielleicht könnt ihr mir helfen...
Sicher, was spricht erstmal gegen die Einbindung der Arduino SPI 
Bibliothek. Wenn alles läuft, kannst du immer noch deine Modifikationen 
einbauen.

> Ich bin mir grad nicht sicher, ob ich den Code als Datei anhängen darf,

Dafür sind Anhänge da.
Kurze Codeabschnitte kannst du natürlich auch direkt einbetten, dann 
aber bitte mit "code" "/code", für C besser noch mit "c" "\c" taggen 
(jeweils eingeschlossen in "[" ... "]" damit die sprachspezifischen 
Hervorhebungen verwendet werden.

von Se J. (ech0_sj)


Lesenswert?

Hi,

danke für die schnelle Antwort. Das mit dem Code merke ich mir.

Ich habe die SPI-Bibliothek per ASF eingebunden und auch diese 
Anpassungen in conf_board.h eingefügt.

Arduino-SPI-Biblithek? Im AtmelStudio? In C? Das gibt es?

Ich hab das SPI-Example Projekt von Atmel genommen und ich meine 
Funktionen  kopiert. mehr eigentlich nicht.

Im Netz hab ich noch 1,2 andere Beispiele für einen "SPI-Master" 
gefunden. Leider ebenfalls ohne Ergebnis.

: Bearbeitet durch User
von Se J. (ech0_sj)


Lesenswert?

Also

SPI funktioniert nun, laut Logic analyzer.
Was genau der Fehler war? Ich weiss es nicht,
evtl was die con_board nicht korrekt eingebunden.

Angebunden werden soll ein eHajo w5500.
Soweit so gut, ich sende ihm init Kommandos...
Jedoch scheint er die Daten nicht zu übernehmen, beim
Rücklesen  ist alles 0.
1
InitResult_t W5500_Init(wiz_NetInfo* NetworkConfig)
2
{
3
  uint8_t tmp;
4
  uint8_t memsize[2][8] = {
5
    {2,2,2,2,2,2,2,2} /* Configure RX Socket Size in kByte*/
6
    ,{2,2,2,2,2,2,2,2} /* Configure TX Socket Size in kByte*/
7
  };
8
  
9
  // w5500_init_io();    //Set the additional IOs to the correct value and direction
10
  
11
  // spi_init_sw();      // Software-SPI-Treiber laden
12
  /* Critical section callback - No use in this example */
13
  //reg_wizchip_cris_cbfunc(0, 0);
14
  /* Chip selection call back */
15
  #if   _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_
16
  reg_wizchip_cs_cbfunc( SPIMaster_SelectCS, SPIMaster_DeselectCS );    //Register Functionpointer for Chipselect in Driver
17
  #elif _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_
18
  reg_wizchip_cs_cbfunc( SPIMaster_SelectCS, SPIMaster_DeselectCS );  //Register Functionpointer for Chipselect in Driver
19
  #else
20
  #if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_
21
  #error "Unknown _WIZCHIP_IO_MODE_"
22
  #else
23
  reg_wizchip_cs_cbfunc( SPIMaster_SelectCS, SPIMaster_DeselectCS );    //Register Functionpointer for Chipselect in Driver
24
  #endif
25
  #endif
26
  /* SPI Read & Write callback function */
27
  reg_wizchip_spi_cbfunc( SPIMaster_ReadByte, SPIMaster_WriteByte );        //Register Functionpointer for Datatransfers in Driver
28
  /* Enter- und Exit-Critical, cli() and sei()...*/
29
  //reg_wizchip_cris_cbfunc(enter_critical,exit_critical);    ///Use with care !
30
  ////////////////////////////////////////////////////////////////////////
31
32
  
33
  /* WIZCHIP SOCKET Buffer initialize */
34
  if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1)
35
  {
36
    return InitError;  //Init went wrong
37
  }
38
  
39
  /* PHY link status check */
40
  if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1)
41
  {
42
    return PhyError;  //Phy in suspect state
43
  }
44
  
45
  //This is wehre the "Black Magic" happens
46
  //
47
  ctlnetwork(CN_SET_NETINFO,NetworkConfig);  //Write Config in Chip
48
  ctlnetwork(CN_GET_NETINFO,NetworkConfig);  //Read Config Back
49
  return Okay;                //Return Okay
50
  //Black Magic done :-), as you given a pointer to your Network-Config, you'll get the current config back from the chip
51
}


Vielleicht habt ihr eine Idee?

Vielen Dank im vorraus

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.