nanoPc T2 bare metal development (3)

-----------------------------Write in front

It's been a long time since I played the MCU. The stm32 I played before is not learning at all. I just use the 51 knowledge I learned before and the library functions that call the atom. If there is anything wrong, please correct me, thank you.

refer to:

http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T2/zh#.E7.BC.96.E8.AF.91U-Boot

The development board is nanoPc T2 using Friendly Arm, the Soc is S5P4418, and other peripherals can be found on the wiki. I think it's pretty good, although I've only used this one, but it's still good to use.

http://weibo.com/p/1001603914482173772682

This is the routine I refer to, although I didn't go in to see it (because I don't have a Weibo...) But I have all his relevant source code, which is on the Weibo. Called the big guy Dicka, he is very strong.


----------------------------text

I will summarize the modification of the serial port baud rate, interrupt, timer, and the above are all learned from the article of the big guy Deca .

1. Serial port baud rate

When we were testing, the baud filter of the serial communication between the nano and the pc was 115200. We didn't set it up, so where did this information come from? Don't forget, we still have 2ndboot that we haven't been able to touch, then the functional effect of the program instructions in him. We modify the serial port baud rate by writing our own program. First of all, we communicate with the pc by sending and receiving through the two pins rx tx, which also involves external pins, that is, the configuration of GPIO.

ok, step by step, first check the schematic


ok, so we know that the UART connected to the outside is UART0, he is GPIOD18, so let's check his pin multiplexing first, you can check GPIOD14 18 first because you don't know what his name is in it, When using search, it may not be found, so we search for GPIOD14 18,

In this way, we know that the multiplexing function number of UARTTXD0 is Function1, which is 01, and we also know that the pin number is 18, and then check

This can find out the address of his register again, so he is assigned a value of 5:4=01, that is, the 5th and 4th bits are 01, and this pin is the UART0 function. Then RT is also searched and set in the same way. ok, continue, TX is output, RX is input, then continue to configure his input and output registers, or the configuration of some enable switches, etc., these can be found on the datasheet. Then there is the clock, and the baud rate must be clocked again.

This is found on the datasheet. If we want to set the baud rate of 9600, the clock needs to be greater than 3.6864MHZ. In the example of Dicka, 10M is used, then we also use 10M, then we can reverse it. Baud Rate Divisor=941.104167, he has two more registers, one for the 16bit integer part and the other for the 6bit fractional part, the hexadecimal of 941 is 0x41, the binary of 0.104167 is 0x000110, which is continuously multiplied and 6 bits are reserved, here is There are errors, but also unavoidable. Well, we can configure it. Then set the stop bit, clear the flag bit, blah blah blah. ok, this works.

OK, how to use it? We send it out, we have to put the data in the data register for it to send, that is, the UARTDR register, OK. This is ready to use.

2. Timer

This is very simple. I didn't look at it carefully. It's similar to setting the baud rate of the UART. It's ok to find the corresponding register and configure it. Direct output pwm, or use a timer to simulate.

3. Interruption

Regarding interrupts, I don't understand very well. Now I haven't found where the CPSR register is, and I haven't found it in the technical documentation. Leave it for now and talk about it later.

Hey, I don't understand. . . That pile of English documents are all about GIC, what kind of stuff. . . . s. See if you can force it.

Let's use VIC:

There are 64 interrupt sources, [31:0] is a group for CH0, and [63:32] is a group for CH1

