### C Application-Specific Pin Setup Examples Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/pinmux-usage.md Demonstrates how to configure pins for common peripherals like UART, I2C, and SPI, as well as application-specific GPIOs for LEDs and buttons using the generic pin configuration functions. ```c // Standard peripheral pin configurations void setup_standard_peripherals(void) { // UART0 configuration (Debug console) pin_config_t uart0_pins[] = { {0x970, 0, true, PULL_UP, true}, // UART0_RXD {0x974, 0, false, PULL_NONE, true} // UART0_TXD }; configure_pins_batch(uart0_pins, 2); // I2C0 configuration (System I2C) pin_config_t i2c0_pins[] = { {0x988, 0, true, PULL_UP, true}, // I2C0_SDA {0x98C, 0, true, PULL_UP, true} // I2C0_SCL }; configure_pins_batch(i2c0_pins, 2); // SPI0 configuration (External flash/sensors) pin_config_t spi0_pins[] = { {0x950, 0, false, PULL_NONE, false}, // SPI0_SCLK {0x954, 0, false, PULL_NONE, false}, // SPI0_MOSI {0x958, 0, true, PULL_UP, false}, // SPI0_MISO {0x95C, 0, false, PULL_NONE, false} // SPI0_CS0 }; configure_pins_batch(spi0_pins, 4); } // GPIO-specific pin setup for common use cases void setup_application_gpio_pins(void) { // LED outputs (GPIO1_12-15) pin_config_t led_pins[] = { {CONF_GPMC_AD12_OFFSET, 7, false, PULL_NONE, true}, // LED0 {CONF_GPMC_AD13_OFFSET, 7, false, PULL_NONE, true}, // LED1 {CONF_GPMC_AD14_OFFSET, 7, false, PULL_NONE, true}, // LED2 {CONF_GPMC_AD15_OFFSET, 7, false, PULL_NONE, true} // LED3 }; configure_pins_batch(led_pins, 4); // Button inputs (GPIO0 pins) pin_config_t button_pins[] = { {0x964, 7, true, PULL_UP, true}, // Button 0 {0x968, 7, true, PULL_UP, true}, // Button 1 {0x96C, 7, true, PULL_UP, true} // Button 2 }; configure_pins_batch(button_pins, 3); } ``` -------------------------------- ### PWM LED Brightness Control Example Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/timer-usage.md This C function demonstrates controlling LED brightness using PWM by gradually increasing and decreasing the duty cycle. It utilizes timer setup and PWM duty cycle setting functions. ```c /** * Example: LED brightness control using PWM */ void pwm_led_demo(void) { int duty; /* Setup Timer4 for 1 kHz PWM */ timer_setup_pwm(4, 1000, 0); timer_start((uint32_t *)TIMER4_BASE); /* Gradually increase brightness */ for (duty = 0; duty <= 100; duty += 10) { timer_set_pwm_duty((uint32_t *)TIMER4_BASE, duty); delay_ms(500); } /* Gradually decrease brightness */ for (duty = 100; duty >= 0; duty -= 10) { timer_set_pwm_duty((uint32_t *)TIMER4_BASE, duty); delay_ms(500); } } ``` -------------------------------- ### Setup GPIO for LED Control (C) Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/gpio-usage.md Provides a complete setup for controlling an LED connected to a GPIO pin. This includes enabling the necessary GPIO clock, configuring the pin as an output, and functions to turn the LED on, off, or toggle its state. Assumes specific register addresses for clock control and GPIO output. ```c // Complete setup for GPIO1_12 as output with LED control void setup_gpio1_12_led(void) { // 1. Enable GPIO1 clock CM_PER_GPIO1_CLKCTRL = 0x2; while ((CM_PER_GPIO1_CLKCTRL & 0x30000) != 0x0); // 2. Configure pin direction as output GPIO1_OE &= ~(1 << 12); // Output // 3. Set initial state (LED off) GPIO1_CLEARDATAOUT = (1 << 12); // GPIO1_12 is now ready for LED control } void led_on(void) { GPIO1_SETDATAOUT = (1 << 12); } void led_off(void) { GPIO1_CLEARDATAOUT = (1 << 12); } void led_toggle(void) { if (GPIO1_DATAOUT & (1 << 12)) { GPIO1_CLEARDATAOUT = (1 << 12); } else { GPIO1_SETDATAOUT = (1 << 12); } } ``` -------------------------------- ### System Initialization and Peripheral Setup (C) Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/interrupt-handling.md Initializes the interrupt controller and configures common peripheral interrupts for the AM335x. This includes setting up UART, GPIO, and Timer interrupts with appropriate priorities. It then enables these configured interrupts and processor interrupts. ```c // Complete system initialization void intc_system_init(void) { // Initialize INTC hardware intc_init(); // Configure common peripheral interrupts setup_peripheral_interrupts(); // Enable processor interrupts intc_enable_processor_irq(); intc_enable_processor_fiq(); } void setup_peripheral_interrupts(void) { // UART interrupts intc_configure_interrupt_enhanced(72, 2, false); // UART0 intc_configure_interrupt_enhanced(73, 2, false); // UART1 // GPIO interrupts intc_configure_interrupt_enhanced(96, 1, false); // GPIO0 intc_configure_interrupt_enhanced(98, 1, false); // GPIO1 intc_configure_interrupt_enhanced(32, 1, false); // GPIO2 intc_configure_interrupt_enhanced(62, 1, false); // GPIO3 // Timer interrupts intc_configure_interrupt_enhanced(66, 3, false); // DMTIMER0 intc_configure_interrupt_enhanced(67, 2, false); // DMTIMER1_1MS // Enable configured interrupts intc_enable_interrupt_atomic(72); // UART0 intc_enable_interrupt_atomic(96); // GPIO0 intc_enable_interrupt_atomic(67); // DMTIMER1_1MS } ``` -------------------------------- ### I2C Clock Setup and Configuration Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/clock-usage.md Implements I2C clock setup, including enabling the clock and validating the SCL frequency against standard I2C limits (up to 400KHz). It defines a structure for clock configuration and provides functions for setting up individual I2C instances and standard clock speeds. ```c // I2C clock setup with frequency calculation typedef struct { uint32_t scl_frequency; // Desired SCL frequency (Hz) uint32_t func_clk_freq; // Functional clock (96MHz from CORE DPLL) } i2c_clock_config_t; // Setup I2C clock for standard speeds int setup_i2c_clock(int i2c_num, uint32_t scl_freq) { int result = enable_i2c_clock(i2c_num); if (result != 0) { return result; } // I2C functional clock is 96MHz from CORE DPLL // SCL frequency is configured in I2C registers using divisors uint32_t func_clk = 96000000; // 96MHz // Verify SCL frequency is achievable if (scl_freq > 400000) { // Max 400KHz for I2C return -1; } return 0; } // Standard I2C frequency configurations void setup_standard_i2c_clocks(void) { setup_i2c_clock(0, 100000); // I2C0: 100KHz standard mode setup_i2c_clock(1, 400000); // I2C1: 400KHz fast mode setup_i2c_clock(2, 100000); // I2C2: 100KHz standard mode } ``` -------------------------------- ### AM3358 Specific DPLL Configuration Examples (C) Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/clock-usage.md Provides C functions to configure the MPU, Core, and Peripheral DPLLs on the AM3358 to specific frequencies. These functions utilize the generic `configure_dpll` function with pre-defined `dpll_config_t` structures. The examples include configurations for MPU at 720 MHz, Core at 1000 MHz, and Peripheral at 960 MHz, assuming a 24MHz input clock. ```c // MPU DPLL configuration (720 MHz default) int configure_mpu_dpll_720mhz(void) { dpll_config_t mpu_config = { .m = 720, // 24MHz * 720 = 17.28GHz .n = 23, // (23 + 1) = 24 .m2 = 1 // 17.28GHz / 24 / 1 = 720MHz }; return configure_dpll(CM_CLKMODE_DPLL_MPU, CM_CLKSEL_DPLL_MPU, CM_IDLEST_DPLL_MPU, &mpu_config); } // Core DPLL configuration (1000 MHz) int configure_core_dpll_1000mhz(void) { dpll_config_t core_config = { .m = 1000, // 24MHz * 1000 = 24GHz .n = 23, // (23 + 1) = 24 .m2 = 10 // 24GHz / 24 / 10 = 100MHz (L3), 200MHz (L4) }; return configure_dpll(CM_CLKMODE_DPLL_CORE, CM_CLKSEL_DPLL_CORE, CM_IDLEST_DPLL_CORE, &core_config); } // Peripheral DPLL configuration (960 MHz) int configure_per_dpll_960mhz(void) { dpll_config_t per_config = { .m = 960, // 24MHz * 960 = 23.04GHz .n = 23, // (23 + 1) = 24 .m2 = 5 // 23.04GHz / 24 / 5 = 192MHz }; return configure_dpll(CM_CLKMODE_DPLL_PER, CM_CLKSEL_DPLL_PER, CM_IDLEST_DPLL_PER, &per_config); } ``` -------------------------------- ### ADC Clock Setup Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/clock-usage.md Implements ADC clock setup, including enabling the peripheral clock for the ADC and Touch Screen Controller (TSC), which share the same clock domain. The functional clock for the ADC is 24MHz from M_OSC. ```c // ADC clock configuration (24MHz max for proper operation) int setup_adc_clock(void) { int result = enable_peripheral_clock(CM_WKUP_ADC_TSC_CLKCTRL); if (result != 0) { return result; } // ADC functional clock is 24MHz from M_OSC // This provides proper timing for ADC conversions return 0; } // Setup ADC with touch screen controller int setup_adc_tsc_clocks(void) { // Both ADC and TSC share the same clock domain return setup_adc_clock(); } ``` -------------------------------- ### AM335x Basic Timer Initialization (C) Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/timer-usage.md Initializes and configures a timer on AM335x processors. This function handles clock enabling, source selection, soft reset, OCP interface configuration, prescaler, and auto-reload settings. It requires a `timer_config_t` structure as input. ```c /** * Initialize timer with basic configuration */ int timer_init(timer_config_t *config) { volatile uint32_t *timer = config->base; uint32_t tclr_value = 0; /* Enable clock first */ int timer_num = ((uint32_t)config->base - TIMER0_BASE) / 0x2000; if (timer_num > 7) timer_num = 1; /* Handle TIMER1 special case */ timer_enable_clock(timer_num); timer_set_clock_source(timer_num, config->clock_source); /* Soft reset the timer */ timer[TIMER_TIOCP_CFG/4] = 0x01; /* Soft reset */ while (timer[TIMER_TIOCP_CFG/4] & 0x01); /* Wait for reset complete */ /* Configure OCP interface */ if (config->posted_mode) { timer[TIMER_TIOCP_CFG/4] = 0x04; /* Posted mode */ } else { timer[TIMER_TIOCP_CFG/4] = 0x00; /* Normal mode */ } /* Stop timer during configuration */ timer[TIMER_TCLR/4] = 0; /* Configure prescaler */ if (config->prescaler > 1) { tclr_value |= TCLR_PRE; /* Enable prescaler */ /* Set prescaler value (log2 of actual prescaler) */ int ptv = 0; int prescaler = config->prescaler; while (prescaler > 1) { prescaler >>= 1; ptv++; } if (ptv > 7) ptv = 7; /* Maximum prescaler is 128 (2^7) */ tclr_value |= (ptv << TCLR_PTV_SHIFT); } /* Configure auto-reload */ if (config->auto_reload) { tclr_value |= TCLR_AR; timer[TIMER_TLDR/4] = 0xFFFFFFFF - config->period + 1; timer[TIMER_TCRR/4] = 0xFFFFFFFF - config->period + 1; } else { timer[TIMER_TLDR/4] = 0; timer[TIMER_TCRR/4] = 0; } /* Apply configuration */ timer[TIMER_TCLR/4] = tclr_value; return 0; /* Success */ } /** * Start timer operation */ void timer_start(volatile uint32_t *timer_base) { volatile uint32_t *timer = timer_base; timer[TIMER_TCLR/4] |= TCLR_ST; } /** * Stop timer operation */ void timer_stop(volatile uint32_t *timer_base) { volatile uint32_t *timer = timer_base; timer[TIMER_TCLR/4] &= ~TCLR_ST; } /** * Read current timer value */ uint32_t timer_read_counter(volatile uint32_t *timer_base) { volatile uint32_t *timer = timer_base; return timer[TIMER_TCRR/4]; } /** * Write timer counter value */ void timer_write_counter(volatile uint32_t *timer_base, uint32_t value) { volatile uint32_t *timer = timer_base; timer[TIMER_TCRR/4] = value; } ``` -------------------------------- ### Setup Multi-Phase Motor Control Timers (C) Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/timer-usage.md Configures multiple timers for three-phase motor control by setting them up for PWM generation with specified frequencies and duty cycles. It also aligns the PWM phases for synchronized operation. This function requires timer PWM setup and phase alignment utilities. ```c /* Three-phase motor control example */ void setup_three_phase_motor(void) { int timers[] = {4, 5, 6}; uint32_t phases[] = {0, 120, 240}; /* 120-degree phase shifts */ /* Setup each timer for PWM */ timer_setup_pwm(4, 20000, 50); /* 20 kHz, 50% duty */ timer_setup_pwm(5, 20000, 50); timer_setup_pwm(6, 20000, 50); /* Align phases for three-phase operation */ timer_align_pwm_phases(timers, phases, 3); } ``` -------------------------------- ### Complete GPIO Pin Setup (C) Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/pinmux-usage.md Configures a GPIO pin with multiplexing and direction settings. It includes steps for setting the pin mode, configuring it as input or output, and comments on enabling GPIO clocks. Dependencies include hardware-specific register definitions. ```c // Complete GPIO pin setup with multiplexing and GPIO configuration void setup_complete_gpio_pin(uint32_t pin_offset, uint32_t gpio_bank, uint32_t pin_num, bool is_input) { // Step 1: Configure pin multiplexing if (is_input) { PIN_CONFIG_REG(pin_offset) = PIN_MODE_7 | PIN_INPUT_PULLUP | PIN_SLEWCTRL; } else { PIN_CONFIG_REG(pin_offset) = PIN_MODE_7 | PIN_OUTPUT; } // Step 2: Configure GPIO direction (assumes GPIO functions available) // This would integrate with GPIO register access // gpio_configure_direction(gpio_bank, pin_num, is_input); // Step 3: Enable GPIO clock if needed // enable_gpio_clock(gpio_bank); } // Example: Complete setup for GPIO1_12 as output LED void setup_gpio1_12_led(void) { setup_complete_gpio_pin(CONF_GPMC_AD12_OFFSET, 1, 12, false); } // Example: Complete setup for GPIO1_13 as input button void setup_gpio1_13_button(void) { setup_complete_gpio_pin(CONF_GPMC_AD13_OFFSET, 1, 13, true); } ``` -------------------------------- ### C Pin Configuration Debugging Utilities Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/pinmux-usage.md Provides functions to print detailed configuration of a specific pin, verify if a pin is configured as a GPIO, and list the status of all GPIO pins. ```c // Debug pin configuration utility void debug_pin_config(uint32_t offset) { uint32_t config = PIN_CONFIG_REG(offset); printf("Pin config at offset 0x%03X: 0x%08X\n", offset, config); printf(" Mode: %d\n", config & PIN_MODE_MASK); printf(" Pull: %s\n", (config & PIN_PULLUDEN) ? "Disabled" : (config & PIN_PULLTYPESEL) ? "Pull-up" : "Pull-down"); printf(" Input: %s\n", (config & PIN_RXACTIVE) ? "Enabled" : "Disabled"); printf(" Slew: %s\n", (config & PIN_SLEWCTRL) ? "Slow" : "Fast"); } // Verify GPIO pin configuration bool verify_gpio_pin_config(uint32_t offset) { uint32_t config = PIN_CONFIG_REG(offset); // Check if configured as GPIO (mode 7) return (config & PIN_MODE_MASK) == PIN_MODE_7; } // Print all GPIO pin configurations void debug_all_gpio_pins(void) { printf("GPIO Pin Configuration Status:\n"); // Check GPIO1 pins (GPMC_AD pins) for (int i = 0; i <= 15; i++) { uint32_t offset = 0x800 + i * 4; if (verify_gpio_pin_config(offset)) { printf(" GPIO1_%d: ", i); debug_pin_config(offset); } } } ``` -------------------------------- ### Setup System Tick Timer (C) Source: https://github.com/sessions-matthew/am335x-doc/blob/main/docs/implementation/timer-usage.md Configures Timer1 to act as a system tick by setting up precise timing and registering a callback function. It requires timer initialization and interrupt controller functions, and enables the Timer1 interrupt. ```c /* Basic system tick implementation */ void setup_system_tick(void) { /* Use Timer1 (1MS) for system tick */ timer1ms_setup_precise(); timer_register_callback(1, system_tick_callback); intc_enable_interrupt(TIMER1_IRQ); } ```