示例#1
0
/* Receive data using DMA. */
void rx_spi(void *data, uint16_t size){
	if(DmaCleanupNeeded)cleanup_dma_spi();

	/* This byte is sent continuously when rx_spi() receives data. */
	static const uint8_t RxSpiDummyByte = 0x00;

	spi_enable_rx_dma(SPI3);
	
	dma_channel_reset(DMA1, DMA_CHANNEL2);
	dma_disable_channel(DMA1, DMA_CHANNEL2);
	dma_set_peripheral_address(DMA1, DMA_CHANNEL2, (uint32_t) &(SPI_DR(SPI3)));
	dma_set_memory_address(DMA1, DMA_CHANNEL2, (uint32_t) data);
	dma_set_number_of_data(DMA1, DMA_CHANNEL2, size);
	dma_set_priority(DMA1, DMA_CHANNEL2, DMA_CCR_PL_HIGH);
	dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT);
	dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT);
	dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL2);
	dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL2);
	dma_set_read_from_peripheral(DMA1, DMA_CHANNEL2);
	dma_enable_channel(DMA1, DMA_CHANNEL2);

	/* The SPI peripheral is driven by transmitted bytes, so dummy bytes
	 * must be sent in order to receive data. This is accomplished with DMA
	 * by simply not incrementing the memory address. */
	dma_channel_reset(DMA1, DMA_CHANNEL3);
	dma_disable_channel(DMA1, DMA_CHANNEL3);
	dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t) &(SPI_DR(SPI3)));
	dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t) &RxSpiDummyByte);
	dma_set_number_of_data(DMA1, DMA_CHANNEL3, size);
	dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH);
	dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT);
	dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT);
	dma_disable_memory_increment_mode(DMA1, DMA_CHANNEL3);
	dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL3);
	dma_set_read_from_memory(DMA1, DMA_CHANNEL3);
	dma_enable_channel(DMA1, DMA_CHANNEL3);
	
	spi_enable_tx_dma(SPI3);
	spi_enable(SPI3);
	DmaCleanupNeeded = true;
}
示例#2
0
/* Simultaneously transmit and receive data using DMA. */
void rxtx_spi(void *rxdata, const void *txdata, uint16_t size){
	if(DmaCleanupNeeded)cleanup_dma_spi();

	spi_enable_rx_dma(SPI3);
	
	dma_channel_reset(DMA1, DMA_CHANNEL2);
	dma_disable_channel(DMA1, DMA_CHANNEL2);
	dma_set_peripheral_address(DMA1, DMA_CHANNEL2, (uint32_t) &(SPI_DR(SPI3)));
	dma_set_memory_address(DMA1, DMA_CHANNEL2, (uint32_t) rxdata);
	dma_set_number_of_data(DMA1, DMA_CHANNEL2, size);
	dma_set_priority(DMA1, DMA_CHANNEL2, DMA_CCR_PL_HIGH);
	dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT);
	dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT);
	dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL2);
	dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL2);
	dma_set_read_from_peripheral(DMA1, DMA_CHANNEL2);
	dma_enable_channel(DMA1, DMA_CHANNEL2);

	dma_channel_reset(DMA1, DMA_CHANNEL3);
	dma_disable_channel(DMA1, DMA_CHANNEL3);
	dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t) &(SPI_DR(SPI3)));
	dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t) txdata);
	dma_set_number_of_data(DMA1, DMA_CHANNEL3, size);
	dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH);
	dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT);
	dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT);
	dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL3);
	dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL3);
	dma_set_read_from_memory(DMA1, DMA_CHANNEL3);
	dma_enable_channel(DMA1, DMA_CHANNEL3);
	
	spi_enable_tx_dma(SPI3);
	spi_enable(SPI3);

	DmaCleanupNeeded = true;
}
void dma_transmit_setup(void)
{
    dma_channel_reset(DMA1, DMA_CHANNEL4);

    nvic_enable_irq(NVIC_DMA1_CHANNEL4_5_IRQ);

    dma_set_peripheral_address(DMA1, DMA_CHANNEL4, (uint32_t) &USART2_TDR);
    dma_set_read_from_memory(DMA1, DMA_CHANNEL4);

    dma_set_peripheral_size(DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_8BIT);
    dma_set_memory_size(DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_8BIT);

    dma_set_priority(DMA1, DMA_CHANNEL4, DMA_CCR_PL_VERY_HIGH);

    dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL4);
    dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL4);

    dma_disable_transfer_error_interrupt(DMA1, DMA_CHANNEL4);
    dma_disable_half_transfer_interrupt(DMA1, DMA_CHANNEL4);
    dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL4);
}
示例#4
0
void ws2812_init( void )
{
	uint32_t i,j;

	for( i = 0; i < WS2812_BUFFERSIZE; i++ )
	{
		bitframe_pattern[i] = 0;
		bitframe_pattern_draw[i] = 0;
	}

	for( i=0; i < (3*NR_OF_LEDS_PER_CH*NR_OF_ROWS); i++)
	{
		frame_pattern[i] = 0;

	}

	/* configure the GPIOs */
	/* Enable GPIOC clock  */
	rcc_periph_clock_enable(RCC_GPIOB);

	/* Setup GPIO pin GPIO8/9 on GPIO port C for LEDs. */
	gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, GPIO0);
	gpio_set_output_options( GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_HIGH, GPIO0);

	/* configure the DMA */
	rcc_periph_clock_enable(RCC_DMA);

	/* configure DMA for sending high constant pattern to port on begin of cycle
	 * send unrolled bitframe on Timer OC1 event
	 * send low on Timer OC3 event
	 */
	dma_channel_reset( DMA1, DMA_CHANNEL3);
	dma_set_peripheral_address( DMA1, DMA_CHANNEL3, (uint32_t)&GPIOB_ODR);
    dma_set_memory_address( DMA1, DMA_CHANNEL3, (uint32_t)&high_pattern);
    dma_set_peripheral_size( DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT);
    dma_set_memory_size( DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT);
    dma_disable_peripheral_increment_mode( DMA1, DMA_CHANNEL3 );
    dma_disable_memory_increment_mode( DMA1, DMA_CHANNEL3 );
    dma_set_priority( DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH);
    dma_set_read_from_memory(DMA1, DMA_CHANNEL3);

	dma_channel_reset( DMA1, DMA_CHANNEL4);
	dma_set_peripheral_address( DMA1, DMA_CHANNEL4, (uint32_t)&GPIOB_ODR);
    dma_set_memory_address( DMA1, DMA_CHANNEL4, (uint32_t)actual_bitframe);
    dma_set_peripheral_size( DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_8BIT);
    dma_set_memory_size( DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_8BIT);
    dma_disable_peripheral_increment_mode( DMA1, DMA_CHANNEL4 );
    dma_enable_memory_increment_mode( DMA1, DMA_CHANNEL4 );
    dma_set_priority( DMA1, DMA_CHANNEL4, DMA_CCR_PL_HIGH);
    dma_set_read_from_memory(DMA1, DMA_CHANNEL4);

	dma_channel_reset( DMA1, DMA_CHANNEL2);
	dma_set_peripheral_address( DMA1, DMA_CHANNEL2, (uint32_t)&GPIOB_ODR);
    dma_set_memory_address( DMA1, DMA_CHANNEL2, (uint32_t)&low_pattern);
    dma_set_peripheral_size( DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT);
    dma_set_memory_size( DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT);
    dma_disable_peripheral_increment_mode( DMA1, DMA_CHANNEL2 );
    dma_disable_memory_increment_mode( DMA1, DMA_CHANNEL2 );
    dma_set_priority( DMA1, DMA_CHANNEL2, DMA_CCR_PL_HIGH);
    dma_set_read_from_memory(DMA1, DMA_CHANNEL2);


    nvic_set_priority(NVIC_DMA1_CHANNEL2_3_IRQ, 0);
    nvic_enable_irq(NVIC_DMA1_CHANNEL2_3_IRQ);
    dma_enable_transfer_complete_interrupt( DMA1, DMA_CHANNEL2);


    /* configure timer */
    rcc_periph_clock_enable(RCC_TIM3);


    /* configure the timer for 800kHz overall frequency */
    timer_reset( TIM3 );
    timer_set_mode( TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
    timer_set_period( TIM3, 60);
    timer_set_repetition_counter( TIM3, 0);
    timer_disable_preload( TIM3 );

    /* timer compare section 1 for low coding */
    timer_set_oc_mode( TIM3, TIM_OC1,TIM_OCM_FROZEN);
    timer_set_oc_value( TIM3, TIM_OC1, 19);
    timer_disable_oc_preload( TIM3, TIM_OC1);

    /* timer compare section 3 for high coding */
    timer_set_oc_mode( TIM3, TIM_OC3,TIM_OCM_FROZEN);
    timer_set_oc_value( TIM3, TIM_OC3, 41);
    timer_disable_oc_preload( TIM3, TIM_OC3);

    nvic_set_priority( NVIC_TIM3_IRQ,1);
    nvic_set_priority( NVIC_PENDSV_IRQ, 2);
    nvic_enable_irq(NVIC_TIM3_IRQ);
    nvic_enable_irq(NVIC_PENDSV_IRQ);

    /* start the sending process */
    ws2812_send();
}
示例#5
0
static void setup_i2c_port(enum I2C_FREQ I2C_speed)
{
	// Disable I2C if it happens to be enabled
	i2c_peripheral_disable(I2C_PORT);
	dma_channel_reset(I2C_TX_DMA, I2C_TX_DMA_CHANNEL);
	i2c_disable_interrupt(I2C_PORT, (I2C_CR2_ITEVTEN | I2C_CR2_ITERREN));
	DISABLE_I2C_INTERRUPT();
	reset_i2c_pins();

	// set: Source, Destination, and Amount (DMA channel must be disabled)
	dma_set_peripheral_address(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, (uint32_t)&I2C_DR(I2C_PORT));
	dma_set_memory_address(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, 0);
	dma_set_number_of_data(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, 0);
	// set the DMA Configuration (DMA_CCRx)
	//			 (BIT 14) mem2mem_mode disabled
	dma_set_priority(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_PL_HIGH); // (BIT 12:13)
	dma_set_memory_size(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_MSIZE_8BIT); // (BIT 10:11)
	dma_set_peripheral_size(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_PSIZE_8BIT); // (BIT 8:9)
	dma_enable_memory_increment_mode(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 7)
	dma_disable_peripheral_increment_mode(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 6)
	//			 (BIT 5) Circular mode is disabled
	dma_set_read_from_memory(I2C_TX_DMA, I2C_TX_DMA_CHANNEL);	// (BIT 4)
	dma_enable_transfer_error_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 3)
	dma_disable_half_transfer_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 2)
	dma_enable_transfer_complete_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 1)

	// This is the slave address when not transmitting data
	i2c_set_own_7bit_slave_address(I2C_PORT, 0x32);
	// do not respond to the specified slave address
	i2c_disable_ack(I2C_PORT);
	// Use DMA to send I2C data
	i2c_enable_dma(I2C_PORT);
	// set which interrupts I2C uses
	i2c_enable_interrupt(I2C_PORT, (I2C_CR2_ITEVTEN | I2C_CR2_ITERREN));
	// APB1 is running at 36MHz = T(PCLK1) = 1/36000000 sec.
	i2c_set_clock_frequency(I2C_PORT, I2C_CR2_FREQ_36MHZ);
	// Set up the hardware for the particular speed
	switch (I2C_speed) {
		// Values found on Internet for the I2C standard
		//   STANDARD : SCL max rise time = 1000ns = 1000/1000000000 sec
		//       FAST : SCL max rise time =  300ns =  300/1000000000 sec
		// 
		// DATASHEET Function:
		//   TRISE = (T(MAX_SCL_RISE) / T(PCLK1)) + 1
		// 
		// DATASHEET Functions:
		//   STANDARD :      
		//     T(high) =      CCR * T(PCLK1)
		//     T(low)  =      CCR * T(PCLK1)
		//   FAST (DUTY=I2C_CCR_DUTY_DIV2)
		//     T(high) =      CCR * T(PCLK1)
		//     T(low)  =  2 * CCR * T(PCLK1)
		//   FAST (DUTY=I2C_CCR_DUTY_16_DIV_9)   [To reach 400KHz]
		//     T(high) =  9 * CCR * T(PCLK1)
		//     T(low)  = 16 * CCR * T(PCLK1)
		// 
		// I2C PERIOD:
		//   STANDARD
		//     PERIOD = T(high) + T(low) = (2 * CCR * T(PCLK1))
		//   FAST (DUTY=I2C_CCR_DUTY_DIV2)
		//     PERIOD = T(high) + T(low) = (3 * CCR * T(PCLK1))
		//   FAST (DUTY=I2C_CCR_DUTY_16_DIV_9)
		//     PERIOD = T(high) + T(low) = (25 * CCR * T(PCLK1))
		case I2C_400KHz:
			// I2C PERIOD: 400KHz = 400000Hz = 1/400000 sec.
			i2c_set_fast_mode(I2C_PORT);
			// I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9
			i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_16_DIV_9);
			// CCR = PERIOD / (25 * T(PCLK1))
			// CCR = (1/400000) / (25/36000000) = 18/5 = 3.6
			// CCR = 4 => I2C PERIOD = 360kHz
			// CCR = 3 => I2C PERIOD = 480kHz
			i2c_set_ccr(I2C_PORT, 4);	// Only fast mode can have a value less than 0x04
			// TRISE = ( (300/1000000000) / (1/36000000) ) + 1 = 59/5 = 11.8
			// TRISE = 12 => SCL max rise time ~= 305.555ns
			// TRISE = 11 => SCL max rise time ~= 277.777ns
			i2c_set_trise(I2C_PORT, 11);
			break;
		case I2C_100KHz:
			// I2C PERIOD: 100KHz = 100000Hz = 1/100000 sec.
			i2c_set_standard_mode(I2C_PORT);
			// I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9
			i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_DIV2);
			// CCR = PERIOD / (2 * T(PCLK1))
			// CCR = (1/100000) / (2/36000000) = 180
			i2c_set_ccr(I2C_PORT, 180);
			// TRISE = ( (1000/1000000000) / (1/36000000) ) + 1 = 37
			i2c_set_trise(I2C_PORT, 37);
			break;
		case I2C_53KHz:
			// ~= 52.91kHz is the slowest I could get to work
			// CCR value of 341 works but not 342 or higher
		case I2C_50KHz:
		default:
			// I2C PERIOD: 50KHz = 50000Hz = 1/50000 sec.
			i2c_set_standard_mode(I2C_PORT);
			// I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9
			i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_DIV2);
			// CCR = PERIOD / (2 * T(PCLK1))
			// CCR = (1/50000) / (2/36000000) = 360
			//   (341 works but not 342 or higher)
			i2c_set_ccr(I2C_PORT, 341);
			// TRISE = ( (1000/1000000000) / (1/36000000) ) + 1 = 37
			i2c_set_trise(I2C_PORT, 37);
			break;
	}
	i2c_peripheral_enable(I2C_PORT);

	// set the priorities for the interrupts
	nvic_set_priority(I2C_EV_IRQ, IRQ_PRI_I2C);
	nvic_set_priority(I2C_ER_IRQ, IRQ_PRI_ER_I2C);
	nvic_set_priority(I2C_DMA_IRQ, IRQ_PRI_DMA_I2C);
}