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