Improve NCO flexibility
This commit is contained in:
		
							parent
							
								
									63d9a59fe6
								
							
						
					
					
						commit
						b31fc626e3
					
				
					 1 changed files with 41 additions and 24 deletions
				
			
		
							
								
								
									
										65
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								src/main.c
									
									
									
									
									
								
							|  | @ -43,23 +43,21 @@ | ||||||
| #define ADC_RATE (2 * MHZ) | #define ADC_RATE (2 * MHZ) | ||||||
| #define DECIMATE 4 | #define DECIMATE 4 | ||||||
| 
 | 
 | ||||||
| /*
 | #define NCO_NUM_PHASES (1 << 8) | ||||||
|  * NOTE: Must have 256 phases with 256 bytes each. | #define NCO_PHASE_BITS 8 | ||||||
|  *       Otherwise the DMA 1-byte write trick wouldn't work. | #define NCO_PHASE_WORDS (1 << (NCO_PHASE_BITS - 2)) | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #define LO_NUM_PHASES 256 |  | ||||||
| #define LO_PHASE_BITS 8 |  | ||||||
| #define LO_PHASE_WORDS (1 << (LO_PHASE_BITS - 2)) |  | ||||||
| #define STEP_BASE ((UINT_MAX + 1.0) / CLK_SYS_HZ) | #define STEP_BASE ((UINT_MAX + 1.0) / CLK_SYS_HZ) | ||||||
| 
 | 
 | ||||||
| static uint32_t nco_step = (uint32_t)(STEP_BASE * INIT_FREQ) * 32 * LO_PHASE_WORDS; | static uint32_t nco_step = (uint32_t)(STEP_BASE * INIT_FREQ) * 32 * NCO_PHASE_WORDS; | ||||||
| static uint32_t nco_null = 0; | static uint32_t nco_null = 0; | ||||||
|  | static uint32_t nco_mask = (1 << NCO_PHASE_BITS) - 1; | ||||||
| 
 | 
 | ||||||
| static uint32_t lo_phase[LO_NUM_PHASES][LO_PHASE_WORDS] | static uint32_t nco_phase[NCO_NUM_PHASES][NCO_PHASE_WORDS] | ||||||
| 	__attribute__((__aligned__(LO_NUM_PHASES * 4 * LO_PHASE_WORDS))); | 	__attribute__((__aligned__(NCO_NUM_PHASES * 4 * NCO_PHASE_WORDS))); | ||||||
| 
 | 
 | ||||||
| static uint32_t nco_addr = (uint32_t)lo_phase; | static_assert(sizeof(nco_phase) == 65536, "sizeof(nco_phase) == 65536"); | ||||||
|  | 
 | ||||||
|  | static uint32_t *nco_addr = &nco_phase[0][0]; | ||||||
| 
 | 
 | ||||||
| #define NUM_GAINS 29 | #define NUM_GAINS 29 | ||||||
| static int gains[NUM_GAINS] = { 0,   9,	  14,  27,  37,	 77,  87,  125, 144, 157, | static int gains[NUM_GAINS] = { 0,   9,	  14,  27,  37,	 77,  87,  125, 144, 157, | ||||||
|  | @ -72,6 +70,7 @@ static int frequency = INIT_FREQ; | ||||||
| static int dma_ch_nco1 = -1; | static int dma_ch_nco1 = -1; | ||||||
| static int dma_ch_nco2 = -1; | static int dma_ch_nco2 = -1; | ||||||
| static int dma_ch_nco3 = -1; | static int dma_ch_nco3 = -1; | ||||||
|  | static int dma_ch_nco4 = -1; | ||||||
| static int dma_ch_mix = -1; | static int dma_ch_mix = -1; | ||||||
| 
 | 
 | ||||||
| static queue_t iq_queue; | static queue_t iq_queue; | ||||||
|  | @ -133,7 +132,7 @@ static void init_lo() | ||||||
| 	pio_sm_exec_wait_blocking(PIO, SM_LO, pio_encode_set(pio_pins, 0)); | 	pio_sm_exec_wait_blocking(PIO, SM_LO, pio_encode_set(pio_pins, 0)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void lo_generate_phase(uint32_t *buf, size_t len, uint32_t step, uint32_t phase) | static void nco_generate_phase(uint32_t *buf, size_t len, uint32_t step, uint32_t phase) | ||||||
| { | { | ||||||
| 	for (size_t i = 0; i < len; i++) { | 	for (size_t i = 0; i < len; i++) { | ||||||
| 		uint32_t bits = 0; | 		uint32_t bits = 0; | ||||||
|  | @ -152,10 +151,11 @@ static void rx_lo_init(double freq) | ||||||
| { | { | ||||||
| 	uint32_t step = STEP_BASE * freq; | 	uint32_t step = STEP_BASE * freq; | ||||||
| 
 | 
 | ||||||
| 	for (uint32_t i = 0; i < LO_NUM_PHASES; i++) | 	for (uint32_t i = 0; i < NCO_NUM_PHASES; i++) | ||||||
| 		lo_generate_phase(lo_phase[i], LO_PHASE_WORDS, step, i << 24); | 		nco_generate_phase(nco_phase[i], NCO_PHASE_WORDS, step, | ||||||
|  | 				   i << (__builtin_clz(NCO_NUM_PHASES) + 1)); | ||||||
| 
 | 
 | ||||||
| 	nco_step = step * 32 * LO_PHASE_WORDS; | 	nco_step = step * 32 * NCO_PHASE_WORDS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void rf_rx_start() | static void rf_rx_start() | ||||||
|  | @ -163,6 +163,7 @@ static void rf_rx_start() | ||||||
| 	dma_ch_nco1 = dma_claim_unused_channel(true); | 	dma_ch_nco1 = dma_claim_unused_channel(true); | ||||||
| 	dma_ch_nco2 = dma_claim_unused_channel(true); | 	dma_ch_nco2 = dma_claim_unused_channel(true); | ||||||
| 	dma_ch_nco3 = dma_claim_unused_channel(true); | 	dma_ch_nco3 = dma_claim_unused_channel(true); | ||||||
|  | 	dma_ch_nco4 = dma_claim_unused_channel(true); | ||||||
| 	dma_ch_mix = dma_claim_unused_channel(true); | 	dma_ch_mix = dma_claim_unused_channel(true); | ||||||
| 
 | 
 | ||||||
| 	dma_channel_config dma_conf; | 	dma_channel_config dma_conf; | ||||||
|  | @ -180,20 +181,31 @@ static void rf_rx_start() | ||||||
| 
 | 
 | ||||||
| 	/* Prepare the phase address. */ | 	/* Prepare the phase address. */ | ||||||
| 	dma_conf = dma_channel_get_default_config(dma_ch_nco2); | 	dma_conf = dma_channel_get_default_config(dma_ch_nco2); | ||||||
| 	channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_8); | 	channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_16); | ||||||
| 	channel_config_set_read_increment(&dma_conf, false); | 	channel_config_set_read_increment(&dma_conf, false); | ||||||
| 	channel_config_set_write_increment(&dma_conf, false); | 	channel_config_set_write_increment(&dma_conf, false); | ||||||
| 	channel_config_set_chain_to(&dma_conf, dma_ch_nco3); | 	channel_config_set_chain_to(&dma_conf, dma_ch_nco3); | ||||||
| 	dma_channel_configure(dma_ch_nco2, &dma_conf, (uint8_t *)(&nco_addr) + 1, | 	dma_channel_configure(dma_ch_nco2, &dma_conf, (void *)(&nco_addr) + 0, | ||||||
| 			      ((uint8_t *)&dma_hw->sniff_data) + 3, 1, false); | 			      ((void *)&dma_hw->sniff_data) + 2, 1, false); | ||||||
| 
 | 
 | ||||||
