WIP
This commit is contained in:
parent
f21e9797a2
commit
2e7724b960
6 changed files with 103 additions and 56 deletions
|
|
@ -14,7 +14,7 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
CUBE_PATH ?= $(wildcard ~)/resource/STM32CubeF0
|
||||
CUBE_PATH ?= $(wildcard ~)/ref/stm32cube/STM32CubeF0
|
||||
CMSIS_PATH ?= $(CUBE_PATH)/Drivers/CMSIS
|
||||
CMSIS_DEV_PATH ?= $(CMSIS_PATH)/Device/ST/STM32F0xx
|
||||
HAL_PATH ?= $(CUBE_PATH)/Drivers/STM32F0xx_HAL_Driver
|
||||
|
|
|
|||
|
|
@ -194,9 +194,7 @@ void receive_bit(struct bit_detector_st *st, int bit) {
|
|||
st->sync = 0;
|
||||
/* Fall through so we also pass the error to receive_symbol */
|
||||
|
||||
GPIOA->BSRR = 1<<9; /* debug */
|
||||
receive_symbol(&st->rx_st, symbol);
|
||||
GPIOA->BRR = 1<<9; /* debug */
|
||||
|
||||
/* Exceedingly handy piece of debug code: The Debug Scope 2000 (TM) */
|
||||
/*
|
||||
|
|
@ -262,7 +260,6 @@ void bit_detector(struct bit_detector_st *st, int a) {
|
|||
}
|
||||
|
||||
void DMA1_Channel1_IRQHandler(void) {
|
||||
GPIOA->BSRR = 1<<5;
|
||||
/* ISR timing measurement for debugging */
|
||||
//int start = SysTick->VAL;
|
||||
|
||||
|
|
@ -304,6 +301,5 @@ void DMA1_Channel1_IRQHandler(void) {
|
|||
tdiff += SysTick->LOAD;
|
||||
st.dma_isr_duration = tdiff;
|
||||
*/
|
||||
GPIOA->BRR = 1<<5;
|
||||
}
|
||||
|
||||
|
|
|
|||
139
center_fw/main.c
139
center_fw/main.c
|
|
@ -30,11 +30,12 @@ void TIM1_BRK_UP_TRG_COM_Handler() {
|
|||
}
|
||||
|
||||
void set_drv_gpios(uint8_t val) {
|
||||
int a=!!(val&1), b=!!(val&2), c=!!(val&4), d=!!(val&8);
|
||||
GPIOA->BSRR = ((!a<<3 | !b<<7 | c<<6 | d<<4)<<16) | (a<<3 | b<<7 | !c<<6 | !d<<4);
|
||||
val = ~val;
|
||||
int a=!(val&1), b=!(val&2), c=!(val&4), d=!(val&8);
|
||||
GPIOA->BSRR = (((!a)<<3 | (!b)<<7 | (!c)<<6 | (!d)<<4)<<16) | ((a<<3) | (b<<7) | (c<<6) | (d<<4));
|
||||
}
|
||||
|
||||
uint8_t out_state = 0x01;
|
||||
uint8_t out_state = 0x0f;
|
||||
void set_outputs(uint8_t val[8]) {
|
||||
/* TODO implement BCM for digital brightness control */
|
||||
int x = 0;
|
||||
|
|
@ -56,111 +57,157 @@ void set_load(bool load) {
|
|||
}
|
||||
|
||||
void blank(void) {
|
||||
GPIOA->BRR = (1<<9) | (1<<10);
|
||||
set_drv_gpios(0);
|
||||
}
|
||||
|
||||
volatile int bit; /* FIXME */
|
||||
void unblank_low(void) {
|
||||
bool has_sync = 0;
|
||||
void unblank_low(int bit) {
|
||||
if (backchannel_frame) { /* Set from protocol.c */
|
||||
if (tx_next_bit() == 1)
|
||||
set_load(1);
|
||||
else /* 0; but also TX_IDLE */
|
||||
set_load(0);
|
||||
|
||||
} else {
|
||||
if (bit)
|
||||
} else if (has_sync) {
|
||||
if (bit) {
|
||||
//GPIOA->BSRR = (1<<10);
|
||||
set_drv_gpios(out_state & 0xf);
|
||||
else
|
||||
|
||||
} else {
|
||||
//GPIOA->BSRR = (1<<9);
|
||||
set_drv_gpios(out_state >> 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sync_ctr = 0xffff;
|
||||
void TIM3_IRQHandler(void) {
|
||||
GPIOA->BSRR = 1<<10; /* debug */
|
||||
if (TIM3->SR & TIM_SR_UIF)
|
||||
unblank_low();
|
||||
else
|
||||
if (TIM3->SR & TIM_SR_CC2IF) {
|
||||
if (sync_ctr > 10)
|
||||
has_sync = 0;
|
||||
else
|
||||
sync_ctr += 1;
|
||||
EXTI->IMR = (1<<0);
|
||||
GPIOB->BSRR = (1<<1);
|
||||
GPIOA->BRR = (1<<9) | (1<<10);
|
||||
|
||||
} else if (TIM3->SR & TIM_SR_CC3IF) {
|
||||
int bit = GPIOA->IDR & (1<<5); /* Sample current polarity */
|
||||
unblank_low(!bit);
|
||||
|
||||
} else {
|
||||
blank();
|
||||
}
|
||||
|
||||
TIM3->SR = 0;
|
||||
GPIOA->BRR = 1<<10; /* debug */
|
||||
}
|
||||
|
||||
void EXTI0_1_IRQHandler(void) {
|
||||
static uint32_t jitter_meas_sum = 0, jitter_meas_cnt = 0;
|
||||
EXTI->PR = (1<<0);
|
||||
|
||||
/* Store old counter value for jitter measurement. Let it overflow to handle negative offsets. */
|
||||
int16_t cnt = (int16_t)TIM3->CNT;
|
||||
/* Re-initialize the counter to align it with the signal edge */
|
||||
TIM3->EGR |= TIM_EGR_UG;
|
||||
|
||||
/* Don't handle overflow of _sum here since this value is only for monitoring anyway */
|
||||
jitter_meas_sum += (cnt >= 0) ? cnt : -cnt;
|
||||
if (++jitter_meas_cnt == 1000) { /* One measurement roughly every 800ms */
|
||||
jitter_meas_avg_ns = jitter_meas_sum;
|
||||
}
|
||||
|
||||
EXTI->IMR = 0;
|
||||
GPIOB->BRR = (1<<1);
|
||||
has_sync = 1;
|
||||
sync_ctr = 0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while (!(RCC->CR&RCC_CR_HSERDY));
|
||||
//RCC->CR |= RCC_CR_HSEON;
|
||||
//while (!(RCC->CR&RCC_CR_HSERDY));
|
||||
RCC->CFGR &= ~RCC_CFGR_PLLMUL_Msk & ~RCC_CFGR_SW_Msk & ~RCC_CFGR_PPRE_Msk & ~RCC_CFGR_HPRE_Msk;
|
||||
RCC->CFGR |= ((6-2)<<RCC_CFGR_PLLMUL_Pos) | RCC_CFGR_PLLSRC_HSE_PREDIV; /* PLL x6 -> 48.0MHz */
|
||||
RCC->CFGR |= ((12-2)<<RCC_CFGR_PLLMUL_Pos); /* PLL / 2 * 12 -> 48.0MHz */
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while (!(RCC->CR&RCC_CR_PLLRDY));
|
||||
RCC->CFGR |= (2<<RCC_CFGR_SW_Pos);
|
||||
SystemCoreClockUpdate();
|
||||
//SysTick_Config(SystemCoreClock/1000); /* 1ms interval */
|
||||
SysTick_Config(SystemCoreClock/1000); /* 1ms interval */
|
||||
|
||||
/* Turn on lots of neat things */
|
||||
RCC->AHBENR |= RCC_AHBENR_DMAEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_FLITFEN;
|
||||
RCC->AHBENR |= RCC_AHBENR_DMAEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_FLITFEN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_ADCEN| RCC_APB2ENR_DBGMCUEN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_TIM1EN;;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
|
||||
/* TIM3 foo */
|
||||
TIM3->CCMR2 = (6<<TIM_CCMR2_OC4M_Pos); /* PWM Mode 1 to get a clean trigger signal */
|
||||
TIM3->CCER = TIM_CCER_CC4E; /* Enable capture/compare unit 4 connected to ADC */
|
||||
TIM3->CCER = TIM_CCER_CC3E; /* Enable capture/compare unit 3 for unblank interrupt */
|
||||
TIM3->CCER = TIM_CCER_CC2E;
|
||||
|
||||
TIM3->PSC = 48-1; /* 48MHz -> 1MHz */
|
||||
TIM3->CCR4 = 170-1; /* CC4 is ADC trigger, fire 30us before end of cycle. */
|
||||
TIM3->ARR = 200-1; /* 1MHz -> 5kHz */
|
||||
TIM3->CCR2 = 800-1-1;
|
||||
TIM3->CCR3 = 100-1; /* CC3 is used for unblanking in the ISR, fires 30us after beginning of cycle. */
|
||||
TIM3->CCR4 = 800-100-1; /* CC4 is ADC trigger, fire 30us before end of cycle. */
|
||||
TIM3->ARR = 800-1; /* 1MHz -> 5kHz */
|
||||
|
||||
TIM3->DIER |= TIM_DIER_UIE | TIM_DIER_CC4IE;
|
||||
TIM3->DIER |= TIM_DIER_CC2IE | TIM_DIER_CC3IE | TIM_DIER_CC4IE | TIM_DIER_UIE;
|
||||
|
||||
TIM3->CR1 |= TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(TIM3_IRQn);
|
||||
NVIC_SetPriority(TIM3_IRQn, 3<<5);
|
||||
|
||||
GPIOB->MODER |= (1<<GPIO_MODER_MODER1_Pos);
|
||||
GPIOB->OSPEEDR |= (2<<GPIO_OSPEEDR_OSPEEDR1_Pos);
|
||||
|
||||
EXTI->IMR = (1<<0); /* PA0 Vmeas_A for sync */
|
||||
EXTI->RTSR |= (1<<0);
|
||||
NVIC_EnableIRQ(EXTI0_1_IRQn);
|
||||
NVIC_SetPriority(EXTI0_1_IRQn, 4<<5);
|
||||
|
||||
GPIOA->MODER |=
|
||||
(0<<GPIO_MODER_MODER0_Pos) /* PA0 - Vmeas_A to ADC */
|
||||
| (0<<GPIO_MODER_MODER1_Pos) /* PA1 - Vmeas_B to ADC */
|
||||
| (0<<GPIO_MODER_MODER1_Pos) /* PA1 - Unused */
|
||||
| (1<<GPIO_MODER_MODER2_Pos) /* PA2 - LOAD */
|
||||
| (1<<GPIO_MODER_MODER3_Pos) /* PA3 - CH0 */
|
||||
| (1<<GPIO_MODER_MODER4_Pos) /* PA4 - CH3 */
|
||||
| (1<<GPIO_MODER_MODER5_Pos) /* PA5 - TP1 */
|
||||
| (0<<GPIO_MODER_MODER5_Pos) /* PA5 - TP1 */
|
||||
| (1<<GPIO_MODER_MODER6_Pos) /* PA6 - CH2 */
|
||||
| (1<<GPIO_MODER_MODER7_Pos) /* PA7 - CH1 */
|
||||
| (1<<GPIO_MODER_MODER9_Pos) /* PA9 - TP2 */
|
||||
| (1<<GPIO_MODER_MODER10_Pos);/* PA10 - TP3 */
|
||||
| (1<<GPIO_MODER_MODER9_Pos) /* PA9 - synchronous rectifier bypass A */
|
||||
| (1<<GPIO_MODER_MODER10_Pos);/* PA10 - synchronous rectifier bypass B */
|
||||
|
||||
GPIOA->PUPDR |= (2<<GPIO_PUPDR_PUPDR5_Pos);
|
||||
|
||||
/* Set shift register IO GPIO output speed */
|
||||
GPIOA->OSPEEDR |=
|
||||
(2<<GPIO_OSPEEDR_OSPEEDR2_Pos) /* LOAD */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR3_Pos) /* CH0 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR4_Pos) /* CH3 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR4_Pos) /* CH3 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR6_Pos) /* CH2 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR7_Pos); /* CH1 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR7_Pos) /* CH1 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR9_Pos) /* synchronous rectifier bypass A */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR10_Pos); /* synchronous rectifier bypass B */
|
||||
|
||||
set_drv_gpios(0);
|
||||
|
||||
protocol_init();
|
||||
|
||||
uint32_t jitter_meas_sum = 0, jitter_meas_cnt = 0;
|
||||
int cnt = 0;
|
||||
int seg_c = 0;
|
||||
while (42) {
|
||||
int new = GPIOA->IDR & (1<<0); /* Sample current polarity */
|
||||
if (new != bit) { /* Zero-crossing detected */
|
||||
bit = new;
|
||||
|
||||
/* Store old counter value for jitter measurement. Let it overflow to handle negative offsets. */
|
||||
int16_t cnt = (int16_t)TIM3->CNT;
|
||||
/* Re-initialize the counter to align it with the signal edge */
|
||||
TIM3->EGR |= TIM_EGR_UG;
|
||||
/* Unblank since the update interrupt will not fire this time */
|
||||
unblank_low();
|
||||
|
||||
/* Don't handle overflow of _sum here since this value is only for monitoring anyway */
|
||||
jitter_meas_sum += (cnt >= 0) ? cnt : -cnt;
|
||||
if (++jitter_meas_cnt == 4000) { /* One measurement roughly every 800ms */
|
||||
/* Divide aggregate over 4000 us-resolution measurements by 4 -> ns-resolution average */
|
||||
uint32_t divided = jitter_meas_sum>>2;
|
||||
jitter_meas_avg_ns = (divided < UINT16_MAX) ? divided : UINT16_MAX;
|
||||
}
|
||||
/*
|
||||
if (cnt > 10000) {
|
||||
cnt = 0;
|
||||
seg_c += 1;
|
||||
if (seg_c == 8)
|
||||
seg_c = 0;
|
||||
set_outputs_binary(1<<seg_c, 255);
|
||||
} else {
|
||||
cnt = cnt+1;
|
||||
}
|
||||
*/
|
||||
/* idle */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ source [find interface/stlink-v2.cfg]
|
|||
#transport select swd
|
||||
|
||||
#source /usr/share/openocd/scripts/target/stm32f0x.cfg
|
||||
source [find target/stm32f0x_stlink.cfg]
|
||||
source [find target/stm32f0x.cfg]
|
||||
|
||||
init
|
||||
arm semihosting enable
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ static int flipbits10(int in) {
|
|||
|
||||
}
|
||||
|
||||
uint8_t spinner = 0; /* FIXME DEBUG */
|
||||
|
||||
int main(void) {
|
||||
/* Startup code */
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
|
|
@ -220,6 +222,7 @@ int main(void) {
|
|||
while (42) {
|
||||
if (sys_flag_1Hz) { /* Update display every second */
|
||||
sys_flag_1Hz = 0;
|
||||
spinner = ~spinner;
|
||||
|
||||
char buf[17];
|
||||
int temp = mcp9801_read_mdegC();
|
||||
|
|
@ -252,8 +255,9 @@ int hamming_weight(int i) {
|
|||
void TIM3_IRQHandler() {
|
||||
static int txpos = -1;
|
||||
static unsigned int tx_start_tick = 0;
|
||||
static uint8_t txbuf[2] = {0x04, 0x05};
|
||||
static uint8_t txbuf[3] = {0x05, 0x01, 0};
|
||||
static int backchannel_counter = 0;
|
||||
txbuf[2] = spinner;
|
||||
|
||||
TIM3->SR &= ~TIM_SR_UIF;
|
||||
int sym = txstate.current_symbol;
|
||||
|
|
@ -294,7 +298,7 @@ void TIM3_IRQHandler() {
|
|||
txstate.current_symbol = sym;
|
||||
|
||||
/* FIXME factor out into header, or even make configurable */
|
||||
#define DEAD_TIME 100
|
||||
#define DEAD_TIME 1
|
||||
/* Set both CCRs to values for opposing polarities. The dead time is always inserted at the beginning of the timer
|
||||
* cycle due to the way the capture/compare unit PWM machinery works. By setting the CCR to 0xffff we make sure the
|
||||
* output is never turned on, since 0xffff is larger than the ARR/counter top value.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
telnet_port 4444
|
||||
gdb_port 3333
|
||||
|
||||
source [find interface/stlink-v2.cfg]
|
||||
#hla_serial "000000000001"
|
||||
source [find interface/stlink.cfg]
|
||||
hla_serial "54FF6B064987495026541187"
|
||||
transport select hla_swd
|
||||
|
||||
source [find target/stm32f0x.cfg]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue