This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

8031 POST (power on self test)

I'm not having much success in finding an 8031 POST (power on self test) online. I'd be especially interested in tests from a microprocessor manufacturer.

For example, are there published tests to verify that the 128 bytes of indirect memory are reliable? Are there simple tests for the SFRs?

Thanks for your comments.

Robert Berkey

Parents
  • You may find the following test useful. However, it is not in Keil assembler and will need some adapting.

    The destructive RAM test tests all 256 bytes of the internal RAM - using only registers to control the loops and save the results. Note that the Stack Pointer is used to address memory - this is the only way to avoid using R0/R1.

    The test is based on an artical for which I cannot now find the reference. The test makes a through check of individual memory cells, detects all but the most exotic addressing faults and will detect most instances where the state of a bit is affected by the state of nearby bits.

    Note that this routine necessarily trashes the stack. The software invoking the destructive RAM test has to jump to this routine and provide a label to jump back to. The invoking software must then set up the stack etc.

    The watchdog refered to in this routine is bespoke hardware.

    ;
    ;	Destructive Ram Test
    ;
    ;	NB. Number of bytes of memory to be tested must be 2^n.
    ;
    							;
    sub_cycles		REG	RCAP2L			;
    sub_cycle_counter	REG	RCAP2H			;
    test_pattern		REG	B			;
    pass			REG	F0			;
    test_failed		REG	F1			;
    							;
    destructive_ram_test:					;BEGIN
    							;
    		CLR	test_failed			;    test_failed := false.
    							;
    		MOV	DPTR,#drt_pattern_table		;
    1$:							;    FOR table_pointer := 0 TO 23 D0
    		SETB	pass				;
    2$:							;        FOR pass := write TO read DO
    							;
    		CLR	A				;
    		MOVC	A,@A+DPTR			;
    		MOV	test_pattern,A			;            Read test_pattern.
    		MOV	A,#01				;
    		MOVC	A,@A+DPTR			;
    		MOV	sub_cycles,A			;            Read sub_cycles.
    							;
    		MOV	SP,#00H				;            Zero the memory pointer.
    							;
    3$:							;            FOR memory_pointer := 0 TO 255 DO
    							;
    		MOV	sub_cycle_counter,sub_cycles	;
    4$:							;                FOR sub_cycle_counter := sub_cycles TO 1 DO
    		JNB	pass,5$				;                    IF pass = write THEN
    							;
    		DEC	SP				;
    		PUSH	test_pattern			;                        Write test_pattern to memory.
    		SJMP	8$				;
    5$:							;                    ELSE
    		POP	Acc				;                        Read memory.
    		INC	SP				;
    		CJNE	A,test_pattern,6$		;                        IF test_pattern = @memory_pointer THEN
    		SJMP	7$				;                            OK
    6$:							;                        ELSE
    		SETB	test_failed			;                            Test failed.
    7$:							;                        ENDIF
    8$:							;                    ENDIF
    		INC	SP				;                    Increment memory_pointer.
    							;
    		MOV	A,SP				;
    		ANL	A,#00011111B			;
    		JNZ	9$				;                    IF memory_pointer MOD 32 = 0 THEN
    							;
    		CPL	reset_watchdog 			;                        Toggle the watchdog with period of about 1 ms.
    							;
    9$:							;                    ENDIF
    							;
    		DJNZ	sub_cycle_counter,4$		;                ENDFOR
    		XRL	test_pattern,#11111111B		;                Invert the test pattern.
    		MOV	A,SP				;
    		CJNE	A,#00,3$			;            ENDFOR
    		JBC	pass,2$				;        ENDFOR
    		INC	DPTR				;
    		INC	DPTR				;        Increment the table pointer.
    		MOV	A,DPL				;
    		CJNE	A,#LOW( drt_pattern_table_end ),1$
    		MOV	A,DPH				;
    		CJNE	A,#HIGH( drt_pattern_table_end ),1$
    							;    ENDFOR
    		MOV	C,test_failed			;
    		MOV	self_test_alarm,C		;    self_test_alarm := result of test.
    							;
    		LJMP	drt_return			;END
    							;
    drt_pattern_table:					;
    			DB	10101010B,1		;00
    			DB	01010101B,1		;01
    			DB	11001100B,1		;02
    			DB	00110011B,1		;03
    			DB	11110000B,1		;04
    			DB	00001111B,1		;05
    			DB	11111111B,1		;06
    			DB	00000000B,1		;07
    			DB	11111111B,2		;08
    			DB	00000000B,2		;09
    			DB	11111111B,4		;10
    			DB	00000000B,4		;11
    			DB	11111111B,8		;12
    			DB	00000000B,8		;13
    			DB	11111111B,16		;14
    			DB	00000000B,16		;15
    			DB	11111111B,32		;16
    			DB	00000000B,32		;17
    			DB	11111111B,64		;18
    			DB	00000000B,64		;19
    			DB	11111111B,128		;20
    			DB	00000000B,128		;21
    			DB	11111111B,.LOW.(256)	;22
    			DB	00000000B,.LOW.(256)	;23
    drt_pattern_table_end	EQU	$			;
    							;
    ;
    

