레이블이 Blink인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Blink인 게시물을 표시합니다. 모든 게시물 표시

2017년 4월 29일 토요일

(E)Silicon Labs C8051 LED Blinky Example Explained(C8051 chip 기본동작 LED 예제로 설명하기)

Purpose
for newbie(software engineer) to understand basic concept of embedded programming.
line by line explanation.

Preparation
board: C8051F560 Development Kit
part(Chip): C8051F568-ACK06Z
datasheet: C8051F55x/56x/57x
development kit document: C8051F560 DEVELOPMENT KIT USER ’S GUIDE
development Tool: Simplicity Studio v4
silicon labs debugger
PC(notebook)

Prerequisite
install simplicity studio v4
connect PC-board-debugger

Create (example) project
simplicity IDE - File - New - Project - Silicon Labs MCU Project
select board
select part
select project type:example
select f55x-57x Blinky
copy contents

Explanation
1. Program Description:
  This program flashes the green LED on the C8051F560 target board about
  five times a second using the interrupt handler for Timer2.

2. How To Test:
  1) Download code to the 'F560 target board
  2) Ensure that the P1.3 pins are shorted together on the J19 header
  3) Run the program.  If the LED flashes, the program is working
  J19: Side A: Connects P1.3_A LED and P1.4_A Switch to MCU port pins


3. Code:
  // Includes
  // Global CONSTANTS -> set system clock speed, and select pin to connect to LED
  // Function PROTOTYPES
  //// OSCILLATOR_Init -> set oscillator speed
  //// PORT_Init -> set pin to manipulate LED
  //// TIMER2_Init -> set timer speed, init(&reload) value, enable interrupt and start timer
  // Interrupt Service Routines
  //// Timer2_ISR -> set interrupt service routine function when timer executed
  // MAIN Routine -> initialize and execute while not to exit firmware.

4. line by line code explanation.
    1) Total 175 line of Code
        - 93 lines of Comments
        - 16 lines of new line
        - 66 line of (meaningful) code
    2) will be continued

37: #include <SI_C8051F550_Defs.h>
-> SFR(Special Function Register) address
-> (IRN) Interrupt Request Numbers

38: #include <SI_C8051F550_Register_Enums.h>
-> Register Names

44: #define SYSCLK       24000000/8        // SYSCLK frequency in Hz
SYSCLK : System  Clock
Processor Clock: Chip Clock
-> more explanation needed
reference: Link

46: SBIT (LED, SFR_P1, 3);                 // LED='1' means ON
LED is variable to connect SFR_P1(port 1), pin 3 with rear LED.
so LED=1 make LED light on

52: void OSCILLATOR_Init (void);
initialize oscillator for oscillation of the crystal

53: void PORT_Init (void);
set pin to execute the chip for purpose
in this case LED pin

54: void TIMER2_Init (U16 counts);
configuration timer 2 to execute chip.
configure consists Interrupt Service Routine, Auto-reload, Timer base

59 ~ 75: Main
explained later

88 ~ 96: OSCILLATOR_Init function
88: void OSCILLATOR_Init (void)
89: {
90:    U8 SFRPAGE_save = SFRPAGE;
To read or modifying the SFR value, we need to contact the register.
the steps are
1. Select the appropriate SFR page number using the SFRPAGE register.
2. Use direct accessing mode to read or write the special function register (MOV instruction).

SFR has pages, for C8051F55x/56x/57x family of devices utilizes three SFR pages: 0x00, 0x0C, and 0x0F (ref: datasheet 12.1. SFR Paging)

91:    SFRPAGE = CONFIG_PAGE;
CONFIG_PAGE is 0x0F, and to modify OSCICN register this address should be accessed
92:
93:    OSCICN = 0xC4;                      // Set oscillator divide to /8
OSCICN: Internal Oscillator Control
0xC4 saids 100: SYSCLK derived from Internal Oscillator divided by 8.
datasheet saids SFR Address = 0xA1; SFR Page = 0x0F
so this makes system clock to 24000000(default) / 8 (line 44)
94:
95:    SFRPAGE = SFRPAGE_save;
return pre-sfrpage
96: }

111: void PORT_Init (void)
112: {
113:    U8 SFRPAGE_save = SFRPAGE;
114:    SFRPAGE = CONFIG_PAGE;
115:
116:    P1MDOUT |= 0x08;                 // Enable LED as a push-pull output
P1MDOUT was declared as
SFR (P1MDOUT,     0xA5); ///< Port 1 Output Mode
0xA5 address's value is assigned to P1MDOUT
to configure P1MDOUT(Port 1 mode Out)
it can be done with config2.exe
0x08 is 00001000 as binary and this means port 1 pin 3 is push-pull output
117:    P1SKIP  |= 0x08;                    // Skip the LED pin on the crossbar
skip port 1 pin 3 not to connect any peripheral
119:    XBR2     = 0x40;                    // Enable crossbar and weak pull-ups
see ref1 below
121:    SFRPAGE = SFRPAGE_save;
122: }

137: void TIMER2_Init (U16 counts)
138: {
139:    U8 SFRPAGE_save = SFRPAGE;
140:    SFRPAGE = LEGACY_PAGE;

142:   TMR2CN  = 0x00;                  // Stop Timer2; Clear TF2;
                                                 // use SYSCLK/12 as timebase
144:   CKCON  &= ~0x60;               // Timer2 clocked based on T2XCLK; <- same as above comment(SYSCLK/12 as timebase)

146:   TMR2RL  = -counts;              // Init reload values
timebase is 250,000 hz(250,000 cycles in 1 second)
counts value is 25,000(number, cycles) so
25,000 times takes 25,000 / 250,000 * 1seconds = 1/10 seconds.
this means 10hz frequency
147:   TMR2    = 0xFFFF;                // Set to reload immediately
148:   IE_ET2  = 1;                        // Enable Timer2 interrupts
149:   TMR2CN_TR2 = 1;               // Start Timer2

151:   SFRPAGE = SFRPAGE_save;
152:}

Timer 2
-> check the block diagram related to each register
-> understand datasheet register definition


166: INTERRUPT(TIMER2_ISR, TIMER2_IRQn)
when timer2 interrupt occurs(TIMER2_IRQn, 5 as constant) this TIMER2_ISR function(interrupt service routine) executed
167: {
168:    TMR2CN_TF2H = 0;               // Clear Timer2 interrupt flag
clear flag for next interrupt, because this function already executed.
169:    LED = !LED;                         // Change state of LED
LED represents LED pin
toggle means once on and once off when this interrupt service routine occurs
170: }

ref1: Link
Basically, it gives the designer the flexibility to chose which pins the desired peripheral is routed to. Let's say you have a UART devices that needs to connect to pins P1.0 and P1.1. The crossbar allows you to bring that signal out to that pin or a different supported pin in another design. Think of it as a multiplexer. Each physical pin is an output and all the peripherals are the inputs.

Hope that helps. Every micro controller has this sort of functionality, though usually a pin is limited to a few peripherals it can connect to. This is generally called "pin muxing".