[BACK]Return to saspi.c CVS log [TXT][DIR] Up to [local] / funnyos / arch / sam7s64 / dev

Diff for /funnyos/arch/sam7s64/dev/saspi.c between version 1.1 and 1.4

version 1.1, 2007/12/18 15:44:21 version 1.4, 2007/12/21 17:40:29
Line 4 
Line 4 
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/device.h>  #include <sys/device.h>
 #include <sys/bus.h>  #include <sys/bus.h>
   #include <sys/bus_spi.h>
   
 #include <arch/sa7s64/dev/at91sam7s64.h>  #include <libkern/printf.h>
   #include <arch/sam7s64/dev/at91sam7.h>
   
 /*  /*
  * SPI driver.   * SPI driver.
  */   */
   
   struct saspi_dd {
           struct spi_bus_handle   sd_sbh;
   
           struct bus_handle               *sd_bhp;
   };
   
   
 int     saspi_attach(struct device *, uint32_t, uint8_t);  int     saspi_attach(struct device *, uint32_t, uint8_t);
   void    saspi_init(struct saspi_dd *ddp);
   uint8_t saspi_transmit(void *selfdd, uint8_t data);
   void    saspi_cs_low(void *selfdd);
   void    saspi_cs_high(void *selfdd);
   
 struct driver spi_dr = {  
         1,  struct driver saspi_dr = {
         spi_attach,          sizeof(struct saspi_dd),
           saspi_attach,
         NULL,          NULL,
         NULL          NULL
 };  };
   
   
 int  int
 spi_attach(struct device *self, uint32_t loc, uint8_t flags)  saspi_attach(struct device *self, uint32_t loc, uint8_t flags)
 {  {
         struct XXX_dd *ddp = self->dv_devdata;          struct saspi_dd *ddp = self->dv_devdata;
   
           /* grab bus_handle */
           ddp->sd_bhp = self->dv_parent->dv_aux;
   
           printf("SAM7 SPI: ");
           /*
            * XXX Check if card present and fail if it is not.
            */
           /* 'Card Present' on PA15 */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << 15);
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 15);
           /* Write Protect' on PA16 */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << 16);
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 16);
   
           if((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDSR) & 1 << 15) == 0)
                   printf("card present; ");
           else {
                   printf("card is not presented\n");
   
                   return(-1);
           }
           printf("write %s\n", (bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDSR) & 1 << 16) ? "protect" : "allowed");
   
           /*
            * Initialize ourselfes and provide spi_bus_handle to children throught dv_aux.
            */
   
           saspi_init(ddp);
   
           ddp->sd_sbh.sb_transmitfunc = saspi_transmit;
           ddp->sd_sbh.sb_cslowfunc = saspi_cs_low;
           ddp->sd_sbh.sb_cshighfunc = saspi_cs_high;
           ddp->sd_sbh.sb_dd = ddp;
   
           self->dv_aux = &ddp->sd_sbh;
   
   
         return(0);          return(0);
   }
   
   
   void
   saspi_init(struct saspi_dd *ddp)
   {
           /*
            * Initialize on-chip SPI controller.
            */
   
           /*
            * Disassociate SPI chip select, clock and data lines from PIO.
            *
            * PA11 - NPCS0
            * PA12 - MISO
            * PA13 - MOSI
            * PA14 - SPCK
            */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDR, 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14);
   
           /* assign pins to Peripheral A */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ASR, 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14);
   
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_BSR, 0);
   
           /* reset and enable SPI */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN | AT91C_SPI_SWRST);
           /* XXX just to be sure */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN);
   
           /* set SPI mode to master; disable decoding of Chip Select; PCS 1110 (using fixed CS line) */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_MR, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | 0x0e << 16); /* XXX 15|16 */
   //      bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_MR, 0xe0011); /* XXX 15|16 */
   
           /*
            * Configure Chip Select Register no. 0 (so no offset from SPI_CSR).
            * CPOL (Clock Polarity) is 0 (SPCK inactive is logic 0);
            * NCPHA (Clock Phase) is 1;
            * 8 bits per transfer;
            * XXX SCBR=4a;
            */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CSR, AT91C_SPI_NCPHA | 0x4a00);
   
           /* enable PDC transfers to/from SPI */
   //      bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PDC_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN);
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN);
   
   }
   
   
   uint8_t
   saspi_transmit(void *selfdd, uint8_t data)
   {
           struct saspi_dd *ddp = (struct saspi_dd *)selfdd;
           /*
            * Shift byte on the SPI bus.
            */
           /* wait for Transmit Data Register Empty flag */
           while((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_SR) & AT91C_SPI_TDRE) == 0)
                   ;
   
           /* okay, send our byte */
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_TDR, 0x0000ffff & data);
   
           /* wait while Receive Register is full and read it */
           while(((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_SR)) & AT91C_SPI_RDRF) == 0)
                   ;
           return( bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_RDR) & 0x0000ffff );
   }
   
   
   void
   saspi_cs_low(void *selfdd)
   {
           struct saspi_dd *ddp = selfdd;
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_CODR, 1 << 11);
   }
   
   
   void
   saspi_cs_high(void *selfdd)
   {
           struct saspi_dd *ddp = selfdd;
           bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_SODR, 1 << 11);
   
 }  }
   

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.4

CVSweb