Отговори на тема  [ 4 мнения ] 
Подкарване на SPI на at91sam7s64 
Автор Съобщение
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пет Юли 01, 2005 10:46 pm
Мнения: 229
Местоположение: Гложене/София
Мнение Подкарване на 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); // и пращаме - ама не иска :(


Пет Юли 06, 2007 9:45 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Не виждам прокарал ли си пиновете през 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 (ако не се лъжа на този го ползвам) а другия някакъв динамичен, вече го забравих....не мога да си стигна до компа в момента да извадя точния код


Съб Юли 07, 2007 11:20 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Заеби тия библиотеки и си го направи директно... За 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);
      }

}


Съб Юли 07, 2007 1:34 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пет Юли 01, 2005 10:46 pm
Мнения: 229
Местоположение: Гложене/София
Мнение 
Тръгна.
Подкарах го по начина по който бях започнал но така и не си открих къде ми е бил проблема.
Благодаря на всички отзовали се.


Съб Юли 07, 2007 11:54 pm
Профил ICQ
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 4 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 5 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни