Добрый день! Я новичок в программировании ARM. Хотелось разобраться с инициализацией SPI для контроллера SAM3S4B. Далее код. После включения SPI в статусных регистрах ничего не высвечивается.
#include "main.h"
/** SPI MISO pin definition. */
#define PIN_SPI_MISO {PIO_PA12A_MISO, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** SPI MOSI pin definition. */
#define PIN_SPI_MOSI {PIO_PA13A_MOSI, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** SPI SPCK pin definition. */
#define PIN_SPI_SPCK {PIO_PA14A_SPCK, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** SPI chip select pin definition. */
#define PIN_SPI_NPCS0_PA11 {PIO_PA11A_NPCS0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** List of SPI pin definitions (MISO, MOSI & SPCK). */
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK
/** Pins used by the application.*/
static const Pin pins[] = {PINS_SPI, PIN_SPI_NPCS0_PA11};
#define SPI_MR_PCS_1 ((0<<0)|(1<<1)|(1<<2)|(1<<3))
int main(void)
{
PIO_Configure(pins, PIO_LISTSIZE(pins));
PMC->PMC_PCER0 = ( 1 << ID_SPI | 1 << ID_PIOA);
SPI->SPI_CR = SPI_CR_SWRST;
SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS;
SPI->SPI_MR |= ( (SPI_MR_PCS_1 << 16) & SPI_CSR_BITS_Msk );
SPI->SPI_CSR[0] = SPI_CSR_CPOL | SPI_CSR_BITS_8_BIT | (0x78 << 8);
SPI->SPI_CR = SPI_CR_SPIEN;
}
Genadi Zawidowski
Oct 14 2015, 13:20
Откуда берется SPI_MR_PCS_1 ? Я в xdk-asf-3.17.0 не нашел его.
Вот такое у меня (инициализация разбита на три части):
Код
// инициализация контроллера SPI
// Get clock
PMC->PMC_PCER0 = (1UL << ID_PIOA) | (1UL << ID_SPI); /* Need PIO too */
// setup PIO pins for SPI bus, disconnect from peripherials
SPIIO_INITIALIZE();
// reset and enable SPI
SPI->SPI_CR = SPI_CR_SWRST;
SPI->SPI_CR = SPI_CR_SWRST;
SPI->SPI_CR = SPI_CR_SPIDIS;
// Работаем с Fixed Peripheral Selectionб и без Peripheral Chip Select Decoding
// USE following line for MASTER MODE operation
//SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PS_FIXED;
SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS | (SPI_MR_PS * 0);
#if WITHSPIHWDMA
SPI->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS;
SPI->SPI_TNCR = 0;
SPI->SPI_RNCR = 0;
SPI->SPI_RCR = 0;
SPI->SPI_TCR = 0;
SPI->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN;
#endif /* WITHSPIHWDMA */
SPI->SPI_IDR = ~ 0; /* Disable all interrupts */
SPI->SPI_CR = SPI_CR_SPIEN;
Код
const ldiv_t v = ldiv(CPU_FREQ, spispeed);
const unsigned long scbr = ulmin(255, (CPU_FREQ > spispeed) ? (v.quot + (v.rem != 0)) : 1); // 72 MHz / scbr = SPI clock freq
const unsigned dlybs = 0;
const unsigned dlybct = 0;
// 8-ми битые передачи
const unsigned long csrbits =
SPI_CSR_BITS_8_BIT | // (SPI) 8 Bits Per transfer
SPI_CSR_SCBR(scbr) | // (SPI_CSR_SCBR_Msk & (scbr << SPI_CSR_SCBR_Pos)) | // (SPI) Serial Clock Baud Rate
SPI_CSR_CSAAT | // (SPI) Chip Select Active After Transfer
SPI_CSR_DLYBS(dlybs) | // (SPI_CSR_DLYBS_Msk & (dlybs << SPI_CSR_DLYBS_Pos)) |
SPI_CSR_DLYBCT(dlybct) | // (SPI_CSR_DLYBCT_Msk & (dlybct << SPI_CSR_DLYBCT_Pos)) |
0;
// 16-ти битые передачи
const unsigned long csrbits16w =
SPI_CSR_BITS_16_BIT | // (SPI) 16 Bits Per transfer
SPI_CSR_SCBR(scbr) | // (SPI_CSR_SCBR_Msk & (scbr << SPI_CSR_SCBR_Pos)) | // (SPI) Serial Clock Baud Rate
SPI_CSR_CSAAT | // (SPI) Chip Select Active After Transfer
SPI_CSR_DLYBS(dlybs) | // (SPI_CSR_DLYBS_Msk & (dlybs << SPI_CSR_DLYBS_Pos)) |
SPI_CSR_DLYBCT(dlybct) | // (SPI_CSR_DLYBCT_Msk & (dlybct << SPI_CSR_DLYBCT_Pos)) |
0;
// подготовка управляющих слов для разных spi mode, используемых контроллером.
// 8-битная передача
csr_val [spispeedindex][SPIC_MODE0] = csrbits | SPI_CSR_NCPHA;
csr_val [spispeedindex][SPIC_MODE1] = csrbits;
csr_val [spispeedindex][SPIC_MODE2] = csrbits | SPI_CSR_CPOL | SPI_CSR_NCPHA;
csr_val [spispeedindex][SPIC_MODE3] = csrbits | SPI_CSR_CPOL;
// подготовка управляющих слов для разных spi mode, используемых контроллером.
// 16-битная передача
csr_val16w [spispeedindex][SPIC_MODE0] = csrbits16w | SPI_CSR_NCPHA;
csr_val16w [spispeedindex][SPIC_MODE1] = csrbits16w;
csr_val16w [spispeedindex][SPIC_MODE2] = csrbits16w | SPI_CSR_CPOL | SPI_CSR_NCPHA;
csr_val16w [spispeedindex][SPIC_MODE3] = csrbits16w | SPI_CSR_CPOL;
Код
SPI->SPI_CSR [0] = csr_val [spispeedindex][spimode];
(void) SPI->SPI_RDR; /* clear AT91C_SPI_RDRF in status register */
HARDWARE_SPI_CONNECT();
Это просто идентификатор для 4х бит PCS в регистре MR. У меня возникает ошибка при отключении PIO и подключении SPI к ножкам. Используя функцию PIO_Configurate, keil при отладке останавливается на startup и не переходит к main. Может Вы знаете как с этим бороться?
Genadi Zawidowski
Oct 14 2015, 20:40
Не знаю, отлаживать не пришлось.