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; }
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; }
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; }
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; }
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; } }
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; } }
/*********************************************************** 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); }
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); }
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; }
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; }
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); }
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); }
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); }
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); }