VICIRQSTATUS read-only read is IRQ interrupt status, affected by mask bit
VICFIQSTATUS read-only read is FIQ interrupt status, affected by mask bit
VICRAWINTR read-only is just like the English expression, it is a raw interrupt (unprocessed, Before masking)
VICINTSELECT is used to select the interrupt source, IRQ or FIQ when the interrupt is interrupted.
VICINTENABLE is used to set a certain interrupt enable
VICINTENCLEAR is used to set a certain interrupt disable
VICSOFTINT is used to set a certain software interrupt enable
VICSOFTINTCLEAR is used to set a certain bit. A software interrupt is disabled
VICPROTECTION Protected mode don't care about it
VICSWPRIORITYMASK 16 interrupt priority masks
VICVECTPRIORITYDAISY vector interrupt priority daisy chain Users can program to select any one of the 16 vector interrupt
priorities as (can't understand)
VICVECTADDR0 -31 A total of 32 registers are used to store the address of the ISR vector, which can only
be written when the relevant interrupt register is disabled. Remember
that if the system does not support the interrupt vector address, the VICECTADDR register can be programmed as the interrupt source port number, which
can easily It is determined that
VICVECTPRIORITY0-31 has a total of 32 registers, selects the interrupt priority
VICADDDRESS The current active ISR, the reset value is 0x00000000, the ISR address can be read by reading, and the current
interrupt is set to be serviced

The above is what I moved directly from the Dicka boss

I can't understand it in the compilation, but I have no time, I have been working for a day. . . a bit tired. Let's talk about the general idea. should work.

An FIQ or an IRQ (interrupt requests) are signaled by the Interrupt Controller to CPU. After arbitrating multiple

requests from internal peripherals and GPIO, the Controller requests an interrupt.

9.4.1 Interrupt Flow Sequence Using AHB
The following procedure shows the sequence for the IRQ interrupt flow:
 An IRQ interrupt occurs.
 The ARM processor branches to the IRQ interrupt vector
 Stack the workspace so that IRQ interrupts can be re-enabled later.
 Perform a dummy read to the VICADDRESS Register to set up priority status control in the VIC.
 Read the VICIRQSTATUS Register and determine which interrupt sources have to be service.
 Execute the ISR. At the beginning of the ISR, the interrupt of the processor can be re-enabled so that a higher
priority interrupt can be serviced.
 Clear the requesting interrupt in the peripheral, or write to the VICSOFTINTCLEAR Register if the request was
generated by a software interrupt.
 Disable the interrupt on the processor and restore the workspace.
 Write to the VICADDRESS Register. This clears the respective interrupt in the internal interrupt priority
hardware.

 Return from the interrupt. This re-enables the interrupts.

The following procedure shows the sequence for the FIQ interrupt flow.
 An FIQ interrupt occurs.
 The ARM processor branches to the FIQ interrupt vector.
 Branch to the ISR.
 Execute the ISR.
 Clear the requesting interrupt in the peripheral, or write to the VICSOFTINTCLEAR Register if the request was
generated by a software interrupt.
 Disable the interrupts and restore the workspace.

 Return from the interrupt. This re-enables the interrupts

This should be the introduction of FIQ IRQ, please translate it when you have time. Mark first.

We only need to know now that there are two interrupt modes that can be set. Then query the interrupt source to know:

7 UART0 UART0 interrupt interrupt source. As long as there is serial port information, an interrupt will be triggered. Pay attention to the following statements:

VICVECTADDR7_CH0 = (unsigned int)UART0_ISR; //UART0_ISR is the interrupt service function, assign the entry address of this function to VICVECTADDR7_CH0

if((addrCH0!=0) && (VICIRQSTTUS_CH0 & (1<<7) )) //Judging that the flag triggers an interrupt
    {
       /*UART0*/
        p_func = (void(*)())addr_CH0;//Read ISR Address, pass the address to the function pointer, you can call this interrupt service function.

    }

The compilation is incomprehensible. . . . .

reset:
    /* set vector base register */
    ldr r0, =_start
    mcr p15, 0, r0, c12, c0, 0
    mrc p15, 0, r0, c1, c0, 0
    bic r0, #(1<<13)
    mcr p15, 0, r0, c1, c0, 0
    /* open irq and fiq */
    mrs r5, cpsr @read cpsr->r5
    bic r5, r5, #0xc0 @allow irq and fiq
    msr cpsr, r5
    /* jump Enter the C language main program*/
    bl main
    /*After the main execution is completed, re-execute*/
    b reset

do_irqs: @Put the irq program here
    ldr sp, =0xffff9970 @Just find an address that should not be used for the stack Area
    sub lr,lr,#4
    stmfd sp!,{r0-r12,lr}
    
    bl do_irq
    

    ldmfd sp!,{r0-r12,pc}^

You can see what's going on by looking at the comments. If you let yourself write it, you won't be able to write it. This is a little embarrassing. It's hard to stop. . . . However, the time for myself is a little short, and I will wait until the next time I come into contact with this aspect.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325774535&siteId=291194637