From 3983f39f34e8fb8c1908aef86168268438c0aed0 Mon Sep 17 00:00:00 2001 From: zchong_cht Date: Wed, 11 Nov 2015 23:44:05 +0800 Subject: Add iar compiler support for am335x. --- bsp/beaglebone/AM335x_sk_DDR3.mac | 551 ++++++++++++++++ bsp/beaglebone/am335x_DDR.icf | 44 ++ bsp/beaglebone/am335x_sk.ewp | 1123 +++++++++++++++++++++++++++++++++ bsp/beaglebone/am335x_sk.eww | 9 + bsp/beaglebone/applications/startup.c | 9 +- bsp/beaglebone/drivers/serial.c | 452 ------------- bsp/beaglebone/drivers/serial.h | 20 - bsp/beaglebone/drivers/serial_reg.h | 109 ---- bsp/beaglebone/drivers/uart.c | 452 +++++++++++++ bsp/beaglebone/drivers/uart.h | 20 + bsp/beaglebone/drivers/uart_reg.h | 109 ++++ bsp/beaglebone/rtconfig.h | 2 +- libcpu/arm/am335x/cp15_iar.s | 154 +++++ libcpu/arm/am335x/cpu.c | 3 + libcpu/arm/am335x/interrupt.c | 14 +- libcpu/arm/am335x/start_iar.s | 292 +++++++++ 16 files changed, 2779 insertions(+), 584 deletions(-) create mode 100644 bsp/beaglebone/AM335x_sk_DDR3.mac create mode 100644 bsp/beaglebone/am335x_DDR.icf create mode 100644 bsp/beaglebone/am335x_sk.ewp create mode 100644 bsp/beaglebone/am335x_sk.eww delete mode 100644 bsp/beaglebone/drivers/serial.c delete mode 100644 bsp/beaglebone/drivers/serial.h delete mode 100644 bsp/beaglebone/drivers/serial_reg.h create mode 100644 bsp/beaglebone/drivers/uart.c create mode 100644 bsp/beaglebone/drivers/uart.h create mode 100644 bsp/beaglebone/drivers/uart_reg.h create mode 100644 libcpu/arm/am335x/cp15_iar.s create mode 100644 libcpu/arm/am335x/start_iar.s diff --git a/bsp/beaglebone/AM335x_sk_DDR3.mac b/bsp/beaglebone/AM335x_sk_DDR3.mac new file mode 100644 index 0000000000..739a03adbd --- /dev/null +++ b/bsp/beaglebone/AM335x_sk_DDR3.mac @@ -0,0 +1,551 @@ +// ----------------------------------------------------------------------- +// This file contains the initial set up configuration for the AM335x. +//------------------------------------------------------------------------- + +__var clk_in; + +CHGBIT (addr, mask, data) +{ +__var reg; + reg = __readMemory32(addr, "Memory"); + reg &= ~mask; + reg |= data; + __writeMemory32(reg, addr, "Memory"); +} + +CLRBIT (addr, mask) +{ +__var reg; + reg = __readMemory32(addr, "Memory"); + reg &= ~mask; + __writeMemory32(reg, addr, "Memory"); +} + +SETBIT (addr, mask) +{ +__var reg; + reg = __readMemory32(addr, "Memory"); + reg |= mask; + __writeMemory32(reg, addr, "Memory"); +} + +TESTBIT (addr, mask) +{ + return(__readMemory32(addr, "Memory") & mask); +} + + +get_input_clock_frequency() +{ + __var temp; + + temp = __readMemory32(((0x44E10000) + 0x40), "Memory"); + temp = temp >> 22; + temp = temp & 0x3; + + if(temp == 0) + { + clk_in = 19; //19.2MHz + __message "Input Clock Read from SYSBOOT[15:14]: 19.2MHz\n"; + } + if(temp == 1) + { + clk_in = 24; //24MHz + __message "Input Clock Read from SYSBOOT[15:14]: 24MHz\n"; + } + if(temp == 2) + { + clk_in = 25; //25MHz + __message "Input Clock Read from SYSBOOT[15:14]: 25MHz\n"; + } + if(temp == 3) + { + clk_in = 26; //26MHz + __message "Input Clock Read from SYSBOOT[15:14]: 26MHz\n"; + } +} + +mpu_pll_config( clk_in, N, M, M2) +{ + __var ref_clk,clk_out; + __var clkmode,clksel,div_m2,idlest_dpll; + __var temp,i; + + ref_clk = clk_in/(N+1); + clk_out = (ref_clk*M)/M2; + + clkmode=__readMemory32((0x44E00000 + 0x488), "Memory"); + clksel= __readMemory32((0x44E00000 + 0x42C), "Memory"); + div_m2= __readMemory32((0x44E00000 + 0x4A8), "Memory"); + + __message "**** Going to Bypass... \n"; + + //put the DPLL in bypass mode + __writeMemory32(0x4, (0x44E00000 + 0x488), "Memory"); + + while(((__readMemory32((0x44E00000 + 0x420), "Memory") & 0x101) != 0x00000100)); //wait for bypass status + + __message "**** Bypassed, changing values... \n"; + + //set multiply and divide values + clksel = clksel & (~0x7FFFF); + clksel = clksel | ((M <<0x8) | N); + __writeMemory32(clksel, (0x44E00000 + 0x42C), "Memory"); + div_m2 = div_m2 & ~0x1F; + div_m2 = div_m2 | M2; + __writeMemory32(div_m2, (0x44E00000 + 0x4A8), "Memory"); + + __message "**** Locking ARM PLL\n"; + + //now lock the DPLL + clkmode = clkmode | 0x7; //enables lock mode + __writeMemory32(clkmode, (0x44E00000 + 0x488), "Memory"); + while(((__readMemory32((0x44E00000 + 0x420), "Memory") & 0x101) != 0x1)); //wait for lock +} + + +core_pll_config( clk_in, N, M, M4, M5, M6) +{ + __var ref_clk,clk_out4,clk_out5,clk_out6; + __var clkmode,clksel,div_m4,div_m5,div_m6,idlest_dpll; + + ref_clk = clk_in/(N+1); + clk_out4 = (ref_clk*M)/M4; //M4=200MHz + clk_out5 = (ref_clk*M)/M5; //M5=250MHz + clk_out6 = (ref_clk*M)/M6; //M6=500MHz + + clkmode= __readMemory32((0x44E00000 + 0x490), "Memory"); + clksel= __readMemory32((0x44E00000 + 0x468), "Memory"); + div_m4= __readMemory32((0x44E00000 + 0x480), "Memory"); + div_m5= __readMemory32((0x44E00000 + 0x484), "Memory"); + div_m6= __readMemory32((0x44E00000 + 0x4D8), "Memory"); + + //put DPLL in bypass mode + clkmode = (clkmode & 0xfffffff8)|0x00000004; + __writeMemory32(clkmode, (0x44E00000 + 0x490), "Memory"); + while((__readMemory32((0x44E00000 + 0x45C), "Memory") & 0x00000100 )!=0x00000100); //wait for bypass status + + __message "**** Core Bypassed\n"; + + //set multiply and divide values + clksel = clksel & (~0x7FFFF); + clksel = clksel | ((M <<0x8) | N); + __writeMemory32(clksel, (0x44E00000 + 0x468), "Memory"); + div_m4= M4; //200MHz + __writeMemory32(div_m4, (0x44E00000 + 0x480), "Memory"); + div_m5= M5; //250MHz + __writeMemory32(div_m5, (0x44E00000 + 0x484), "Memory"); + div_m6= M6; //500MHz + __writeMemory32(div_m6, (0x44E00000 + 0x4D8), "Memory"); + + __message "**** Now locking Core...\n"; + + //now lock the PLL + clkmode =(clkmode&0xfffffff8)|0x00000007; + __writeMemory32(clkmode, (0x44E00000 + 0x490), "Memory"); + + while((__readMemory32((0x44E00000 + 0x45C), "Memory") & 0x00000001 )!=0x00000001); + __message "**** Core locked\n"; +} + +ddr_pll_config( clk_in, N, M, M2) +{ + __var ref_clk,clk_out ; + __var clkmode,clksel,div_m2,idlest_dpll; + + ref_clk = clk_in/(N+1); + clk_out = (ref_clk*M)/M2; + + clkmode=__readMemory32((0x44E00000 + 0x494), "Memory"); + clksel= __readMemory32((0x44E00000 + 0x440), "Memory"); + div_m2= __readMemory32((0x44E00000 + 0x4A0), "Memory"); + + clkmode =(clkmode&0xfffffff8)|0x00000004; + __writeMemory32(clkmode, (0x44E00000 + 0x494), "Memory"); + while((__readMemory32((0x44E00000 + 0x434), "Memory") & 0x00000100 )!=0x00000100); + + __message "**** DDR DPLL Bypassed\n"; + + clksel = clksel & (~0x7FFFF); + clksel = clksel | ((M <<0x8) | N); + __writeMemory32(clksel, (0x44E00000 + 0x440), "Memory"); + div_m2 = __readMemory32((0x44E00000 + 0x4A0), "Memory"); + div_m2 = (div_m2&0xFFFFFFE0) | M2; + __writeMemory32(div_m2, (0x44E00000 + 0x4A0), "Memory"); + clkmode =(clkmode&0xfffffff8)|0x00000007; + __writeMemory32(clkmode, (0x44E00000 + 0x494), "Memory"); + + while((__readMemory32((0x44E00000 + 0x434), "Memory") & 0x00000001 )!=0x00000001); + + __message "**** DDR DPLL Locked\n"; +} + +per_pll_config( clk_in, N, M, M2) +{ + __var ref_clk,clk_out; + __var clkmode,clksel,div_m2,idlest_dpll; + + ref_clk = clk_in/(N+1); + clk_out = (ref_clk*M)/M2; + + clkmode=__readMemory32((0x44E00000 + 0x48C), "Memory"); + clksel= __readMemory32((0x44E00000 + 0x49C), "Memory"); + div_m2= __readMemory32((0x44E00000 + 0x4AC), "Memory"); + + clkmode =(clkmode&0xfffffff8)|0x00000004; + __writeMemory32(clkmode, (0x44E00000 + 0x48C), "Memory"); + while((__readMemory32((0x44E00000 + 0x470), "Memory") & 0x00000100 )!=0x00000100); + + __message "**** PER DPLL Bypassed\n"; + + clksel = clksel & (~0x7FFFF); + clksel = clksel | ((M <<0x8) | N); + __writeMemory32(clksel, (0x44E00000 + 0x49C), "Memory"); + div_m2= 0xFFFFFF80 | M2; + __writeMemory32(div_m2, (0x44E00000 + 0x4AC), "Memory"); + clkmode =(clkmode&0xfffffff8)|0x00000007; + __writeMemory32(clkmode,(0x44E00000 + 0x48C), "Memory"); + + while((__readMemory32((0x44E00000 + 0x470), "Memory") & 0x00000001 )!=0x00000001); + + __message "**** PER DPLL Locked\n"; +} + +disp_pll_config( clk_in, N, M, M2) +{ + __var ref_clk,clk_out; + __var clkmode,clksel,div_m2,idlest_dpll; + + __message "**** DISP PLL Config is in progress .......... \n"; + + ref_clk = clk_in/(N+1); + clk_out = (ref_clk*M)/M2; + + clkmode=__readMemory32((0x44E00000 + 0x498), "Memory"); + clksel= __readMemory32((0x44E00000 + 0x454), "Memory"); + div_m2= __readMemory32((0x44E00000 + 0x4A4), "Memory"); + + clkmode =(clkmode&0xfffffff8)|0x00000004; + __writeMemory32(clkmode, (0x44E00000 + 0x498), "Memory"); + while((__readMemory32((0x44E00000 + 0x448), "Memory") & 0x00000100 )!=0x00000100); + + clksel = clksel & (~0x7FFFF); + clksel = clksel | ((M <<0x8) | N); + __writeMemory32(clksel, (0x44E00000 + 0x454), "Memory"); + div_m2= 0xFFFFFFE0 | M2; + __writeMemory32(div_m2, (0x44E00000 + 0x4A4), "Memory"); + clkmode =(clkmode&0xfffffff8)|0x00000007; + __writeMemory32(clkmode, (0x44E00000 + 0x498), "Memory"); + + while((__readMemory32((0x44E00000 + 0x448), "Memory") & 0x00000001 )!=0x00000001); + + __message "**** DISP PLL Config is DONE .......... \n"; +} + +arm_opp120_config() +{ + __message "**** Subarctic ALL ADPLL Config for OPP == OPP100 is In Progress ......... \n"; + get_input_clock_frequency(); + + if (clk_in == 24) + { + mpu_pll_config(clk_in, 23, 550, 1); + core_pll_config(clk_in, 23, 1000, 10, 8, 4); + ddr_pll_config(clk_in, 23, 303, 1); + per_pll_config(clk_in, 23, 960, 5); + disp_pll_config(clk_in, 23, 48, 1); + __message "**** Subarctic ALL ADPLL Config for OPP == OPP100 is Done ......... \n"; + } + else + { + __message "**** Subarctic PLL Config failed!! Check SYSBOOT[15:14] for proper input freq config \n"; + } + +} + + +emif_prcm_clk_enable() +{ + __message "EMIF PRCM is in progress ....... \n"; + + __writeMemory32(0x2, (0x44E00000 + 0x0D0), "Memory"); + __writeMemory32(0x2, (0x44E00000 + 0x028), "Memory"); + while(__readMemory32((0x44E00000 + 0x028), "Memory")!= 0x02); + + __message "EMIF PRCM Done \n"; +} + +vtp_enable() +{ + /* Write 1 to enable VTP */ + __writeMemory32((__readMemory32(((0x44E10000) + 0x0E0C), "Memory") | 0x00000040),((0x44E10000) + 0x0E0C) , "Memory"); + /* Write 0 to CLRZ bit */ + __writeMemory32((__readMemory32(((0x44E10000) + 0x0E0C), "Memory") & 0xFFFFFFFE),((0x44E10000) + 0x0E0C) ,"Memory"); + /* Write 1 to CLRZ bit */ + __writeMemory32((__readMemory32(((0x44E10000) + 0x0E0C), "Memory") | 0x00000001),((0x44E10000) + 0x0E0C) , "Memory"); + __message "Waiting for VTP Ready .......\n"; + while((__readMemory32(((0x44E10000) + 0x0E0C), "Memory") & 0x00000020) != 0x00000020); + + __message "VTP Enable Done \n"; +} + +cmd_macro_config( REG_PHY_CTRL_SLAVE_RATIO_value, CMD_REG_PHY_CTRL_SLAVE_FORCE_value, CMD_REG_PHY_CTRL_SLAVE_DELAY_value, PHY_DLL_LOCK_DIFF_value, CMD_PHY_INVERT_CLKOUT_value) +{ + __message "\DDR PHY CMD0 Register configuration is in progress ....... \n"; + + __writeMemory32(REG_PHY_CTRL_SLAVE_RATIO_value, (0x01C + (0x44E12000)), "Memory"); + __writeMemory32(CMD_REG_PHY_CTRL_SLAVE_FORCE_value, (0x020 + (0x44E12000)), "Memory"); + __writeMemory32(CMD_REG_PHY_CTRL_SLAVE_DELAY_value, (0x024 + (0x44E12000)), "Memory"); + __writeMemory32(PHY_DLL_LOCK_DIFF_value, (0x028 + (0x44E12000)), "Memory"); + __writeMemory32(CMD_PHY_INVERT_CLKOUT_value, (0x02C + (0x44E12000)), "Memory"); + + __message "\DDR PHY CMD1 Register configuration is in progress ....... \n"; + + __writeMemory32(REG_PHY_CTRL_SLAVE_RATIO_value, (0x050 + (0x44E12000)), "Memory"); + __writeMemory32(CMD_REG_PHY_CTRL_SLAVE_FORCE_value, (0x054 + (0x44E12000)), "Memory"); + __writeMemory32(CMD_REG_PHY_CTRL_SLAVE_DELAY_value, (0x058 + (0x44E12000)), "Memory"); + __writeMemory32(PHY_DLL_LOCK_DIFF_value, (0x05C + (0x44E12000)), "Memory"); + __writeMemory32(CMD_PHY_INVERT_CLKOUT_value, (0x060 + (0x44E12000)), "Memory"); + + __message "\DDR PHY CMD2 Register configuration is in progress ....... \n"; + + __writeMemory32(REG_PHY_CTRL_SLAVE_RATIO_value, (0x084 + (0x44E12000)), "Memory"); + __writeMemory32(CMD_REG_PHY_CTRL_SLAVE_FORCE_value, (0x088 + (0x44E12000)), "Memory"); + __writeMemory32(CMD_REG_PHY_CTRL_SLAVE_DELAY_value, (0x08C + (0x44E12000)), "Memory"); + __writeMemory32(PHY_DLL_LOCK_DIFF_value, (0x090 + (0x44E12000)), "Memory"); + __writeMemory32(CMD_PHY_INVERT_CLKOUT_value, (0x094 + (0x44E12000)), "Memory"); +} + +data_macro_config( dataMacroNum, PHY_RD_DQS_SLAVE_RATIO_value, PHY_WR_DQS_SLAVE_RATIO_value, REG_PHY_WRLVL_INIT_RATIO_value, + REG_PHY_GATELVL_INIT_RATIO_value, REG_PHY_FIFO_WE_SLAVE_RATIO_value, REG_PHY_WR_DATA_SLAVE_RATIO_value) +{ + __var offset; + if(dataMacroNum == 0) + { + offset = 0x00; + __message "DDR PHY DATA0 Register configuration is in progress ....... \n"; + } + else if(dataMacroNum == 1) + { + offset = 0xA4; + __message "DDR PHY DATA1 Register configuration is in progress ....... \n"; + } + + __writeMemory32(((PHY_RD_DQS_SLAVE_RATIO_value<<30)|(PHY_RD_DQS_SLAVE_RATIO_value<<20)|(PHY_RD_DQS_SLAVE_RATIO_value<<10)|(PHY_RD_DQS_SLAVE_RATIO_value<<0)), ((0x0C8 + (0x44E12000)) + offset), "Memory"); + __writeMemory32(PHY_RD_DQS_SLAVE_RATIO_value>>2, ((0x0CC + (0x44E12000)) + offset), "Memory"); + + __writeMemory32(((PHY_WR_DQS_SLAVE_RATIO_value<<30)|(PHY_WR_DQS_SLAVE_RATIO_value<<20)|(PHY_WR_DQS_SLAVE_RATIO_value<<10)|(PHY_WR_DQS_SLAVE_RATIO_value<<0)), ((0x0DC + (0x44E12000)) + offset), "Memory"); + __writeMemory32(PHY_WR_DQS_SLAVE_RATIO_value>>2, ((0x0E0 + (0x44E12000)) + offset), "Memory"); + + __writeMemory32(((REG_PHY_WRLVL_INIT_RATIO_value<<30)|(REG_PHY_WRLVL_INIT_RATIO_value<<20)|(REG_PHY_WRLVL_INIT_RATIO_value<<10)|(REG_PHY_WRLVL_INIT_RATIO_value<<0)), ((0x0F0 + (0x44E12000)) + offset), "Memory"); + __writeMemory32(REG_PHY_WRLVL_INIT_RATIO_value>>2, ((0x0F4 + (0x44E12000)) + offset), "Memory"); + + __writeMemory32(((REG_PHY_GATELVL_INIT_RATIO_value<<30)|(REG_PHY_GATELVL_INIT_RATIO_value<<20)|(REG_PHY_GATELVL_INIT_RATIO_value<<10)|(REG_PHY_GATELVL_INIT_RATIO_value<<0)), ((0x0FC + (0x44E12000)) + offset), "Memory"); + __writeMemory32(REG_PHY_GATELVL_INIT_RATIO_value>>2, ((0x100 + (0x44E12000)) + offset), "Memory"); + + __writeMemory32(((REG_PHY_FIFO_WE_SLAVE_RATIO_value<<30)|(REG_PHY_FIFO_WE_SLAVE_RATIO_value<<20)|(REG_PHY_FIFO_WE_SLAVE_RATIO_value<<10)|(REG_PHY_FIFO_WE_SLAVE_RATIO_value<<0)), ((0x108 + (0x44E12000)) + offset), "Memory"); + __writeMemory32(REG_PHY_FIFO_WE_SLAVE_RATIO_value>>2,((0x10C + (0x44E12000)) + offset), "Memory"); + + __writeMemory32(((REG_PHY_WR_DATA_SLAVE_RATIO_value<<30)|(REG_PHY_WR_DATA_SLAVE_RATIO_value<<20)|(REG_PHY_WR_DATA_SLAVE_RATIO_value<<10)|(REG_PHY_WR_DATA_SLAVE_RATIO_value<<0)),((0x120 + (0x44E12000)) + offset), "Memory"); + __writeMemory32(REG_PHY_WR_DATA_SLAVE_RATIO_value>>2, ((0x124 + (0x44E12000)) + offset), "Memory"); + __writeMemory32(0x0,((0x138 + (0x44E12000)) + offset), "Memory"); +} + + +emif_mmr_config( Read_Latency, Timing1, Timing2, Timing3, Sdram_Config, Ref_Ctrl) +{ + __var i; + + __message "emif Timing register configuration is in progress ....... \n"; + + __writeMemory32(Read_Latency, (0x4C000000 + 0x0E4), "Memory"); + __writeMemory32(Read_Latency, (0x4C000000 + 0x0E8), "Memory"); + __writeMemory32(Read_Latency, (0x4C000000 + 0x0EC), "Memory"); + + __writeMemory32(Timing1, (0x4C000000 + 0x018), "Memory"); + __writeMemory32(Timing1, (0x4C000000 + 0x01C), "Memory"); + + __writeMemory32(Timing2, (0x4C000000 + 0x020), "Memory"); + __writeMemory32(Timing2, (0x4C000000 + 0x024), "Memory"); + + __writeMemory32(Timing3, (0x4C000000 + 0x028), "Memory"); + __writeMemory32(Timing3, (0x4C000000 + 0x02C), "Memory"); + + __writeMemory32(Sdram_Config, (0x4C000000 + 0x008), "Memory"); + __writeMemory32(Sdram_Config, (0x4C000000 + 0x00C), "Memory"); + __writeMemory32(0x00004650, (0x4C000000 + 0x010), "Memory"); + __writeMemory32(0x00004650, (0x4C000000 + 0x014), "Memory"); + + for(i=0;i<5000;i++) + { + } + + __writeMemory32(Ref_Ctrl, (0x4C000000 + 0x010), "Memory"); + __writeMemory32(Ref_Ctrl, (0x4C000000 + 0x014), "Memory"); + + __writeMemory32(Sdram_Config, (0x4C000000 + 0x008), "Memory"); + __writeMemory32(Sdram_Config, (0x4C000000 + 0x00C), "Memory"); + + __message "emif Timing register configuration is done ....... \n"; +} + +gpio_module_clk_config() +{ + __var buff; + + buff = __readMemory32((0x400 + 0x44E00000 + 0x8), "Memory"); + + buff |= 0x2; + + __writeMemory32(buff, (0x400 + 0x44E00000 + 0x8), "Memory"); + + while((__readMemory32((0x400 + 0x44E00000 + 0x8), "Memory") & 0x3) != 0x2); + + buff = __readMemory32((0x400 + 0x44E00000 + 0x8), "Memory"); + + buff |= 0x00040000; + + __writeMemory32(buff, (0x400 + 0x44E00000 + 0x8), "Memory"); + + while((__readMemory32((0x400 + 0x44E00000 + 0x8), "Memory") & 0x00040000) != 0x00040000); + + while((__readMemory32((0x400 + 0x44E00000 + 0x8), "Memory") & 0x00030000) != 0x0); + + while((__readMemory32((0x400 + 0x44E00000), "Memory") & 0x00000100) != 0x00000100); + + __message "GPIO module clock configuration is done ....... \n"; + +} + +phy_config_cmd() +{ + __var i; + + for(i = 0; i < 3; i++) + { + __message "DDR PHY CMD Register configuration is in progress ....... \n"; + + __writeMemory32(0x40, ((0x44E12000 + 0x01c) + (i * 0x34)), "Memory"); + + __writeMemory32(0x1, ((0x44E12000 + 0x02c) + (i * 0x34)), "Memory"); + + } + +} + +phy_config_data() +{ + __var i; + + for(i = 0; i < 2; i++) + { + __message "DDR PHY Data Register configuration is in progress ....... \n"; + + __writeMemory32(0x3B, ((0x44E12000 + 0x0c8) + (i * 0xA4)), "Memory"); + + __writeMemory32(0x85, ((0x44E12000 + 0x0DC) + (i * 0xA4)), "Memory"); + + __writeMemory32(0x100, ((0x44E12000 + 0x108) + (i * 0xA4)), "Memory"); + + __writeMemory32(0xC1, ((0x44E12000 + 0x120) + (i * 0xA4)), "Memory"); + + } + +} + +ddr3_emif_config() +{ + __message "**** AM335x OPP120 DDR3 EMIF and PHY configuration is in progress......... \n"; + + emif_prcm_clk_enable(); + + __message "DDR PHY Configuration In progress \n"; + + /* Perform GPIO module clock configuration. */ + gpio_module_clk_config(); + + __writeMemory32(0x00000067, (0x44E10000 + 0x964), "Memory"); + + __writeMemory32((__readMemory32((0x44E07000 + 0x130), "Memory") & 0xFFFFFFFE), (0x44E07000 + 0x130), "Memory"); + + __writeMemory32((__readMemory32((0x44E07000 + 0x10), "Memory") | 0x02), (0x44E07000 + 0x10), "Memory"); + + /* Wait until GPIO module is reset. */ + + while(!(__readMemory32((0x44E07000 + 0x114), "Memory") & 0x01)); + + __writeMemory32((__readMemory32((0x44E07000 + 0x134), "Memory") & ~(1 << 7)), (0x44E07000 + 0x134), "Memory"); + + __writeMemory32((1 << 7), (0x44E07000 + 0x194), "Memory"); + + __writeMemory32((__readMemory32((0x44E10000 + 0x0E0C), "Memory") & 0xFFFFFFFE), (0x44E10000 + 0x0E0C), "Memory"); + + __writeMemory32((__readMemory32((0x44E10000 + 0x0E0C), "Memory") | 0x00000001), (0x44E10000 + 0x0E0C), "Memory"); + + vtp_enable(); + + phy_config_cmd(); + + phy_config_data(); + + __writeMemory32(0x18B, (0x1404 + 0x44E10000), "Memory"); + __writeMemory32(0x18B, (0x1408 + 0x44E10000), "Memory"); + __writeMemory32(0x18B, (0x140C + 0x44E10000), "Memory"); + __writeMemory32(0x18B, (0x1440 + 0x44E10000), "Memory"); + __writeMemory32(0x18B, (0x1444 + 0x44E10000), "Memory"); + + __writeMemory32((__readMemory32((0x0E04 + 0x44E10000), "Memory") & ~0x10000000), (0x0E04 + 0x44E10000), "Memory"); + + __writeMemory32((__readMemory32((0x131C + 0x44E10000), "Memory") | 0x00000001), (0x131C + 0x44E10000), "Memory"); + + __message "EMIF Timing register configuration is in progress ....... \n"; + + __writeMemory32(0x06, (0x0E4 + 0x4C000000), "Memory"); + __writeMemory32(0x06, (0x0E8 + 0x4C000000), "Memory"); + __writeMemory32(0x06, (0x0EC + 0x4C000000), "Memory"); + + __writeMemory32(0x0888A39B, (0x018 + 0x4C000000), "Memory"); + __writeMemory32(0x0888A39B, (0x01C + 0x4C000000), "Memory"); + + __writeMemory32(0x26337FDA, (0x020 + 0x4C000000), "Memory"); + __writeMemory32(0x26337FDA, (0x024 + 0x4C000000), "Memory"); + + __writeMemory32(0x501F830F, (0x028 + 0x4C000000), "Memory"); + __writeMemory32(0x501F830F, (0x02C + 0x4C000000), "Memory"); + + __writeMemory32(0x0000093B, (0x010 + 0x4C000000), "Memory"); + __writeMemory32(0x0000093B, (0x014 + 0x4C000000), "Memory"); + + __writeMemory32(0x50074BE4, (0x0C8 + 0x4C000000), "Memory"); + + __writeMemory32(0x61C04AB2, (0x008 + 0x4C000000), "Memory"); + + __message "EMIF Timing register configuration is done ....... \n"; + + if((__readMemory32((0x4C000000 + 0x004), "Memory") & 0x4) == 0x4) + { + __message "PHY is READY!!\n"; + } + + __message "DDR PHY Configuration done \n"; + + __message "**** AM335x OPP120 DDR3 EMIF and PHY configuration is done......... \n"; +} + +am335x_evm_initialization() +{ +__var psc_base; +__var reg; +__var module_offest; + + __message " AM335x EVM-SK Initialization is in progress .......... \n"; + arm_opp120_config(); + ddr3_emif_config(); + __message " AM335x EVM-SK Initialization is done .......... \n"; +} + +execUserPreload() +{ + am335x_evm_initialization(); +} + diff --git a/bsp/beaglebone/am335x_DDR.icf b/bsp/beaglebone/am335x_DDR.icf new file mode 100644 index 0000000000..8f158d8432 --- /dev/null +++ b/bsp/beaglebone/am335x_DDR.icf @@ -0,0 +1,44 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x82000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x82000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x87FFFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x88000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x8FFFFFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x100; +define symbol __ICFEDIT_size_svcstack__ = 0x1000; +define symbol __ICFEDIT_size_irqstack__ = 0x100; +define symbol __ICFEDIT_size_fiqstack__ = 0x100; +define symbol __ICFEDIT_size_undstack__ = 0x100; +define symbol __ICFEDIT_size_abtstack__ = 0x100; +define symbol __ICFEDIT_size_heap__ = 0x400; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { }; +define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { }; +define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { }; +define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { }; +define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; +keep { section FSymTab }; +keep { section VSymTab }; +keep { section .rti_fn* }; + +place at address mem :__ICFEDIT_intvec_start__ {readonly section .intvec}; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, + block UND_STACK, block ABT_STACK, block HEAP }; diff --git a/bsp/beaglebone/am335x_sk.ewp b/bsp/beaglebone/am335x_sk.ewp new file mode 100644 index 0000000000..c71c566b05 --- /dev/null +++ b/bsp/beaglebone/am335x_sk.ewp @@ -0,0 +1,1123 @@ + + + + 2 + + DDR Debug + + ARM + + 1 + + General + 3 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + app + + $PROJ_DIR$\applications\application.c + + + $PROJ_DIR$\applications\board.c + + + $PROJ_DIR$\applications\startup.c + + + + bsp + + $PROJ_DIR$\..\..\libcpu\arm\am335x\context_iar.S + + + $PROJ_DIR$\..\..\libcpu\arm\am335x\cp15_iar.s + + + $PROJ_DIR$\..\..\libcpu\arm\am335x\cpu.c + + + $PROJ_DIR$\..\..\libcpu\arm\am335x\interrupt.c + + + $PROJ_DIR$\..\..\libcpu\arm\am335x\stack.c + + + $PROJ_DIR$\..\..\libcpu\arm\am335x\start_iar.s + + + $PROJ_DIR$\..\..\libcpu\arm\am335x\trap.c + + + + components + + finsh + + $PROJ_DIR$\..\..\components\finsh\cmd.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_compiler.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_error.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_heap.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_init.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_node.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_ops.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_parser.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_token.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_var.c + + + $PROJ_DIR$\..\..\components\finsh\finsh_vm.c + + + $PROJ_DIR$\..\..\components\finsh\msh.c + + + $PROJ_DIR$\..\..\components\finsh\msh_cmd.c + + + $PROJ_DIR$\..\..\components\finsh\shell.c + + + $PROJ_DIR$\..\..\components\finsh\symbol.c + + + + $PROJ_DIR$\..\..\components\drivers\src\completion.c + + + $PROJ_DIR$\..\..\components\drivers\src\dataqueue.c + + + + drivers + + $PROJ_DIR$\..\..\components\drivers\serial\serial.c + + + $PROJ_DIR$\drivers\uart.c + + + + kernel + + $PROJ_DIR$\..\..\src\clock.c + + + $PROJ_DIR$\..\..\src\components.c + + + $PROJ_DIR$\..\..\src\device.c + + + $PROJ_DIR$\..\..\src\idle.c + + + $PROJ_DIR$\..\..\src\ipc.c + + + $PROJ_DIR$\..\..\src\irq.c + + + $PROJ_DIR$\..\..\src\kservice.c + + + $PROJ_DIR$\..\..\src\mem.c + + + $PROJ_DIR$\..\..\src\memheap.c + + + $PROJ_DIR$\..\..\src\mempool.c + + + $PROJ_DIR$\..\..\src\module.c + + + $PROJ_DIR$\..\..\src\object.c + + + $PROJ_DIR$\..\..\src\scheduler.c + + + $PROJ_DIR$\..\..\src\slab.c + + + $PROJ_DIR$\..\..\src\thread.c + + + $PROJ_DIR$\..\..\src\timer.c + + + + + diff --git a/bsp/beaglebone/am335x_sk.eww b/bsp/beaglebone/am335x_sk.eww new file mode 100644 index 0000000000..b9b4660828 --- /dev/null +++ b/bsp/beaglebone/am335x_sk.eww @@ -0,0 +1,9 @@ + + + + + $WS_DIR$\am335x_sk.ewp + + + + diff --git a/bsp/beaglebone/applications/startup.c b/bsp/beaglebone/applications/startup.c index a34e406a0a..c079240b63 100644 --- a/bsp/beaglebone/applications/startup.c +++ b/bsp/beaglebone/applications/startup.c @@ -10,6 +10,7 @@ * Change Logs: * Date Author Notes * 2012-12-05 Bernard the first version + * 2015-11-11 zchong support iar compiler */ #include @@ -18,7 +19,9 @@ #include extern int rt_application_init(void); - +#ifdef __ICCARM__ +#pragma section="HEAP" +#endif /** * This function will startup RT-Thread RTOS. */ @@ -34,7 +37,11 @@ void rtthread_startup(void) /* initialize memory system */ #ifdef RT_USING_HEAP +#ifdef __ICCARM__ +rt_system_heap_init(__segment_end("HEAP"), (void*)0x8FFFFFFF); +#else rt_system_heap_init(HEAP_BEGIN, HEAP_END); +#endif #endif /* initialize scheduler system */ diff --git a/bsp/beaglebone/drivers/serial.c b/bsp/beaglebone/drivers/serial.c deleted file mode 100644 index 776ef3fa3c..0000000000 --- a/bsp/beaglebone/drivers/serial.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * File : serial.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2013-07-06 Bernard the first version - * 2014-01-11 RTsien support UART0 to UART5 straightly - */ - -#include -#include -#include - -#include -#include -#include "serial.h" -#include "serial_reg.h" - -struct am33xx_uart -{ - unsigned long base; - int irq; -}; - -static void am33xx_uart_isr(int irqno, void* param) -{ - rt_uint32_t iir; - struct am33xx_uart* uart; - struct rt_serial_device *serial; - - serial = (struct rt_serial_device*)param; - uart = (struct am33xx_uart *)serial->parent.user_data; - - iir = UART_IIR_REG(uart->base); - - if ((iir & (0x02 << 1)) || (iir & (0x6 << 1))) - { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); - } -} - -#define NOT_IMPLEMENTED() RT_ASSERT(0) - -static rt_err_t am33xx_configure(struct rt_serial_device *serial, struct serial_configure *cfg) -{ - struct am33xx_uart* uart; - unsigned long base; - - RT_ASSERT(serial != RT_NULL); - uart = (struct am33xx_uart *)serial->parent.user_data; - RT_ASSERT(uart); - base = uart->base; - -#define __LCR UART_LCR_REG(base) - - if (cfg->data_bits == DATA_BITS_8) - __LCR |= 3; - else - NOT_IMPLEMENTED(); - - if (cfg->stop_bits == STOP_BITS_1) - __LCR &= ~(1<<2); - else - __LCR |= (1<<2); - - if (cfg->parity == PARITY_NONE) - __LCR &= ~(1<<3); - else - __LCR |= (1<<3); - - __LCR |= (1<<7); - if (cfg->baud_rate == BAUD_RATE_115200) - { - UART_DLL_REG(base) = 26; - UART_DLH_REG(base) = 0; - } - else if (cfg->baud_rate == BAUD_RATE_9600) - { - UART_DLL_REG(base) = 0x38; - UART_DLH_REG(base) = 1; - } - else - { - NOT_IMPLEMENTED(); - } - __LCR &= ~(1<<7); - - UART_MDR1_REG(base) = 0; - UART_MDR2_REG(base) = 0; - -#undef __LCR - return RT_EOK; -} - -static rt_err_t am33xx_control(struct rt_serial_device *serial, int cmd, void *arg) -{ - struct am33xx_uart* uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct am33xx_uart *)serial->parent.user_data; - - switch (cmd) - { - case RT_DEVICE_CTRL_CLR_INT: - /* disable rx irq */ - rt_hw_interrupt_mask(uart->irq); - break; - case RT_DEVICE_CTRL_SET_INT: - /* enable rx irq */ - rt_hw_interrupt_umask(uart->irq); - break; - } - - return RT_EOK; -} - -int printkc(char c) -{ - int base = 0xf9e09000; - - while (!(UART_LSR_REG(base) & 0x20)); - UART_THR_REG(base) = c; - - return 1; -} - -static int am33xx_putc(struct rt_serial_device *serial, char c) -{ - struct am33xx_uart* uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct am33xx_uart *)serial->parent.user_data; - - while (!(UART_LSR_REG(uart->base) & 0x20)); - UART_THR_REG(uart->base) = c; - - return 1; -} - -static int am33xx_getc(struct rt_serial_device *serial) -{ - int ch; - struct am33xx_uart* uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct am33xx_uart *)serial->parent.user_data; - - ch = -1; - if (UART_LSR_REG(uart->base) & 0x01) - { - ch = UART_RHR_REG(uart->base) & 0xff; - } - - return ch; -} - -static const struct rt_uart_ops am33xx_uart_ops = -{ - am33xx_configure, - am33xx_control, - am33xx_putc, - am33xx_getc, -}; - -/* UART device driver structure */ -#ifdef RT_USING_UART0 -struct am33xx_uart uart0 = -{ - UART0_BASE, - UART0_INT, -}; -struct rt_serial_device serial0; -#endif - -#ifdef RT_USING_UART1 -struct am33xx_uart uart1 = -{ - UART1_BASE, - UART1_INT, -}; -struct rt_serial_device serial1; -#endif - -#ifdef RT_USING_UART2 -struct am33xx_uart uart2 = -{ - UART2_BASE, - UART2_INT, -}; -struct rt_serial_device serial2; -#endif - -#ifdef RT_USING_UART3 -struct am33xx_uart uart3 = -{ - UART3_BASE, - UART3_INT, -}; -struct rt_serial_device serial3; -#endif - -#ifdef RT_USING_UART4 -struct am33xx_uart uart4 = -{ - UART4_BASE, - UART4_INT, -}; -struct rt_serial_device serial4; -#endif - -#ifdef RT_USING_UART5 -struct am33xx_uart uart5 = -{ - UART5_BASE, - UART5_INT, -}; -struct rt_serial_device serial5; -#endif - -#define write_reg(base, value) *(int*)(base) = value -#define read_reg(base) *(int*)(base) - -#define PRM_PER_INTRANSLATION (1 << 20) -#define PRM_PER_POWSTATEOFF (0) -#define PRM_PER_PERMEMSTATEOFF (0) - -static void poweron_per_domain(void) -{ - unsigned long prcm_base; - unsigned long prm_state; - - prcm_base = AM33XX_PRCM_REGS; - - /* wait for ongoing translations */ - for (prm_state = PRM_PER_PWRSTST_REG(prcm_base); - prm_state & PRM_PER_INTRANSLATION; - prm_state = PRM_PER_PWRSTST_REG(prcm_base)) - ; - - /* check power state */ - if ((prm_state & 0x03) == PRM_PER_POWSTATEOFF) - /* power on PER domain */ - PRM_PER_PWRSTCTRL_REG(prcm_base) |= 0x3; - - /* check per mem state */ - if ((prm_state & 0x03) == PRM_PER_PERMEMSTATEOFF) - /* power on PER domain */ - PRM_PER_PWRSTCTRL_REG(prcm_base) |= 0x3 << 25; - - while (PRM_PER_PWRSTST_REG(prcm_base) & PRM_PER_INTRANSLATION) - ; -} - -static void start_uart_clk(void) -{ - unsigned long prcm_base; - - prcm_base = AM33XX_PRCM_REGS; - - /* software forced wakeup */ - CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) |= 0x2; - - /* Waiting for the L4LS clock */ - while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<8))) - ; - - /* enable uart1 */ -#ifdef RT_USING_UART1 - CM_PER_UART1_CLKCTRL_REG(prcm_base) |= 0x2; - /* wait for uart1 clk */ - while ((CM_PER_UART1_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) - ; -#endif - -#ifdef RT_USING_UART2 - CM_PER_UART2_CLKCTRL_REG(prcm_base) |= 0x2; - /* wait for uart2 clk */ - while ((CM_PER_UART2_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) - ; -#endif - -#ifdef RT_USING_UART3 - CM_PER_UART3_CLKCTRL_REG(prcm_base) |= 0x2; - /* wait for uart3 clk */ - while ((CM_PER_UART3_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) - ; -#endif - -#ifdef RT_USING_UART4 - CM_PER_UART4_CLKCTRL_REG(prcm_base) |= 0x2; - /* wait for uart4 clk */ - while ((CM_PER_UART4_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) - ; -#endif - -#ifdef RT_USING_UART5 - CM_PER_UART5_CLKCTRL_REG(prcm_base) |= 0x2; - /* wait for uart5 clk */ - while ((CM_PER_UART5_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) - ; -#endif - - /* Waiting for the L4LS UART clock */ - while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<10))) - ; -} - -static void config_pinmux(void) -{ - unsigned long ctlm_base; - - ctlm_base = AM33XX_CTLM_REGS; - - /* make sure the pin mux is OK for uart */ -#ifdef RT_USING_UART1 - REG32(ctlm_base + 0x800 + 0x180) = 0x20; - REG32(ctlm_base + 0x800 + 0x184) = 0x00; -#endif - -#ifdef RT_USING_UART2 - REG32(ctlm_base + 0x800 + 0x150) = 0x20; - REG32(ctlm_base + 0x800 + 0x154) = 0x00; -#endif - -#ifdef RT_USING_UART3 - REG32(ctlm_base + 0x800 + 0x164) = 0x01; -#endif - -#ifdef RT_USING_UART4 - REG32(ctlm_base + 0x800 + 0x070) = 0x26; - REG32(ctlm_base + 0x800 + 0x074) = 0x06; -#endif - -#ifdef RT_USING_UART5 - REG32(ctlm_base + 0x800 + 0x0C4) = 0x24; - REG32(ctlm_base + 0x800 + 0x0C0) = 0x04; -#endif -} - -int rt_hw_serial_init(void) -{ - struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - - poweron_per_domain(); - start_uart_clk(); - config_pinmux(); - -#ifdef RT_USING_UART0 - serial0.ops = &am33xx_uart_ops; - serial0.config = config; - - /* enable RX interrupt */ - UART_IER_REG(uart0.base) = 0x01; - /* install ISR */ - rt_hw_interrupt_install(uart0.irq, am33xx_uart_isr, &serial0, "uart0"); - rt_hw_interrupt_control(uart0.irq, 0, 0); - rt_hw_interrupt_mask(uart0.irq); - /* register UART0 device */ - rt_hw_serial_register(&serial0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - &uart0); -#endif - -#ifdef RT_USING_UART1 - serial1.ops = &am33xx_uart_ops; - serial1.config = config; - /* enable RX interrupt */ - UART_IER_REG(uart1.base) = 0x01; - /* install ISR */ - rt_hw_interrupt_install(uart1.irq, am33xx_uart_isr, &serial1, "uart1"); - rt_hw_interrupt_control(uart1.irq, 0, 0); - rt_hw_interrupt_mask(uart1.irq); - /* register UART0 device */ - rt_hw_serial_register(&serial1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - &uart1); -#endif - -#ifdef RT_USING_UART2 - serial2.ops = &am33xx_uart_ops; - serial2.config = config; - /* enable RX interrupt */ - UART_IER_REG(uart2.base) = 0x01; - /* install ISR */ - rt_hw_interrupt_install(uart2.irq, am33xx_uart_isr, &serial2, "uart2"); - rt_hw_interrupt_control(uart2.irq, 0, 0); - rt_hw_interrupt_mask(uart2.irq); - /* register UART2 device */ - rt_hw_serial_register(&serial2, "uart2", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - &uart2); -#endif - -#ifdef RT_USING_UART3 - serial3.ops = &am33xx_uart_ops; - serial3.config = config; - /* enable RX interrupt */ - UART_IER_REG(uart3.base) = 0x01; - /* install ISR */ - rt_hw_interrupt_install(uart3.irq, am33xx_uart_isr, &serial3, "uart3"); - rt_hw_interrupt_control(uart3.irq, 0, 0); - rt_hw_interrupt_mask(uart3.irq); - /* register UART3 device */ - rt_hw_serial_register(&serial3, "uart3", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - &uart3); -#endif - -#ifdef RT_USING_UART4 - /* use 9600bps for GDB stub. */ - config.baud_rate = BAUD_RATE_9600; - - serial4.ops = &am33xx_uart_ops; - serial4.config = config; - /* enable RX interrupt */ - UART_IER_REG(uart4.base) = 0x00; - /* install ISR */ - rt_hw_interrupt_install(uart4.irq, am33xx_uart_isr, &serial4, "uart4"); - rt_hw_interrupt_control(uart4.irq, 0, 0); - rt_hw_interrupt_mask(uart4.irq); - /* register UART4 device */ - rt_hw_serial_register(&serial4, "uart4", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - &uart4); -#endif - -#ifdef RT_USING_UART5 - config.baud_rate = BAUD_RATE_115200; - - serial5.ops = &am33xx_uart_ops; - serial5.config = config; - /* enable RX interrupt */ - UART_IER_REG(uart5.base) = 0x01; - /* install ISR */ - rt_hw_interrupt_install(uart5.irq, am33xx_uart_isr, &serial5, "uart5"); - rt_hw_interrupt_control(uart5.irq, 0, 0); - rt_hw_interrupt_mask(uart5.irq); - /* register UART4 device */ - rt_hw_serial_register(&serial5, "uart5", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - &uart5); -#endif - - return 0; -} -INIT_BOARD_EXPORT(rt_hw_serial_init); diff --git a/bsp/beaglebone/drivers/serial.h b/bsp/beaglebone/drivers/serial.h deleted file mode 100644 index 15f7f2c399..0000000000 --- a/bsp/beaglebone/drivers/serial.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * File : serial.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2013-07-06 Bernard the first version - */ - -#ifndef __SERIAL_H__ -#define __SERIAL_H__ - -int rt_hw_serial_init(void); - -#endif diff --git a/bsp/beaglebone/drivers/serial_reg.h b/bsp/beaglebone/drivers/serial_reg.h deleted file mode 100644 index cb984631f8..0000000000 --- a/bsp/beaglebone/drivers/serial_reg.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef SERIAL_REG_H -#define SERIAL_REG_H - -/** @brief Base addresses of UART memory mapped registers */ -#define UART0_BASE (0x44E09000) -#define UART1_BASE (0x48022000) -#define UART2_BASE (0x48024000) -#define UART3_BASE (0x481A6000) -#define UART4_BASE (0x481A8000) -#define UART5_BASE (0x481AA000) - -/* UART registers */ -#define UART_DLL(base) (base + 0x0) -#define UART_RHR(base) (base + 0x0) -#define UART_THR(base) (base + 0x0) -#define UART_DLH(base) (base + 0x4) -#define UART_IER(base) (base + 0x4) -#define UART_EFR(base) (base + 0x8) -#define UART_FCR(base) (base + 0x8) -#define UART_IIR(base) (base + 0x8) -#define UART_LCR(base) (base + 0xC) -#define UART_MCR(base) (base + 0x10) -#define UART_XON1_ADDR1(base) (base + 0x10) -#define UART_LSR(base) (base + 0x14) -#define UART_XON2_ADDR2(base) (base + 0x14) -#define UART_MSR(base) (base + 0x18) -#define UART_TCR(base) (base + 0x18) -#define UART_XOFF1(base) (base + 0x18) -#define UART_SPR(base) (base + 0x1C) -#define UART_TLR(base) (base + 0x1C) -#define UART_XOFF2(base) (base + 0x1C) -#define UART_MDR1(base) (base + 0x20) -#define UART_MDR2(base) (base + 0x24) -#define UART_SFLSR(base) (base + 0x28) -#define UART_TXFLL(base) (base + 0x28) -#define UART_RESUME(base) (base + 0x2C) -#define UART_TXFLH(base) (base + 0x2C) -#define UART_RXFLL(base) (base + 0x30) -#define UART_SFREGL(base) (base + 0x30) -#define UART_RXFLH(base) (base + 0x34) -#define UART_SFREGH(base) (base + 0x34) -#define UART_BLR(base) (base + 0x38) -#define UART_UASR(base) (base + 0x38) -#define UART_ACREG(base) (base + 0x3C) -#define UART_SCR(base) (base + 0x40) -#define UART_SSR(base) (base + 0x44) -#define UART_EBLR(base) (base + 0x48) -#define UART_MVR(base) (base + 0x50) -#define UART_SYSC(base) (base + 0x54) -#define UART_SYSS(base) (base + 0x58) -#define UART_WER(base) (base + 0x5C) -#define UART_CFPS(base) (base + 0x60) -#define UART_RXFIFO_LVL(base) (base + 0x64) -#define UART_TXFIFO_LVL(base) (base + 0x68) -#define UART_IER2(base) (base + 0x6C) -#define UART_ISR2(base) (base + 0x70) -#define UART_FREQ_SEL(base) (base + 0x74) -#define UART_MDR3(base) (base + 0x80) -#define UART_TX_DMA_THRESHOLD(base) (base + 0x84) - -#define UART_DLL_REG(base) REG16(UART_DLL(base)) -#define UART_RHR_REG(base) REG16(UART_RHR(base)) -#define UART_THR_REG(base) REG16(UART_THR(base)) -#define UART_DLH_REG(base) REG16(UART_DLH(base)) -#define UART_IER_REG(base) REG16(UART_IER(base)) -#define UART_EFR_REG(base) REG16(UART_EFR(base)) -#define UART_FCR_REG(base) REG16(UART_FCR(base)) -#define UART_IIR_REG(base) REG16(UART_IIR(base)) -#define UART_LCR_REG(base) REG16(UART_LCR(base)) -#define UART_MCR_REG(base) REG16(UART_MCR(base)) -#define UART_XON1_ADDR1_REG(base) REG16(UART_XON1_ADDR1(base)) -#define UART_LSR_REG(base) REG16(UART_LSR(base)) -#define UART_XON2_ADDR2_REG(base) REG16(UART_XON2_ADDR2(base)) -#define UART_MSR_REG(base) REG16(UART_MSR(base)) -#define UART_TCR_REG(base) REG16(UART_TCR(base)) -#define UART_XOFF1_REG(base) REG16(UART_XOFF1(base)) -#define UART_SPR_REG(base) REG16(UART_SPR(base)) -#define UART_TLR_REG(base) REG16(UART_TLR(base)) -#define UART_XOFF2_REG(base) REG16(UART_XOFF2(base)) -#define UART_MDR1_REG(base) REG16(UART_MDR1(base)) -#define UART_MDR2_REG(base) REG16(UART_MDR2(base)) -#define UART_SFLSR_REG(base) REG16(UART_SFLSR(base)) -#define UART_TXFLL_REG(base) REG16(UART_TXFLL(base)) -#define UART_RESUME_REG(base) REG16(UART_RESUME(base)) -#define UART_TXFLH_REG(base) REG16(UART_TXFLH(base)) -#define UART_RXFLL_REG(base) REG16(UART_RXFLL(base)) -#define UART_SFREGL_REG(base) REG16(UART_SFREGL(base)) -#define UART_RXFLH_REG(base) REG16(UART_RXFLH(base)) -#define UART_SFREGH_REG(base) REG16(UART_SFREGH(base)) -#define UART_BLR_REG(base) REG16(UART_BLR(base)) -#define UART_UASR_REG(base) REG16(UART_UASR(base)) -#define UART_ACREG_REG(base) REG16(UART_ACREG(base)) -#define UART_SCR_REG(base) REG16(UART_SCR(base)) -#define UART_SSR_REG(base) REG16(UART_SSR(base)) -#define UART_EBLR_REG(base) REG16(UART_EBLR(base)) -#define UART_MVR_REG(base) REG16(UART_MVR(base)) -#define UART_SYSC_REG(base) REG16(UART_SYSC(base)) -#define UART_SYSS_REG(base) REG16(UART_SYSS(base)) -#define UART_WER_REG(base) REG16(UART_WER(base)) -#define UART_CFPS_REG(base) REG16(UART_CFPS(base)) -#define UART_RXFIFO_LVL_REG(base) REG16(UART_RXFIFO_LVL(base)) -#define UART_TXFIFO_LVL_REG(base) REG16(UART_TXFIFO_LVL(base)) -#define UART_IER2_REG(base) REG16(UART_IER2(base)) -#define UART_ISR2_REG(base) REG16(UART_ISR2(base)) -#define UART_FREQ_SEL_REG(base) REG16(UART_FREQ_SEL(base)) -#define UART_MDR3_REG(base) REG16(UART_MDR3(base)) -#define UART_TX_DMA_THRESHOLD_REG(base) REG16(UART_TX_DMA_THRESHOLD(base)) - -#endif /* end of include guard: SERIAL_REG_H */ diff --git a/bsp/beaglebone/drivers/uart.c b/bsp/beaglebone/drivers/uart.c new file mode 100644 index 0000000000..776ef3fa3c --- /dev/null +++ b/bsp/beaglebone/drivers/uart.c @@ -0,0 +1,452 @@ +/* + * File : serial.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard the first version + * 2014-01-11 RTsien support UART0 to UART5 straightly + */ + +#include +#include +#include + +#include +#include +#include "serial.h" +#include "serial_reg.h" + +struct am33xx_uart +{ + unsigned long base; + int irq; +}; + +static void am33xx_uart_isr(int irqno, void* param) +{ + rt_uint32_t iir; + struct am33xx_uart* uart; + struct rt_serial_device *serial; + + serial = (struct rt_serial_device*)param; + uart = (struct am33xx_uart *)serial->parent.user_data; + + iir = UART_IIR_REG(uart->base); + + if ((iir & (0x02 << 1)) || (iir & (0x6 << 1))) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + } +} + +#define NOT_IMPLEMENTED() RT_ASSERT(0) + +static rt_err_t am33xx_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct am33xx_uart* uart; + unsigned long base; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am33xx_uart *)serial->parent.user_data; + RT_ASSERT(uart); + base = uart->base; + +#define __LCR UART_LCR_REG(base) + + if (cfg->data_bits == DATA_BITS_8) + __LCR |= 3; + else + NOT_IMPLEMENTED(); + + if (cfg->stop_bits == STOP_BITS_1) + __LCR &= ~(1<<2); + else + __LCR |= (1<<2); + + if (cfg->parity == PARITY_NONE) + __LCR &= ~(1<<3); + else + __LCR |= (1<<3); + + __LCR |= (1<<7); + if (cfg->baud_rate == BAUD_RATE_115200) + { + UART_DLL_REG(base) = 26; + UART_DLH_REG(base) = 0; + } + else if (cfg->baud_rate == BAUD_RATE_9600) + { + UART_DLL_REG(base) = 0x38; + UART_DLH_REG(base) = 1; + } + else + { + NOT_IMPLEMENTED(); + } + __LCR &= ~(1<<7); + + UART_MDR1_REG(base) = 0; + UART_MDR2_REG(base) = 0; + +#undef __LCR + return RT_EOK; +} + +static rt_err_t am33xx_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct am33xx_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am33xx_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + rt_hw_interrupt_mask(uart->irq); + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + rt_hw_interrupt_umask(uart->irq); + break; + } + + return RT_EOK; +} + +int printkc(char c) +{ + int base = 0xf9e09000; + + while (!(UART_LSR_REG(base) & 0x20)); + UART_THR_REG(base) = c; + + return 1; +} + +static int am33xx_putc(struct rt_serial_device *serial, char c) +{ + struct am33xx_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am33xx_uart *)serial->parent.user_data; + + while (!(UART_LSR_REG(uart->base) & 0x20)); + UART_THR_REG(uart->base) = c; + + return 1; +} + +static int am33xx_getc(struct rt_serial_device *serial) +{ + int ch; + struct am33xx_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am33xx_uart *)serial->parent.user_data; + + ch = -1; + if (UART_LSR_REG(uart->base) & 0x01) + { + ch = UART_RHR_REG(uart->base) & 0xff; + } + + return ch; +} + +static const struct rt_uart_ops am33xx_uart_ops = +{ + am33xx_configure, + am33xx_control, + am33xx_putc, + am33xx_getc, +}; + +/* UART device driver structure */ +#ifdef RT_USING_UART0 +struct am33xx_uart uart0 = +{ + UART0_BASE, + UART0_INT, +}; +struct rt_serial_device serial0; +#endif + +#ifdef RT_USING_UART1 +struct am33xx_uart uart1 = +{ + UART1_BASE, + UART1_INT, +}; +struct rt_serial_device serial1; +#endif + +#ifdef RT_USING_UART2 +struct am33xx_uart uart2 = +{ + UART2_BASE, + UART2_INT, +}; +struct rt_serial_device serial2; +#endif + +#ifdef RT_USING_UART3 +struct am33xx_uart uart3 = +{ + UART3_BASE, + UART3_INT, +}; +struct rt_serial_device serial3; +#endif + +#ifdef RT_USING_UART4 +struct am33xx_uart uart4 = +{ + UART4_BASE, + UART4_INT, +}; +struct rt_serial_device serial4; +#endif + +#ifdef RT_USING_UART5 +struct am33xx_uart uart5 = +{ + UART5_BASE, + UART5_INT, +}; +struct rt_serial_device serial5; +#endif + +#define write_reg(base, value) *(int*)(base) = value +#define read_reg(base) *(int*)(base) + +#define PRM_PER_INTRANSLATION (1 << 20) +#define PRM_PER_POWSTATEOFF (0) +#define PRM_PER_PERMEMSTATEOFF (0) + +static void poweron_per_domain(void) +{ + unsigned long prcm_base; + unsigned long prm_state; + + prcm_base = AM33XX_PRCM_REGS; + + /* wait for ongoing translations */ + for (prm_state = PRM_PER_PWRSTST_REG(prcm_base); + prm_state & PRM_PER_INTRANSLATION; + prm_state = PRM_PER_PWRSTST_REG(prcm_base)) + ; + + /* check power state */ + if ((prm_state & 0x03) == PRM_PER_POWSTATEOFF) + /* power on PER domain */ + PRM_PER_PWRSTCTRL_REG(prcm_base) |= 0x3; + + /* check per mem state */ + if ((prm_state & 0x03) == PRM_PER_PERMEMSTATEOFF) + /* power on PER domain */ + PRM_PER_PWRSTCTRL_REG(prcm_base) |= 0x3 << 25; + + while (PRM_PER_PWRSTST_REG(prcm_base) & PRM_PER_INTRANSLATION) + ; +} + +static void start_uart_clk(void) +{ + unsigned long prcm_base; + + prcm_base = AM33XX_PRCM_REGS; + + /* software forced wakeup */ + CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) |= 0x2; + + /* Waiting for the L4LS clock */ + while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<8))) + ; + + /* enable uart1 */ +#ifdef RT_USING_UART1 + CM_PER_UART1_CLKCTRL_REG(prcm_base) |= 0x2; + /* wait for uart1 clk */ + while ((CM_PER_UART1_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) + ; +#endif + +#ifdef RT_USING_UART2 + CM_PER_UART2_CLKCTRL_REG(prcm_base) |= 0x2; + /* wait for uart2 clk */ + while ((CM_PER_UART2_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) + ; +#endif + +#ifdef RT_USING_UART3 + CM_PER_UART3_CLKCTRL_REG(prcm_base) |= 0x2; + /* wait for uart3 clk */ + while ((CM_PER_UART3_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) + ; +#endif + +#ifdef RT_USING_UART4 + CM_PER_UART4_CLKCTRL_REG(prcm_base) |= 0x2; + /* wait for uart4 clk */ + while ((CM_PER_UART4_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) + ; +#endif + +#ifdef RT_USING_UART5 + CM_PER_UART5_CLKCTRL_REG(prcm_base) |= 0x2; + /* wait for uart5 clk */ + while ((CM_PER_UART5_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) + ; +#endif + + /* Waiting for the L4LS UART clock */ + while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<10))) + ; +} + +static void config_pinmux(void) +{ + unsigned long ctlm_base; + + ctlm_base = AM33XX_CTLM_REGS; + + /* make sure the pin mux is OK for uart */ +#ifdef RT_USING_UART1 + REG32(ctlm_base + 0x800 + 0x180) = 0x20; + REG32(ctlm_base + 0x800 + 0x184) = 0x00; +#endif + +#ifdef RT_USING_UART2 + REG32(ctlm_base + 0x800 + 0x150) = 0x20; + REG32(ctlm_base + 0x800 + 0x154) = 0x00; +#endif + +#ifdef RT_USING_UART3 + REG32(ctlm_base + 0x800 + 0x164) = 0x01; +#endif + +#ifdef RT_USING_UART4 + REG32(ctlm_base + 0x800 + 0x070) = 0x26; + REG32(ctlm_base + 0x800 + 0x074) = 0x06; +#endif + +#ifdef RT_USING_UART5 + REG32(ctlm_base + 0x800 + 0x0C4) = 0x24; + REG32(ctlm_base + 0x800 + 0x0C0) = 0x04; +#endif +} + +int rt_hw_serial_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + poweron_per_domain(); + start_uart_clk(); + config_pinmux(); + +#ifdef RT_USING_UART0 + serial0.ops = &am33xx_uart_ops; + serial0.config = config; + + /* enable RX interrupt */ + UART_IER_REG(uart0.base) = 0x01; + /* install ISR */ + rt_hw_interrupt_install(uart0.irq, am33xx_uart_isr, &serial0, "uart0"); + rt_hw_interrupt_control(uart0.irq, 0, 0); + rt_hw_interrupt_mask(uart0.irq); + /* register UART0 device */ + rt_hw_serial_register(&serial0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &uart0); +#endif + +#ifdef RT_USING_UART1 + serial1.ops = &am33xx_uart_ops; + serial1.config = config; + /* enable RX interrupt */ + UART_IER_REG(uart1.base) = 0x01; + /* install ISR */ + rt_hw_interrupt_install(uart1.irq, am33xx_uart_isr, &serial1, "uart1"); + rt_hw_interrupt_control(uart1.irq, 0, 0); + rt_hw_interrupt_mask(uart1.irq); + /* register UART0 device */ + rt_hw_serial_register(&serial1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &uart1); +#endif + +#ifdef RT_USING_UART2 + serial2.ops = &am33xx_uart_ops; + serial2.config = config; + /* enable RX interrupt */ + UART_IER_REG(uart2.base) = 0x01; + /* install ISR */ + rt_hw_interrupt_install(uart2.irq, am33xx_uart_isr, &serial2, "uart2"); + rt_hw_interrupt_control(uart2.irq, 0, 0); + rt_hw_interrupt_mask(uart2.irq); + /* register UART2 device */ + rt_hw_serial_register(&serial2, "uart2", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &uart2); +#endif + +#ifdef RT_USING_UART3 + serial3.ops = &am33xx_uart_ops; + serial3.config = config; + /* enable RX interrupt */ + UART_IER_REG(uart3.base) = 0x01; + /* install ISR */ + rt_hw_interrupt_install(uart3.irq, am33xx_uart_isr, &serial3, "uart3"); + rt_hw_interrupt_control(uart3.irq, 0, 0); + rt_hw_interrupt_mask(uart3.irq); + /* register UART3 device */ + rt_hw_serial_register(&serial3, "uart3", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &uart3); +#endif + +#ifdef RT_USING_UART4 + /* use 9600bps for GDB stub. */ + config.baud_rate = BAUD_RATE_9600; + + serial4.ops = &am33xx_uart_ops; + serial4.config = config; + /* enable RX interrupt */ + UART_IER_REG(uart4.base) = 0x00; + /* install ISR */ + rt_hw_interrupt_install(uart4.irq, am33xx_uart_isr, &serial4, "uart4"); + rt_hw_interrupt_control(uart4.irq, 0, 0); + rt_hw_interrupt_mask(uart4.irq); + /* register UART4 device */ + rt_hw_serial_register(&serial4, "uart4", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &uart4); +#endif + +#ifdef RT_USING_UART5 + config.baud_rate = BAUD_RATE_115200; + + serial5.ops = &am33xx_uart_ops; + serial5.config = config; + /* enable RX interrupt */ + UART_IER_REG(uart5.base) = 0x01; + /* install ISR */ + rt_hw_interrupt_install(uart5.irq, am33xx_uart_isr, &serial5, "uart5"); + rt_hw_interrupt_control(uart5.irq, 0, 0); + rt_hw_interrupt_mask(uart5.irq); + /* register UART4 device */ + rt_hw_serial_register(&serial5, "uart5", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &uart5); +#endif + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_serial_init); diff --git a/bsp/beaglebone/drivers/uart.h b/bsp/beaglebone/drivers/uart.h new file mode 100644 index 0000000000..15f7f2c399 --- /dev/null +++ b/bsp/beaglebone/drivers/uart.h @@ -0,0 +1,20 @@ +/* + * File : serial.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard the first version + */ + +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + +int rt_hw_serial_init(void); + +#endif diff --git a/bsp/beaglebone/drivers/uart_reg.h b/bsp/beaglebone/drivers/uart_reg.h new file mode 100644 index 0000000000..cb984631f8 --- /dev/null +++ b/bsp/beaglebone/drivers/uart_reg.h @@ -0,0 +1,109 @@ +#ifndef SERIAL_REG_H +#define SERIAL_REG_H + +/** @brief Base addresses of UART memory mapped registers */ +#define UART0_BASE (0x44E09000) +#define UART1_BASE (0x48022000) +#define UART2_BASE (0x48024000) +#define UART3_BASE (0x481A6000) +#define UART4_BASE (0x481A8000) +#define UART5_BASE (0x481AA000) + +/* UART registers */ +#define UART_DLL(base) (base + 0x0) +#define UART_RHR(base) (base + 0x0) +#define UART_THR(base) (base + 0x0) +#define UART_DLH(base) (base + 0x4) +#define UART_IER(base) (base + 0x4) +#define UART_EFR(base) (base + 0x8) +#define UART_FCR(base) (base + 0x8) +#define UART_IIR(base) (base + 0x8) +#define UART_LCR(base) (base + 0xC) +#define UART_MCR(base) (base + 0x10) +#define UART_XON1_ADDR1(base) (base + 0x10) +#define UART_LSR(base) (base + 0x14) +#define UART_XON2_ADDR2(base) (base + 0x14) +#define UART_MSR(base) (base + 0x18) +#define UART_TCR(base) (base + 0x18) +#define UART_XOFF1(base) (base + 0x18) +#define UART_SPR(base) (base + 0x1C) +#define UART_TLR(base) (base + 0x1C) +#define UART_XOFF2(base) (base + 0x1C) +#define UART_MDR1(base) (base + 0x20) +#define UART_MDR2(base) (base + 0x24) +#define UART_SFLSR(base) (base + 0x28) +#define UART_TXFLL(base) (base + 0x28) +#define UART_RESUME(base) (base + 0x2C) +#define UART_TXFLH(base) (base + 0x2C) +#define UART_RXFLL(base) (base + 0x30) +#define UART_SFREGL(base) (base + 0x30) +#define UART_RXFLH(base) (base + 0x34) +#define UART_SFREGH(base) (base + 0x34) +#define UART_BLR(base) (base + 0x38) +#define UART_UASR(base) (base + 0x38) +#define UART_ACREG(base) (base + 0x3C) +#define UART_SCR(base) (base + 0x40) +#define UART_SSR(base) (base + 0x44) +#define UART_EBLR(base) (base + 0x48) +#define UART_MVR(base) (base + 0x50) +#define UART_SYSC(base) (base + 0x54) +#define UART_SYSS(base) (base + 0x58) +#define UART_WER(base) (base + 0x5C) +#define UART_CFPS(base) (base + 0x60) +#define UART_RXFIFO_LVL(base) (base + 0x64) +#define UART_TXFIFO_LVL(base) (base + 0x68) +#define UART_IER2(base) (base + 0x6C) +#define UART_ISR2(base) (base + 0x70) +#define UART_FREQ_SEL(base) (base + 0x74) +#define UART_MDR3(base) (base + 0x80) +#define UART_TX_DMA_THRESHOLD(base) (base + 0x84) + +#define UART_DLL_REG(base) REG16(UART_DLL(base)) +#define UART_RHR_REG(base) REG16(UART_RHR(base)) +#define UART_THR_REG(base) REG16(UART_THR(base)) +#define UART_DLH_REG(base) REG16(UART_DLH(base)) +#define UART_IER_REG(base) REG16(UART_IER(base)) +#define UART_EFR_REG(base) REG16(UART_EFR(base)) +#define UART_FCR_REG(base) REG16(UART_FCR(base)) +#define UART_IIR_REG(base) REG16(UART_IIR(base)) +#define UART_LCR_REG(base) REG16(UART_LCR(base)) +#define UART_MCR_REG(base) REG16(UART_MCR(base)) +#define UART_XON1_ADDR1_REG(base) REG16(UART_XON1_ADDR1(base)) +#define UART_LSR_REG(base) REG16(UART_LSR(base)) +#define UART_XON2_ADDR2_REG(base) REG16(UART_XON2_ADDR2(base)) +#define UART_MSR_REG(base) REG16(UART_MSR(base)) +#define UART_TCR_REG(base) REG16(UART_TCR(base)) +#define UART_XOFF1_REG(base) REG16(UART_XOFF1(base)) +#define UART_SPR_REG(base) REG16(UART_SPR(base)) +#define UART_TLR_REG(base) REG16(UART_TLR(base)) +#define UART_XOFF2_REG(base) REG16(UART_XOFF2(base)) +#define UART_MDR1_REG(base) REG16(UART_MDR1(base)) +#define UART_MDR2_REG(base) REG16(UART_MDR2(base)) +#define UART_SFLSR_REG(base) REG16(UART_SFLSR(base)) +#define UART_TXFLL_REG(base) REG16(UART_TXFLL(base)) +#define UART_RESUME_REG(base) REG16(UART_RESUME(base)) +#define UART_TXFLH_REG(base) REG16(UART_TXFLH(base)) +#define UART_RXFLL_REG(base) REG16(UART_RXFLL(base)) +#define UART_SFREGL_REG(base) REG16(UART_SFREGL(base)) +#define UART_RXFLH_REG(base) REG16(UART_RXFLH(base)) +#define UART_SFREGH_REG(base) REG16(UART_SFREGH(base)) +#define UART_BLR_REG(base) REG16(UART_BLR(base)) +#define UART_UASR_REG(base) REG16(UART_UASR(base)) +#define UART_ACREG_REG(base) REG16(UART_ACREG(base)) +#define UART_SCR_REG(base) REG16(UART_SCR(base)) +#define UART_SSR_REG(base) REG16(UART_SSR(base)) +#define UART_EBLR_REG(base) REG16(UART_EBLR(base)) +#define UART_MVR_REG(base) REG16(UART_MVR(base)) +#define UART_SYSC_REG(base) REG16(UART_SYSC(base)) +#define UART_SYSS_REG(base) REG16(UART_SYSS(base)) +#define UART_WER_REG(base) REG16(UART_WER(base)) +#define UART_CFPS_REG(base) REG16(UART_CFPS(base)) +#define UART_RXFIFO_LVL_REG(base) REG16(UART_RXFIFO_LVL(base)) +#define UART_TXFIFO_LVL_REG(base) REG16(UART_TXFIFO_LVL(base)) +#define UART_IER2_REG(base) REG16(UART_IER2(base)) +#define UART_ISR2_REG(base) REG16(UART_ISR2(base)) +#define UART_FREQ_SEL_REG(base) REG16(UART_FREQ_SEL(base)) +#define UART_MDR3_REG(base) REG16(UART_MDR3(base)) +#define UART_TX_DMA_THRESHOLD_REG(base) REG16(UART_TX_DMA_THRESHOLD(base)) + +#endif /* end of include guard: SERIAL_REG_H */ diff --git a/bsp/beaglebone/rtconfig.h b/bsp/beaglebone/rtconfig.h index a4e2bc2b8f..31f04a79c7 100644 --- a/bsp/beaglebone/rtconfig.h +++ b/bsp/beaglebone/rtconfig.h @@ -127,7 +127,7 @@ // #define RT_USING_LIBC // -#define RT_USING_PTHREADS +//#define RT_USING_PTHREADS // //
diff --git a/libcpu/arm/am335x/cp15_iar.s b/libcpu/arm/am335x/cp15_iar.s new file mode 100644 index 0000000000..ae59ed04dc --- /dev/null +++ b/libcpu/arm/am335x/cp15_iar.s @@ -0,0 +1,154 @@ +/* + * File : cp15_iar.s + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * http://www.rt-thread.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-04-06 zchong change to iar compiler from convert from cp15_gcc.S + */ + + SECTION .text:CODE:NOROOT(2) + + ARM + + EXPORT rt_cpu_vector_set_base +rt_cpu_vector_set_base: + MCR p15, #0, r0, c12, c0, #0 + DSB + BX lr + + EXPORT rt_cpu_vector_get_base +rt_cpu_vector_get_base: + MRC p15, #0, r0, c12, c0, #0 + BX lr + + EXPORT rt_cpu_get_sctlr +rt_cpu_get_sctlr: + MRC p15, #0, r0, c1, c0, #0 + BX lr + + EXPORT rt_cpu_dcache_enable +rt_cpu_dcache_enable: + MRC p15, #0, r0, c1, c0, #0 + ORR r0, r0, #0x00000004 + MCR p15, #0, r0, c1, c0, #0 + BX lr + + EXPORT rt_cpu_icache_enable +rt_cpu_icache_enable: + MRC p15, #0, r0, c1, c0, #0 + ORR r0, r0, #0x00001000 + MCR p15, #0, r0, c1, c0, #0 + BX lr + +;_FLD_MAX_WAY DEFINE 0x3ff +;_FLD_MAX_IDX DEFINE 0x7ff + + + EXPORT rt_cpu_dcache_clean_flush +rt_cpu_dcache_clean_flush: + PUSH {r4-r11} + DMB + MRC p15, #1, r0, c0, c0, #1 ; read clid register + ANDS r3, r0, #0x7000000 ; get level of coherency + MOV r3, r3, lsr #23 + BEQ finished + MOV r10, #0 +loop1: + ADD r2, r10, r10, lsr #1 + MOV r1, r0, lsr r2 + AND r1, r1, #7 + CMP r1, #2 + BLT skip + MCR p15, #2, r10, c0, c0, #0 + ISB + MRC p15, #1, r1, c0, c0, #0 + AND r2, r1, #7 + ADD r2, r2, #4 + ;LDR r4, _FLD_MAX_WAY + LDR r4, =0x3FF + ANDS r4, r4, r1, lsr #3 + CLZ r5, r4 + ;LDR r7, _FLD_MAX_IDX + LDR r7, =0x7FF + ANDS r7, r7, r1, lsr #13 +loop2: + MOV r9, r4 +loop3: + ORR r11, r10, r9, lsl r5 + ORR r11, r11, r7, lsl r2 + MCR p15, #0, r11, c7, c14, #2 + SUBS r9, r9, #1 + BGE loop3 + SUBS r7, r7, #1 + BGE loop2 +skip: + ADD r10, r10, #2 + CMP r3, r10 + BGT loop1 + +finished: + DSB + ISB + POP {r4-r11} + BX lr + + + EXPORT rt_cpu_dcache_disable +rt_cpu_dcache_disable: + PUSH {r4-r11, lr} + MRC p15, #0, r0, c1, c0, #0 + BIC r0, r0, #0x00000004 + MCR p15, #0, r0, c1, c0, #0 + BL rt_cpu_dcache_clean_flush + POP {r4-r11, lr} + BX lr + + + EXPORT rt_cpu_icache_disable +rt_cpu_icache_disable: + MRC p15, #0, r0, c1, c0, #0 + BIC r0, r0, #0x00001000 + MCR p15, #0, r0, c1, c0, #0 + BX lr + + EXPORT rt_cpu_mmu_disable +rt_cpu_mmu_disable: + MCR p15, #0, r0, c8, c7, #0 ; invalidate tlb + MRC p15, #0, r0, c1, c0, #0 + BIC r0, r0, #1 + MCR p15, #0, r0, c1, c0, #0 ; clear mmu bit + DSB + BX lr + + EXPORT rt_cpu_mmu_enable +rt_cpu_mmu_enable: + MRC p15, #0, r0, c1, c0, #0 + ORR r0, r0, #0x001 + MCR p15, #0, r0, c1, c0, #0 ; set mmu enable bit + DSB + BX lr + + EXPORT rt_cpu_tlb_set +rt_cpu_tlb_set: + MCR p15, #0, r0, c2, c0, #0 + DMB + BX lr + + END diff --git a/libcpu/arm/am335x/cpu.c b/libcpu/arm/am335x/cpu.c index e67983eed0..d75600711f 100644 --- a/libcpu/arm/am335x/cpu.c +++ b/libcpu/arm/am335x/cpu.c @@ -92,6 +92,8 @@ rt_inline void cache_disable(rt_uint32_t bit) } #endif + +#if defined(__CC_ARM)|(__GNUC__) /** * enable I-Cache * @@ -145,6 +147,7 @@ rt_base_t rt_hw_cpu_dcache_status() { return (cp15_rd() & DCACHE_MASK); } +#endif /** * shutdown CPU diff --git a/libcpu/arm/am335x/interrupt.c b/libcpu/arm/am335x/interrupt.c index 081bdd6b41..a13d089a7f 100644 --- a/libcpu/arm/am335x/interrupt.c +++ b/libcpu/arm/am335x/interrupt.c @@ -10,6 +10,7 @@ * Change Logs: * Date Author Notes * 2013-07-06 Bernard first version + * 2015-11-06 zchong support iar compiler */ #include @@ -53,13 +54,22 @@ void rt_dump_aintc(void) const unsigned int AM335X_VECTOR_BASE = 0x4030FC00; extern void rt_cpu_vector_set_base(unsigned int addr); +#ifdef __ICCARM__ +extern int __vector; +#else extern int system_vectors; +#endif static void rt_hw_vector_init(void) { unsigned int *dest = (unsigned int *)AM335X_VECTOR_BASE; + +#ifdef __ICCARM__ + unsigned int *src = (unsigned int *)&__vector; +#else unsigned int *src = (unsigned int *)&system_vectors; - +#endif + rt_memcpy(dest, src, 16 * 4); rt_cpu_vector_set_base(AM335X_VECTOR_BASE); } @@ -203,3 +213,5 @@ void rt_dump_isr_table(void) } } /*@}*/ + + diff --git a/libcpu/arm/am335x/start_iar.s b/libcpu/arm/am335x/start_iar.s new file mode 100644 index 0000000000..61f977f2c6 --- /dev/null +++ b/libcpu/arm/am335x/start_iar.s @@ -0,0 +1,292 @@ +/* + * File : start_iar.s + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-04-06 zchong the first version + */ + + MODULE ?cstartup + + ; -------------------- +; Mode, correspords to bits 0-5 in CPSR + +MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR +I_Bit DEFINE 0x80 ; when I bit is set, IRQ is disabled +F_Bit DEFINE 0x40 ; when F bit is set, FIQ is disabled + +USR_MODE DEFINE 0x10 ; User mode +FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode +IRQ_MODE DEFINE 0x12 ; Interrupt Request mode +SVC_MODE DEFINE 0x13 ; Supervisor mode +ABT_MODE DEFINE 0x17 ; Abort mode +UND_MODE DEFINE 0x1B ; Undefined Instruction mode +SYS_MODE DEFINE 0x1F ; System mode + + + ;; Forward declaration of sections. + SECTION IRQ_STACK:DATA:NOROOT(3) + SECTION FIQ_STACK:DATA:NOROOT(3) + SECTION SVC_STACK:DATA:NOROOT(3) + SECTION ABT_STACK:DATA:NOROOT(3) + SECTION UND_STACK:DATA:NOROOT(3) + SECTION CSTACK:DATA:NOROOT(3) + SECTION .text:CODE + + + SECTION .intvec:CODE:NOROOT(5) + + PUBLIC __vector + PUBLIC __iar_program_start + + +__iar_init$$done: ; The vector table is not needed + ; until after copy initialization is done + +__vector: ; Make this a DATA label, so that stack usage + ; analysis doesn't consider it an uncalled fun + ARM + + ; All default exception handlers (except reset) are + ; defined as weak symbol definitions. + ; If a handler is defined by the application it will take precedence. + LDR PC,Reset_Addr ; Reset + LDR PC,Undefined_Addr ; Undefined instructions + LDR PC,SWI_Addr ; Software interrupt (SWI/SVC) + LDR PC,Prefetch_Addr ; Prefetch abort + LDR PC,Abort_Addr ; Data abort + DCD 0 ; RESERVED + LDR PC,IRQ_Addr ; IRQ + LDR PC,FIQ_Addr ; FIQ + + DATA + +Reset_Addr: DCD __iar_program_start +Undefined_Addr: DCD Undefined_Handler +SWI_Addr: DCD SWI_Handler +Prefetch_Addr: DCD Prefetch_Handler +Abort_Addr: DCD Abort_Handler +IRQ_Addr: DCD IRQ_Handler +FIQ_Addr: DCD FIQ_Handler + + +; -------------------------------------------------- +; ?cstartup -- low-level system initialization code. +; +; After a reset execution starts here, the mode is ARM, supervisor +; with interrupts disabled. +; + + SECTION .text:CODE:NOROOT(2) + + EXTERN rt_hw_trap_udef + EXTERN rt_hw_trap_swi + EXTERN rt_hw_trap_pabt + EXTERN rt_hw_trap_dabt + EXTERN rt_hw_trap_fiq + EXTERN rt_hw_trap_irq + EXTERN rt_interrupt_enter + EXTERN rt_interrupt_leave + EXTERN rt_thread_switch_interrupt_flag + EXTERN rt_interrupt_from_thread + EXTERN rt_interrupt_to_thread + EXTERN rt_current_thread + EXTERN vmm_thread + EXTERN vmm_virq_check + + EXTERN __cmain + REQUIRE __vector + EXTWEAK __iar_init_core + EXTWEAK __iar_init_vfp + + + ARM + +__iar_program_start: +?cstartup: + +; +; Add initialization needed before setup of stackpointers here. +; + +; +; Initialize the stack pointers. +; The pattern below can be used for any of the exception stacks: +; FIQ, IRQ, SVC, ABT, UND, SYS. +; The USR mode uses the same stack as SYS. +; The stack segments must be defined in the linker command file, +; and be declared above. +; + + MRS r0, cpsr ; Original PSR value + + ;; Set up the interrupt stack pointer. + BIC r0, r0, #MODE_MSK ; Clear the mode bits + ORR r0, r0, #IRQ_MODE ; Set IRQ mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(IRQ_STACK) ; End of IRQ_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + ;; Set up the fast interrupt stack pointer. + BIC r0, r0, #MODE_MSK ; Clear the mode bits + ORR r0, r0, #FIQ_MODE ; Set FIR mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(FIQ_STACK) ; End of FIQ_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + BIC r0,r0,#MODE_MSK ; Clear the mode bits + ORR r0,r0,#ABT_MODE ; Set Abort mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(ABT_STACK) ; End of ABT_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + BIC r0,r0,#MODE_MSK ; Clear the mode bits + ORR r0,r0,#UND_MODE ; Set Undefined mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(UND_STACK) ; End of UND_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + ;; Set up the normal stack pointer. + BIC r0 ,r0, #MODE_MSK ; Clear the mode bits + ORR r0 ,r0, #SVC_MODE ; Set System mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(SVC_STACK) ; End of SVC_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + ;; Turn on core features assumed to be enabled. + BL __iar_init_core + + ;; Initialize VFP (if needed). + BL __iar_init_vfp + + + ;; Continue to __cmain for C-level initialization. + B __cmain + + +Undefined_Handler: + SUB sp, sp, #72 + STMIA sp, {r0 - r12} ;/* Calling r0-r12 */ + ADD r8, sp, #60 + + MRS r1, cpsr + MRS r2, spsr + ORR r2,r2, #I_Bit | F_Bit + MSR cpsr_c, r2 + MOV r0, r0 + STMDB r8, {sp, lr} ;/* Calling SP, LR */ + MSR cpsr_c, r1 ;/* return to Undefined Instruction mode */ + + STR lr, [r8, #0] ;/* Save calling PC */ + MRS r6, spsr + STR r6, [r8, #4] ;/* Save CPSR */ + STR r0, [r8, #8] ;/* Save OLD_R0 */ + MOV r0, sp + + BL rt_hw_trap_udef + + LDMIA sp, {r0 - r12} ;/* Calling r0 - r2 */ + MOV r0, r0 + LDR lr, [sp, #60] ;/* Get PC */ + ADD sp, sp, #72 + MOVS pc, lr ;/* return & move spsr_svc into cpsr */ + +SWI_Handler: + BL rt_hw_trap_swi + +Prefetch_Handler: + BL rt_hw_trap_pabt + +Abort_Handler: + SUB sp, sp, #72 + STMIA sp, {r0 - r12} ;/* Calling r0-r12 */ + ADD r8, sp, #60 + STMDB r8, {sp, lr} ;/* Calling SP, LR */ + STR lr, [r8, #0] ;/* Save calling PC */ + MRS r6, spsr + STR r6, [r8, #4] ;/* Save CPSR */ + STR r0, [r8, #8] ;/* Save OLD_R0 */ + MOV r0, sp + + BL rt_hw_trap_dabt + + LDMIA sp, {r0 - r12} ;/* Calling r0 - r2 */ + MOV r0, r0 + LDR lr, [sp, #60] ;/* Get PC */ + ADD sp, sp, #72 + MOVS pc, lr ;/* return & move spsr_svc into cpsr */ + +FIQ_Handler: + STMFD sp!,{r0-r7,lr} + BL rt_hw_trap_fiq + LDMFD sp!,{r0-r7,lr} + SUBS pc,lr,#4 + +IRQ_Handler: + STMFD sp!, {r0-r12,lr} + + BL rt_interrupt_enter + BL rt_hw_trap_irq + BL rt_interrupt_leave + + ; if rt_thread_switch_interrupt_flag set, jump to + ; rt_hw_context_switch_interrupt_do and don't return + LDR r0, =rt_thread_switch_interrupt_flag + LDR r1, [r0] + CMP r1, #1 + BEQ rt_hw_context_switch_interrupt_do + + LDMFD sp!, {r0-r12,lr} + SUBS pc, lr, #4 + +rt_hw_context_switch_interrupt_do: + MOV r1, #0 ; clear flag + STR r1, [r0] + + LDMFD sp!, {r0-r12,lr}; reload saved registers + STMFD sp, {r0-r2} ; save r0-r2 + + MRS r0, spsr ; get cpsr of interrupt thread + + SUB r1, sp, #4*3 + SUB r2, lr, #4 ; save old task's pc to r2 + + ; switch to SVC mode with no interrupt + MSR cpsr_c, #I_Bit | F_Bit | SVC_MODE + + STMFD sp!, {r2} ; push old task's pc + STMFD sp!, {r3-r12,lr}; push old task's lr,r12-r4 + LDMFD r1, {r1-r3} ; restore r0-r2 of the interrupt thread + STMFD sp!, {r1-r3} ; push old task's r0-r2 + STMFD sp!, {r0} ; push old task's cpsr + + LDR r4, =rt_interrupt_from_thread + LDR r5, [r4] + STR sp, [r5] ; store sp in preempted tasks's TCB + + LDR r6, =rt_interrupt_to_thread + LDR r6, [r6] + LDR sp, [r6] ; get new task's stack pointer + + LDMFD sp!, {r4} ; pop new task's cpsr to spsr + MSR spsr_cxsf, r4 + + LDMFD sp!, {r0-r12,lr,pc}^ ; pop new task's r0-r12,lr & pc, copy spsr to cpsr + + END -- cgit v1.3.1