NUC120 port

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
Post Reply
fjarnjak
Posts: 9
Joined: Tue Oct 11, 2011 8:16 am

NUC120 port

Post by fjarnjak »

Well, to let you know about my port of ChibiOS to NUC120 platform.
It is not complete (no HAL ports) but it manages to run code succesfully.

Port is for NUC120LE3AN MCU from Nuvoton on a NUC120-TINY-SDK board I have received from them some time back.
It is a Cortex M0.

So, basically I have copied all directories related to LPC11xx and made new NUC120 subdirectories.

os\ports\GCC\ARMCMx\NUC120:

vectors.c - does not need any change because LPC11xx and NUC120 have same exception vectors. CortexM0 exception
vectors (mandatory ones) are the same. NUC120 and LPC11xx have same number of other 31 exception vectors.
Since I didn't have to use any of them, I didn't change the names to human readable ones and left the same
names as in LPC11xx file. So basically, no change needed.

cmparams.h - stays the same.

os\hal\platforms\NUC120:

For this to workI didn't port fully PAL drivers. I also used CMSIS files for implemeting hal_lld functions.
I have removed almost all defines from hal_lld header file, except function defintions.
I have modified platform.mk to not compile PAL, SPI, Serial, etc drivers but to compile DrvGPIO and DrvSYS
from CMSIS. Added header file for NUC120 to define ports, pins, registers, etc. core_m0.h stays the same.

So make does:

Code: Select all

PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/NUC120/hal_lld.c \
         ${CHIBIOS}/os/hal/platforms/NUC120/DrvSYS.c \
         ${CHIBIOS}/os/hal/platforms/NUC120/DrvGPIO.c

And hal_lld.c has:

Code: Select all

void hal_lld_init(void) {

  /* SysTick initialization using the system clock.*/
  NVICSetSystemHandlerPriority(HANDLER_SYSTICK, CORTEX_PRIORITY_SYSTICK);

   SysTick->LOAD = 50000000 / CH_FREQUENCY - 1;
   SysTick->VAL = 0;
   SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
                  SysTick_CTRL_ENABLE_Msk |
                  SysTick_CTRL_TICKINT_Msk;
}

/**
 * @brief   NUC120 clocks and PLL initialization.
 * @note    All the involved constants come from the file @p board.h.
 * @note    This function must be invoked only after the system reset.
 *
 * @special
 */
void nuc120_clock_init(void) {

   int t;

   DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1); // Enable External 12Mhz Crystal
   for(t=0;t<100;++t); // Delay for clock to stabilize
   DrvSYS_SetPllSrc(E_DRVSYS_EXT_12M);
   DrvSYS_SetPLLPowerDown(0);
   DrvSYS_Open (12000, 50000); // Run System Clock @ 50Mhz from external 12Mhz crystal
}



boards\NUC120:

boards.h stays the same. In real port #define's should be removed but since we don't use them..

board.c is:

Code: Select all


/*
 * Early initialization code.
 * This initialization must be performed just after stack setup and before
 * any other initialization.
 */
void __early_init(void) {

  nuc120_clock_init();
}

/*
 * Board-specific initialization code.
 */
void boardInit(void) {

  /*
   * Extra, board-specific, initializations.
   */
}




demos/NUC120:

Linker file is the same except above SECTIONS it is changed to:

Code: Select all


/*
 * NUC120LE3AN memory setup.
 */
__main_stack_size__     = 0x0100;
/* __process_stack_size__  = 0x0100; */
/*__stacks_total_size__   = __main_stack_size__ + __process_stack_size__; */

__stacks_total_size__   = __main_stack_size__;

MEMORY
{
  flash :  ORIGIN = 0x00000000, LENGTH = 0x00020000
  ram : ORIGIN = 0x20000000, LENGTH = 0x00004000
}

__ram_start__           = ORIGIN(ram);
__ram_size__            = LENGTH(ram);
__ram_end__             = __ram_start__ + __ram_size__;

