Esempio n. 1
0
struct serial_dev * stm32f_uart4_serial_dma_init(unsigned int baudrate, 
												 unsigned int flags)
{
	struct stm32f_serial_dma_drv * drv = &uart4_serial_dma_drv;

	DCC_LOG(LOG_TRACE, "...");

	stm32_dmactl_init(&drv->rx.dmactl, STM32F_DMA1, 2); 
	stm32_dmactl_init(&drv->tx.dmactl, STM32F_DMA1, 4); 
	stm32f_serial_dma_init(drv, baudrate, flags, 4);

	/* configure and Enable interrupts */
#ifdef THINKAPP
	thinkos_irq_register(STM32_IRQ_UART4, SERIAL_IRQ_PRIORITY, 
						 stm32f_uart4_isr);

	thinkos_irq_register(STM32F_IRQ_DMA1_STREAM2, SERIAL_IRQ_PRIORITY, 
						 stm32f_dma1_stream2_isr);
#else
	cm3_irq_pri_set(STM32_IRQ_UART4, SERIAL_IRQ_PRIORITY);
	cm3_irq_enable(STM32_IRQ_UART4);

	cm3_irq_pri_set(STM32F_IRQ_DMA1_STREAM2, SERIAL_IRQ_PRIORITY);
	cm3_irq_enable(STM32F_IRQ_DMA1_STREAM2);
#endif

	DCC_LOG(LOG_TRACE, "done!");

	return (struct serial_dev *)&uart4_serial_dma_dev;
}
Esempio n. 2
0
void i2c_master_init(unsigned int scl_freq)
{
	struct stm32f_i2c * i2c = STM32F_I2C1;
	struct stm32f_rcc * rcc = STM32F_RCC;
	uint32_t pclk = stm32f_apb1_hz;
#if defined(STM32F1X)
	struct stm32f_afio * afio = STM32F_AFIO;
	/* Use alternate pins for I2C1 */
	afio->mapr |= AFIO_I2C1_REMAP;
#endif

	stm32f_gpio_mode(I2C1_SCL, ALT_FUNC, OPEN_DRAIN);
	stm32f_gpio_mode(I2C1_SDA, ALT_FUNC, OPEN_DRAIN);

#if defined(STM32F4X)
	stm32f_gpio_af(I2C1_SCL, GPIO_AF4);
	stm32f_gpio_af(I2C1_SDA, GPIO_AF4);
#endif

	/* Enable I2C clock */
	rcc->apb1enr |= RCC_I2C1EN;

	/* Software reset */
	i2c->cr1 = I2C_SWRST; 

	DCC_LOG3(LOG_TRACE, "CR1=0x%04x CR2=0x%04x CCR=0x%04x", 
			 i2c->cr1, i2c->cr2, i2c->ccr);

	DCC_LOG3(LOG_TRACE, "OAR1=0x%04x OAR2=0x%04x TRISE=0x%04x", 
			 i2c->oar1, i2c->oar2, i2c->trise);

	DCC_LOG2(LOG_TRACE, "SR1=0x%04x SR2=0x%04x ", i2c->sr1, i2c->sr2);

	i2c->cr1 = 0;

	/* I2C Control register 2 (I2C_CR2) */
	i2c->cr2 = I2C_FREQ_SET(pclk / 1000000);
	/*	I2C Own address register 1 (I2C_OAR1) */
	i2c->oar1 = 0;
	/*	I2C Own address register 2 (I2C_OAR2) */
	i2c->oar2 = 0;
	/* I2C Clock control register (I2C_CCR) */ 
	i2c->ccr = I2C_CCR_SET(pclk / scl_freq / 2);
	/* I2C TRISE register (I2C_TRISE) */
	i2c->trise = I2C_TRISE_SET((pclk / 1000000) + 1);

	xfer.flag = thinkos_flag_alloc();

	cm3_irq_enable(STM32F_IRQ_I2C1_EV);
	/* set event IRQ to very high priority */
	cm3_irq_pri_set(STM32F_IRQ_DMA1_STREAM0, I2C_IRQ_PRIORITY);
	cm3_irq_enable(STM32F_IRQ_I2C1_ER);
	/* set error IRQ to high priority */
	cm3_irq_pri_set(STM32F_IRQ_DMA1_STREAM0, I2C_IRQ_PRIORITY);

	DCC_LOG(LOG_TRACE, "Enabling interrupts....");
	/* enable ACK, events and errors */
	i2c->cr2 |= I2C_ITERREN | I2C_ITEVTEN | I2C_ITBUFEN;
}
Esempio n. 3
0
void isink_init(void)
{
	struct stm32f_dac * dac = STM32_DAC;
	struct stm32f_tim * tim = STM32_TIM4;
	uint32_t div;

	stm32_gpio_clr(SINK1);
	stm32_gpio_clr(SINK2);
	stm32_gpio_clr(SINK3);
	stm32_gpio_clr(SINK4);
	stm32_gpio_mode(SINK1, OUTPUT, PUSH_PULL | SPEED_HIGH);
	stm32_gpio_mode(SINK2, OUTPUT, PUSH_PULL | SPEED_HIGH);
	stm32_gpio_mode(SINK3, OUTPUT, PUSH_PULL | SPEED_HIGH);
	stm32_gpio_mode(SINK4, OUTPUT, OPEN_DRAIN | SPEED_HIGH);
	stm32_gpio_af(SINK1, GPIO_AF2);
	stm32_gpio_af(SINK2, GPIO_AF2);
	stm32_gpio_af(SINK3, GPIO_AF2);

	/* Timer clock enable */
	stm32_clk_enable(STM32_RCC, STM32_CLK_TIM4);
	
	/* get the total divisior */
	div = (stm32f_tim1_hz + (FREQ_1MHZ / 2)) / FREQ_1MHZ;
	/* Timer configuration */
	tim->cr1 = 0;
	tim->psc = div - 1;
	tim->arr = 1;
	tim->ccmr1 = TIM_OC1M_PWM_MODE2 | TIM_OC2M_PWM_MODE2;
	tim->ccmr2 = TIM_OC3M_PWM_MODE2 | TIM_OC4M_PWM_MODE2;
	tim->ccer = TIM_CC1E | TIM_CC2E | TIM_CC3E | TIM_CC4E;
	//	TIM_CC1P | TIM_CC2P | TIM_CC3P | TIM_CC4P;
	tim->ccr1 = 1;
	tim->ccr2 = 1;
	tim->ccr3 = 1;
	tim->ccr4 = 1;


	tim->dier = TIM_UIE; /* Update interrupt enable */
	cm3_irq_pri_set(STM32_IRQ_TIM4, IRQ_PRIORITY_HIGH);
	/* Enable interrupt */
	cm3_irq_enable(STM32_IRQ_TIM4);

	/* I/O pins config */
	stm32_gpio_mode(IRATE, ANALOG, 0);
	stm32_gpio_clr(IRATE);

	/* DAC clock enable */
	stm32_clk_enable(STM32_RCC, STM32_CLK_DAC);

	/* DAC disable */
	dac->cr = 0;
	/* DAC configure */
	dac->cr = DAC_EN2;
	/* DAC channel 2 initial value */
	dac->dhr12r2 = 0;
	/* DAC channel 1 initial value */
	dac->dhr12r1 = 0;

	isink_drv.mode = -1;
}
Esempio n. 4
0
struct file * uart_console_open(struct stm32f_usart * us)
{
	struct uart_console_dev * dev = &uart_console_dev;

