|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 1:09 am
|
Страница 1 от 1
|
[ 4 мнения ] |
|
Подкарване на SPI на at91sam7s64
| Автор |
Съобщение |
|
dumfree
Ранг: Ориентиран
Регистриран на: Пет Юли 01, 2005 10:46 pm Мнения: 229 Местоположение: Гложене/София
|
 Подкарване на SPI на at91sam7s64
Опитвам се да подкарам SPI на това чудо, обаче то категорично отказва, къде бъркам?
Средата която ползвам е IAR, закачил съм анализатора на MISO, MOSI, SCK ама нищо не мърда.
|
| Пет Юли 06, 2007 9:45 pm |
|
 |
|
Predator_MF
Ранг: Форумен бог
Регистриран на: Чет Окт 07, 2004 1:22 pm Мнения: 1949 Местоположение: София
|
Не виждам прокарал ли си пиновете през PIO-то ?
Имаше и още едно дърво като го подкарвах, CS пиновете се клатят според режима на който си пуснал SPI-а (автоматично към устройството, на което пращаш), единия беше FIXED (ако не се лъжа на този го ползвам) а другия някакъв динамичен, вече го забравих....не мога да си стигна до компа в момента да извадя точния код
|
| Съб Юли 07, 2007 11:20 am |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 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 |
|
 |
|
dumfree
Ранг: Ориентиран
Регистриран на: Пет Юли 01, 2005 10:46 pm Мнения: 229 Местоположение: Гложене/София
|
Тръгна.
Подкарах го по начина по който бях започнал но така и не си открих къде ми е бил проблема.
Благодаря на всички отзовали се.
|
| Съб Юли 07, 2007 11:54 pm |
|
|
|
Страница 1 от 1
|
[ 4 мнения ] |
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 5 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|