
// ****************************************************************************
//
//                                 Main code
//
// ****************************************************************************
// ADC input to console.

/*
Debug output
------------
===========================
RP2040 ADC and Test Console
===========================

Commands:
c0, ... : Select ADC channel n
s       : Sample once
S       : Sample many
w       : Wiggle pins
s
0x2eb -> 0.601831 V
*/

#include "include.h"

#define N_SAMPLES 1000
uint16_t sample_buf[N_SAMPLES];

void printhelp()
{
	puts("\nCommands:");
	puts("c0, ...\t: Select ADC channel n");
	puts("s\t: Sample once");
	puts("S\t: Sample many");
	puts("w\t: Wiggle pins");
}

void __not_in_flash_func(adc_capture)(uint16_t *buf, size_t count)
{
	int i;
	adc_fifo_setup(true, false, 0, false, false);
	adc_run(true);
	for (i = 0; i < count; i = i + 1)
		buf[i] = adc_fifo_get_blocking();
	adc_run(false);
	adc_fifo_drain();
}

int main()
{
	int i;
	char c;
	uint32_t result;
	const float conversion_factor = 3.3f / (1 << 12);

	stdio_init_all();
	adc_init();
	adc_set_temp_sensor_enabled(true);

	// Set all pins to input (as far as SIO is concerned)
	gpio_set_dir_all_bits(0);
	for (i = 2; i < 30; ++i)
	{
		gpio_set_function(i, GPIO_FUNC_SIO);
		if (i >= 26)
		{
			gpio_disable_pulls(i);
			gpio_set_input_enabled(i, false);
		}
	}

	printf("\n===========================\n");
	printf("RP2040 ADC and Test Console\n");
	printf("===========================\n");
	printhelp();

	while (1)
	{
		c = getchar();
		printf("%c", c);
		switch (c)
		{
		case 'c':
			c = getchar();
			printf("%c\n", c);
			if (c < '0' || c > '7')
			{
				printf("Unknown input channel\n");
				printhelp();
			}
			else
			{
				adc_select_input(c - '0');
				printf("Switched to channel %c\n", c);
			}
			break;

		case 's':
			result = adc_read();
			printf("\n0x%03x -> %f V\n", result, result * conversion_factor);
			break;

		case 'S':
			printf("\nStarting capture\n");
			adc_capture(sample_buf, N_SAMPLES);
			printf("Done\n");
			for (i = 0; i < N_SAMPLES; i = i + 1)
				printf("%03x\n", sample_buf[i]);
			break;

		case 'w':
			printf("\nPress any key to stop wiggling\n");
			i = 1;
			gpio_set_dir_all_bits(-1);
			while (getchar_timeout_us(0) == PICO_ERROR_TIMEOUT)
			{
				// Pattern: Flash all pins for a cycle,
				// Then scan along pins for one cycle each
				i = i ? i << 1 : 1;
				gpio_put_all(i ? i : ~0);
			}
			gpio_set_dir_all_bits(0);
			printf("Wiggling halted.\n");
			break;

		case '\n':
		case '\r':
			break;

		case 'h':
			printhelp();
			break;

		default:
			printf("\nUnrecognised command: %c\n", c);
			printhelp();
			break;
		}
	}
}
