Digital IO

The Following is a simple program for the pyCPU (Python Hardware Processor). Keep in mind that the Databitwitdth is limited to a constant factor set by CPU_BITWIDTH. The following is the main.py file.


PYCPU_CONFIGS={ 
  "PREDEFINED_IO_ADDRESSES":{'PORTA_IN':0,'PORTB_IN':1,'PORTC_OUT':2,'PORTD_OUT':3,'RS232Data':4,'RS232_READ_ADDRESS':5,'RS232_RECEIVE_ADDRESS':6,'RS232_WRITEBUFFER_FULL':7}, 
  "Prog_mem_SIZE":1024,          # Spezifies the minimal programm length, the programm memory will have this lenght even if the current programm dont needs it  
  "Var_mem_SIZE":128,            # Size of the Memory for local variables 
  "Globals_mem_SIZE":128,        # Size of Global memory + constants memory + PREDEFINED_IO_ADDRESSES
  "STACK_SIZE":4,                # Minimal Size of one local Stackblock, that the cpu implements, even if the programm needs less stack
  "CPU_BITWIDTH":8,              # Bitwidth of integer values
  "CPU_CLK_FREQ":12e6,           # Needed to for RS232 Baudrate calc
  "CPU_RS232_BAUDRATE":115200,   # Baudrate of the RS232 Unit 
  "NR_FUNCTION_ARGUMENTS":8,     # Limits the maximal number of arguments in a function call
  "NR_NESTED_LOOPS":32           # Limits the maximal number of nested Loops
}

def busywait(time):
  x=0
  while x<100:
    td=0
    x=x+1
    while td<100:
      td=td+1
      ss=0
      while ss<time:
	ss=ss+1

def main():
  global PORTA_IN,PORTB_IN,PORTC_OUT,PORTD_OUT
  x=0
  while 1:
    PORTD_OUT=PORTD_OUT^16
    busywait(20)
    if (PORTB_IN & 0x01)==1:
      PORTD_OUT=PORTD_OUT|0x20
    else:
      PORTD_OUT=PORTD_OUT&0xdf

This small Programm blinks an LED which is connected at PORTD_OUT[4] (the fourth bit of PORTD_OUT). Additionally, as long as the Button which is connected to PORTB_IN[0] is pressed the LED which is is connected to PORTD_OUT[5] will light up.

To get a little insight you can use the dis python module to show the bytecode instructions. The instructions for the function CPU_main are shown below. These instructions after some modifications are pushed into the pyCpu RAM so that they can be executed.

import dis
dis.dis(main)
  3           0 LOAD_CONST               1 (0)
              3 STORE_FAST               0 (x)

  4           6 SETUP_LOOP              62 (to 71)

  5     >>    9 LOAD_GLOBAL              0 (PORTD_OUT)
             12 LOAD_CONST               2 (16)
             15 BINARY_XOR          
             16 STORE_GLOBAL             0 (PORTD_OUT)

  6          19 LOAD_GLOBAL              1 (busywait)
             22 LOAD_CONST               3 (20)
             25 CALL_FUNCTION            1
             28 POP_TOP             

  7          29 LOAD_GLOBAL              2 (PORTB_IN)
             32 LOAD_CONST               4 (1)
             35 BINARY_AND          
             36 LOAD_CONST               4 (1)
             39 COMPARE_OP               2 (==)
             42 POP_JUMP_IF_FALSE       58

  8          45 LOAD_GLOBAL              0 (PORTD_OUT)
             48 LOAD_CONST               5 (32)
             51 BINARY_OR           
             52 STORE_GLOBAL             0 (PORTD_OUT)
             55 JUMP_ABSOLUTE            9

 10     >>   58 LOAD_GLOBAL              0 (PORTD_OUT)
             61 LOAD_CONST               6 (223)
             64 BINARY_AND          
             65 STORE_GLOBAL             0 (PORTD_OUT)
             68 JUMP_ABSOLUTE            9
        >>   71 LOAD_CONST               0 (None)
             74 RETURN_VALUE

Leave a comment