Код: Выделить всё
uint8_t dma_answ[5] = {0};
void clock_init(){
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_SW);
RCC->CR &= ~RCC_CR_PLLON;
RCC->CFGR |= RCC_CFGR_SW_PLL;
RCC->CFGR &= ~RCC_CFGR_PLLMULL;
RCC->CFGR |= RCC_CFGR_PLLMULL9;// | RCC_CFGR_PLLSRC ;
RCC->CR |= RCC_CR_PLLON | RCC_CR_HSEON;
while((RCC->CR & RCC_CR_PLLRDY)==0);
}
void SPI_Init(uint8_t lsbFirst, uint8_t clockPol, uint8_t clockEdg){
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций включено
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Тактирование порта А включено
//------- TEST-PIN ----------------
GPIOA->CRH |= GPIO_CRH_MODE12; // Выход, 50 МГц
GPIOA->CRH &= ~GPIO_CRH_CNF12; // Общего назначения, push-pull
GPIOA->BSRR = GPIO_BSRR_BR12;
//---------------------------------
//------- CS-PIN ------------------
GPIOA->CRL |= GPIO_CRL_MODE4; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF4; // Общего назначения, push-pull
GPIOA->BSRR = GPIO_BSRR_BS4; // Высокий уровень
//---------------------------------
//------- SCK-PIN -----------------
GPIOA->CRL |= GPIO_CRL_MODE5; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF5;
GPIOA->CRL |= GPIO_CRL_CNF5_1; // Альтернативная функция, push-pull
//---------------------------------
//------- MISO-PIN ----------------
GPIOA->CRL &= ~GPIO_CRL_MODE6; // Вход
GPIOA->CRL &= ~GPIO_CRL_CNF6;
GPIOA->CRL |= GPIO_CRL_CNF6_1; // Альтернативная функция, pull-up/pull-down
GPIOA->BSRR = GPIO_BSRR_BS6; // Высокий уровень
//---------------------------------
//------- MOSI-PIN ----------------
GPIOA->CRL |= GPIO_CRL_MODE7; // Выход, 50 МГц
GPIOA->CRL &= ~GPIO_CRL_CNF7;
GPIOA->CRL |= GPIO_CRL_CNF7_1; // Альтернативная функция, push-pull
//---------------------------------
SPI1->CR1 = 0x0000; // Обнуляем регистр конфигурации SPI1
SPI1->CR2 = 0x0000; // Обнуляем регистр конфигурации SPI1
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Тактирование SPI1 включено
SPI1->CR1 = SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_MSTR; // Программное управление выводом CS, SPI1 в режиме ведущего
if(!lsbFirst) SPI1->CR1 &= ~SPI_CR1_LSBFIRST; // Старшим битом вперёд
else SPI1->CR1 |= SPI_CR1_LSBFIRST; // Младшим битом вперёд
if(!clockPol) SPI1->CR1 &= ~SPI_CR1_CPOL; // 0 - когда отпущена
else SPI1->CR1 |= SPI_CR1_CPOL; // 1 - когда отпущена
if(!clockEdg) SPI1->CR1 &= ~SPI_CR1_CPHA; // Выборка по переднему фронту
else SPI1->CR1 |= SPI_CR1_CPHA; // Выборка по заднему фронту
SPI1->CR2 |= SPI_CR2_RXDMAEN;
SPI1->CR1 |= SPI_CR1_BR_1 | SPI_CR1_BR_0 ; // Выбор делителя частоты тактирования шины APB2 (fAPB/16 = 2.25 МГц)
SPI1->CR1 |= SPI_CR1_SPE; // Работа SPI1 разрешена
NVIC_EnableIRQ(SPI1_IRQn);
}
void dma_spi_recive( uint8_t* data, uint8_t bytesNumber ){
RCC->AHBENR = RCC_AHBENR_DMA1EN;
DMA1_Channel2->CCR = 0x0F;
DMA1_Channel2->CPAR = (uint32_t) & SPI1->DR;
DMA1_Channel2->CMAR = (uint32_t) dma_answ;
DMA1_Channel2->CNDTR = bytesNumber;
DMA1_Channel2->CCR |= DMA_CCR2_PL_0 | DMA_CCR2_MINC | DMA_CCR2_TCIE | DMA_CCR2_EN;
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
}
uint8_t SPI_Read( uint8_t data, uint8_t bytesNumber ){
dma_spi_recive(dma_answ, bytesNumber);
ADI_PART_CS_LOW;
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = data;
for(uint8_t byte = 0; byte < bytesNumber; byte++ )
{
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0x00;
}
while ( SPI1->SR & SPI_SR_BSY );
ADI_PART_CS_HIGH;
return 1;
}
uint8_t SPI_Read( uint8_t data, uint8_t bytesNumber ){
dma_spi_recive(dma_answ, bytesNumber);
ADI_PART_CS_LOW;
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = data;
for(uint8_t byte = 0; byte < bytesNumber; byte++ )
{
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0x00;
}
while ( SPI1->SR & SPI_SR_BSY );
ADI_PART_CS_HIGH;
return 1;
}
uint32_t AD7190_GetRegisterValue(uint8_t registerAddress){
uint8_t registerWord = 0;
uint32_t buffer = 0;
registerWord = AD7190_COMM_READ | AD7190_COMM_ADDR( registerAddress );
//-- Проверяем, какой длины считываемый регистр -------------------------------
if( registerAddress == AD7190_REG_STAT ||
registerAddress == AD7190_REG_ID ||
registerAddress == AD7190_REG_GPOCON ) // если регистры однобайтные
{
SPI_Read(registerWord, 1);
}
else // если регистры трёхбайтные
{
SPI_Read(registerWord, 3);
}
//---------------------------------------------------------------------------
return buffer;
}
unsigned char AD7190_Init(void){
unsigned char status = 1;
unsigned long regVal = 0;
AD7190_Reset();
regVal = AD7190_GetRegisterValue(AD7190_REG_ID);
if( regVal != ID_AD7190)
{
return status = 0;
}
GPIOA->BSRR = GPIO_BSRR_BS12; // Высокий уровень
return status ;
}
void AD7190_Reset(void){
for( uint8_t byte = 0; byte <6; byte++ )
{
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0xFF;
} // Посылаем 40 импульсов для сброса
TIME_DelayUs(920);
}
int main(){
clock_init();
for(uint32_t i=0; i<720000; i++);
SPI_Init(0, 1, 1);
usart_init();
AD7190_Init();
AD7190_GetRegisterValue(AD7190_REG_CONF);
__enable_irq ();
while(1){
}
}
void DMA1_Channel2_IRQHandler(void){
if(DMA1->ISR & DMA_ISR_TCIF2){
DMA1_Channel2->CCR &= ~DMA_CCR2_EN;
// Flag = 1;
if(!(GPIOA->IDR & GPIO_IDR_IDR12)) GPIOA->BSRR = GPIO_BSRR_BS12;
else GPIOA->BSRR = GPIO_BSRR_BR12;
DMA1->IFCR = DMA_IFCR_CGIF2;
}
}