SECTIONS
{
....



halconf.h is changed to remove all drivers.

main.c:

Code: Select all


#include "ch.h"
#include "hal.h"
#include "test.h"
#include "DrvGPIO.h"

static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {

  (void)arg;
  chRegSetThreadName("blinker1");
  unsigned char t;
  uint32_t i;
  while(TRUE)
  {
           for(t = 0; t<3;++t)
           {
                 DrvGPIO_ClrBit(GPB, 0);
                 chThdSleepMilliseconds(10);
                    DrvGPIO_SetBit(GPB, 0);
                    chThdSleepMilliseconds(10);
           }
           chThdSleepMilliseconds(500);
  }

}

static WORKING_AREA(waThread2, 128);
static msg_t Thread2(void *arg) {

  (void)arg;
  chRegSetThreadName("blinker2");
  while(TRUE)
  {
             DrvGPIO_SetBit(GPB, 0);
           DrvGPIO_ClrBit(GPB, 0);
           chThdSleepMilliseconds(1000);
           DrvGPIO_SetBit(GPB, 0);
           chThdSleepMilliseconds(1000);
  }
}

/*
 * Application entry point.
 */
int main(void) {
  uint32_t i,t;

  halInit();
  chSysInit();

  DrvGPIO_Open(GPB, 0, IO_OUTPUT);

  /*
   * Creates the blinker threads.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
  chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, NULL);

  i = 0;
 
  while (TRUE) {
    chThdSleepMilliseconds(500);
    i = (i + 1) & 15;
  }

}



So, with above you have ChibiOS running on NUC120 hardware; it should run on all NUC1xx devices except linker
script should be changed for various devices and possibly vectors.c.

Of course, port is not complete; hal_lld.h should maybe be done with #defines to define system setup
and not use CMSIS for Clock Setting. Allow for internal RC osciallator.
Vectors.c should be changed so that exception vectors have real name for NUC1xx devices for developers to use.
board.c setup should also be done, etc.


Since I had to use Windows7 project was compiled as follows:


    Used Windows XP mode (virtual machine coming with Win7) and installed Yagarto latest ARM GCC / binutils.
    Copied executable elf back to Windows 7.
    Used CoFlash (from Coocox) to load elf and flash the board since it supports Nu-Link programmer
    that comes with the board.


About CMSIS:

Actually what is community feel about using CMSIS library instead of accessing MCU directly? For example like I
did in activating external crystal, setting PLL and using it as a system clock? I find it easier since
API is standardized and it is quicker to do.


I wouldn't mind working on this more to make it official port and contribute to the project, so let me know what needs to be done,
any suggestions to the above I have written, etc and I can find time to do it...
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: NUC120 port

Post by Giovanni »

Hi fjarnjak,

Good work with the port, it is nice to see how it is progressing. About contributing to the project, it is possible, others are doing it already, of course some conditions have to be met:

  • Usually at least HAL and Serial drivers should be implemented, PAL and SPI would be nice too, other drivers are optional but of course would contribute into making the port interesting for other users. A full set of drivers would make the platform extremely convenient to use for potential users/customers.
  • The implementation would have to grow in a separate repository branch until it is complete enough then it can be reviewed and merged in the trunk. You would have access to the repository of course.
  • It will have to be compliant with ChibiOS standards about things like: code quality, code style, demos, testing, documentation etc. The code is a surprisingly small part of the whole work.
  • I'll have to find some hardware in order to be able to run regression tests on the port before releases. Code that cannot be maintained/tested cannot go into the mainline (but could become a separate add-on package maintained by you, I would still give it space in the website and a dedicated page in the wiki and it would be "officially" recognized).
  • You would have full credits for the contribution but there must not be copyright claims into the contributed code because ChibiOS is also a commercial product. This is not an issue if you choose to support it as a purely open source package maintained by you.

About CMSIS, usually the HAL is implemented natively without use of external libraries except for register-level headers in order to avoid copyright-related issues and because efficiency concerns, imagine having to include the whole ST FW library into the STM32 HAL, it would be 10x the current size. Of course it would be your choice.

Ciao,
Giovanni
Post Reply