Reply
  • You may find the following test useful. However, it is not in Keil assembler and will need some adapting.

    The destructive RAM test tests all 256 bytes of the internal RAM - using only registers to control the loops and save the results. Note that the Stack Pointer is used to address memory - this is the only way to avoid using R0/R1.

    The test is based on an artical for which I cannot now find the reference. The test makes a through check of individual memory cells, detects all but the most exotic addressing faults and will detect most instances where the state of a bit is affected by the state of nearby bits.

    Note that this routine necessarily trashes the stack. The software invoking the destructive RAM test has to jump to this routine and provide a label to jump back to. The invoking software must then set up the stack etc.

    The watchdog refered to in this routine is bespoke hardware.

    ;
    ;	Destructive Ram Test
    ;
    ;	NB. Number of bytes of memory to be tested must be 2^n.
    ;
    							;
    sub_cycles		REG	RCAP2L			;
    sub_cycle_counter	REG	RCAP2H			;
    test_pattern		REG	B			;
    pass			REG	F0			;
    test_failed		REG	F1			;
    							;
    destructive_ram_test:					;BEGIN
    							;
    		CLR	test_failed			;    test_failed := false.
    							;
    		MOV	DPTR,#drt_pattern_table		;
    1$:							;    FOR table_pointer := 0 TO 23 D0
    		SETB	pass				;
    2$:							;        FOR pass := write TO read DO
    							;
    		CLR	A				;
    		MOVC	A,@A+DPTR			;
    		MOV	test_pattern,A			;            Read test_pattern.
    		MOV	A,#01				;
    		MOVC	A,@A+DPTR			;
    		MOV	sub_cycles,A			;            Read sub_cycles.
    							;
    		MOV	SP,#00H				;            Zero the memory pointer.
    							;
    3$:							;            FOR memory_pointer := 0 TO 255 DO
    							;
    		MOV	sub_cycle_counter,sub_cycles	;
    4$:							;                FOR sub_cycle_counter := sub_cycles TO 1 DO
    		JNB	pass,5$				;                    IF pass = write THEN
    							;
    		DEC	SP				;
    		PUSH	test_pattern			;                        Write test_pattern to memory.
    		SJMP	8$				;
    5$:							;                    ELSE
    		POP	Acc				;                        Read memory.
    		INC	SP				;
    		CJNE	A,test_pattern,6$		;                        IF test_pattern = @memory_pointer THEN
    		SJMP	7$				;                            OK
    6$:							;                        ELSE
    		SETB	test_failed			;                            Test failed.
    7$:							;                        ENDIF
    8$:							;                    ENDIF
    		INC	SP				;                    Increment memory_pointer.
    							;
    		MOV	A,SP				;
    		ANL	A,#00011111B			;
    		JNZ	9$				;                    IF memory_pointer MOD 32 = 0 THEN
    							;
    		CPL	reset_watchdog 			;                        Toggle the watchdog with period of about 1 ms.
    							;
    9$:							;                    ENDIF
    							;
    		DJNZ	sub_cycle_counter,4$		;                ENDFOR
    		XRL	test_pattern,#11111111B		;                Invert the test pattern.
    		MOV	A,SP				;
    		CJNE	A,#00,3$			;            ENDFOR
    		JBC	pass,2$				;        ENDFOR
    		INC	DPTR				;
    		INC	DPTR				;        Increment the table pointer.
    		MOV	A,DPL				;
    		CJNE	A,#LOW( drt_pattern_table_end ),1$
    		MOV	A,DPH				;
    		CJNE	A,#HIGH( drt_pattern_table_end ),1$
    							;    ENDFOR
    		MOV	C,test_failed			;
    		MOV	self_test_alarm,C		;    self_test_alarm := result of test.
    							;
    		LJMP	drt_return			;END
    							;
    drt_pattern_table:					;
    			DB	10101010B,1		;00
    			DB	01010101B,1		;01
    			DB	11001100B,1		;02
    			DB	00110011B,1		;03
    			DB	11110000B,1		;04
    			DB	00001111B,1		;05
    			DB	11111111B,1		;06
    			DB	00000000B,1		;07
    			DB	11111111B,2		;08
    			DB	00000000B,2		;09
    			DB	11111111B,4		;10
    			DB	00000000B,4		;11
    			DB	11111111B,8		;12
    			DB	00000000B,8		;13
    			DB	11111111B,16		;14
    			DB	00000000B,16		;15
    			DB	11111111B,32		;16
    			DB	00000000B,32		;17
    			DB	11111111B,64		;18
    			DB	00000000B,64		;19
    			DB	11111111B,128		;20
    			DB	00000000B,128		;21
    			DB	11111111B,.LOW.(256)	;22
    			DB	00000000B,.LOW.(256)	;23
    drt_pattern_table_end	EQU	$			;
    							;
    ;
    

Children