Untitled

mail@pastecode.io avatar
unknown
c_cpp
a year ago
5.3 kB
30
Indexable
Never
#include "stm32f030x6.h"

#define t1 								100
#define t2 								200
#define t3 								300

#define T0H 							0xC0
#define T1H 							0xFC
#define NUMBER_OF_LEDS 		1
#define NUMBER_OF_BYTES 	(NUMBER_OF_LEDS * 24) + 64

uint8_t data_LED[NUMBER_OF_BYTES];

uint32_t time = 0;

void system_Clock_Init(void);
void GPIO_Init(void);
void Systick_Init(void);
void DMA_Init(void);
void SPI1_Init(void);
void WS2812_Send(void);
void clear_LEDS(void);


int main(void)
{
	__disable_irq();
	
	system_Clock_Init();
	
	GPIO_Init();

	Systick_Init();
	
	DMA_Init();
	
	SPI1_Init();
	
	__enable_irq();
	
	clear_LEDS();
	WS2812_Send();
	
	while(1)
	{
		//WS2812_Send();
		if (time >= t1)
		{
			GPIOA->ODR ^= GPIO_ODR_0;
			time = 0;
		}
	}
}

void SysTick_Handler(void)
{
  time++;
}

void SPI1_IRQHandler(void)
{
	  DMA1_Channel3->CCR &= ~( DMA_CCR_EN );
}

void system_Clock_Init(void)
{
	// Reset the Flash 'Access Control Register', and
  // then set 1 wait-state and enable the prefetch buffer.
  // (The device header files only show 1 bit for the F0
  //  line, but the reference manual shows 3...)
	// 48MHz clock HSE
	FLASH->ACR &= ~(0x00000017U);
  FLASH->ACR |=  (FLASH_ACR_LATENCY | FLASH_ACR_PRFTBE);
	
	// ENABLE HSE and wait for the HSE to become Ready
	RCC->CR |= RCC_CFGR_PLLSRC_HSE_PREDIV;  
	while (!(RCC->CR & (1<<17)));
	// Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
	RCC->APB1ENR |= 1<<28;
	RCC->CFGR |= RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PPRE_DIV1 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PLLMUL6;
	RCC->CFGR2 |= RCC_CFGR2_PREDIV_DIV1;
	RCC->CR |= RCC_CR_PLLON;
	while (!(RCC->CR & RCC_CR_PLLRDY));
	RCC->CFGR |= RCC_CFGR_SW_PLL; 
	while (!(RCC->CFGR & RCC_CFGR_SWS_PLL));
}

void GPIO_Init()
{
	RCC->AHBENR |= RCC_AHBENR_GPIOAEN;																									//Enable GPIOA clock
	GPIOA->AFR[0] &= ~(0xF0F00000);																													//Set PA6 pin to a alternate function mode
	GPIOA->MODER |= GPIO_MODER_MODER0_0 | GPIO_MODER_MODER7_1 | GPIO_MODER_MODER5_1;		//Set PA0 pin to output mode and PA6 to atlrnate mode				
	GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_0);
	GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR7 | GPIO_OSPEEDER_OSPEEDR5;
	GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR0);
}

void Systick_Init()
{
	/* Configure SysTick */
	SysTick->LOAD = 48000 - 1;    									
	SysTick->VAL = 0;
	SysTick->CTRL = 7; 
	
	NVIC_EnableIRQ(SysTick_IRQn);
	NVIC_SetPriority(SysTick_IRQn, 1);
}

void DMA_Init()
{
	// DMA configuration (channel 1).
  // CCR register:
  // - Memory-to-peripheral
  // - Circular mode enabled.
  // - Increment memory ptr, don't increment periph ptr.
  // - -bit data size for both source and destination.
  // - High priority.
	RCC->AHBENR |= RCC_AHBENR_DMA1EN;
  DMA1_Channel3->CCR &= ~( DMA_CCR_MEM2MEM |
                           DMA_CCR_PL |
                           DMA_CCR_MSIZE |
                           DMA_CCR_PSIZE |
                           DMA_CCR_PINC |
                           DMA_CCR_EN );
  DMA1_Channel3->CCR |=  ( DMA_CCR_PL_1 |
                           DMA_CCR_MINC |
                           DMA_CCR_CIRC |
                           DMA_CCR_DIR );
  // Set DMA source and destination addresses.
  // Source: Address of the framebuffer.
  DMA1_Channel3->CMAR  = ( uint32_t )&data_LED;
  // Destination: SPI1 data register.
  DMA1_Channel3->CPAR  = ( uint32_t )&( SPI1->DR );
  // Set DMA data transfer length (framebuffer length).
  DMA1_Channel3->CNDTR = ( uint16_t )NUMBER_OF_BYTES;
}

void SPI1_Init()
{
	// SPI1 configuration:
  // - Clock phase/polarity: 1/1
  // - Assert internal CS signal (software CS pin control)
  // - MSB-first
  // - 8-bit frames
  // - Baud rate prescaler of 8 (for a 6MHz bit-clock)
  // - TX DMA requests enabled.
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
  SPI1->CR1 &= ~( SPI_CR1_LSBFIRST |
                  SPI_CR1_BR );
  SPI1->CR1 |=  ( SPI_CR1_SSM |
                  SPI_CR1_SSI |
                  0x2 << SPI_CR1_BR_Pos |
                  SPI_CR1_MSTR |
                  SPI_CR1_CPOL |
                  SPI_CR1_CPHA );
  SPI1->CR2 &= ~( SPI_CR2_DS );
  SPI1->CR2 |=  ( 0x7 << SPI_CR2_DS_Pos |
                  SPI_CR2_TXDMAEN | SPI_CR2_TXEIE);
  // Enable the SPI peripheral.
  SPI1->CR1 |=  ( SPI_CR1_SPE );
	
	//NVIC->ISER[0] |= (1u << 25);
	
	NVIC_EnableIRQ(SPI1_IRQn);
	NVIC_SetPriority(SPI1_IRQn, 2);
}

void WS2812_Send()
{
	uint32_t index = 0;
	for(int i = 0; i < NUMBER_OF_LEDS; i++)
	{
		for(int j = 0; j < 24; j++)
		{
			if(j == 8)
			{
				data_LED[index] = T1H;
				index++;
			}
			else
			{
				data_LED[index] = T0H;
				index++;
			}
		}
	}
	for(int i = 0; i < 64; i++)
	{
		data_LED[index] = 0x00;
		index++;
	}
	// Enable DMA1 Channel 1 to start sending colors.
  DMA1_Channel3->CCR |= ( DMA_CCR_EN );
}

void clear_LEDS()
{
	uint32_t index = 0;
	for(int i = 0; i < NUMBER_OF_LEDS; i++)
	{
		for(int j = 0; j < 24; j++)
		{
			data_LED[index] = T0H;
			index++;
		}
	}
	for(int i = 0; i < 64; i++)
	{
		data_LED[index] = 0x00;
		index++;
	}
	// Enable DMA1 Channel 1 to start sending colors.
  DMA1_Channel3->CCR |= ( DMA_CCR_EN );
}