From 2e05f03d83e55feadd05ba63b9f1abfb924e0f7c Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Mon, 11 Jun 2012 22:39:22 +0200 Subject: [PATCH] Startup & Performance test using SysTick Timer. --- firmware/startup_systick/Makefile | 9 + firmware/startup_systick/README | 12 + firmware/startup_systick/startup_systick.c | 325 ++++++++++++++++++ firmware/startup_systick_rom_to_ram/Makefile | 10 + firmware/startup_systick_rom_to_ram/README | 12 + .../startup_systick.c | 325 ++++++++++++++++++ 6 files changed, 693 insertions(+) create mode 100644 firmware/startup_systick/Makefile create mode 100644 firmware/startup_systick/README create mode 100644 firmware/startup_systick/startup_systick.c create mode 100644 firmware/startup_systick_rom_to_ram/Makefile create mode 100644 firmware/startup_systick_rom_to_ram/README create mode 100644 firmware/startup_systick_rom_to_ram/startup_systick.c diff --git a/firmware/startup_systick/Makefile b/firmware/startup_systick/Makefile new file mode 100644 index 00000000..5d5ccfd4 --- /dev/null +++ b/firmware/startup_systick/Makefile @@ -0,0 +1,9 @@ +# Hey Emacs, this is a -*- makefile -*- + +BINARY = startup_systick + +SRC = $(BINARY).c \ + ../common/hackrf_core.c \ + ../common/si5351c.c + +include ../common/Makefile_inc.mk diff --git a/firmware/startup_systick/README b/firmware/startup_systick/README new file mode 100644 index 00000000..c99ad470 --- /dev/null +++ b/firmware/startup_systick/README @@ -0,0 +1,12 @@ +This program is an example of the startup sequence for HackRF (Jellybean with +Lemondrop attached). +LED1, LED2, and LED3 are blinking at exactly a frequency of 1Hz upon success. + +Required Lemondrop -> Jellybean connections: + +SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 +SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 +SDA: Lemondrop P7 pin 6 -> Jellybean P6 pin 6 +VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 +1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 +GND: Lemondrop P5 -> Jellybean P13 diff --git a/firmware/startup_systick/startup_systick.c b/firmware/startup_systick/startup_systick.c new file mode 100644 index 00000000..b80a1b59 --- /dev/null +++ b/firmware/startup_systick/startup_systick.c @@ -0,0 +1,325 @@ +/* + * Copyright 2010 - 2012 Michael Ossmann + * + * 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 + +#include "hackrf_core.h" + +/* Global counter incremented by SysTick Interrupt each millisecond */ +volatile u32 g_ulSysTickCount; +u32 g_NbCyclePerSecond; + +void gpio_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; +} + +void systick_setup(void) +{ + u32 systick_reload_val; + g_ulSysTickCount = 0; + + /* Disable IRQ globally */ + asm volatile ("cpsid i"); + + /* Set processor Clock as Source Clock */ + systick_set_clocksource(STK_CTRL_CLKSOURCE); + + /* Get SysTick calibration value to obtain by default 1 tick = 10ms */ + systick_reload_val = systick_get_calib(); + /* + * Calibration seems wrong on LPC43xx(TBC) for default Freq it assume System Clock is 12MHz but it is 12*17=204MHz + * Fix the Calibration value bu multiplication by 17 + */ + systick_reload_val = (systick_reload_val*17); + + /* To obtain 1ms per tick just divide by 10 the 10ms base tick and set the reload */ + systick_reload_val = systick_reload_val/10; + systick_set_reload(systick_reload_val); + + systick_interrupt_enable(); + + /* Start counting. */ + systick_counter_enable(); + + /* Set SysTick Priority to maximum */ + nvic_set_priority(NVIC_SYSTICK_IRQ, 0xFF); + + /* Enable IRQ globally */ + asm volatile ("cpsie i"); +} + +void scs_dwt_cycle_counter_enabled(void) +{ + SCS_DEMCR |= SCS_DEMCR_TRCENA; + SCS_DWT_CTRL |= SCS_DWT_CTRL_CYCCNTENA; +} + +u32 sys_tick_get_time_ms(void) +{ + return g_ulSysTickCount; +} + +u32 sys_tick_delta_time_ms(u32 start, u32 end) +{ + #define MAX_T_U32 ((2^32)-1) + u32 diff; + + if(end > start) + { + diff=end-start; + }else + { + diff=MAX_T_U32-(start-end)+1; + } + + return diff; +} + +void sys_tick_wait_time_ms(u32 wait_ms) +{ + u32 start, end; + u32 tickms; + + start = sys_tick_get_time_ms(); + + do + { + end = sys_tick_get_time_ms(); + tickms = sys_tick_delta_time_ms(start, end); + }while(tickms < wait_ms); +} + +/* Called each 1ms/1000Hz by interrupt + 1) Count the number of cycle per second. + 2) Increment g_ulSysTickCount counter. +*/ +void sys_tick_handler(void) +{ + if(g_ulSysTickCount==0) + { + /* Clear Cycle Counter*/ + SCS_DWT_CYCCNT = 0; + }else if(g_ulSysTickCount==1000) + { + /* Capture number of cycle elapsed during 1 second */ + g_NbCyclePerSecond = SCS_DWT_CYCCNT; + } + + g_ulSysTickCount++; +} + +u32 test_nb_instruction_per_sec(void) +{ + u32 start, end, wait_ms; + u32 tickms; + u32 nb_instructions_per_sec; + + nb_instructions_per_sec = 0; + wait_ms = 1000; + + start = sys_tick_get_time_ms(); + + do + { + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + nb_instructions_per_sec += 100; + + end = sys_tick_get_time_ms(); + tickms = sys_tick_delta_time_ms(start, end); + }while(tickms < wait_ms); + + return nb_instructions_per_sec; +} + + +u32 nb_inst_per_sec0; +u32 nb_inst_per_sec1; + +int main(void) +{ + gpio_setup(); + + gpio_set(PORT_EN1V8, PIN_EN1V8); /* 1V8 on */ + + cpu_clock_init(); + + scs_dwt_cycle_counter_enabled(); + + systick_setup(); + + /* Test number of instruction per second */ + nb_inst_per_sec0 = test_nb_instruction_per_sec(); + nb_inst_per_sec1 = test_nb_instruction_per_sec(); + + gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LEDs on */ + + while (1) + { + gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */ + gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ + gpio_set(PORT_LED1_3, (PIN_LED3)); /* LED3 on */ + + sys_tick_wait_time_ms(500); + + gpio_clear(PORT_LED1_3, (PIN_LED3)); /* LED3 off */ + gpio_clear(PORT_LED1_3, (PIN_LED2)); /* LED2 off */ + gpio_clear(PORT_LED1_3, (PIN_LED1)); /* LED1 off */ + + sys_tick_wait_time_ms(500); + } + + return 0; +} diff --git a/firmware/startup_systick_rom_to_ram/Makefile b/firmware/startup_systick_rom_to_ram/Makefile new file mode 100644 index 00000000..8841bd0c --- /dev/null +++ b/firmware/startup_systick_rom_to_ram/Makefile @@ -0,0 +1,10 @@ +# Hey Emacs, this is a -*- makefile -*- + +BINARY = startup_systick + +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/startup_systick_rom_to_ram/README b/firmware/startup_systick_rom_to_ram/README new file mode 100644 index 00000000..c99ad470 --- /dev/null +++ b/firmware/startup_systick_rom_to_ram/README @@ -0,0 +1,12 @@ +This program is an example of the startup sequence for HackRF (Jellybean with +Lemondrop attached). +LED1, LED2, and LED3 are blinking at exactly a frequency of 1Hz upon success. + +Required Lemondrop -> Jellybean connections: + +SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 +SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 +SDA: Lemondrop P7 pin 6 -> Jellybean P6 pin 6 +VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 +1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 +GND: Lemondrop P5 -> Jellybean P13 diff --git a/firmware/startup_systick_rom_to_ram/startup_systick.c b/firmware/startup_systick_rom_to_ram/startup_systick.c new file mode 100644 index 00000000..b80a1b59 --- /dev/null +++ b/firmware/startup_systick_rom_to_ram/startup_systick.c @@ -0,0 +1,325 @@ +/* + * Copyright 2010 - 2012 Michael Ossmann + * + * 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 + +#include "hackrf_core.h" + +/* Global counter incremented by SysTick Interrupt each millisecond */ +volatile u32 g_ulSysTickCount; +u32 g_NbCyclePerSecond; + +void gpio_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; +} + +void systick_setup(void) +{ + u32 systick_reload_val; + g_ulSysTickCount = 0; + + /* Disable IRQ globally */ + asm volatile ("cpsid i"); + + /* Set processor Clock as Source Clock */ + systick_set_clocksource(STK_CTRL_CLKSOURCE); + + /* Get SysTick calibration value to obtain by default 1 tick = 10ms */ + systick_reload_val = systick_get_calib(); + /* + * Calibration seems wrong on LPC43xx(TBC) for default Freq it assume System Clock is 12MHz but it is 12*17=204MHz + * Fix the Calibration value bu multiplication by 17 + */ + systick_reload_val = (systick_reload_val*17); + + /* To obtain 1ms per tick just divide by 10 the 10ms base tick and set the reload */ + systick_reload_val = systick_reload_val/10; + systick_set_reload(systick_reload_val); + + systick_interrupt_enable(); + + /* Start counting. */ + systick_counter_enable(); + + /* Set SysTick Priority to maximum */ + nvic_set_priority(NVIC_SYSTICK_IRQ, 0xFF); + + /* Enable IRQ globally */ + asm volatile ("cpsie i"); +} + +void scs_dwt_cycle_counter_enabled(void) +{ + SCS_DEMCR |= SCS_DEMCR_TRCENA; + SCS_DWT_CTRL |= SCS_DWT_CTRL_CYCCNTENA; +} + +u32 sys_tick_get_time_ms(void) +{ + return g_ulSysTickCount; +} + +u32 sys_tick_delta_time_ms(u32 start, u32 end) +{ + #define MAX_T_U32 ((2^32)-1) + u32 diff; + + if(end > start) + { + diff=end-start; + }else + { + diff=MAX_T_U32-(start-end)+1; + } + + return diff; +} + +void sys_tick_wait_time_ms(u32 wait_ms) +{ + u32 start, end; + u32 tickms; + + start = sys_tick_get_time_ms(); + + do + { + end = sys_tick_get_time_ms(); + tickms = sys_tick_delta_time_ms(start, end); + }while(tickms < wait_ms); +} + +/* Called each 1ms/1000Hz by interrupt + 1) Count the number of cycle per second. + 2) Increment g_ulSysTickCount counter. +*/ +void sys_tick_handler(void) +{ + if(g_ulSysTickCount==0) + { + /* Clear Cycle Counter*/ + SCS_DWT_CYCCNT = 0; + }else if(g_ulSysTickCount==1000) + { + /* Capture number of cycle elapsed during 1 second */ + g_NbCyclePerSecond = SCS_DWT_CYCCNT; + } + + g_ulSysTickCount++; +} + +u32 test_nb_instruction_per_sec(void) +{ + u32 start, end, wait_ms; + u32 tickms; + u32 nb_instructions_per_sec; + + nb_instructions_per_sec = 0; + wait_ms = 1000; + + start = sys_tick_get_time_ms(); + + do + { + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + asm volatile ("nop "); + nb_instructions_per_sec += 100; + + end = sys_tick_get_time_ms(); + tickms = sys_tick_delta_time_ms(start, end); + }while(tickms < wait_ms); + + return nb_instructions_per_sec; +} + + +u32 nb_inst_per_sec0; +u32 nb_inst_per_sec1; + +int main(void) +{ + gpio_setup(); + + gpio_set(PORT_EN1V8, PIN_EN1V8); /* 1V8 on */ + + cpu_clock_init(); + + scs_dwt_cycle_counter_enabled(); + + systick_setup(); + + /* Test number of instruction per second */ + nb_inst_per_sec0 = test_nb_instruction_per_sec(); + nb_inst_per_sec1 = test_nb_instruction_per_sec(); + + gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LEDs on */ + + while (1) + { + gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */ + gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ + gpio_set(PORT_LED1_3, (PIN_LED3)); /* LED3 on */ + + sys_tick_wait_time_ms(500); + + gpio_clear(PORT_LED1_3, (PIN_LED3)); /* LED3 off */ + gpio_clear(PORT_LED1_3, (PIN_LED2)); /* LED2 off */ + gpio_clear(PORT_LED1_3, (PIN_LED1)); /* LED1 off */ + + sys_tick_wait_time_ms(500); + } + + return 0; +}