Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Подкарване на SPI на at91sam7s64
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=4478
Страница 1 от 1

Автор:  dumfree [ Пет Юли 06, 2007 9:45 pm ]
Заглавие:  Подкарване на SPI на at91sam7s64

Опитвам се да подкарам SPI на това чудо, обаче то категорично отказва, къде бъркам?
Средата която ползвам е IAR, закачил съм анализатора на MISO, MOSI, SCK ама нищо не мърда.

Код:
       
       AT91F_SPI_Reset(pSPI);
        AT91F_SPI_CfgPIO();
        AT91F_SPI_CfgPMC();
       
        AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR |AT91C_SPI_PS_FIXED);   // мастер режим, фиксиран брой устройства
        AT91F_SPI_CfgPCS(pSPI, 0x01); // едно устройство
        AT91F_SPI_CfgCs(pSPI, 1, AT91C_SPI_BITS_8 | AT91C_SPI_SCBR); // Конгигурираме му разрядността и скорост
        AT91F_SPI_Enable(pSPI); // и го пускаме

       AT91F_SPI_PutChar(pSPI, 0xAA, 1); // и пращаме - ама не иска :(

Автор:  Predator_MF [ Съб Юли 07, 2007 11:20 am ]
Заглавие: 

Не виждам прокарал ли си пиновете през PIO-то ?

Код:
  //port0.11 -> NPCS0
  //port0.12 -> MISO
  //port0.13 -> MOSI
  //port0.14 -> SPCK
  s_pPio->PIO_PDR = BIT(11) | BIT(12) | BIT(13) | BIT(14);
  s_pPio->PIO_ASR = BIT(11) | BIT(12) | BIT(13) | BIT(14);
  s_pPio->PIO_BSR = 0;


Имаше и още едно дърво като го подкарвах, CS пиновете се клатят според режима на който си пуснал SPI-а (автоматично към устройството, на което пращаш), единия беше FIXED (ако не се лъжа на този го ползвам) а другия някакъв динамичен, вече го забравих....не мога да си стигна до компа в момента да извадя точния код

Автор:  miro_atc [ Съб Юли 07, 2007 1:34 pm ]
Заглавие: 

Заеби тия библиотеки и си го направи директно... За CS най-добрия начин е да си го клатиш ръчно като GPIO иначе много грижи може да имаш. И SPI без DMA при тоя процесор също не е добра идея...

Ето ти малко примерен код, ама трябва да си отсееш плявата:
Код:
void SPI_RESET_CS(SPI_DRIVER_INFO drv_info)
{
    AT91PS_PIO      pPIO;
    unsigned int   pins;


   pPIO = drv_info->pPIO;
   pins = drv_info->cs_pins;

   pPIO->PIO_SODR = pins;   // set level = 1
   pPIO->PIO_PER = pins;    // Set in PIO mode
   pPIO->PIO_OER = pins;    // Configure in Output
   pPIO->PIO_PPUDR = pins;   // pull-up off

   //MOSI, MISO, SPCK
   pins = drv_info->spi_pins;
   pPIO->PIO_ASR = pins;      // A select
    pPIO->PIO_PDR = pins;      // PIO mode disable
    pPIO->PIO_PPUDR = pins;      //disable pull-up
}

void SPI_START_TRANSACTION(HANDLE hnd, SPI_DRIVER_INFO drv_info)
{
    DRV_SPI_MODE mode;
    AT91PS_SPI pSPI;

   mode = (DRV_SPI_MODE)hnd->param[2].as_voidptr;
    drv_info->pPIO->PIO_CODR = mode->cs_pin;

    pSPI = drv_info->pSPI;
    pSPI->SPI_CSR[0] = mode->cs_reg;
   pSPI->SPI_IER = AT91C_SPI_ENDRX;
}
//////////////////////////////////////////////////////////////////////////
//
//         SPI Driver
//
//   Resposible for:
//         -
//         -
//   Notes:
//      - SPI master mode(SPI_MR->MSTR=1) supported only
//      - Fixed peripheral select mode (SPI_MR->PS=0) is used to allow use of PDC
//      - CSs are driven in PIO mode because of the LASTXFER bug when CSAAT=1 and mutiple transfers
//       - To perform multiple transfers on a single CS, the LOCK bit must be set for
//         all handles except the last one in the transaction.
//      - request for R, W and RW operations are supported
//      - if Write-only operations are used in multiple transfers (locked handles), the length of
//         single buffer should be less than sizeof(drv_spi_temp)
//////////////////////////////////////////////////////////////////////////

#include "spi_drv.h"
#include <tmos.h>

__no_init unsigned char drv_spi_temp[254];


