mirror of
https://github.com/livingcomputermuseum/UniBone.git
synced 2026-03-09 04:09:21 +00:00
PRU1: multiple parallel timeouts
This commit is contained in:
@@ -75,6 +75,7 @@ OBJECTS_COMMON= \
|
||||
$(OBJ_DIR)/pru1_statemachine_intr.object \
|
||||
$(OBJ_DIR)/pru1_statemachine_powercycle.object \
|
||||
$(OBJ_DIR)/pru1_statemachine_slave.object \
|
||||
$(OBJ_DIR)/pru1_timeouts.object \
|
||||
$(OBJ_DIR)/pru1_utils.object
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "resource_table_empty.h"
|
||||
|
||||
#include "pru1_utils.h"
|
||||
#include "pru1_timeouts.h"
|
||||
|
||||
#include "pru_pru_mailbox.h"
|
||||
#include "mailbox.h"
|
||||
@@ -67,6 +68,8 @@ void main(void) {
|
||||
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
|
||||
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
|
||||
|
||||
timeout_init() ;
|
||||
|
||||
// clear all tables, as backup if ARM fails todo
|
||||
iopageregisters_init();
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "resource_table_empty.h"
|
||||
|
||||
#include "pru1_utils.h"
|
||||
#include "pru1_timeouts.h"
|
||||
|
||||
#include "pru_pru_mailbox.h"
|
||||
#include "mailbox.h"
|
||||
@@ -88,6 +89,8 @@ void main(void) {
|
||||
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
|
||||
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
|
||||
|
||||
timeout_init() ;
|
||||
|
||||
// clear all tables, as backup if ARM fails todo
|
||||
iopageregisters_init();
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "mailbox.h"
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_utils.h"
|
||||
#include "pru1_timeouts.h"
|
||||
|
||||
#include "pru1_statemachine_arbitration.h"
|
||||
#include "pru1_statemachine_dma.h"
|
||||
@@ -184,7 +185,7 @@ static statemachine_state_func sm_dma_state_1() {
|
||||
} else {
|
||||
// DATO to external slave
|
||||
// wait for a slave SSYN
|
||||
TIMEOUT_SET(NANOSECS(1000*UNIBUS_TIMEOUT_PERIOD_US));
|
||||
timeout_set(TIMEOUT_DMA, MICROSECS(UNIBUS_TIMEOUT_PERIOD_US));
|
||||
return (statemachine_state_func)&sm_dma_state_21; // wait SSYN DATAO
|
||||
}
|
||||
} else {
|
||||
@@ -230,7 +231,7 @@ static statemachine_state_func sm_dma_state_1() {
|
||||
} else {
|
||||
// DATI to external slave
|
||||
// wait for a slave SSYN
|
||||
TIMEOUT_SET(NANOSECS(1000*UNIBUS_TIMEOUT_PERIOD_US));
|
||||
timeout_set(TIMEOUT_DMA, MICROSECS(UNIBUS_TIMEOUT_PERIOD_US));
|
||||
return (statemachine_state_func)&sm_dma_state_11; // wait SSYN DATI
|
||||
}
|
||||
}
|
||||
@@ -239,7 +240,7 @@ static statemachine_state_func sm_dma_state_1() {
|
||||
// DATI to external slave: MSYN set, wait for SSYN or timeout
|
||||
static statemachine_state_func sm_dma_state_11() {
|
||||
uint16_t tmpval;
|
||||
sm_dma.state_timeout = TIMEOUT_REACHED;
|
||||
sm_dma.state_timeout = timeout_reached(TIMEOUT_DMA);
|
||||
// SSYN = latch[4], bit 5
|
||||
if (!sm_dma.state_timeout && !(buslatches_getbyte(4) & BIT(5)))
|
||||
return (statemachine_state_func)&sm_dma_state_11; // no SSYN yet: wait
|
||||
@@ -262,7 +263,7 @@ static statemachine_state_func sm_dma_state_11() {
|
||||
|
||||
// DATO to external slave: wait for SSYN or timeout
|
||||
static statemachine_state_func sm_dma_state_21() {
|
||||
sm_dma.state_timeout = TIMEOUT_REACHED; // SSYN timeout?
|
||||
sm_dma.state_timeout = timeout_reached(TIMEOUT_DMA); // SSYN timeout?
|
||||
// SSYN = latch[4], bit 5
|
||||
if (!sm_dma.state_timeout && !(buslatches_getbyte(4) & BIT(5)))
|
||||
return (statemachine_state_func)&sm_dma_state_21; // no SSYN yet: wait
|
||||
@@ -314,6 +315,7 @@ static statemachine_state_func sm_dma_state_99() {
|
||||
// remove BBSY: latch[1], bit 6
|
||||
buslatches_setbits(1, BIT(6), 0);
|
||||
// SACK already de-asserted at wordcount==1
|
||||
timeout_cleanup(TIMEOUT_DMA) ;
|
||||
mailbox.dma.cur_status = final_dma_state; // signal to ARM
|
||||
return NULL; // now stopped
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "mailbox.h"
|
||||
#include "pru1_utils.h"
|
||||
#include "pru1_timeouts.h"
|
||||
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_statemachine_init.h"
|
||||
@@ -66,7 +67,7 @@ static statemachine_state_func sm_init_state_1(void);
|
||||
|
||||
// setup
|
||||
statemachine_state_func sm_init_start() {
|
||||
TIMEOUT_SET(MILLISECS(INITPULSE_DELAY_MS))
|
||||
timeout_set(TIMEOUT_INIT, MILLISECS(INITPULSE_DELAY_MS))
|
||||
;
|
||||
// INIT: latch[7], bit 3
|
||||
buslatches_setbits(7, BIT(3), BIT(3)); // assert INIT
|
||||
@@ -77,9 +78,10 @@ statemachine_state_func sm_init_start() {
|
||||
|
||||
|
||||
static statemachine_state_func sm_init_state_1() {
|
||||
if (!TIMEOUT_REACHED)
|
||||
if (!timeout_reached(TIMEOUT_INIT))
|
||||
return (statemachine_state_func)&sm_init_state_1; // wait
|
||||
buslatches_setbits(7, BIT(3), 0); // deassert INIT
|
||||
do_event_initializationsignals() ;
|
||||
timeout_cleanup(TIMEOUT_INIT) ;
|
||||
return NULL ; // ready
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
#include "mailbox.h"
|
||||
#include "pru1_utils.h"
|
||||
#include "pru1_timeouts.h"
|
||||
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_statemachine_init.h"
|
||||
@@ -69,8 +70,7 @@ statemachine_state_func sm_powercycle_start() {
|
||||
// "Line power shutdown": assert ACLO, then wait
|
||||
static statemachine_state_func sm_powercycle_state_1() {
|
||||
buslatches_setbits(7, BIT(4), BIT(4)); // ACLO asserted
|
||||
TIMEOUT_SET(MILLISECS(POWERCYCLE_DELAY_MS))
|
||||
; // wait for DC power shutdown
|
||||
timeout_set(TIMEOUT_POWERCYCLE, MILLISECS(POWERCYCLE_DELAY_MS)) ; // wait for DC power shutdown
|
||||
// DEBUG_OUT(0x01) ;
|
||||
do_event_initializationsignals() ;
|
||||
// DEBUG_OUT(0x02) ;
|
||||
@@ -79,10 +79,10 @@ static statemachine_state_func sm_powercycle_state_1() {
|
||||
|
||||
// "Power supply switched off": assert DCLO, then wait
|
||||
static statemachine_state_func sm_powercycle_state_2() {
|
||||
if (!TIMEOUT_REACHED)
|
||||
if (!timeout_reached(TIMEOUT_POWERCYCLE))
|
||||
return (statemachine_state_func)&sm_powercycle_state_2; // wait
|
||||
buslatches_setbits(7, BIT(5), BIT(5)); // DCLO asserted
|
||||
TIMEOUT_SET(MILLISECS(POWERCYCLE_DELAY_MS))
|
||||
timeout_set(TIMEOUT_POWERCYCLE, MILLISECS(POWERCYCLE_DELAY_MS))
|
||||
; // system powered off
|
||||
// DEBUG_OUT(0x03) ;
|
||||
do_event_initializationsignals() ;
|
||||
@@ -92,10 +92,10 @@ static statemachine_state_func sm_powercycle_state_2() {
|
||||
|
||||
// "Line power back again": deassert ACLO, then wait
|
||||
static statemachine_state_func sm_powercycle_state_3() {
|
||||
if (!TIMEOUT_REACHED)
|
||||
if (!timeout_reached(TIMEOUT_POWERCYCLE))
|
||||
return (statemachine_state_func)&sm_powercycle_state_3; // wait
|
||||
buslatches_setbits(7, BIT(4), 0); // ACLO deasserted
|
||||
TIMEOUT_SET(MILLISECS(POWERCYCLE_DELAY_MS))
|
||||
timeout_set(TIMEOUT_POWERCYCLE, MILLISECS(POWERCYCLE_DELAY_MS))
|
||||
; // "power supply stabilizing"
|
||||
do_event_initializationsignals() ;
|
||||
return (statemachine_state_func)&sm_powercycle_state_4;
|
||||
@@ -103,10 +103,11 @@ static statemachine_state_func sm_powercycle_state_3() {
|
||||
|
||||
// "Logic power stabilized": deassert DCLO, ready
|
||||
static statemachine_state_func sm_powercycle_state_4() {
|
||||
if (!TIMEOUT_REACHED)
|
||||
if (!timeout_reached(TIMEOUT_POWERCYCLE))
|
||||
return (statemachine_state_func)&sm_powercycle_state_4;
|
||||
buslatches_setbits(7, BIT(5), 0); // DCLO deasserted
|
||||
do_event_initializationsignals() ;
|
||||
timeout_cleanup(TIMEOUT_POWERCYCLE) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
117
10.01_base/2_src/pru1/pru1_timeouts.c
Normal file
117
10.01_base/2_src/pru1/pru1_timeouts.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* pru1_timeouts.c: timeout conditions
|
||||
|
||||
Copyright (c) 2019, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
3-jul-2019 JH begin edit
|
||||
|
||||
Several timers are needed, but PRU hs only one
|
||||
global cycle counter CYCLEOUNT. It is 32 bit and runs at 200 MHz,
|
||||
so rollaround every 21 seconds.
|
||||
|
||||
Usage:
|
||||
- if no timer is running, the first "timeout" reuqest clears CYCLEOUNT
|
||||
- for each timer, the "timeout" cycle count is set
|
||||
- tiemr msut be polled for timeout by user.
|
||||
- a timer is considered "timed-out", if its timeout is 0.
|
||||
- a global variable regsiteres the active running timeouts.
|
||||
- a running timeout MUST be canceled, or polled until "timeout_rechaed" !!
|
||||
|
||||
|
||||
The PRU CYCLECOUNT may not be reset if one timeout is active.
|
||||
So the total run time of all parallel running timeous must not exceed 21 seconds
|
||||
At least every 21 seconds all timers must be expired.
|
||||
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pru1_utils.h"
|
||||
#include "pru1_timeouts.h" // own
|
||||
|
||||
// count running timers.
|
||||
static uint8_t timeouts_active = 0 ;
|
||||
|
||||
// cycle end count for each active timeoput.
|
||||
uint32_t timeout_target_cycles[TIMEOUT_COUNT] ;
|
||||
|
||||
// all functions receive a pointer to one of these array members
|
||||
|
||||
|
||||
|
||||
#define TIMEOUT_INTERNAL_CYCLES 24
|
||||
|
||||
void timeout_set(uint32_t *target_cycles_var, uint32_t delta_cycles) {
|
||||
// stop timeout, if already running
|
||||
if (*target_cycles_var > 0) {
|
||||
*target_cycles_var = 0 ;
|
||||
timeouts_active-- ; // was inactive
|
||||
}
|
||||
|
||||
if (timeouts_active == 0) {
|
||||
// must see this regulary, else count logic damaged!
|
||||
// DEBUG_PIN_SET(1) ;
|
||||
// first timeout: clear and restart counter
|
||||
PRU1_CTRL.CTRL_bit.CTR_EN = 0;
|
||||
PRU1_CTRL.CYCLE = 0 ;
|
||||
}
|
||||
|
||||
/* 4 cycle used in TIMEOUT_REACHED */
|
||||
if (delta_cycles < TIMEOUT_INTERNAL_CYCLES)
|
||||
delta_cycles = 0 ;
|
||||
else delta_cycles -= TIMEOUT_INTERNAL_CYCLES ;
|
||||
*target_cycles_var = PRU1_CTRL.CYCLE + delta_cycles ;
|
||||
PRU1_CTRL.CTRL_bit.CTR_EN = 1;
|
||||
timeouts_active++ ; // now one more active
|
||||
}
|
||||
|
||||
// msut be called, if timeout polled anymore for "timeout-reached()
|
||||
void timeout_cleanup(uint32_t *target_cycles_var) {
|
||||
if (*target_cycles_var > 0) {
|
||||
*target_cycles_var = 0 ;
|
||||
timeouts_active-- ; // was inactive
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// test a timeout, wehter it reached its arg count nor or earlier
|
||||
bool timeout_reached(uint32_t *target_cycles_var) {
|
||||
// fast path: assume timeout_reached() is called
|
||||
// because timeout is active
|
||||
if ( PRU1_CTRL.CYCLE < *target_cycles_var)
|
||||
return false ;
|
||||
else if (*target_cycles_var == 0)
|
||||
return true ; // already inactive
|
||||
else {
|
||||
// switched from "running" to "timeout reached"
|
||||
*target_cycles_var = 0 ;
|
||||
timeouts_active-- ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void timeout_init(void) {
|
||||
timeouts_active = 0 ;
|
||||
memset(timeout_target_cycles, 0, sizeof(uint32_t) * TIMEOUT_COUNT) ;
|
||||
}
|
||||
52
10.01_base/2_src/pru1/pru1_timeouts.h
Normal file
52
10.01_base/2_src/pru1/pru1_timeouts.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* pru1_timeouts.h: timeout conditions
|
||||
|
||||
Copyright (c) 2019, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
3-jul-2019 JH begin edit
|
||||
*/
|
||||
#ifndef _PRU1_TIMEOUTS_H_
|
||||
#define _PRU1_TIMEOUTS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
// predefined timeouts
|
||||
#define TIMEOUT_COUNT 3
|
||||
|
||||
// fixed pointers
|
||||
#define TIMEOUT_DMA (&timeout_target_cycles[0])
|
||||
#define TIMEOUT_INIT (&timeout_target_cycles[1])
|
||||
#define TIMEOUT_POWERCYCLE (&timeout_target_cycles[2])
|
||||
|
||||
|
||||
// cycle end count for each active timeoput.
|
||||
extern uint32_t timeout_target_cycles[TIMEOUT_COUNT] ;
|
||||
|
||||
// call all functions mit timeout_func(TIMEOUT_*,..)
|
||||
// This allows the compiler to optimize the timeout_target_cycles[idx] expr
|
||||
|
||||
void timeout_init(void) ;
|
||||
void timeout_set(uint32_t *target_cycles_var, uint32_t delta_cycles) ;
|
||||
bool timeout_reached(uint32_t *target_cycles_var) ;
|
||||
void timeout_cleanup(uint32_t *target_cycles_var) ;
|
||||
|
||||
#endif
|
||||
@@ -96,17 +96,6 @@ http://theembeddedkitchen.net/beaglelogic-building-a-logic-analyzer-with-the-pru
|
||||
* introduces delay in PRU0 outputs!
|
||||
|
||||
*/
|
||||
#define TIMEOUT_INTERNAL_CYCLES 24
|
||||
#define TIMEOUT_SET(cycles) do { \
|
||||
PRU1_CTRL.CTRL_bit.CTR_EN = 0; \
|
||||
PRU1_CTRL.CYCLE = 0 ; \
|
||||
timeout_target = ((cycles) > TIMEOUT_INTERNAL_CYCLES) ? ((cycles) - TIMEOUT_INTERNAL_CYCLES) : 0 ; /* 4 cycle used in TIMEOUT_REACHED */ \
|
||||
PRU1_CTRL.CTRL_bit.CTR_EN = 1; \
|
||||
} while(0)
|
||||
|
||||
#define TIMEOUT_REACHED \
|
||||
( (PRU1_CTRL.CYCLE >= timeout_target))
|
||||
|
||||
|
||||
// set PRU1_12 to 0 or 1
|
||||
#define DEBUG_PIN_SET(val) ( (val) ? (__R30 |= (1 << 12) ) : (__R30 &= ~(1<< 12)) )
|
||||
|
||||
Reference in New Issue
Block a user