/**
* @file sketch.ino
* @brief ECE 315 Assignment 3 - Pico ADC + SPI Custom Chip Interface
*
* This program runs on a Raspberry Pi Pico in the Wokwi simulator
* using the Arduino-Pico framework.
*
* It performs the following:
* 1. Reads the built-in ADC on GPIO26 (A0) to sample an analogue
* voltage from a custom "noise-maker" chip once per second.
* 2. Transmits the formatted reading over SPI to a custom
* "my-output-display" SPI peripheral chip.
* 3. Prints the reading to the Pico's serial console.
*
* Hardware connections (defined in diagram.json):
* noise-maker OUT -> GP26 (A0 / ADC0)
* my-output-display SCK -> GP18 (SPI0 SCK)
* my-output-display SDI -> GP19 (SPI0 TX / MOSI)
* my-output-display nCS -> GP17 (active-low chip select)
*
* @author Yousef Moussa ymoussa
* @date 2026
* @course ECE 315
*/
#include <SPI.h>
/* ---------- Pin Definitions ---------- */
#define ADC_PIN 26 /* GPIO26 = A0, ADC input channel 0 */
#define PIN_SPI_CS 17 /* Manual chip-select -> GP17 (active low) */
/* ---------- Constants ---------- */
#define ADC_MAX_VALUE 1023.0f /* Arduino analogRead returns 10-bit (0-1023)*/
#define ADC_REF_VOLTAGE 3.3f /* ADC reference voltage in volts */
#define SAMPLE_PERIOD_MS 1000 /* Sampling period in milliseconds (1 sec) */
#define MSG_BUF_SIZE 64 /* Size of the SPI message buffer */
/**
* @brief Transmit a string over SPI to the output-display chip.
*
* Asserts the chip-select line (active low), sends the data bytes
* using SPI.transfer(), then deasserts chip-select.
*
* @param data Pointer to the null-terminated string to transmit.
* @param len Number of bytes to transmit.
*/
static void spi_send_string(const char *data, size_t len) {
digitalWrite(PIN_SPI_CS, LOW);
for (size_t i = 0; i < len; i++) {
SPI.transfer(data[i]);
}
digitalWrite(PIN_SPI_CS, HIGH);
}
/**
* @brief Arduino setup - runs once at startup.
*
* Initialises the serial console, ADC input pin, SPI master,
* and chip-select GPIO.
*/
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("ECE 315 Assignment 3 - ADC + SPI Demo Started");
pinMode(ADC_PIN, INPUT);
pinMode(PIN_SPI_CS, OUTPUT);
digitalWrite(PIN_SPI_CS, HIGH);
SPI.begin();
}
/**
* @brief Arduino loop - runs repeatedly.
*
* Samples the ADC once per second, converts the raw reading to a
* voltage, prints it to the serial console, and sends the formatted
* string over SPI to the output-display chip.
*/
void loop() {
uint16_t raw_adc = analogRead(ADC_PIN);
float voltage = (float)raw_adc * (ADC_REF_VOLTAGE / ADC_MAX_VALUE);
char msg[MSG_BUF_SIZE];
snprintf(msg, sizeof(msg), "ADC: raw=%u, voltage=%.4f V\n",
raw_adc, voltage);
Serial.printf("[Pico] %s", msg);
spi_send_string(msg, strlen(msg));
delay(SAMPLE_PERIOD_MS);
}