void spi_start_dma(HANDLE hnd, AT91PS_PDC pPDC)
{
    unsigned int len;

    len = hnd->len;

    if(hnd->res_cmd.low & FLAG_WRITE)
      pPDC->PDC_TPR = hnd->param[1].as_int;
    else
      pPDC->PDC_TPR = RAM_START;

    if(hnd->res_cmd.low & FLAG_READ)
      pPDC->PDC_RPR = hnd->param[0].as_int;
    else
    {
      if( len > sizeof(drv_spi_temp))
        {
         len = sizeof(drv_spi_temp);
            hnd->param[1].as_int += len;
        }
      pPDC->PDC_RPR = (unsigned int)drv_spi_temp;
    }


   pPDC->PDC_RCR = len;
   pPDC->PDC_TCR = len;
    hnd->len -= len;
}

//*----------------------------------------------------------------------------
//*         DCR function
//*----------------------------------------------------------------------------
__interwork RES_CODE SPI_DCR(SPI_DRIVER_INFO drv_info, unsigned int reason, void * param)
{

   switch(reason)
    {
        case DCR_RESET:
      #define pSPI ((AT91PS_SPI) param)
         //Manual asserting for SPI CSs
         SPI_RESET_CS(drv_info);      

         //enable periph clock
         CfgPMC(drv_info->hw_id);

         //Reset SPI
         pSPI->SPI_CR = AT91C_SPI_SWRST;
      
         // set invalid mode
         pSPI->SPI_MR = 0x00000011;
            pSPI->SPI_CSR[0] = 0xFF00FE03;
         pSPI->SPI_CR = AT91C_SPI_SPIEN;
            pSPI->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
      
            EnableISR(drv_info->hw_id);
         return RES_OK;
      #undef pSPI

    }
   return RES_FATAL;
}
//*----------------------------------------------------------------------------


//*----------------------------------------------------------------------------
//*         DSR function
//*----------------------------------------------------------------------------
__interwork RES_CODE SPI_DSR(HANDLE hnd, SPI_DRIVER_DATA drv_data, SPI_DRIVER_INFO drv_info)
{
    unsigned int locker;

    if((locker = drv_data->locker))
   {
        //lock X
        if(locker != hnd->client.drv_index)
            return hnd_try_waiting(hnd, (DRIVER_DATA)drv_data);

      if( !(hnd->res_cmd.low & FLAG_LOCK) )
         drv_data->locker = 0;
      if(   drv_data->pending)
      {
          spi_start_dma(hnd, (AT91PS_PDC)&drv_info->pPDC->PDC_RNPR);
         drv_data->pending2 = hnd;
         return svc_HND_SET_STATUS(hnd, RES_PENDING);
      }

   } else
    {
      if(   drv_data->pending)
         return hnd_try_waiting(hnd, (DRIVER_DATA)drv_data);
   
      SPI_START_TRANSACTION(hnd, drv_info);
      if( hnd->res_cmd .low & FLAG_LOCK)
         drv_data->locker = hnd->client.drv_index;
    }

    spi_start_dma(hnd, drv_info->pPDC);
   drv_data->pending = hnd;
    return svc_HND_SET_STATUS(hnd, RES_PENDING);

}




//*----------------------------------------------------------------------------
//*         ISR function
//*----------------------------------------------------------------------------
__interwork void SPI_ISR(SPI_DRIVER_INFO drv_info, AT91PS_SPI pSPI)
{
   SPI_DRIVER_DATA drv_data;
    HANDLE hnd;

    drv_data = drv_info->drv_data;

    //read SPI_SR
    hnd = (HANDLE)pSPI->SPI_SR;

    //direct call assuming no higer ISRs will use SPI
   if(   (hnd=drv_data->pending2) )
   {
      if(!pSPI->SPI_RNCR)
      {
            drv_data->pending2 = NULL;
         usr_HND_SET_STATUS(drv_data->pending, RES_OK);
            drv_data->pending = hnd;
      }
        return;
   }

   if(pSPI->SPI_RCR)
        return;

   if(   (hnd=drv_data->pending) )
   {
      if(hnd->len)
      {
         spi_start_dma(hnd, drv_info->pPDC);
         return;
      }

        pSPI->SPI_IDR = AT91C_SPI_ENDRX | AT91C_SPI_TXEMPTY;
      if (!drv_data->locker)
        {
            if ( !(pSPI->SPI_SR & AT91C_SPI_TXEMPTY) )
            {
            pSPI->SPI_IER = AT91C_SPI_TXEMPTY;
                return;
            }
         SPI_END_TRANSACTION(drv_info, hnd);
        }
      drv_data->pending = NULL;
      usr_HND_SET_STATUS(hnd, RES_OK);
   }

   if (!drv_data->locker)
      if( (hnd = drv_data->waiting) )
      {
         drv_data->waiting = hnd->next;
         drv_data->pending = hnd;
         SPI_START_TRANSACTION(hnd, drv_info);
          spi_start_dma(hnd, drv_info->pPDC);
         if( hnd->res_cmd.low & FLAG_LOCK)
            drv_data->locker = hnd->client.drv_index;
         usr_HND_SET_STATUS(hnd, RES_PENDING);
      }

}

Автор:  dumfree [ Съб Юли 07, 2007 11:54 pm ]
Заглавие: 

Тръгна.
Подкарах го по начина по който бях започнал но така и не си открих къде ми е бил проблема.
Благодаря на всички отзовали се.

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/