| 	/* Trigger LO using the address. */ | 	/* Copy it to the DMA. */ | ||||||
| 	dma_conf = dma_channel_get_default_config(dma_ch_nco3); | 	dma_conf = dma_channel_get_default_config(dma_ch_nco3); | ||||||
| 	channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_32); | 	channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_32); | ||||||
| 	channel_config_set_read_increment(&dma_conf, false); | 	channel_config_set_read_increment(&dma_conf, false); | ||||||
| 	channel_config_set_write_increment(&dma_conf, false); | 	channel_config_set_write_increment(&dma_conf, false); | ||||||
| 	dma_channel_configure(dma_ch_nco3, &dma_conf, &dma_hw->ch[dma_ch_mix].al3_read_addr_trig, | 	channel_config_set_chain_to(&dma_conf, dma_ch_nco4); | ||||||
| 			      &nco_addr, 1, false); | 	dma_channel_configure(dma_ch_nco3, &dma_conf, &dma_hw->ch[dma_ch_mix].read_addr, &nco_addr, | ||||||
|  | 			      1, false); | ||||||
|  | 
 | ||||||
|  | 	/* Trigger LO by clearing the bottom bits. */ | ||||||
|  | 	dma_conf = dma_channel_get_default_config(dma_ch_nco4); | ||||||
|  | 	channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_32); | ||||||
|  | 	channel_config_set_read_increment(&dma_conf, false); | ||||||
|  | 	channel_config_set_write_increment(&dma_conf, false); | ||||||
|  | 	dma_channel_configure(dma_ch_nco4, &dma_conf, | ||||||
|  | 			      (void *)&dma_hw->ch[dma_ch_mix].al3_read_addr_trig + | ||||||
|  | 				      REG_ALIAS_CLR_BITS, | ||||||
|  | 			      &nco_mask, 1, false); | ||||||
| 
 | 
 | ||||||
