mirror of
https://github.com/livingcomputermuseum/UniBone.git
synced 2026-01-11 23:52:51 +00:00
PRU statemachines easier to control from main thread
This commit is contained in:
parent
e23b2cf4d3
commit
04869fb46f
@ -46,7 +46,8 @@ CFLAGS_OPTIMIZER=--opt_level=3 --opt_for_speed=5 --auto_inline --c_src_interli
|
||||
#CFLAGS_OPTIMIZER=--opt_level=3 --auto_inline --c_src_interlist --optimizer_interlist --gen_opt_info=2
|
||||
#Common compiler and linker flags (Defined in 'PRU Optimizing C/C++ Compiler User's Guide)
|
||||
CFLAGS=-v3 $(CFLAGS_OPTIMIZER) \
|
||||
--display_error_number --endian=little --hardware_mac=on --obj_directory=$(OBJ_DIR) --pp_directory=$(OBJ_DIR) -ppd -ppa
|
||||
--display_error_number --emit_warnings_as_errors --verbose_diagnostics \
|
||||
--endian=little --hardware_mac=on --obj_directory=$(OBJ_DIR) --pp_directory=$(OBJ_DIR) -ppd -ppa
|
||||
|
||||
#Linker flags (Defined in 'PRU Optimizing C/C++ Compiler User's Guide)
|
||||
LFLAGS=--reread_libs --warn_sections --stack_size=$(STACK_SIZE) --heap_size=$(HEAP_SIZE)
|
||||
|
||||
@ -56,6 +56,11 @@
|
||||
#include "pru1_statemachine_init.h"
|
||||
#include "pru1_statemachine_powercycle.h"
|
||||
|
||||
// supress warnigns about using void * as fucntion pinters
|
||||
// sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
// while (sm_slave_state = sm_slave_state()) << usage
|
||||
#pragma diag_push
|
||||
#pragma diag_remark=515
|
||||
|
||||
void main(void) {
|
||||
|
||||
@ -174,20 +179,22 @@ void main(void) {
|
||||
buslatches_powercycle();
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_DMA_ARB_NONE:
|
||||
sm_dma_start(); // without NPR/NPG arbitration
|
||||
case ARM2PRU_DMA_ARB_NONE: {
|
||||
// without NPR/NPG arbitration
|
||||
statemachine_state_func sm_dma_state = (statemachine_state_func)&sm_dma_start;
|
||||
// simply call current state function, until stopped
|
||||
// parallel the BUS-slave statemachine is triggered
|
||||
// by master logic.
|
||||
while (!sm_dma.state())
|
||||
while (sm_dma_state = sm_dma_state())
|
||||
;
|
||||
}
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_DDR_FILL_PATTERN:
|
||||
ddrmem_fill_pattern();
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_DDR_SLAVE_MEMORY:
|
||||
case ARM2PRU_DDR_SLAVE_MEMORY:
|
||||
// respond to UNIBUS cycles as slave and
|
||||
// access DDR as UNIBUS memory.
|
||||
|
||||
@ -197,9 +204,9 @@ void main(void) {
|
||||
// do UNIBUS slave cycles, until ARM abort this by
|
||||
// writing into mailbox.arm2pru_req
|
||||
while (mailbox.arm2pru_req == ARM2PRU_DDR_SLAVE_MEMORY) {
|
||||
sm_slave_start();
|
||||
statemachine_state_func sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
// do all states of an access, start when MSYN found.
|
||||
while (!sm_slave.state())
|
||||
while (sm_slave_state = sm_slave_state())
|
||||
;
|
||||
}
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
@ -207,4 +214,5 @@ void main(void) {
|
||||
} // switch
|
||||
} // while
|
||||
}
|
||||
#pragma diag_pop
|
||||
|
||||
|
||||
@ -62,7 +62,63 @@
|
||||
#include "pru1_statemachine_init.h"
|
||||
#include "pru1_statemachine_powercycle.h"
|
||||
|
||||
|
||||
|
||||
#ifdef FUNCPTRTEST
|
||||
////// TEST
|
||||
|
||||
// need a function returning a pointer to type of its own,
|
||||
// with "statemachine_state_func" as forward
|
||||
// typedef statemachine_state_func * (*statemachine_state_func)(void);
|
||||
// Not possible?! So retirn void * and cast to void *(func(void) on use
|
||||
typedef void * (*sm_state_func)(void);
|
||||
|
||||
sm_state_func sm_2(void); // forward
|
||||
|
||||
sm_state_func sm_1(void) {
|
||||
//printf("1\n");
|
||||
return (sm_state_func) &sm_2;
|
||||
}
|
||||
|
||||
statemachine_state_func sm_2(void) {
|
||||
//printf("2\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int xmain() {
|
||||
//printf("Hello world ... from " __DATE__ " " __TIME__ "!\n");
|
||||
//printf("My sizeof(long) is %u.\n", (unsigned) sizeof(long));
|
||||
|
||||
// excute 2 states indicectly
|
||||
sm_state_func smfunc = (sm_state_func) &sm_1;
|
||||
while ((smfunc = smfunc()))
|
||||
;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// supress warnigns about using void * as fucntion pinters
|
||||
// sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
// while (sm_slave_state = sm_slave_state()) << usage
|
||||
#pragma diag_push
|
||||
#pragma diag_remark=515
|
||||
|
||||
|
||||
void test(){
|
||||
while(1) {
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main(void) {
|
||||
// state function pointer for different state machines
|
||||
statemachine_state_func sm_slave_state ;
|
||||
statemachine_state_func sm_arb_state ;
|
||||
statemachine_state_func sm_dma_state ;
|
||||
statemachine_state_func sm_intr_state ;
|
||||
statemachine_state_func sm_init_state ;
|
||||
statemachine_state_func sm_powercycle_state ;
|
||||
|
||||
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
|
||||
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
|
||||
@ -96,15 +152,15 @@ void main(void) {
|
||||
// buslatches_pulse_debug ;
|
||||
|
||||
// base operation: accept and execute slave cycles
|
||||
sm_slave_start();
|
||||
|
||||
while (true) {
|
||||
uint32_t arm2pru_req_cached;
|
||||
// do all states of an access, start when MSYN found.
|
||||
|
||||
// slave cycles may trigger events to ARM, which changes "active" registers
|
||||
// and issues interrupts
|
||||
while (!sm_slave.state())
|
||||
|
||||
sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
while (sm_slave_state = sm_slave_state())
|
||||
; // execute complete slave cycle, then check NPR/INTR
|
||||
|
||||
// update state of init lines
|
||||
@ -129,9 +185,10 @@ void main(void) {
|
||||
break;
|
||||
case ARM2PRU_DMA_ARB_NONE: // ignore SACK condition
|
||||
case ARM2PRU_DMA_ARB_MASTER: // also without arbitration, TODO!
|
||||
sm_dma_start();
|
||||
while (!sm_dma.state())
|
||||
sm_dma_state = (statemachine_state_func)&sm_dma_start;
|
||||
while (sm_dma_state = sm_dma_state())
|
||||
;
|
||||
|
||||
// a dma cycle into a device register may trigger an interrupt
|
||||
// do not delete that condition
|
||||
if (mailbox.arm2pru_req == arm2pru_req_cached)
|
||||
@ -140,22 +197,24 @@ void main(void) {
|
||||
case ARM2PRU_DMA_ARB_CLIENT:
|
||||
// start DMA cycle
|
||||
// can not run parallel with INTR levels
|
||||
sm_arb_start(ARBITRATION_PRIORITY_BIT_NP);
|
||||
while (!sm_arb.state()) {
|
||||
|
||||
sm_arb_state = (statemachine_state_func)sm_arb_start(ARBITRATION_PRIORITY_BIT_NP);
|
||||
while (sm_arb_state && (sm_arb_state = sm_arb_state())) {
|
||||
// sm_slave is most time critical, as it must keep track with MSYN/SSYN bus traffic.
|
||||
// so give it more cpu cycles
|
||||
while (!sm_slave.state())
|
||||
sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
while (sm_slave_state = sm_slave_state())
|
||||
;
|
||||
}
|
||||
// now SACK held and BBSY set, slave state machine ended, since BBSY found inactive
|
||||
|
||||
// debug pin reset by bus access
|
||||
//DEBUG_PIN_SET(1) ;
|
||||
sm_dma_start();
|
||||
//DEBUG_PIN_SET(1) ;
|
||||
while (!sm_dma.state())
|
||||
sm_dma_state = (statemachine_state_func)&sm_dma_start;
|
||||
while (sm_dma_state = sm_dma_state())
|
||||
//DEBUG_PIN_SET(1) ;
|
||||
;// execute dma master cycles
|
||||
|
||||
// a dma cycle into a device register may trigger an interrupt
|
||||
// do not delete that condition
|
||||
if (mailbox.arm2pru_req == arm2pru_req_cached)
|
||||
@ -165,37 +224,49 @@ void main(void) {
|
||||
// start one INTR cycle. May be raised in midst of slave cycle
|
||||
// by ARM, if access to "active" register triggers INTR.
|
||||
// no multiple levels simultaneously allowed, not parallel with DMA !
|
||||
sm_arb_start(mailbox.intr.priority_bit);
|
||||
sm_arb_state = (statemachine_state_func)sm_arb_start(mailbox.intr.priority_bit);
|
||||
// wait while INTR is accepted. This may take long time,
|
||||
// if system is at high processor priority (PSW register)
|
||||
while (!sm_arb.state()) {
|
||||
while (sm_arb_state && (sm_arb_state = sm_arb_state())) {
|
||||
// sm_slave is most time critical, as it must keep track with MSYN/SSYN bus traffic.
|
||||
// so give it more cpu cycles
|
||||
while (!sm_slave.state())
|
||||
sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
while (sm_slave_state = sm_slave_state())
|
||||
;
|
||||
}
|
||||
|
||||
// now SACK held and BBSY set, slave state machine ended, since BBSY found inactive
|
||||
sm_intr_start();
|
||||
while (!sm_intr.state())
|
||||
sm_intr_state = (statemachine_state_func)&sm_intr_start;
|
||||
while (sm_intr_state = sm_intr_state())
|
||||
; // execute intr cycle as bus master
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // clear request
|
||||
break;
|
||||
case ARM2PRU_INITPULSE: // generate a pulse on UNIBUS INIT
|
||||
// only busmaster may assert INIT. violated here!
|
||||
sm_slave_start();
|
||||
sm_init_start();
|
||||
while (!sm_slave.state() || !sm_init.state())
|
||||
;
|
||||
|
||||
// while INIT cycle is running, do slave cycles
|
||||
sm_init_state = (statemachine_state_func)&sm_init_start;
|
||||
while(sm_init_state=sm_init_state()) {
|
||||
if (sm_slave_state)
|
||||
sm_slave_state = sm_slave_state() ;
|
||||
else // restart
|
||||
sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
}
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_POWERCYCLE: // do ACLO/DCLO power cycle
|
||||
// Runs for 4* POWERCYCLE_DELAY_MS millsecs, approx 1 sec.
|
||||
// perform slave states in parallel, so emulated memory
|
||||
// is existent for power fail trap and reboot
|
||||
sm_slave_start();
|
||||
sm_powercycle_start();
|
||||
while (!sm_slave.state() || !sm_powercycle.state())
|
||||
;
|
||||
|
||||
// while power cycle is running, do slave cycles
|
||||
sm_powercycle_state = (statemachine_state_func)&sm_powercycle_start;
|
||||
while(sm_powercycle_state=sm_powercycle_state()) {
|
||||
if (sm_slave_state)
|
||||
sm_slave_state = sm_slave_state() ;
|
||||
else // restart
|
||||
sm_slave_state = (statemachine_state_func)&sm_slave_start;
|
||||
}
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
|
||||
@ -206,4 +277,5 @@ void main(void) {
|
||||
|
||||
// never reached
|
||||
}
|
||||
#pragma diag_pop
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
Statemachine for execution of the Priority Arbitration protocol
|
||||
@ -71,6 +72,7 @@
|
||||
|
||||
#define _PRU1_STATEMACHINE_ARBITRATION_C_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pru1_utils.h"
|
||||
@ -83,61 +85,62 @@
|
||||
statemachine_arbitration_t sm_arb;
|
||||
|
||||
// forwards ;
|
||||
static uint8_t sm_arb_state_1(void);
|
||||
static uint8_t sm_arb_state_2(void);
|
||||
static uint8_t sm_arb_state_3(void);
|
||||
static uint8_t sm_arb_state_4(void);
|
||||
static statemachine_state_func sm_arb_state_1(void);
|
||||
static statemachine_state_func sm_arb_state_2(void);
|
||||
static statemachine_state_func sm_arb_state_3(void);
|
||||
|
||||
/********** NPR/NPG/SACK arbitrations **************/
|
||||
void sm_arb_start(uint8_t priority_bit) {
|
||||
statemachine_state_func sm_arb_start(uint8_t priority_bit) {
|
||||
sm_arb.priority_bit = priority_bit; // single priority bit for this arbitration process
|
||||
sm_arb.state = &sm_arb_state_1;
|
||||
return (statemachine_state_func)&sm_arb_state_1;
|
||||
}
|
||||
|
||||
// idle. call _start()
|
||||
// execute in parallel with slave!
|
||||
// pass BGIN[4-7],NPGIN to next device , if DMA engine idle
|
||||
uint8_t sm_arb_state_idle() {
|
||||
statemachine_state_func sm_arb_state_idle() {
|
||||
uint8_t tmpval;
|
||||
tmpval = buslatches_getbyte(0);
|
||||
// forward all 5 GRANT IN inverted to GRANT OUT
|
||||
buslatches_setbits(0, ARBITRATION_PRIORITY_MASK, ~tmpval)
|
||||
;
|
||||
return 1;
|
||||
return (statemachine_state_func)&sm_arb_state_idle;
|
||||
}
|
||||
|
||||
// wait for GRANT idle
|
||||
// Assert REQUEST, wait for GRANT, assert SACK, wait for NPG==0, set SACK=0 ,
|
||||
// execute in parallel with slave!
|
||||
static uint8_t sm_arb_state_1() {
|
||||
static statemachine_state_func sm_arb_state_1() {
|
||||
uint8_t tmpval;
|
||||
tmpval = buslatches_getbyte(0);
|
||||
// forward all lines, until idle
|
||||
buslatches_setbits(0, ARBITRATION_PRIORITY_MASK, ~tmpval) ;
|
||||
// wait for GRANT idle, other cycle in progress?
|
||||
if (tmpval & sm_arb.priority_bit)
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_arb_state_1; // wait
|
||||
// no need to wait for SACK: arbitrator responds only with a GRANT IN
|
||||
buslatches_setbits(1, sm_arb.priority_bit, sm_arb.priority_bit); // REQUEST = latch1
|
||||
sm_arb.state = &sm_arb_state_2; // wait for GRANT IN active
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_arb_state_2; // wait for GRANT IN active
|
||||
}
|
||||
|
||||
|
||||
|
||||
// wait for BG*,NPG or INIT
|
||||
// execute in parallel with slave!
|
||||
static uint8_t sm_arb_state_2() {
|
||||
static statemachine_state_func sm_arb_state_2() {
|
||||
uint8_t tmpval;
|
||||
|
||||
tmpval = buslatches_getbyte(0);
|
||||
if (buslatches_getbyte(7) & BIT(3)) { // INIT stops transaction: latch[7], bit 3
|
||||
// cleanup: clear all REQUESTS and SACK
|
||||
// cleanup: clear all 5 BR/NPR and SACK
|
||||
buslatches_setbits(1, ARBITRATION_PRIORITY_MASK| BIT(5), 0);
|
||||
|
||||
// forward all 5 GRANT IN inverted to GRANT OUT
|
||||
buslatches_setbits(0, ARBITRATION_PRIORITY_MASK, ~tmpval) ;
|
||||
|
||||
// Todo: signal INIT to ARM!
|
||||
sm_arb.state = &sm_arb_state_idle;
|
||||
return 0 ;
|
||||
return NULL ;
|
||||
}
|
||||
tmpval = buslatches_getbyte(0);
|
||||
// forward all other BG lines
|
||||
// preceding arbitration must see BG removed by master on SACK
|
||||
|
||||
@ -147,42 +150,36 @@ static uint8_t sm_arb_state_2() {
|
||||
buslatches_setbits(0, ARBITRATION_PRIORITY_MASK, ~tmpval); // forward all without our GRANT
|
||||
// set SACK
|
||||
buslatches_setbits(1, BIT(5), BIT(5));
|
||||
sm_arb.state = &sm_arb_state_3;
|
||||
} else
|
||||
return (statemachine_state_func)&sm_arb_state_3;
|
||||
} else {
|
||||
buslatches_setbits(0, ARBITRATION_PRIORITY_MASK, ~tmpval); // forward all
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_arb_state_2 ; // wait
|
||||
}
|
||||
}
|
||||
|
||||
// GRANT received. wait for previous bus master to complete transaction,
|
||||
// then become bus master
|
||||
// Forwarding of other GRANTs not necessary ... arbitrator granted us.
|
||||
static uint8_t sm_arb_state_3() {
|
||||
static statemachine_state_func sm_arb_state_3() {
|
||||
if (buslatches_getbyte(7) & BIT(3)) { // INIT stops transaction: latch[7], bit 3
|
||||
// cleanup: clear all REQUESTS and SACk
|
||||
buslatches_setbits(1, ARBITRATION_PRIORITY_MASK| BIT(5), 0);
|
||||
// Todo: signal INIT to ARM!
|
||||
sm_arb.state = &sm_arb_state_idle;
|
||||
return 1;
|
||||
return NULL;
|
||||
}
|
||||
if (buslatches_getbyte(0) & sm_arb.priority_bit) // wait for GRANT IN to be deasserted
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_arb_state_3; // wait
|
||||
// wait until old bus master cleared BBSY
|
||||
if (buslatches_getbyte(1) & BIT(6))
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_arb_state_3; // wait
|
||||
// wait until SSYN deasserted by old slave
|
||||
if (buslatches_getbyte(4) & BIT(5))
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_arb_state_3; // wait
|
||||
// now become new bus master: Set BBSY, Clear REQUEST
|
||||
// BBSY= bit 6
|
||||
buslatches_setbits(1, sm_arb.priority_bit | BIT(6), BIT(6));
|
||||
// SACK is cleared later in "data transfer" statemachines (DMA or INTR)
|
||||
sm_arb.state = &sm_arb_state_4; // bus mastership acquired
|
||||
return 1;
|
||||
}
|
||||
|
||||
// bus mastership acquired. DMA data transfer must terminate this state
|
||||
static uint8_t sm_arb_state_4() {
|
||||
return 1;
|
||||
return NULL; // bus mastership acquired
|
||||
}
|
||||
|
||||
#ifdef USED
|
||||
|
||||
@ -20,18 +20,15 @@
|
||||
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.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
*/
|
||||
#ifndef _PRU1_STATEMACHINE_ARBITRATION_H_
|
||||
#define _PRU1_STATEMACHINE_ARBITRATION_H_
|
||||
|
||||
|
||||
// execution of a state. return : 1, if statemachine stopped
|
||||
typedef uint8_t (*sm_arb_state_func_ptr)(void);
|
||||
#include "pru1_utils.h" // statemachine_state_func
|
||||
|
||||
typedef struct {
|
||||
sm_arb_state_func_ptr state; // current state as ptr to "state function"
|
||||
uint8_t priority_bit ; // single priority bit for this arbitration process
|
||||
// one of ARBITRATION_PRIORITY_*
|
||||
} statemachine_arbitration_t;
|
||||
@ -41,7 +38,7 @@ typedef struct {
|
||||
extern statemachine_arbitration_t sm_arb;
|
||||
#endif
|
||||
|
||||
void sm_arb_start(uint8_t priority_bit);
|
||||
uint8_t sm_arb_state_idle(void) ;
|
||||
statemachine_state_func sm_arb_start(uint8_t priority_bit);
|
||||
statemachine_state_func sm_arb_state_idle(void) ;
|
||||
|
||||
#endif
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
|
||||
@ -51,6 +52,7 @@
|
||||
*/
|
||||
#define _PRU1_STATEMACHINE_DMA_C_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@ -72,31 +74,31 @@ statemachine_dma_t sm_dma;
|
||||
|
||||
/********** Master DATA cycles **************/
|
||||
// forwards ;
|
||||
static uint8_t sm_dma_state_1(void);
|
||||
static uint8_t sm_dma_state_11(void);
|
||||
static uint8_t sm_dma_state_21(void);
|
||||
static uint8_t sm_dma_state_99(void);
|
||||
static statemachine_state_func sm_dma_state_1(void);
|
||||
static statemachine_state_func sm_dma_state_11(void);
|
||||
static statemachine_state_func sm_dma_state_21(void);
|
||||
static statemachine_state_func sm_dma_state_99(void);
|
||||
|
||||
// dma mailbox setup with
|
||||
// startaddr, wordcount, cycle, words[] ?
|
||||
// "cycle" must be UNIBUS_CONTROL_DATI or UNIBUS_CONTROL_DATO
|
||||
// BBSY already set, SACK held asserted
|
||||
void sm_dma_start() {
|
||||
statemachine_state_func sm_dma_start() {
|
||||
// assert BBSY: latch[1], bit 6
|
||||
// buslatches_setbits(1, BIT(6), BIT(6));
|
||||
|
||||
mailbox.dma.cur_addr = mailbox.dma.startaddr;
|
||||
sm_dma.dataptr = (uint16_t *) mailbox.dma.words; // point to start of data buffer
|
||||
sm_dma.state = &sm_dma_state_1;
|
||||
sm_dma.cur_wordsleft = mailbox.dma.wordcount;
|
||||
mailbox.dma.cur_status = DMA_STATE_RUNNING;
|
||||
// next call to sm_dma.state() starts state machine
|
||||
return (statemachine_state_func)&sm_dma_state_1 ;
|
||||
}
|
||||
|
||||
// place address and control bits onto bus, also data for DATO
|
||||
// If slave address is internal (= implemented by UniBone),
|
||||
// fast UNIBUS slave protocol is generated on the bus.
|
||||
static uint8_t sm_dma_state_1() {
|
||||
static statemachine_state_func sm_dma_state_1() {
|
||||
uint32_t tmpval;
|
||||
uint32_t addr = mailbox.dma.cur_addr; // non-volatile snapshot
|
||||
uint16_t data;
|
||||
@ -107,7 +109,7 @@ static uint8_t sm_dma_state_1() {
|
||||
|
||||
// should test SACK and BBSY !
|
||||
if (mailbox.dma.cur_status != DMA_STATE_RUNNING || mailbox.dma.wordcount == 0)
|
||||
return 1; // still stopped
|
||||
return NULL; // still stopped
|
||||
|
||||
|
||||
if (sm_dma.cur_wordsleft == 1) {
|
||||
@ -178,12 +180,12 @@ static uint8_t sm_dma_state_1() {
|
||||
while (mailbox.events.eventmask) ;
|
||||
|
||||
buslatches_setbits(4, BIT(5), 0); // slave deassert SSYN
|
||||
sm_dma.state = &sm_dma_state_99; // next word
|
||||
return (statemachine_state_func)&sm_dma_state_99; // next word
|
||||
} else {
|
||||
// DATO to external slave
|
||||
// wait for a slave SSYN
|
||||
TIMEOUT_SET(NANOSECS(1000*UNIBUS_TIMEOUT_PERIOD_US));
|
||||
sm_dma.state = &sm_dma_state_21; // wait SSYN DATAO
|
||||
return (statemachine_state_func)&sm_dma_state_21; // wait SSYN DATAO
|
||||
}
|
||||
} else {
|
||||
// DATI or DATIP
|
||||
@ -224,25 +226,23 @@ static uint8_t sm_dma_state_1() {
|
||||
while (mailbox.events.eventmask) ;
|
||||
|
||||
buslatches_setbits(4, BIT(5), 0); // slave deassert SSYN
|
||||
sm_dma.state = &sm_dma_state_99; // next word
|
||||
return (statemachine_state_func)&sm_dma_state_99; // next word
|
||||
} else {
|
||||
// DATI to external slave
|
||||
// wait for a slave SSYN
|
||||
TIMEOUT_SET(NANOSECS(1000*UNIBUS_TIMEOUT_PERIOD_US));
|
||||
sm_dma.state = &sm_dma_state_11; // wait SSYN DATI
|
||||
return (statemachine_state_func)&sm_dma_state_11; // wait SSYN DATI
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // still running
|
||||
}
|
||||
|
||||
// DATI to external slave: MSYN set, wait for SSYN or timeout
|
||||
static uint8_t sm_dma_state_11() {
|
||||
static statemachine_state_func sm_dma_state_11() {
|
||||
uint16_t tmpval;
|
||||
sm_dma.state_timeout = TIMEOUT_REACHED;
|
||||
// SSYN = latch[4], bit 5
|
||||
if (!sm_dma.state_timeout && !(buslatches_getbyte(4) & BIT(5)))
|
||||
return 0; // no SSYN yet: wait
|
||||
return (statemachine_state_func)&sm_dma_state_11; // no SSYN yet: wait
|
||||
// SSYN set by slave (or timeout). read data
|
||||
__delay_cycles(NANOSECS(75) - 6); // assume 2*3 cycles for buslatches_getbyte
|
||||
|
||||
@ -257,16 +257,15 @@ static uint8_t sm_dma_state_11() {
|
||||
buslatches_setbits(4, BIT(4), 0);
|
||||
// DATI: remove address,control, MSYN,SSYN from bus, 75ns after MSYN inactive
|
||||
__delay_cycles(NANOSECS(75) - 8); // assume 8 cycles for state change
|
||||
sm_dma.state = &sm_dma_state_99;
|
||||
return 0; // still running
|
||||
return (statemachine_state_func)&sm_dma_state_99;
|
||||
}
|
||||
|
||||
// DATO to external slave: wait for SSYN or timeout
|
||||
static uint8_t sm_dma_state_21() {
|
||||
static statemachine_state_func sm_dma_state_21() {
|
||||
sm_dma.state_timeout = TIMEOUT_REACHED; // SSYN timeout?
|
||||
// SSYN = latch[4], bit 5
|
||||
if (!sm_dma.state_timeout && !(buslatches_getbyte(4) & BIT(5)))
|
||||
return 0; // no SSYN yet: wait
|
||||
return (statemachine_state_func)&sm_dma_state_21; // no SSYN yet: wait
|
||||
|
||||
// SSYN set by slave (or timeout): negate MSYN, remove DATA from bus
|
||||
buslatches_setbits(4, BIT(4), 0); // deassert MSYN
|
||||
@ -274,12 +273,11 @@ static uint8_t sm_dma_state_21() {
|
||||
buslatches_setbyte(6, 0);
|
||||
// DATO: remove address,control, MSYN,SSYN from bus, 75ns after MSYN inactive
|
||||
__delay_cycles(NANOSECS(75) - 8); // assume 8 cycles for state change
|
||||
sm_dma.state = &sm_dma_state_99;
|
||||
return 0; // still running
|
||||
return (statemachine_state_func)&sm_dma_state_99;
|
||||
}
|
||||
|
||||
// word is transfered, or timeout.
|
||||
static uint8_t sm_dma_state_99() {
|
||||
static statemachine_state_func sm_dma_state_99() {
|
||||
uint8_t final_dma_state;
|
||||
// from state_12, state_21
|
||||
|
||||
@ -302,14 +300,12 @@ static uint8_t sm_dma_state_99() {
|
||||
buslatches_setbits(1, BIT(5), 0); // deassert SACK = latch[1], bit 5
|
||||
} else
|
||||
final_dma_state = DMA_STATE_RUNNING; // more words: continue
|
||||
|
||||
}
|
||||
sm_dma.state = &sm_dma_state_1; // in any case, reloop
|
||||
|
||||
if (final_dma_state == DMA_STATE_RUNNING) {
|
||||
// dataptr and wordsleft already incremented
|
||||
// dataptr and words_left already incremented
|
||||
mailbox.dma.cur_addr += 2; // signal progress to ARM
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_dma_state_1; // reloop
|
||||
} else {
|
||||
// remove addr and control from bus
|
||||
buslatches_setbyte(2, 0);
|
||||
@ -317,10 +313,9 @@ static uint8_t sm_dma_state_99() {
|
||||
buslatches_setbits(4, 0x3f, 0);
|
||||
// remove BBSY: latch[1], bit 6
|
||||
buslatches_setbits(1, BIT(6), 0);
|
||||
// terminate arbitration state
|
||||
sm_arb.state = &sm_arb_state_idle;
|
||||
// SACK already de-asserted at wordcount==1
|
||||
mailbox.dma.cur_status = final_dma_state; // signal to ARM
|
||||
return 1; // now stopped
|
||||
return NULL; // now stopped
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
*/
|
||||
|
||||
@ -28,14 +29,11 @@
|
||||
#define _PRU1_STATEMACHINE_DMA_H_
|
||||
|
||||
|
||||
|
||||
// execution of a state. return : 1, if statemachine stopped
|
||||
typedef uint8_t (*sm_dma_state_func_ptr)(void);
|
||||
#include "pru1_utils.h" // statemachine_state_func
|
||||
|
||||
|
||||
// Transfers a block of worst as data cycles
|
||||
typedef struct {
|
||||
sm_dma_state_func_ptr state; // current state as ptr to "state fucntion"
|
||||
uint8_t state_timeout; // timeout occured?
|
||||
uint16_t *dataptr ; // points to current word in mailbox.words[] ;
|
||||
uint16_t cur_wordsleft; // # of words left to transfer
|
||||
@ -48,6 +46,6 @@ extern statemachine_dma_t sm_dma;
|
||||
#endif
|
||||
|
||||
|
||||
void sm_dma_start(void) ;
|
||||
statemachine_state_func sm_dma_start(void) ;
|
||||
|
||||
#endif
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
Statemachine for a pulse on UNIBUS INIT
|
||||
@ -29,6 +30,7 @@
|
||||
|
||||
#define _PRU1_STATEMACHINE_INIT_C_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mailbox.h"
|
||||
@ -59,33 +61,25 @@ void do_event_initializationsignals() {
|
||||
|
||||
|
||||
|
||||
|
||||
statemachine_init_t sm_init;
|
||||
|
||||
// forwards
|
||||
uint8_t sm_init_state_idle(void);
|
||||
static uint8_t sm_init_state_1(void);
|
||||
static statemachine_state_func sm_init_state_1(void);
|
||||
|
||||
// setup
|
||||
void sm_init_start() {
|
||||
statemachine_state_func sm_init_start() {
|
||||
TIMEOUT_SET(MILLISECS(INITPULSE_DELAY_MS))
|
||||
;
|
||||
// INIT: latch[7], bit 3
|
||||
buslatches_setbits(7, BIT(3), BIT(3)); // assert INIT
|
||||
mailbox.events.initialization_signals_prev &= ~INITIALIZATIONSIGNAL_INIT ; // force INIT event
|
||||
do_event_initializationsignals() ;
|
||||
sm_init.state = &sm_init_state_1;
|
||||
return (statemachine_state_func)&sm_init_state_1;
|
||||
}
|
||||
|
||||
uint8_t sm_init_state_idle() {
|
||||
return 1; // ready
|
||||
}
|
||||
|
||||
static uint8_t sm_init_state_1() {
|
||||
static statemachine_state_func sm_init_state_1() {
|
||||
if (!TIMEOUT_REACHED)
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_init_state_1; // wait
|
||||
buslatches_setbits(7, BIT(3), 0); // deassert INIT
|
||||
do_event_initializationsignals() ;
|
||||
sm_init.state = &sm_init_state_idle;
|
||||
return 1;
|
||||
return NULL ; // ready
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
*/
|
||||
#ifndef _PRU1_STATEMACHINE_INIT_H_
|
||||
@ -28,24 +29,17 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "pru1_utils.h" // statemachine_state_func
|
||||
|
||||
#define INITPULSE_DELAY_MS 250 // length of INIT pulse
|
||||
|
||||
// execution of a state. return : 1, if statemachine stopped
|
||||
typedef uint8_t (*sm_powercycle_init_func_ptr)(void);
|
||||
|
||||
typedef struct {
|
||||
sm_powercycle_init_func_ptr state; // current state as ptr to "state function"
|
||||
} statemachine_init_t;
|
||||
|
||||
#ifndef _PRU1_STATEMACHINE_INIT_C_
|
||||
extern uint8_t prev_initialization_signals ;
|
||||
extern statemachine_init_t sm_init;
|
||||
#endif
|
||||
|
||||
void do_event_initializationsignals(void) ;
|
||||
|
||||
void sm_init_start();
|
||||
statemachine_state_func sm_init_start();
|
||||
|
||||
#endif
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
State machines to transfer an interrupt vector.
|
||||
@ -30,6 +31,7 @@
|
||||
*/
|
||||
#define _PRU1_STATEMACHINE_INTR_C_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//#include "devices.h"
|
||||
@ -37,30 +39,23 @@
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_utils.h"
|
||||
|
||||
#include "pru1_statemachine_arbitration.h"
|
||||
//#include "pru1_statemachine_arbitration.h"
|
||||
#include "pru1_statemachine_intr.h"
|
||||
|
||||
statemachine_intr_t sm_intr;
|
||||
|
||||
// forwards
|
||||
static uint8_t sm_intr_state_idle(void);
|
||||
static uint8_t sm_intr_state_1(void);
|
||||
static uint8_t sm_intr_state_2(void);
|
||||
static statemachine_state_func sm_intr_state_1(void);
|
||||
static statemachine_state_func sm_intr_state_2(void);
|
||||
|
||||
// BBSY already set, SACK held asserted
|
||||
void sm_intr_start() {
|
||||
statemachine_state_func sm_intr_start() {
|
||||
// BBSY already asserted. : latch[1], bit 6
|
||||
// buslatches_setbits(1, BIT(6), BIT(6));
|
||||
sm_intr.state = &sm_intr_state_1;
|
||||
return (statemachine_state_func)&sm_intr_state_1;
|
||||
// next call to sm_intr.state() starts state machine
|
||||
}
|
||||
|
||||
static uint8_t sm_intr_state_idle() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// place vector onto data, then set INTR
|
||||
static uint8_t sm_intr_state_1() {
|
||||
static statemachine_state_func sm_intr_state_1() {
|
||||
uint16_t vector = mailbox.intr.vector;
|
||||
|
||||
buslatches_setbyte(5, vector & 0xff); // DATA[0..7] = latch[5]
|
||||
@ -75,25 +70,24 @@ static uint8_t sm_intr_state_1() {
|
||||
buslatches_setbits(1, BIT(5), 0); // SACK = latch[1], bit 5
|
||||
|
||||
// wait for processor to accept vector (no timeout?)
|
||||
sm_intr.state = &sm_intr_state_2;
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_intr_state_2;
|
||||
}
|
||||
|
||||
// wait for SSYN
|
||||
static uint8_t sm_intr_state_2() {
|
||||
static statemachine_state_func sm_intr_state_2() {
|
||||
if (!(buslatches_getbyte(4) & BIT(5)))
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_intr_state_2; // wait
|
||||
// received SSYN
|
||||
|
||||
//remove vector, then remove INTR
|
||||
// remove vector, then remove INTR
|
||||
buslatches_setbyte(5, 0); // DATA[0..7] = latch[5]
|
||||
buslatches_setbyte(6, 0); // DATA[8..15] = latch[6]
|
||||
buslatches_setbits(7, BIT(0), 0); // INTR = latch 7, bit 0
|
||||
// deassert BBSY
|
||||
buslatches_setbits(1, BIT(6), 0);
|
||||
// SACK already removed
|
||||
|
||||
sm_intr.state = &sm_intr_state_idle;
|
||||
return 1;
|
||||
return NULL; // ready
|
||||
// master still drives SSYN
|
||||
}
|
||||
|
||||
|
||||
@ -21,23 +21,17 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
*/
|
||||
#ifndef _PRU1_STATEMACHINE_INTR_H_
|
||||
#define _PRU1_STATEMACHINE_INTR_H_
|
||||
|
||||
// execution of a state. return : 1, if statemachine stopped
|
||||
typedef uint8_t (*sm_intr_state_func_ptr)(void);
|
||||
#include "pru1_utils.h" // statemachine_state_func
|
||||
|
||||
// Transfers a block of worst as data cycles
|
||||
typedef struct {
|
||||
sm_intr_state_func_ptr state; // current state as ptr to "state fucntion"
|
||||
} statemachine_intr_t;
|
||||
|
||||
#ifndef _PRU1_STATEMACHINE_INTR_C_
|
||||
extern statemachine_dma_t sm_intr;
|
||||
#endif
|
||||
|
||||
void sm_intr_start(void);
|
||||
statemachine_state_func sm_intr_start(void);
|
||||
|
||||
#endif
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
|
||||
@ -41,9 +42,9 @@
|
||||
|
||||
#define _PRU1_STATEMACHINE_POWERCYCLE_C_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "mailbox.h"
|
||||
#include "pru1_utils.h"
|
||||
|
||||
@ -52,70 +53,60 @@
|
||||
|
||||
#include "pru1_statemachine_powercycle.h"
|
||||
|
||||
statemachine_powercycle_t sm_powercycle;
|
||||
|
||||
// forwards ; /
|
||||
uint8_t sm_powercycle_state_idle(void);
|
||||
static uint8_t sm_powercycle_state_1(void);
|
||||
static uint8_t sm_powercycle_state_2(void);
|
||||
static uint8_t sm_powercycle_state_3(void);
|
||||
static uint8_t sm_powercycle_state_4(void);
|
||||
static statemachine_state_func sm_powercycle_state_1(void);
|
||||
static statemachine_state_func sm_powercycle_state_2(void);
|
||||
static statemachine_state_func sm_powercycle_state_3(void);
|
||||
static statemachine_state_func sm_powercycle_state_4(void);
|
||||
|
||||
// setup with
|
||||
void sm_powercycle_start() {
|
||||
sm_powercycle.state = &sm_powercycle_state_1;
|
||||
statemachine_state_func sm_powercycle_start() {
|
||||
return (statemachine_state_func)&sm_powercycle_state_1;
|
||||
// next call to sm_slave.state() starts state machine
|
||||
}
|
||||
|
||||
uint8_t sm_powercycle_state_idle() {
|
||||
return 1; // ready
|
||||
}
|
||||
|
||||
// "Line power shutdown": assert ACLO, then wait
|
||||
static uint8_t sm_powercycle_state_1() {
|
||||
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
|
||||
sm_powercycle.state = &sm_powercycle_state_2;
|
||||
// DEBUG_OUT(0x01) ;
|
||||
do_event_initializationsignals() ;
|
||||
// DEBUG_OUT(0x02) ;
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_powercycle_state_2;
|
||||
}
|
||||
|
||||
// "Power supply switched off": assert DCLO, then wait
|
||||
static uint8_t sm_powercycle_state_2() {
|
||||
static statemachine_state_func sm_powercycle_state_2() {
|
||||
if (!TIMEOUT_REACHED)
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_powercycle_state_2; // wait
|
||||
buslatches_setbits(7, BIT(5), BIT(5)); // DCLO asserted
|
||||
TIMEOUT_SET(MILLISECS(POWERCYCLE_DELAY_MS))
|
||||
; // system powered off
|
||||
sm_powercycle.state = &sm_powercycle_state_3;
|
||||
// DEBUG_OUT(0x03) ;
|
||||
do_event_initializationsignals() ;
|
||||
// DEBUG_OUT(0x04) ;
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_powercycle_state_3;
|
||||
}
|
||||
|
||||
// "Line power back again": deassert ACLO, then wait
|
||||
static uint8_t sm_powercycle_state_3() {
|
||||
static statemachine_state_func sm_powercycle_state_3() {
|
||||
if (!TIMEOUT_REACHED)
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_powercycle_state_3; // wait
|
||||
buslatches_setbits(7, BIT(4), 0); // ACLO deasserted
|
||||
TIMEOUT_SET(MILLISECS(POWERCYCLE_DELAY_MS))
|
||||
; // "power supply stabilizing"
|
||||
sm_powercycle.state = &sm_powercycle_state_4;
|
||||
do_event_initializationsignals() ;
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_powercycle_state_4;
|
||||
}
|
||||
|
||||
// "Logic power stabilized": deassert DCLO, ready
|
||||
static uint8_t sm_powercycle_state_4() {
|
||||
static statemachine_state_func sm_powercycle_state_4() {
|
||||
if (!TIMEOUT_REACHED)
|
||||
return 0;
|
||||
return (statemachine_state_func)&sm_powercycle_state_4;
|
||||
buslatches_setbits(7, BIT(5), 0); // DCLO deasserted
|
||||
sm_powercycle.state = &sm_powercycle_state_idle;
|
||||
do_event_initializationsignals() ;
|
||||
return 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -21,26 +21,18 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
*/
|
||||
#ifndef _PRU1_STATEMACHINE_POWERCYCLE_H_
|
||||
#define _PRU1_STATEMACHINE_POWERCYCLE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "pru1_utils.h" // statemachine_state_func
|
||||
|
||||
#define POWERCYCLE_DELAY_MS 100 // wait period in millsecs between ACLO/DCLO transitions
|
||||
|
||||
// execution of a state. return : 1, if statemachine stopped
|
||||
typedef uint8_t (*sm_powercycle_state_func_ptr)(void);
|
||||
|
||||
typedef struct {
|
||||
sm_powercycle_state_func_ptr state; // current state as ptr to "state function"
|
||||
} statemachine_powercycle_t;
|
||||
|
||||
#ifndef _PRU1_STATEMACHINE_POWERCYCLE_C_
|
||||
extern statemachine_powercycle_t sm_powercycle;
|
||||
#endif
|
||||
|
||||
void sm_powercycle_start();
|
||||
statemachine_state_func sm_powercycle_start();
|
||||
|
||||
#endif
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
Statemachine for execution of slave DATO* or DATI* cycles.
|
||||
@ -35,6 +36,7 @@
|
||||
|
||||
#define _PRU1_STATEMACHINE_SLAVE_C_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pru1_utils.h"
|
||||
@ -46,22 +48,15 @@
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_statemachine_slave.h"
|
||||
|
||||
statemachine_slave_t sm_slave;
|
||||
|
||||
// forwards ;
|
||||
static uint8_t sm_slave_state_1(void);
|
||||
static uint8_t sm_slave_state_10(void);
|
||||
static uint8_t sm_slave_state_20(void);
|
||||
static uint8_t sm_slave_state_99(void);
|
||||
//statemachine_state_func sm_slave_start(void);
|
||||
static statemachine_state_func sm_slave_state_10(void);
|
||||
static statemachine_state_func sm_slave_state_20(void);
|
||||
static statemachine_state_func sm_slave_state_99(void);
|
||||
|
||||
// setup with
|
||||
void sm_slave_start() {
|
||||
sm_slave.state = &sm_slave_state_1;
|
||||
// next call to sm_slave.state() starts state machine
|
||||
}
|
||||
|
||||
// check for MSYN active
|
||||
static uint8_t sm_slave_state_1() {
|
||||
statemachine_state_func sm_slave_start() {
|
||||
uint8_t latch2val, latch3val, latch4val;
|
||||
// uint8_t iopage;
|
||||
uint32_t addr;
|
||||
@ -76,10 +71,10 @@ static uint8_t sm_slave_state_1() {
|
||||
|
||||
// MSYN active ?
|
||||
if (!(latch4val & BIT(4)))
|
||||
return 1; // still idle
|
||||
return NULL; // still idle
|
||||
if (latch4val & BIT(5))
|
||||
// SSYN active: cycle answered by other bus slave
|
||||
return 1; // still idle
|
||||
return NULL; // still idle
|
||||
// checking against SSYN guarantees address if valid if fetched now.
|
||||
// However, another Bus slave can SSYN immediately
|
||||
|
||||
@ -118,12 +113,11 @@ static uint8_t sm_slave_state_1() {
|
||||
//DEBUG_PIN_PULSE ; // trigger scope/LA. auto cleared on next reg_sel
|
||||
// set SSYN = latch[4], bit 5
|
||||
buslatches_setbits(4, BIT(5), BIT(5));
|
||||
sm_slave.state = &sm_slave_state_20;
|
||||
return (statemachine_state_func)&sm_slave_state_20;
|
||||
// perhaps PRU2ARM_INTERRUPT now active
|
||||
} else
|
||||
// no address match: wait for MSYN to go inactive
|
||||
sm_slave.state = &sm_slave_state_99;
|
||||
break;
|
||||
return (statemachine_state_func)&sm_slave_state_99;
|
||||
case UNIBUS_CONTROL_DATO:
|
||||
// fetch data in any case
|
||||
// DATA[0..7] = latch[5]
|
||||
@ -136,12 +130,11 @@ static uint8_t sm_slave_state_1() {
|
||||
// SSYN = latch[4], bit 5
|
||||
buslatches_setbits(4, BIT(5), BIT(5));
|
||||
// wait for MSYN to go inactive, then SSYN inactive
|
||||
sm_slave.state = &sm_slave_state_10;
|
||||
return (statemachine_state_func)&sm_slave_state_10;
|
||||
// perhaps PRU2ARM_INTERRUPT now active
|
||||
} else
|
||||
// no address match: wait for MSYN to go inactive
|
||||
sm_slave.state = &sm_slave_state_99;
|
||||
break;
|
||||
return (statemachine_state_func)&sm_slave_state_99;
|
||||
case UNIBUS_CONTROL_DATOB:
|
||||
// A00 = 1, odd address: get upper byte
|
||||
// A00 = 0: even address, get lower byte
|
||||
@ -157,42 +150,40 @@ static uint8_t sm_slave_state_1() {
|
||||
// SSYN = latch[4], bit 5
|
||||
buslatches_setbits(4, BIT(5), BIT(5));
|
||||
// wait for MSYN to go inactive, then SSYN inactive
|
||||
sm_slave.state = &sm_slave_state_10;
|
||||
return (statemachine_state_func)&sm_slave_state_10;
|
||||
// perhaps PRU2ARM_INTERRUPT now active
|
||||
} else
|
||||
// no address match: wait for MSYN to go inactive
|
||||
sm_slave.state = &sm_slave_state_99;
|
||||
break;
|
||||
return (statemachine_state_func)&sm_slave_state_99;
|
||||
}
|
||||
return 0; // busy
|
||||
return NULL ; // not reached
|
||||
}
|
||||
|
||||
// End DATO: wait for MSYN to go inactive, then SSYN inactive
|
||||
// also wait for EVENT ACK
|
||||
static uint8_t sm_slave_state_10() {
|
||||
static statemachine_state_func sm_slave_state_10() {
|
||||
// MSYN = latch[4], bit 4
|
||||
if (buslatches_getbyte(4) & BIT(4))
|
||||
return 0; // MSYN still active
|
||||
return (statemachine_state_func)&sm_slave_state_10; // wait, MSYN still active
|
||||
if (mailbox.events.eventmask)
|
||||
return 0; // long SSYN delay until ARM acknowledges all events
|
||||
return (statemachine_state_func)&sm_slave_state_10; // wait, long SSYN delay until ARM acknowledges all events
|
||||
// if ARM was triggered by event and changed the device state,
|
||||
// now an Interrupt arbitration may be pending!
|
||||
|
||||
// clear SSYN = latch[4], bit 5
|
||||
buslatches_setbits(4, BIT(5), 0);
|
||||
|
||||
sm_slave.state = &sm_slave_state_1;
|
||||
return 1; // ready }
|
||||
return NULL; // ready
|
||||
}
|
||||
|
||||
// End DATI: wait for MSYN to go inactive, then SSYN and DATA inactive
|
||||
// also wait for EVENT ACK
|
||||
static uint8_t sm_slave_state_20() {
|
||||
static statemachine_state_func sm_slave_state_20() {
|
||||
// MSYN = latch[4], bit 4
|
||||
if (buslatches_getbyte(4) & BIT(4))
|
||||
return 0; // MSYN still active
|
||||
return (statemachine_state_func)&sm_slave_state_20; // wait, MSYN still active
|
||||
if (mailbox.events.eventmask)
|
||||
return 0; // long SSYN delay until ARM acknowledges event
|
||||
return (statemachine_state_func)&sm_slave_state_20; // wait, long SSYN delay until ARM acknowledges event
|
||||
// if ARM was triggered by event and changed the device state,
|
||||
// now an Interrupt arbitration may be pending!
|
||||
|
||||
@ -203,16 +194,14 @@ static uint8_t sm_slave_state_20() {
|
||||
buslatches_setbyte(6, 0);
|
||||
// clear SSYN = latch[4], bit 5
|
||||
buslatches_setbits(4, BIT(5), 0);
|
||||
sm_slave.state = &sm_slave_state_1;
|
||||
return 1; // ready }
|
||||
return NULL; // ready
|
||||
}
|
||||
|
||||
// end of inactive cycle: wait for MSYN to go inactive
|
||||
static uint8_t sm_slave_state_99() {
|
||||
static statemachine_state_func sm_slave_state_99() {
|
||||
// MSYN = latch[4], bit 4
|
||||
if (buslatches_getbyte(4) & BIT(4))
|
||||
return 0; // MSYN still active
|
||||
return (statemachine_state_func)&sm_slave_state_99; // wait, MSYN still active
|
||||
|
||||
sm_slave.state = &sm_slave_state_1;
|
||||
return 1; // ready }
|
||||
return NULL; // ready
|
||||
}
|
||||
|
||||
@ -21,27 +21,15 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
29-jun-2019 JH rework: state returns ptr to next state func
|
||||
12-nov-2018 JH entered beta phase
|
||||
*/
|
||||
#ifndef _PRU1_STATEMACHINE_SLAVE_H_
|
||||
#define _PRU1_STATEMACHINE_SLAVE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "pru1_utils.h" // statemachine_state_func
|
||||
|
||||
// execution of a state. return : 1, if statemachine stopped
|
||||
typedef uint8_t (*sm_slave_state_func_ptr)(void);
|
||||
|
||||
typedef struct {
|
||||
sm_slave_state_func_ptr state; // current state as ptr to "state function"
|
||||
// uint32_t addr; // adress fetched from bus on MSYN
|
||||
// uint8_t control; // C1,C0 fetched from bus on MSYN
|
||||
// uint16_t data; // data fetched from bus on MSYN/ to be written to BUS on SSYN
|
||||
} statemachine_slave_t;
|
||||
|
||||
#ifndef _PRU1_STATEMACHINE_SLAVE_C_
|
||||
extern statemachine_slave_t sm_slave;
|
||||
#endif
|
||||
|
||||
void sm_slave_start();
|
||||
statemachine_state_func sm_slave_start(void);
|
||||
|
||||
#endif
|
||||
|
||||
@ -37,6 +37,12 @@ volatile register uint32_t __R30;
|
||||
volatile register uint32_t __R31;
|
||||
|
||||
|
||||
// execution of a state. return : next state; or NULL if statemachine stopped
|
||||
// return type is void *, but should be statemachine_state_func_ptr recursively
|
||||
// typedef statemachine_state_func * (*statemachine_state_func)(void);
|
||||
// Not possible?! So return void * and cast to void *(func(void) on use
|
||||
typedef void * (*statemachine_state_func)(void);
|
||||
|
||||
|
||||
|
||||
#define MILLION 1000000L
|
||||
|
||||
@ -176,7 +176,7 @@ void cpu_c::on_init_changed(void) {
|
||||
// write all registers to "reset-values"
|
||||
if (init_asserted) {
|
||||
reset_unibus_registers();
|
||||
INFO("demo_io_c::on_init()");
|
||||
INFO("cpu::on_init()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ public:
|
||||
parameter_bool_c runmode = parameter_bool_c(this, "run", "r",/*readonly*/
|
||||
false, "1 = CPU running, 0 = halt");
|
||||
parameter_bool_c init = parameter_bool_c(this, "init", "i",/*readonly*/
|
||||
false, "1 = CPU initalizing");
|
||||
false, "1 = CPU initializing");
|
||||
|
||||
struct Bus bus; // UNIBU Sinterface of CPU
|
||||
struct KA11 ka11; // Angelos CPU state
|
||||
|
||||
@ -111,7 +111,7 @@ public:
|
||||
// working position
|
||||
blockaddr_c cur_blockaddr;
|
||||
|
||||
// initalize drive
|
||||
// initialize drive
|
||||
virtual void init(unsigned unitnr) = 0;
|
||||
// read access
|
||||
virtual void readtrack(unsigned unitnr, uint8_t *data) = 0;
|
||||
|
||||
@ -39,7 +39,7 @@ public:
|
||||
|
||||
// implement abstracts
|
||||
|
||||
// initalize drive
|
||||
// initialize drive
|
||||
virtual void init(unsigned unitnr);
|
||||
// read access
|
||||
virtual void readtrack(unsigned unitnr, uint8_t *data);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user