Skip to content

Commit

Permalink
Merge pull request greatscottgadgets#1255 from miek/h1r9-fw
Browse files Browse the repository at this point in the history
Add firmware support for h1r9
  • Loading branch information
mossmann authored Jan 10, 2023
2 parents 6f26b74 + 3796bc9 commit 6f1cee1
Show file tree
Hide file tree
Showing 26 changed files with 1,904 additions and 211 deletions.
112 changes: 112 additions & 0 deletions firmware/common/clkin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright 2022 Great Scott Gadgets
*
* 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 "gpdma.h"
#include <libopencm3/lpc43xx/timer.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/gima.h>
#include <libopencm3/lpc43xx/creg.h>
#include <stdint.h>

#define CLOCK_CYCLES_1_MS (204000)
#define MEASUREMENT_WINDOW_MS (50)
#define MEASUREMENT_CYCLES (CLOCK_CYCLES_1_MS * MEASUREMENT_WINDOW_MS)

/* DMA linked list item */
typedef struct {
uint32_t src;
uint32_t dest;
uint32_t next_lli;
uint32_t control;
} dma_lli;

/* timer control register configuration sequence */
typedef struct {
uint32_t first_tcr;
uint32_t second_tcr;
} tcr_sequence;

dma_lli timer_dma_lli;
tcr_sequence reset;

void clkin_detect_init(void)
{
/* Timer1 triggers periodic measurement */
timer_set_prescaler(TIMER1, 0);
timer_set_mode(TIMER1, TIMER_CTCR_MODE_TIMER);
TIMER1_MCR = TIMER_MCR_MR0R;
TIMER1_EMR = (TIMER_EMR_EMC_SET << TIMER_EMR_EMC0_SHIFT) |
(TIMER_EMR_EMC_TOGGLE << TIMER_EMR_EMC3_SHIFT);
TIMER1_MR3 = MEASUREMENT_CYCLES;
TIMER1_MR0 = MEASUREMENT_CYCLES;

/* prevent TIMER1_MR3 from interfering with SCT */
CREG_CREG6 |= CREG_CREG6_CTOUTCTRL;

/* Timer2 counts CLKIN */
timer_set_prescaler(TIMER2, 0);
TIMER2_CCR = TIMER_CCR_CAP3RE;
GIMA_CAP2_3_IN = 0x20; // T1_MAT3

/* measure CLKIN_DETECT signal on P4_8, pin 15, CTIN_5 */
TIMER2_CTCR = TIMER_CTCR_MODE_COUNTER_RISING | TIMER_CTCR_CINSEL_CAPN_2;
scu_pinmux(P4_8, SCU_GPIO_PDN | SCU_CONF_FUNCTION1); // CTIN_5
GIMA_CAP2_2_IN = 0x00; // CTIN_5

reset.first_tcr = TIMER_TCR_CEN | TIMER_TCR_CRST;
reset.second_tcr = TIMER_TCR_CEN;
timer_dma_lli.src = (uint32_t) & (reset);
timer_dma_lli.dest = (uint32_t) & (TIMER2_TCR);
timer_dma_lli.next_lli = (uint32_t) & (timer_dma_lli);
timer_dma_lli.control = GPDMA_CCONTROL_TRANSFERSIZE(2) |
GPDMA_CCONTROL_SBSIZE(0) // 1
| GPDMA_CCONTROL_DBSIZE(0) // 1
| GPDMA_CCONTROL_SWIDTH(2) // 32-bit word
| GPDMA_CCONTROL_DWIDTH(2) // 32-bit word
| GPDMA_CCONTROL_S(0) // AHB Master 0
| GPDMA_CCONTROL_D(1) // AHB Master 1
| GPDMA_CCONTROL_SI(1) // increment source
| GPDMA_CCONTROL_DI(0) // do not increment destination
| GPDMA_CCONTROL_PROT1(0) // user mode
| GPDMA_CCONTROL_PROT2(0) // not bufferable
| GPDMA_CCONTROL_PROT3(0) // not cacheable
| GPDMA_CCONTROL_I(0); // interrupt disabled
gpdma_controller_enable();
GPDMA_C0SRCADDR = timer_dma_lli.src;
GPDMA_C0DESTADDR = timer_dma_lli.dest;
GPDMA_C0LLI = timer_dma_lli.next_lli;
GPDMA_C0CONTROL = timer_dma_lli.control;
GPDMA_C0CONFIG = GPDMA_CCONFIG_DESTPERIPHERAL(0x3) // T1_MAT0
| GPDMA_CCONFIG_FLOWCNTRL(1) // memory-to-peripheral
| GPDMA_CCONFIG_H(0); // do not halt
gpdma_channel_enable(0);

/* start counting */
timer_reset(TIMER2);
timer_reset(TIMER1);
timer_enable_counter(TIMER2);
timer_enable_counter(TIMER1);
}

uint32_t clkin_frequency(void)
{
return TIMER2_CR3 * (1000 / MEASUREMENT_WINDOW_MS);
};
30 changes: 30 additions & 0 deletions firmware/common/clkin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2022 Great Scott Gadgets
*
* 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.
*/

#ifndef __CLKIN_H__
#define __CLKIN_H__

#include <stdint.h>

void clkin_detect_init(void);
uint32_t clkin_frequency(void);

#endif //__CLKIN_H__
2 changes: 1 addition & 1 deletion firmware/common/firmware_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#ifdef JAWBREAKER
#define SUPPORTED_PLATFORM PLATFORM_JAWBREAKER
#elif HACKRF_ONE
#define SUPPORTED_PLATFORM PLATFORM_HACKRF1_OG
#define SUPPORTED_PLATFORM (PLATFORM_HACKRF1_OG | PLATFORM_HACKRF1_R9)
#elif RAD1O
#define SUPPORTED_PLATFORM PLATFORM_RAD1O
#else
Expand Down
Loading

0 comments on commit 6f1cee1

Please sign in to comment.