| 	/* Drive the LO capacitor. */ | 	/* Drive the LO capacitor. */ | ||||||
| 	dma_conf = dma_channel_get_default_config(dma_ch_mix); | 	dma_conf = dma_channel_get_default_config(dma_ch_mix); | ||||||
|  | @ -202,8 +214,8 @@ static void rf_rx_start() | ||||||
| 	channel_config_set_write_increment(&dma_conf, false); | 	channel_config_set_write_increment(&dma_conf, false); | ||||||
| 	channel_config_set_dreq(&dma_conf, pio_get_dreq(PIO, SM_LO, GPIO_OUT)); | 	channel_config_set_dreq(&dma_conf, pio_get_dreq(PIO, SM_LO, GPIO_OUT)); | ||||||
| 	channel_config_set_chain_to(&dma_conf, dma_ch_nco1); | 	channel_config_set_chain_to(&dma_conf, dma_ch_nco1); | ||||||
| 	dma_channel_configure(dma_ch_mix, &dma_conf, &PIO->txf[SM_LO], lo_phase, LO_PHASE_WORDS, | 	dma_channel_configure(dma_ch_mix, &dma_conf, &PIO->txf[SM_LO], &nco_phase[0][0], | ||||||
| 			      false); | 			      NCO_PHASE_WORDS, false); | ||||||
| 
 | 
 | ||||||
| 	init_lo(); | 	init_lo(); | ||||||
| 
 | 
 | ||||||
|  | @ -221,26 +233,31 @@ static void rf_rx_stop(void) | ||||||
| 	dma_channel_clear_chain_to(dma_ch_nco1); | 	dma_channel_clear_chain_to(dma_ch_nco1); | ||||||
| 	dma_channel_clear_chain_to(dma_ch_nco2); | 	dma_channel_clear_chain_to(dma_ch_nco2); | ||||||
| 	dma_channel_clear_chain_to(dma_ch_nco3); | 	dma_channel_clear_chain_to(dma_ch_nco3); | ||||||
|  | 	dma_channel_clear_chain_to(dma_ch_nco4); | ||||||
| 	dma_channel_clear_chain_to(dma_ch_mix); | 	dma_channel_clear_chain_to(dma_ch_mix); | ||||||
| 
 | 
 | ||||||
| 	dma_channel_abort(dma_ch_nco1); | 	dma_channel_abort(dma_ch_nco1); | ||||||
| 	dma_channel_abort(dma_ch_nco2); | 	dma_channel_abort(dma_ch_nco2); | ||||||
| 	dma_channel_abort(dma_ch_nco3); | 	dma_channel_abort(dma_ch_nco3); | ||||||
|  | 	dma_channel_abort(dma_ch_nco4); | ||||||
| 	dma_channel_abort(dma_ch_mix); | 	dma_channel_abort(dma_ch_mix); | ||||||
| 
 | 
 | ||||||
| 	dma_channel_cleanup(dma_ch_nco1); | 	dma_channel_cleanup(dma_ch_nco1); | ||||||
| 	dma_channel_cleanup(dma_ch_nco2); | 	dma_channel_cleanup(dma_ch_nco2); | ||||||
| 	dma_channel_cleanup(dma_ch_nco3); | 	dma_channel_cleanup(dma_ch_nco3); | ||||||
|  | 	dma_channel_cleanup(dma_ch_nco4); | ||||||
| 	dma_channel_cleanup(dma_ch_mix); | 	dma_channel_cleanup(dma_ch_mix); | ||||||
| 
 | 
 | ||||||
| 	dma_channel_unclaim(dma_ch_nco1); | 	dma_channel_unclaim(dma_ch_nco1); | ||||||
| 	dma_channel_unclaim(dma_ch_nco2); | 	dma_channel_unclaim(dma_ch_nco2); | ||||||
| 	dma_channel_unclaim(dma_ch_nco3); | 	dma_channel_unclaim(dma_ch_nco3); | ||||||
|  | 	dma_channel_unclaim(dma_ch_nco4); | ||||||
| 	dma_channel_unclaim(dma_ch_mix); | 	dma_channel_unclaim(dma_ch_mix); | ||||||
| 
 | 
 | ||||||
| 	dma_ch_nco1 = -1; | 	dma_ch_nco1 = -1; | ||||||
| 	dma_ch_nco2 = -1; | 	dma_ch_nco2 = -1; | ||||||
| 	dma_ch_nco3 = -1; | 	dma_ch_nco3 = -1; | ||||||
|  | 	dma_ch_nco4 = -1; | ||||||
| 	dma_ch_mix = -1; | 	dma_ch_mix = -1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue