From fab51038c081a248c5871e5ebe4bd3b793f5dca6 Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Sun, 15 Jul 2012 18:17:27 +0200 Subject: [PATCH] SGPIO Test with CPLD passthrough mode => work in progress because I have some hardware issues on my board. For details on Hardware issues see Test_SGPIO0_to15.pdf or Test_SGPIO0_to15.ods --- .../sgpio_passthrough_rom_to_ram/Makefile | 10 + firmware/sgpio_passthrough_rom_to_ram/README | 5 + .../Test_SGPIO0_to15.ods | Bin 0 -> 12245 bytes .../Test_SGPIO0_to15.pdf | Bin 0 -> 54376 bytes ...t_SGPIO_GPIO_mode_test_sgpio_interface.txt | 68 +++ .../sgpio_passthrough.c | 419 ++++++++++++++++++ 6 files changed, 502 insertions(+) create mode 100644 firmware/sgpio_passthrough_rom_to_ram/Makefile create mode 100644 firmware/sgpio_passthrough_rom_to_ram/README create mode 100644 firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO0_to15.ods create mode 100644 firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO0_to15.pdf create mode 100644 firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt create mode 100644 firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c diff --git a/firmware/sgpio_passthrough_rom_to_ram/Makefile b/firmware/sgpio_passthrough_rom_to_ram/Makefile new file mode 100644 index 00000000..98eb5746 --- /dev/null +++ b/firmware/sgpio_passthrough_rom_to_ram/Makefile @@ -0,0 +1,10 @@ +# Hey Emacs, this is a -*- makefile -*- + +BINARY = sgpio_passthrough + +SRC = $(BINARY).c \ + ../common/hackrf_core.c \ + ../common/si5351c.c + +LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld +include ../common/Makefile_inc.mk diff --git a/firmware/sgpio_passthrough_rom_to_ram/README b/firmware/sgpio_passthrough_rom_to_ram/README new file mode 100644 index 00000000..2489f791 --- /dev/null +++ b/firmware/sgpio_passthrough_rom_to_ram/README @@ -0,0 +1,5 @@ +A program to test SGPIO with CPLD passthrough Input & Output via the SGPIO CPLD interface (P8 BANK2_AUX). +For this test connect P10 BANK1_AUX AUX9 pin to +1V8 (in order to have P8 BANK2_AUX AUX1 to 16 as Output). +This test requires: + * JellyBean+Lemondrop(to set clock at 204MHz). + * CPLD X2C64A hardware\jellybean\sgpio_if_passthrough\sgpio_if_passthrough.svf to be loaded first. diff --git a/firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO0_to15.ods b/firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO0_to15.ods new file mode 100644 index 0000000000000000000000000000000000000000..a3843c9e33571f88e27f913abca37525925e2363 GIT binary patch literal 12245 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 sQofPui?$O?*whhE0i&fLXZjI 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 literal 0 HcmV?d00001 diff --git a/firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt b/firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt new file mode 100644 index 00000000..6c2f3ba9 --- /dev/null +++ b/firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt @@ -0,0 +1,68 @@ + +Test SGPIO GPIO mode, with LPC4330@204MHz (JellyBean+Lemondrop) and code executed in RAM. + +Test1: +------ +while(1) +{ + for (uint_fast8_t i = 0; i < 8; i++) + { + SGPIO_GPIO_OUTREG ^= (1L << i); + + } +} +Oscilloscope result (on SGPIO0): Frequency 750KHz => 272 cycles + +Test2: +------ +while(1) +{ + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + SGPIO_GPIO_OUTREG ^= 0x5555; +} +Oscilloscope result (on SGPIO0): 3.923 MHz => 52 cycles + +Test3: +------ +while(1) +{ + SGPIO_GPIO_OUTREG ^= 0x5555; +} +Oscilloscope result (on SGPIO0): Frequency 7.28MHz => 28 cycles + +Test4: +------ +while(1) +{ + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + SGPIO_GPIO_OUTREG = 0x5555; + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + SGPIO_GPIO_OUTREG = 0xAAAA; +} +Oscilloscope result (on SGPIO0): Frequency 17MHz => 12 cycles + +Test5: +------ +while(1) +{ + SGPIO_GPIO_OUTREG = 0x5555; + SGPIO_GPIO_OUTREG = 0xAAAA; +} +Oscilloscope result (on SGPIO0): Frequency 25.5MHz => 8 cycles diff --git a/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c b/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c new file mode 100644 index 00000000..c5525c57 --- /dev/null +++ b/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c @@ -0,0 +1,419 @@ +/* + * Copyright 2012 Michael Ossmann + * Copyright (C) 2012 Jared Boone + * Copyright (C) 2012 Benjamin Vernoux + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include + +void pin_setup(void) { + /* Configure SCU Pin Mux as GPIO */ + scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); + + /* Configure all GPIO as Input (safe state) */GPIO0_DIR = 0; + GPIO1_DIR = 0; + GPIO2_DIR = 0; + GPIO3_DIR = 0; + GPIO4_DIR = 0; + GPIO5_DIR = 0; + GPIO6_DIR = 0; + GPIO7_DIR = 0; + + /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ + GPIO2_DIR |= (PIN_LED1 | PIN_LED2 | PIN_LED3); + + /* GPIO3[6] on P6_10 as output. */ + GPIO3_DIR |= PIN_EN1V8; + + /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ + scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); + scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); +} + +void enable_1v8_power() { + gpio_set(PORT_EN1V8, PIN_EN1V8); +} + +void release_cpld_jtag_pins() { + scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); + scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + + GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO; + GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK; + GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS; + GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI; +} + +void configure_sgpio_pin_functions() { + scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); + scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); + scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO3, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO4, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO5, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO6, SCU_GPIO_FAST | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_SGPIO7, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO8, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO9, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO10, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO11, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO12, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); +} + +void test_sgpio_sliceA_D(void) +{ + SGPIO_GPIO_OENREG = 0; // All inputs for the moment. + + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + // Configure pin functions. + configure_sgpio_pin_functions(); + + /****************************************************/ + /* Enable SGPIO pin outputs. */ + /****************************************************/ + SGPIO_GPIO_OENREG = + 0xFFFF; // data: output for SGPIO0 to SGPIO15 + + /*******************************************************************************/ + /* SGPIO pin 0 outputs slice A bit 0. (see Table 212. Output pin multiplexing) */ + /*******************************************************************************/ + SGPIO_OUT_MUX_CFG(0) = + (0L << 4) | // P_OE_CFG = X + (0L << 0); // P_OUT_CFG = 0, dout_doutm1 (1-bit mode) + + // SGPIO pin 12 outputs slice D bit 0. (see Table 212. Output pin multiplexing) + SGPIO_OUT_MUX_CFG(12) = + (0L << 4) | // P_OE_CFG = X + (0L << 0); // P_OUT_CFG = 0, dout_doutm1 (1-bit mode) + + /****************************************************/ + /* Slice A */ + /****************************************************/ + SGPIO_MUX_CFG(SGPIO_SLICE_A) = + (0L << 12) | // CONCAT_ORDER = 0 (self-loop) + (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) + (0L << 9) | // QUALIFIER_SLICE_MODE = X + (0L << 7) | // QUALIFIER_PIN_MODE = X + (0L << 5) | // QUALIFIER_MODE = 0 (enable) + (0L << 3) | // CLK_SOURCE_SLICE_MODE = 0, slice D + (0L << 1) | // CLK_SOURCE_PIN_MODE = X + (0L << 0); // EXT_CLK_ENABLE = 0, internal clock signal (slice) + + SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = + (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) + (0L << 6) | // PARALLEL_MODE = 0 (shift 1 bit per clock) + (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) + (0L << 3) | // INV_OUT_CLK = 0 (normal clock) + (0L << 2) | // CLKGEN_MODE = 0 (use clock from COUNTER) + (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) + (0L << 0); // MATCH_MODE = 0 (do not match data) + + SGPIO_PRESET(SGPIO_SLICE_A) = 1; + SGPIO_COUNT(SGPIO_SLICE_A) = 0; + SGPIO_POS(SGPIO_SLICE_A) = (0x1FL << 8) | (0x1FL << 0); + SGPIO_REG(SGPIO_SLICE_A) = 0xAAAAAAAA; // Primary output data register + SGPIO_REG_SS(SGPIO_SLICE_A) = 0xAAAAAAAA; // Shadow output data register + + /****************************************************/ + /* Slice D (clock for Slice A) */ + /****************************************************/ + SGPIO_MUX_CFG(SGPIO_SLICE_D) = + (0L << 12) | // CONCAT_ORDER = 0 (self-loop) + (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) + (0L << 9) | // QUALIFIER_SLICE_MODE = X + (0L << 7) | // QUALIFIER_PIN_MODE = X + (0L << 5) | // QUALIFIER_MODE = 0 (enable) + (0L << 3) | // CLK_SOURCE_SLICE_MODE = 0, slice D + (0L << 1) | // CLK_SOURCE_PIN_MODE = X + (0L << 0); // EXT_CLK_ENABLE = 0, internal clock signal (slice) + + SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_D) = + (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) + (0L << 6) | // PARALLEL_MODE = 0 (shift 1 bit per clock) + (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) + (0L << 3) | // INV_OUT_CLK = 0 (normal clock) + (0L << 2) | // CLKGEN_MODE = 0 (use clock from COUNTER) + (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) + (0L << 0); // MATCH_MODE = 0 (do not match data) + + SGPIO_PRESET(SGPIO_SLICE_D) = 0; + SGPIO_COUNT(SGPIO_SLICE_D) = 0; + SGPIO_POS(SGPIO_SLICE_D) = (0x1FL << 8) | (0x1FL << 0); + SGPIO_REG(SGPIO_SLICE_D) = 0xAAAAAAAA; // Primary output data register + SGPIO_REG_SS(SGPIO_SLICE_D) = 0xAAAAAAAA; // Shadow output data register + + + /****************************************************/ + /* Start SGPIO operation by enabling slice clocks. */ + /****************************************************/ + SGPIO_CTRL_ENABLE = + (1L << SGPIO_SLICE_D) | // Slice D + (1L << SGPIO_SLICE_A); // Slice A + // Start SGPIO operation by enabling slice clocks. + + /* + Expected: + SGPIO12 = MCU Freq/2 + SGPIO0 = SGPIO12/2 MHz= 51MHz (SliceD/2) + */ + +} + + +/*******************************************************************************/ +/* Output 1bit table (see Table 212. Output pin multiplexing) */ +/* SGPIO pin 00 outputs slice A bit 0. */ +/* SGPIO pin 01 outputs slice I bit 0. */ +/* SGPIO pin 02 outputs slice E bit 0. */ +/* SGPIO pin 03 outputs slice J bit 0. */ +/* SGPIO pin 04 outputs slice C bit 0. */ +/* SGPIO pin 05 outputs slice K bit 0. */ +/* SGPIO pin 06 outputs slice F bit 0. */ +/* SGPIO pin 07 outputs slice L bit 0. */ +/* SGPIO pin 08 outputs slice B bit 0. */ +/* SGPIO pin 09 outputs slice M bit 0. */ +/* SGPIO pin 10 outputs slice G bit 0. */ +/* SGPIO pin 11 outputs slice N bit 0. */ +/* SGPIO pin 12 outputs slice D bit 0. */ +/* SGPIO pin 13 outputs slice O bit 0. */ +/* SGPIO pin 14 outputs slice H bit 0. */ +/* SGPIO pin 15 outputs slice P bit 0. */ +/*******************************************************************************/ +const u8 slice_preset_tab[16] = +{ + 0, /* Idx00 = Slice A => SGPIO0 Freq Div by 1=0 */ + 8, /* Idx01 = Slice B => SGPIO8 Freq Div by 9=8 */ + 4, /* Idx02 = Slice C => SGPIO4 Freq Div by 5=4 */ + 12, /* Idx03 = Slice D => SGPIO12 Freq Div by 13=12 */ + 2, /* Idx04 = Slice E => SGPIO2 Freq Div by 3=2 */ + 6, /* Idx05 = Slice F => SGPIO6 Freq Div by 7=6 */ + 10, /* Idx06 = Slice G => SGPIO10 Freq Div by 11=10 */ + 14, /* Idx07 = Slice H => SGPIO14 Freq Div by 15=14 */ + 1, /* Idx08 = Slice I => SGPIO1 Freq Div by 2=1 */ + 3, /* Idx09 = Slice J => SGPIO3 Freq Div by 4=3 */ + 5, /* Idx10 = Slice K => SGPIO5 Freq Div by 6=5 */ + 7, /* Idx11 = Slice L => SGPIO7 Freq Div by 8=7 */ + 9, /* Idx12 = Slice M => SGPIO9 Freq Div by 10=9 */ + 11, /* Idx13 = Slice N => SGPIO11 Freq Div by 12=11 */ + 13, /* Idx14 = Slice O => SGPIO13 Freq Div by 14=13 */ + 15 /* Idx15 = Slice P => SGPIO15 Freq Div by 16=15 */ +}; + +void test_sgpio_all_slices(void) +{ + + SGPIO_GPIO_OENREG = 0; // All inputs for the moment. + + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + // Configure pin functions. + configure_sgpio_pin_functions(); + + /****************************************************/ + /* Enable SGPIO pin outputs. */ + /****************************************************/ + SGPIO_GPIO_OENREG = + 0xFFFF; // data: output for SGPIO0 to SGPIO15 + + for(uint_fast8_t i=0; i<16; i++) + { + SGPIO_OUT_MUX_CFG(i) = + (0L << 4) | // P_OE_CFG = X + (0L << 0); // P_OUT_CFG = 0, dout_doutm1 (1-bit mode) + } + + /****************************************************/ + /* Slice A to P */ + /****************************************************/ + for(uint_fast8_t i=0; i<16; i++) + { + SGPIO_MUX_CFG(i) = + (0L << 12) | // CONCAT_ORDER = 0 (self-loop) + (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) + (0L << 9) | // QUALIFIER_SLICE_MODE = X + (0L << 7) | // QUALIFIER_PIN_MODE = X + (0L << 5) | // QUALIFIER_MODE = 0 (enable) + (0L << 3) | // CLK_SOURCE_SLICE_MODE = 0, slice D + (0L << 1) | // CLK_SOURCE_PIN_MODE = X + (0L << 0); // EXT_CLK_ENABLE = 0, internal clock signal (slice) + + SGPIO_SLICE_MUX_CFG(i) = + (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) + (0L << 6) | // PARALLEL_MODE = 0 (shift 1 bit per clock) + (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) + (0L << 3) | // INV_OUT_CLK = 0 (normal clock) + (0L << 2) | // CLKGEN_MODE = 0 (use clock from COUNTER) + (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) + (0L << 0); // MATCH_MODE = 0 (do not match data) + + SGPIO_PRESET(i) = slice_preset_tab[i]; + SGPIO_COUNT(i) = 0; + SGPIO_POS(i) = (0x1FL << 8) | (0x1FL << 0); + SGPIO_REG(i) = 0xAAAAAAAA; // Primary output data register + SGPIO_REG_SS(i) = 0xAAAAAAAA; // Shadow output data register + } + + /****************************************************/ + /* Start SGPIO operation by enabling slice clocks. */ + /****************************************************/ + SGPIO_CTRL_ENABLE = 0xFFFF; /* Start all slices A to P */ +/* + (1L << SGPIO_SLICE_D) | // Slice D + (1L << SGPIO_SLICE_A); // Slice A + // Start SGPIO operation by enabling slice clocks. +*/ + /* + Expected: + MCU Freq MHz = 204 + SGPIO Theorical Freq MHz + SGPIO00 = 102,00000 + SGPIO01 = 51,00000 + SGPIO02 = 34,00000 + SGPIO03 = 25,50000 + SGPIO04 = 20,40000 + SGPIO05 = 17,00000 + SGPIO06 = 14,57143 + SGPIO07 = 12,75000 + SGPIO08 = 11,33333 + SGPIO09 = 10,20000 + SGPIO10 = 9,27273 + SGPIO11 = 8,50000 + SGPIO12 = 7,84615 + SGPIO13 = 7,28571 + SGPIO14 = 6,80000 + SGPIO15 = 6,37500 + TitanMKD: I have problems with my boards and this test see document Test_SGPIO0_to15.ods / Test_SGPIO0_to15.pdf + */ +} + +void test_sgpio_interface(void) +{ + SGPIO_GPIO_OENREG = 0; // All inputs for the moment. + + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + configure_sgpio_pin_functions(); + + // Make all SGPIO controlled by SGPIO's "GPIO" registers + for (uint_fast8_t i = 0; i < 16; i++) { + SGPIO_OUT_MUX_CFG(i) = (0L << 4) | (4L << 0); + } + + // Enable SGPIO pin outputs (SGPIO0 to 15). + SGPIO_GPIO_OENREG = 0xFFFF; + + /* Set values for SGPIO0 to 15 */ + while (1) + { + // 750KHz => 272 cycles + /* + for (uint_fast8_t i = 0; i < 8; i++) { + SGPIO_GPIO_OUTREG ^= (1L << i); + + } + */ + + // 3.923 MHz => 52 cycles + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + SGPIO_GPIO_OUTREG ^= 0x5555; + + // 7.28 MHz => 28 cycles + /* + SGPIO_GPIO_OUTREG ^= 0x5555; + */ + + // 17 MHz => 12 cycles + /* + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + SGPIO_GPIO_OUTREG = 0x5555; + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + __asm__(" nop"); + SGPIO_GPIO_OUTREG = 0xAAAA; + */ + // 25.50 MHz => 8 cycles + /* + SGPIO_GPIO_OUTREG = 0x5555; + SGPIO_GPIO_OUTREG = 0xAAAA; + */ + } + + /* TitanMKD: I have problems with my board with this test (see test_sgpio_all_slices()) */ +} + +int main(void) +{ + pin_setup(); + enable_1v8_power(); + cpu_clock_init(); + ssp1_init(); + + CGU_BASE_PERIPH_CLK = (CGU_BASE_CLK_AUTOBLOCK + | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + + CGU_BASE_APB1_CLK = (CGU_BASE_CLK_AUTOBLOCK + | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + + gpio_set(PORT_LED1_3, PIN_LED1); + + //test_sgpio_sliceA_D(); + test_sgpio_interface(); + //test_sgpio_all_slices(); + + while(1); + + return 0; +}