	DCC_LOG(LOG_INFO, "...");
	dev->rx_flag = thinkos_flag_alloc(); 
#if ENABLE_UART_TX_BLOCK
	dev->tx_flag = thinkos_flag_alloc(); 
#endif
#if ENABLE_UART_TX_MUTEX
	dev->tx_mutex = thinkos_mutex_alloc(); 
#endif
	uart_fifo_init(&dev->tx_fifo, UART_TX_FIFO_BUF_LEN);
	uart_fifo_init(&dev->rx_fifo, UART_RX_FIFO_BUF_LEN);

	dev->txie = CM3_BITBAND_DEV(&us->cr1, 7);
	dev->uart = us;

	cm3_irq_pri_set(STM32F_IRQ_USART1, UART_IRQ_PRIORITY);
	cm3_irq_enable(STM32F_IRQ_USART1);

	/* enable RX interrupt */
	us->cr1 |= USART_RXNEIE | USART_IDLEIE;

	return (struct file *)&uart_console_file;
}
Esempio n. 5
0
void __thinkos_irq_reset_all(void)
{
	int irq;
	/* adjust IRQ priorities to regular (above SysTick and bellow SVC) */
	for (irq = 0; irq < THINKOS_IRQ_MAX; irq++) {
		cm3_irq_pri_set(irq, IRQ_DEF_PRIORITY);
		thinkos_rt.irq_th[irq] = THINKOS_THREAD_IDLE;
	}
}
Esempio n. 6
0
void thinkos_irq_ctl_svc(int32_t * arg)
{
	unsigned int req = arg[0];
	unsigned int irq = arg[1];
#if THINKOS_ENABLE_ARG_CHECK
	int irq_max = ((uintptr_t)&__sizeof_rom_vectors / sizeof(void *)) - 16;

	if (irq >= irq_max) {
		DCC_LOG1(LOG_ERROR, "invalid IRQ %d!", irq);
		__thinkos_error(THINKOS_ERR_IRQ_INVALID);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#endif
	arg[0] = 0;
	
	switch (req) {
	case THINKOS_IRQ_ENABLE:
		DCC_LOG1(LOG_TRACE, "enabling IRQ %d", irq);
		/* clear pending interrupt */
		cm3_irq_enable(irq);
		break;

	case THINKOS_IRQ_DISABLE:
		cm3_irq_disable(irq);
		break;

	case THINKOS_IRQ_PRIORITY_SET:
		{
			int priority = arg[2];

			if (priority > IRQ_PRIORITY_VERY_LOW)
				priority = IRQ_PRIORITY_VERY_LOW;
			else if (priority < IRQ_PRIORITY_VERY_HIGH)
				priority = IRQ_PRIORITY_VERY_HIGH;

			/* set the interrupt priority */
			cm3_irq_pri_set(irq, priority);
		}
		break;

//	case THINKOS_IRQ_SVC_SET:
//		break;

	default:
		DCC_LOG1(LOG_ERROR, "invalid IRQ ctl request %d!", req);
		arg[0] = THINKOS_EINVAL;
		break;
	}
}
Esempio n. 7
0
/***********************************************************
  ADC Configuration
 ***********************************************************/
void stm32f_adc_init(void)
{
	struct stm32_rcc * rcc = STM32_RCC;
	struct stm32f_adc * adc = STM32F_ADC1;
	const uint8_t adc_chan_seq[] = {6, 18, 6};

#ifdef	STM32F_ADCC
	struct stm32f_adcc * adcc = STM32F_ADCC;
	/* Common Control */
	adcc->ccr = ADC_TSVREFE | ADC_VBATE | ADC_ADCPRE_4;
	/* PCLK2 = 60MHz
	   ADCCLK = PCLK2/4 = 15MHz */
#endif

	/* ADC clock enable */
	rcc->apb2enr |= RCC_ADC1EN;

	/* configure for DMA use, select timer2 trigger */
	adc->cr1 = ADC_RES_12BIT | ADC_SCAN;
	adc->cr2 = ADC_EXTEN_RISING | ADC_EXTSEL_TIM2_TRGO | ADC_ADON |
			   ADC_DDS | ADC_DMA;
	/* Chan 6 is external
	   Chan 18 is the battery (VBAT)
	   Chan 16 is the internal temperature sensor */
	stm32f_adc_seq_set(adc, adc_chan_seq, 3);
	/* set the sample time */
	stm32f_adc_smp_set(adc, 6, ADC_SMP_56_CYC);
	stm32f_adc_smp_set(adc, 18, ADC_SMP_56_CYC);
	stm32f_adc_smp_set(adc, 16, ADC_SMP_56_CYC);

	adc_gpio_init();

	adc_dma2_init(adc_buf[0], adc_buf[1], (void *)&adc->dr, ADC_CHANS);

#if (ENABLE_ADC_SYNC)
	/* synchronization event */
	adc_dma_sync = thinkos_flag_alloc(); 
#endif
	
	/* Set DMA to very low priority */
	cm3_irq_pri_set(STM32F_IRQ_DMA2_STREAM0, 0xf0);
	/* Enable DMA interrupt */
	cm3_irq_enable(STM32F_IRQ_DMA2_STREAM0);

	/* Configure timer and start periodic conversion */
	adc_tim2_init(ADC_RATE);
}
Esempio n. 8
0
void capture_init(void)
{
	struct capture_drv * drv = &uart2_capture_drv;
	struct stm32_usart * uart = STM32_USART2;
	uint32_t clk;

	DCC_LOG2(LOG_TRACE, "drv=%p uart=%p...", drv, uart);

	clk = profclk_get();
	drv->rx_fifo.head = drv->rx_fifo.tail = 0;
	drv->rx_fifo.seq = 0;
	drv->rx_fifo.buf[0].clk = clk;
	drv->rx_fifo.buf[0].cnt = 0;
	drv->rx_fifo.buf[0].seq = 0;
	drv->rx_fifo.clk = clk;
#if SERIAL_STATS_ENABLE
	drv->err_cnt = 0;
	drv->ore_cnt = 0;
	drv->fe_cnt = 0;
#endif
	drv->idle_bits = 2;

	/* clock enable */
	stm32_clk_enable(STM32_RCC, STM32_CLK_USART2);

	/* UART --------------------------------------------------------------- */

	/* Disable UART */
	uart->cr1 = 0;
	/* Clear pending TC and BRK interrupts */
	uart->sr = 0;
	uart->gtpr = 1;
	capture_baudrate_set(SERIAL_BAUDRATE);
	/* configure the UART */
	uart->cr3 = USART_ONEBIT;
	/* Configure 8N1 */
	uart->cr2 = USART_STOP_1;
	/* enable UART, RX and IDLE interrupts */
	uart->cr1 = USART_UE | USART_RXNEIE;
	/* Errors interrupt */
	uart->cr3 |= USART_EIE;

	/* configure interrupts */
	cm3_irq_pri_set(STM32_IRQ_USART2, IRQ_PRIORITY_HIGHEST);
	/* enable interrupts */
	cm3_irq_enable(STM32_IRQ_USART2);
}
Esempio n. 9
0
struct serial_dev * stm32f_uart1_serial_init(unsigned int baudrate, 
											 unsigned int flags)
{
	struct stm32f_serial_drv * drv = &uart1_serial_drv;

	DCC_LOG(LOG_TRACE, "IDLE!");

	stm32f_serial_init(drv, baudrate, flags);

#ifdef THINKAPP
	/* configure and Enable interrupt */
	thinkos_irq_register(STM32_IRQ_USART1, SERIAL_IRQ_PRIORITY, 
						 stm32f_usart1_isr);
#else
	/* configure interrupts */
	cm3_irq_pri_set(STM32_IRQ_USART1, SERIAL_IRQ_PRIORITY);
	/* enable interrupts */
	cm3_irq_enable(STM32_IRQ_USART1);
#endif

	return (struct serial_dev *)&uart1_serial_dev;
}
Esempio n. 10
0
struct serdrv * serdrv_init(unsigned int speed)
{
    struct serdrv * drv  = &serial2_dev;
    struct stm32_usart * uart = STM32_USART2;

    DCC_LOG1(LOG_MSG, "speed=%d", speed);

    drv->tx_fifo.head = drv->tx_fifo.tail = 0;
    drv->rx_fifo.head = drv->rx_fifo.tail = 0;
    drv->txie = CM3_BITBAND_DEV(&uart->cr1, 7);
    thinkos_flag_give(SERDRV_TX_FLAG);

    /* clock enable */
    stm32_clk_enable(STM32_RCC, STM32_CLK_USART2);

    /*********************************************
     * USART
     *********************************************/
    stm32_usart_init(uart);
    stm32_usart_baudrate_set(uart, speed);
    stm32_usart_mode_set(uart, SERIAL_8N1);

    /* Enable DMA for transmission and reception */
//	uart->cr3 |= USART_DMAT | USART_DMAR;
    /* enable idle line interrupt */
    /* enable RX interrupt */
    uart->cr1 |= USART_RXNEIE | USART_IDLEIE;

    /* enable UART */
    stm32_usart_enable(uart);

    /* configure interrupts */
    cm3_irq_pri_set(STM32_IRQ_USART2, IRQ_PRIORITY_LOW);
    /* enable interrupts */
    cm3_irq_enable(STM32_IRQ_USART2);

    return drv;
}
Esempio n. 11
0
void thinkos_irq_register_svc(int32_t * arg)
{
	unsigned int irq = arg[0];
	unsigned int priority = arg[1];
	void * isr = (void *)arg[2];

#if THINKOS_ENABLE_ARG_CHECK
	int irq_max = ((uintptr_t)&__sizeof_rom_vectors / sizeof(void *)) - 16;

	if (irq >= irq_max) {
		DCC_LOG1(LOG_ERROR, "invalid IRQ %d!", irq);
		__thinkos_error(THINKOS_ERR_IRQ_INVALID);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#endif

	/* disable this interrupt source */
	cm3_irq_disable(irq);

	if (priority > IRQ_PRIORITY_VERY_LOW)
		priority = IRQ_PRIORITY_VERY_LOW;
	else if (priority < IRQ_PRIORITY_VERY_HIGH)
		priority = IRQ_PRIORITY_VERY_HIGH;

	/* set the interrupt priority */
	cm3_irq_pri_set(irq, priority);

	/* clear pending interrupt */
	cm3_irq_pend_clr(irq);

	/* set the vector */
	__ram_vectors[irq + 16] = isr;

	/* enable this interrupt source */
	cm3_irq_enable(irq);
}
Esempio n. 12
0
void irq_test(void)
{
	int timer_th;
	int event_th;
	struct set max;
	struct set avg;
	struct set ticks;
	struct set ticks0;
	struct set dt;
	int i;
	int ms;

	/* make sure IRQs are disabled */
	cm3_irq_disable(STM32F_IRQ_TIM6);
	cm3_irq_disable(STM32F_IRQ_TIM7);
	cm3_irq_disable(STM32F_IRQ_TIM9);

	/* allocate semaphore */
	printf("1.\n");
	sem_timer = thinkos_sem_alloc(0); 
	/* allocate event */
	printf("2.\n");
	ev_timer = thinkos_ev_alloc(); 

	/* initialize timer 6 */
	timer_init(STM32F_TIM6);

	/* initialize timer 7 */
	timer_init(STM32F_TIM7);
	/* set timer 7 to very high priority */
	cm3_irq_pri_set(STM32F_IRQ_TIM7, 0x20);
	cm3_irq_enable(STM32F_IRQ_TIM7);

	/* initialize timer 9 */
	timer_init(STM32F_TIM9);
	/* set timer 9 to very low priority */
	cm3_irq_pri_set(STM32F_IRQ_TIM9, 0xff);
	cm3_irq_enable(STM32F_IRQ_TIM9);

	printf("4.\n");
	event_th = thinkos_thread_create(event_wait_task, NULL, 
						  stack[1], STACK_SIZE, 
						  THINKOS_OPT_PRIORITY(0) |
						  THINKOS_OPT_ID(0));

	printf("5.\n");
	timer_th = thinkos_thread_create(timer_isr_task, NULL, 
						  stack[2], STACK_SIZE, 
						  THINKOS_OPT_PRIORITY(0) |
						  THINKOS_OPT_ID(0));


	thinkos_sleep(100);

//	printf("- All times in microseconds\n");
	printf("| TIM6 IRQ Wait  | TIM7 High Pri  "
		   "| TIM9 Low Pri   | TIM7 > Ev Wait |\n"); 

	printf("|   dt  avg  max |   dt  avg  max "
		   "|   dt  avg  max |   dt  avg  max |\n"); 
		   
	memset(&meter, 0, sizeof(meter));

	timer_start(STM32F_TIM6);
	timer_start(STM32F_TIM7);
	timer_start(STM32F_TIM9);

	ticks0.tim6 = 0;
	ticks0.tim7 = 0;
	ticks0.tim9 = 0;
	ticks0.event = 0;

//	for (i = 0; i < 10; i++) {
	for (i = 0; i < 5; i++) {
		for (ms = 0; ms < 1000; ms++) 
			thinkos_sem_wait(sem_timer);

		/* get data */
		max = meter.max;
		avg = meter.avg;
		ticks = meter.ticks;

		avg.tim6 = (avg.tim6 * 33) / 64;
		max.tim6 *= 33;

		avg.tim7 = (avg.tim7 * 33) / 64;
		max.tim7 *= 33;

		avg.tim9 = (avg.tim9 * 33) / 64;
		max.tim9 *= 33;

		avg.event = (avg.event * 33) / 64;
		max.event *= 33;

		dt.tim6 = ticks.tim6 - ticks0.tim6;
		ticks0.tim6 = ticks.tim6;

		dt.tim7 = ticks.tim7 - ticks0.tim7;
		ticks0.tim7 = ticks.tim7;

		dt.tim9 = ticks.tim9 - ticks0.tim9;
		ticks0.tim9 = ticks.tim9;

		dt.event = ticks.event - ticks0.event;
		ticks0.event = ticks.event;

		printf("| %4d %4d %4d | %4d %4d %4d | %4d %4d %4d | %4d %4d %4d |\n", 
			   dt.tim6, avg.tim6, max.tim6, 
			   dt.tim7, avg.tim7, max.tim7, 
			   dt.tim9, avg.tim9, max.tim9,
			   dt.event, avg.event, max.event);
	}
	printf("\n");

	cm3_irq_disable(STM32F_IRQ_TIM7);
	cm3_irq_disable(STM32F_IRQ_TIM9);

	thinkos_cancel(event_th, 0);
	thinkos_cancel(timer_th, 0);

	thinkos_ev_free(ev_timer);
	thinkos_sem_free(sem_timer);
}
Esempio n. 13
0
void dac_init(void)
{
	struct stm32f_rcc * rcc = STM32F_RCC;
	struct stm32f_dac * dac = STM32F_DAC;
	struct stm32f_dma * dma = STM32F_DMA1;

	/* I/O pins config */
	stm32f_gpio_mode(DAC2_GPIO, ANALOG, 0);
	stm32f_gpio_mode(DAC1_GPIO, ANALOG, 0);

	/* DAC clock enable */
	rcc->apb1enr |= RCC_DACEN;
	/* DAC disable */
	dac->cr = 0;

	/* DMA clock enable */
	rcc->ahbenr |= RCC_DMA1EN;

	/* DMA Disable */
	dma->ch[DAC1_DMA_CHAN].ccr = 0;
	/* Wait for the channel to be ready .. */
	while (dma->ch[DAC1_DMA_CHAN].ccr & DMA_EN);

	/* DMA Disable */
	dma->ch[DAC2_DMA_CHAN].ccr = 0;
	/* Wait for the channel to be ready .. */
	while (dma->ch[DAC2_DMA_CHAN].ccr & DMA_EN);

	/* DAC configure */
	dac->cr = DAC_EN2 | DAC_TSEL2_TIMER2 | DAC_TEN2 | DAC_DMAEN2 |
			  DAC_EN1 | DAC_TSEL1_TIMER2 | DAC_TEN1 | DAC_DMAEN1;

	/* DAC channel 2 initial value */
	dac->dhr12r2 = 2482;
	/* DAC channel 1 initial value */
	dac->dhr12r1 = 2482;

	/*  DMA Configuration */
	/* Peripheral address */
	dma->ch[DAC1_DMA_CHAN].cpar = &dac->dhr12r1;
	/* Memory pointer */
	dma->ch[DAC1_DMA_CHAN].cmar = (void *)wave_lut[0].buf;
	/* Number of data items to transfer */
	dma->ch[DAC1_DMA_CHAN].cndtr = wave_lut[0].len;
	/* Configuration single buffer circular */
	dma->ch[DAC1_DMA_CHAN].ccr = DMA_MSIZE_16 | DMA_PSIZE_16 | DMA_MINC |
		DMA_CIRC | DMA_DIR_MTP | DMA_EN;

	/*  DMA Configuration */
	/* Peripheral address */
	dma->ch[DAC2_DMA_CHAN].cpar = &dac->dhr12r2;
	/* Memory pointer */
	dma->ch[DAC2_DMA_CHAN].cmar = (void *)wave_lut[0].buf;
	/* Number of data items to transfer */
	dma->ch[DAC2_DMA_CHAN].cndtr = wave_lut[0].len;
	/* Configuration single buffer circular */
	dma->ch[DAC2_DMA_CHAN].ccr = DMA_MSIZE_16 | DMA_PSIZE_16 | DMA_MINC |
		DMA_CIRC | DMA_DIR_MTP | DMA_EN;

	dac_timer_init(SAMPLE_RATE);

	/* Set DMA IRQ priority */
	cm3_irq_pri_set(STM32F_IRQ_DMA1_STREAM2, 0x10);
	/* Enable DMA interrupt */
	cm3_irq_enable(STM32F_IRQ_DMA1_STREAM2);

	/* Set DMA IRQ priority */
	cm3_irq_pri_set(STM32F_IRQ_DMA1_STREAM3, 0x10);
	/* Enable DMA interrupt */
	cm3_irq_enable(STM32F_IRQ_DMA1_STREAM3);
}
Esempio n. 14
0
void i2s_slave_init(void)
{
	struct stm32f_spi * spi = STM32F_SPI2;
	struct stm32f_spi * i2s_ext = STM32F_I2S2EXT;
	struct stm32f_rcc * rcc = STM32F_RCC;
	struct stm32f_dma * dma = STM32F_DMA1;

	tracef("%s SPI=0x%08x", __func__, (uint32_t)spi);
	tracef("%s I2S_EXT=0X%08x", __func__, (uint32_t)i2s_ext);


	stm32f_gpio_af(I2S2_WS, GPIO_AF5);
	stm32f_gpio_af(I2S2_CK, GPIO_AF5);
	stm32f_gpio_af(I2S2EXT_SD, GPIO_AF6);
	stm32f_gpio_af(I2S2_SD, GPIO_AF5);

	/* DMA clock enable */
	rcc->ahb1enr |= RCC_DMA1EN;

	DCC_LOG(LOG_TRACE, "1.");

	/* Disable DMA channel */
	dma->s[I2S_DMA_RX_STRM].cr = 0;
	while (dma->s[I2S_DMA_RX_STRM].cr & DMA_EN); 

	dma->s[I2S_DMA_TX_STRM].cr = 0;
	while (dma->s[I2S_DMA_TX_STRM].cr & DMA_EN); 

	DCC_LOG(LOG_TRACE, "2.");

	/* Enable SPI clock */
	rcc->apb1enr |= RCC_SPI2EN;

	/* disable peripherals */
	spi->i2scfgr &= ~SPI_I2SE;
	i2s_ext->i2scfgr &= ~SPI_I2SE;

	spi->cr1 = 0;
	spi->cr2 = 0;
	spi->i2scfgr = SPI_I2SMOD | SPI_I2SCFG_SLV_RCV | 
		SPI_PCMSYNC_SHORT | SPI_I2SSTD_PCM | SPI_DATLEN_16 | SPI_CHLEN_16;
	spi->i2spr = 0;
	spi->cr2 = SPI_RXDMAEN;

	DCC_LOG(LOG_TRACE, "3.");

	i2s_ext->cr1 = 0;
	i2s_ext->cr2 = 0;
	i2s_ext->i2scfgr = SPI_I2SMOD | SPI_I2SCFG_SLV_XMT | 
		SPI_PCMSYNC_SHORT | SPI_I2SSTD_PCM | SPI_DATLEN_16 | SPI_CHLEN_16;
	i2s_ext->i2spr = 0;
	i2s_ext->cr2 = SPI_TXDMAEN;

	DCC_LOG(LOG_TRACE, "4.");

	i2s.tx.buf[0] = (sndbuf_t *)&sndbuf_zero;
	i2s.tx.buf[1] = (sndbuf_t *)&sndbuf_zero;
	i2s.tx.idx = 0;

	i2s.rx.buf[0] = &sndbuf_null;
	i2s.rx.buf[1] = &sndbuf_null;
	i2s.rx.idx = 0;

	/* Configure DMA channel */
	dma->s[I2S_DMA_RX_STRM].cr = DMA_CHSEL_SET(I2S_DMA_RX_CHAN) | 
		DMA_MBURST_1 | DMA_PBURST_1 | DMA_MSIZE_16 | DMA_PSIZE_16 | 
		DMA_CT_M0AR | DMA_DBM |  DMA_CIRC | DMA_MINC | DMA_DIR_PTM |
		DMA_TCIE | DMA_TEIE | DMA_DMEIE;
	dma->s[I2S_DMA_RX_STRM].par = &spi->dr;
	dma->s[I2S_DMA_RX_STRM].m0ar = i2s.rx.buf[0]->data;
	i2s.rx.xfr[0] = i2s.rx.buf[0];
	dma->s[I2S_DMA_RX_STRM].m1ar = i2s.rx.buf[1]->data;
	i2s.rx.xfr[1] = i2s.rx.buf[1];
	dma->s[I2S_DMA_RX_STRM].ndtr = SNDBUF_LEN;
	dma->s[I2S_DMA_RX_STRM].fcr = DMA_FEIE | DMA_DMDIS | DMA_FTH_FULL;

	DCC_LOG(LOG_TRACE, "5.");

	dma->s[I2S_DMA_TX_STRM].cr = DMA_CHSEL_SET(I2S_DMA_TX_CHAN) | 
		DMA_MBURST_1 | DMA_PBURST_1 | DMA_MSIZE_16 | DMA_PSIZE_16 | 
		DMA_CT_M0AR | DMA_DBM | DMA_CIRC | DMA_MINC | DMA_DIR_MTP |
		DMA_TCIE | DMA_TEIE | DMA_DMEIE;
	dma->s[I2S_DMA_RX_STRM].par = &spi->dr;
	dma->s[I2S_DMA_TX_STRM].par = &i2s_ext->dr;
	dma->s[I2S_DMA_TX_STRM].m0ar = i2s.tx.buf[0]->data;
	dma->s[I2S_DMA_TX_STRM].m1ar = i2s.tx.buf[1]->data;
	dma->s[I2S_DMA_TX_STRM].ndtr = SNDBUF_LEN;
	dma->s[I2S_DMA_TX_STRM].fcr = DMA_FEIE | DMA_DMDIS | DMA_FTH_FULL;


	DCC_LOG(LOG_TRACE, "6.");

	/* Set DMA to medium priority */
	cm3_irq_pri_set(I2S_DMA_RX_IRQ, 0x10);
	cm3_irq_enable(I2S_DMA_RX_IRQ);

	DCC_LOG(LOG_TRACE, "7.");

	cm3_irq_pri_set(I2S_DMA_TX_IRQ, 0x10);
	cm3_irq_enable(I2S_DMA_TX_IRQ);

	DCC_LOG(LOG_TRACE, "8.");

	i2s.io_flag = thinkos_flag_alloc(); 
	tracef("%s(): flag=%d.", __func__, i2s.io_flag);
}