Commit 27df5bb0 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Added GPIO output setup

parent 7fab1300
Loading
Loading
Loading
Loading

ezynq_gpio_defs.py

0 → 100644
+428 −0

File added.

Preview size limit exceeded, changes collapsed.

+40 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ __status__ = "Development"
import ezynq_registers
#import ezynq_feature_config
import ezynq_slcr_clk_def
import ezynq_gpio_defs
MIO_ATTRIBS=['SLOW','FAST','PULLUP','NOPULLUP']

MIO_TEMPLATES = {
@@ -284,9 +285,11 @@ class EzynqMIO:
    def __init__(self, verbosity, qualifier_char, regs_masked, permit_undefined_bits=False):
#        print ezynq_slcr_clk_def.MIO_PINS_DEFS
        self.MIO_PINS_DEFS=  ezynq_slcr_clk_def.SLCR_DEFS #combined
        self.GPIO_DEFS=ezynq_gpio_defs.GPIO_DEFS
        self.qualifier_char=qualifier_char
        self.verbosity=     verbosity
        self.slcr_register_set=  ezynq_registers.EzynqRegisters(self.MIO_PINS_DEFS,0,regs_masked,permit_undefined_bits)
        self.gpio_register_set=  ezynq_registers.EzynqRegisters(self.GPIO_DEFS,0,regs_masked,permit_undefined_bits)

    def generate_led_off_on(self, mio_pin):
        # generate code to be included in u-boot for debugging early boot stages
@@ -617,7 +620,7 @@ class EzynqMIO:
                        print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value
                        print 'Polarity can only be IN, OUT or BIDIR'
                        exit (ERROR_DEFS['INOUT'])
                    if (pin==7) or (pin==8) and (value!='OUT'):
                    if ((pin==7) or (pin==8)) and (value!='OUT'):
                        print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value
                        print 'Polarity for MIO pins 7 and 8 can only be OUT'
                        exit (ERROR_DEFS['INOUT'])
@@ -664,6 +667,42 @@ class EzynqMIO:
            
        return self.slcr_register_set.get_register_sets(True,True)

    def setregs_gpio(self,current_reg_sets,force=True):
        mask_data_regs_mio=('mask_data_0_lsw','mask_data_0_msw','mask_data_1_lsw','mask_data_1_msw');
        self.slcr_register_set.set_initial_state(current_reg_sets, True)# start from the current registers state   
        # first find out which groups of 16 pins are outputs (if any)
        for i,mio_pin in enumerate(self.mio):
            if ('DATA_OUT' in mio_pin) or (('INOUT' in mio_pin) and (mio_pin['INOUT'] != 'IN')):
                break
        else:
            return current_reg_sets # no outputs to program
        # 1. Program SLCR (should be already done, now just no clean up after debug LED unknown state)
        for i,mio_pin in enumerate(self.mio):
            if ('DATA_OUT' in mio_pin) or (('INOUT' in mio_pin) and (mio_pin['INOUT'] != 'IN')):
                self.slcr_register_set.set_bitfields('mio_pin_%02i'%i,(('tri_enable',0),),force) # disable tristate
        reg_sets=self.slcr_register_set.get_register_sets(True,True)
        self.gpio_register_set.set_initial_state(reg_sets, True) #continuing with GPIO registers
        # 2. set DIRM for outputs
        for i,mio_pin in enumerate(self.mio):
            if ('DATA_OUT' in mio_pin) or (('INOUT' in mio_pin) and (mio_pin['INOUT'] == 'OUT')):
                    self.gpio_register_set.set_bitfields('dirm_%i'%(i/32),
                                                     (('dirm_%02i'%i,1),),force) # direction - output               
                
        self.gpio_register_set.flush()
        # 3. set data for outputs
        for i,mio_pin in enumerate(self.mio):
            if 'DATA_OUT' in mio_pin:
                self.gpio_register_set.set_bitfields(mask_data_regs_mio[i/16],
                                                     (('mask%02i'%i,0), # enable setting bit
                                                      ('data%02i'%i,mio_pin['DATA_OUT']!=0)),force) # data to set
        self.gpio_register_set.flush()
        # 4. Output enable        
        for i,mio_pin in enumerate(self.mio):
            if ('DATA_OUT' in mio_pin) or (('INOUT' in mio_pin) and (mio_pin['INOUT'] == 'OUT')):
                    self.gpio_register_set.set_bitfields('oen_%i'%(i/32),
                                                     (('oe_%02i'%i,1),),force) # enable output               
        return self.gpio_register_set.get_register_sets(True,True)
    
    # Just add to the HTML output
    def output_mio(self,f,MIO_HTML_MASK):
        # initialize register_set
+16 −6
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ def print_html_registers(html_file, reg_sets, from_index, show_bit_fields=True,
                    prev_sdata='-'
                new_data=((old_data ^ data) & mask) ^ old_data
                new_mask= old_mask | mask
                if not 'FORCE_DFLT' in r_def: # do not save state if force default (always start from default value) is in effect
                    current_reg_state[addr]=(new_data,new_mask)
            else:
                new_data= data
@@ -179,6 +180,14 @@ def accumulate_reg_data(reg_sets,accumulate_mask=False):
    cumulative_regs=[() for _ in reg_sets]
    for index, (op, addr, data, mask, module_name, register_name, r_def) in enumerate (reg_sets):
        if (op == 's') and (addr in initial_state): # only accumulate register set operations, not wait for equal ('=') or wait for not-equal ('!')
            if 'FORCE_DFLT' in r_def:
                #is old_mask=0 enough? no need for old_data
                try:
                    old_data=r_def['DFLT']
                except:
                    old_data=0
                old_mask=0
            else:        
                old_data,old_mask=initial_state[addr]
            data=((old_data ^ data) & mask) ^ old_data
            if accumulate_mask:
@@ -232,6 +241,8 @@ class EzynqRegisters:
        
        
    def set_initial_state(self,added_reg_sets, init=True):
#                    new_sets.append((op,addr,data,mask,self.module_name,register_name,self.defs[register_name]))

        if init:
            self.initial_state={}
            self.previous_reg_sets=[]
@@ -242,13 +253,12 @@ class EzynqRegisters:
        if not added_reg_sets:
            return
        self.previous_reg_sets+=added_reg_sets # appends, not overwrites
        for op,addr,data,mask,_,_,_ in added_reg_sets: # Do not need to care about default values - they will have 0 in the mask bits.
        for op,addr,data,mask,_,_,defs in added_reg_sets: # Do not need to care about default values - they will have 0 in the mask bits.
            if 'FORCE_DFLT' in defs:
                continue # do not use previous value, always use default value
            if (op == 's') and (addr in self.initial_state):
#                old_data,old_mask=self.initial_state[addr]
                old_data,_=self.initial_state[addr]
                data=((old_data ^ data) & mask) ^ old_data
#                mask |= old_mask
#            self.initial_state[addr]=(data,mask)
            self.initial_state[addr]=(data,0) # ignoring old mask - only accumulating newly set bits in this set
            
    def get_reg_names(self):
+15 −1
Original line number Diff line number Diff line
@@ -220,6 +220,15 @@ inline void pll_setup(void)
        self.cfile+='''/* Reset defined peripherals */        
inline void reset_peripherals(void)
{
'''
        self._add_reg_writes(reg_sets)            
        self.cfile+='}\n\n'

    def gpio_out (self, reg_sets):
        self.sections.append('gpio_out')
        self.cfile+='''/* Setup GPIO outputs */        
inline void setup_gpio_outputs(void)
{
'''
        self._add_reg_writes(reg_sets)            
        self.cfile+='}\n\n'
@@ -499,9 +508,14 @@ int arch_cpu_init(void)
            self.cfile+='\tuart_wait_tx_fifo_empty(); /* u-boot may re-program UART differently, wait all is sent before getting there */\n'
#uart_wait_tx_fifo_empty() - add if u-boot debug is on
        self._cp_led('LED_CHECKPOINT_12') # Before leaving lowlevel_init()

#Setup GPIO outputs (after LED debug is over)        
        if 'gpio_out' in self.sections:
            self.cfile+='\tsetup_gpio_outputs(); /* Setup GPIO outputs */\n'
        
#LOCK_SLCR        
        if self.features.get_par_value_or_none('LOCK_SLCR') is False:
            self.cfile+='/* Leaving SLCR registers UNLOCKED according setting of %s */\n'%self.features.get_par_confname('LOCK_SLCR')
            self.cfile+='/* Leaving SLCR registers UNLOCKED according to setting of %s */\n'%self.features.get_par_confname('LOCK_SLCR')
        else:            
            self.cfile+='''/* Lock SLCR back after everything with it is done */
\tlock_slcr();
+16 −1
Original line number Diff line number Diff line
@@ -448,6 +448,13 @@ if raw_config_value('CONFIG_EZYNQ_SKIP_DDR', raw_configs) is None:
    reg_sets=ddr.ddr_start(reg_sets,False,False)
    segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DDR_START','TITLE':'DDR initialization start'})


#Set GPIO output pins    
reg_sets=mio_regs.setregs_gpio(reg_sets)
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'GPIO','TITLE':'GPIO outputs setup'})

#    def setregs_gpio(self,current_reg_sets,force=True):

# Generate lock/unlock SLCR to be used in u-boot
reg_sets_lock_unlock=clk.generate_lock_unlock()
#print reg_sets[len(reg_sets)-1]
@@ -466,6 +473,7 @@ segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DDRC_STA','TITLE':'regis
    

    
    
#    def generate_led_off_on(self, mio_pin):
#CONFIG_EZYNQ_LED_DEBUG=47 # toggle LED during boot
#CONFIG_EZYNQ_BOOT_DEBUG
@@ -493,6 +501,9 @@ if html_file:
    for segment in segments:
        start=segment['FROM']
        end=segment['TO']
#        print segment['NAME'],start,end
        if (start==end):
            continue # nothing in this section    
        show_bit_fields= (MIO_HTML_MASK & 0x100,MIO_HTML_MASK & 0x800)[segment['NAME']=='MIO']
        show_comments=    MIO_HTML_MASK & 0x200
        filter_fields=not MIO_HTML_MASK & 0x400
@@ -573,6 +584,10 @@ if (args.lowlevel):
        u_boot.ddr_start      (reg_sets[segment_dict['DDR_START']['FROM']:segment_dict['DDR_START']['TO']])
    if 'DDRC_STA' in segment_dict: 
        u_boot.ddrc_wait_empty_queue(reg_sets[segment_dict['DDRC_STA']['FROM']:segment_dict['DDRC_STA']['TO']])
    if ('GPIO' in segment_dict) and (segment_dict['GPIO']['TO']>segment_dict['GPIO']['FROM']): 
        u_boot.gpio_out(reg_sets[segment_dict['GPIO']['FROM']:segment_dict['GPIO']['TO']])

#segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'GPIO','TITLE':'GPIO outputs setup'})
    
    u_boot.make_arch_cpu_init()
    u_boot.output_c_file(args.lowlevel)
Loading