Changing Module Hardware

The Module examples were designed to be easy to port to different compilers or processors. All functions that access the hardware have been encapsulated in one Hardware Abstraction Library (HAL) file. Which HAL file to use is defined in hal.h. This makes it easy to redirect all the examples to the HAL file that you are using. For example, the Launchpad uses the file hal_launchpad.c.

To use the Module library with a different processor you will need to implement several functions in the HAL file to your development environment. Refer to the HTML documentation for hal_launchpad.c to see which methods need to be ported.

We've created a helper utility to assist you in testing your HAL file. See hal_helper.c in the HAL directory. This file contains a multitude of tests that exercise each of the Module methods required in the HAL files. This has been used by several people to use the Module library with a different MSP430 and a different development environment (CodeSourcery for Stellaris). This utility includes several tests shown below which should be completed in order. This will help you build up your hal file. Please note that the list below may not exactly match the contents of the file as we periodically add more tests as needed. /* Uncomment only ONE of the tests below to run that test */ //#define TEST_PUTCHAR         //STEP 2 - get putchar working so that printf will work //#define TEST_PRINTF          //STEP 3 - test printf with a simple hello world application //#define TEST_ZM_RESET       //STEP 4 - verify ZM is being reset //#define TEST_SPI_WRITE       //STEP 5 - verify the SPI port is configured correctly (if using SPI) //#define TEST_SYS_RESET_IND   //STEP 6 - Do something useful - reset the ZM and display the response //#define TEST_SYS_GET_MAC     //STEP 7 - Do something even more useful - query the ZM for the MAC Address
 * 1) define TEST_DELAY           //STEP 1 - get basic delay, LEDs working

The module library has been ported to a plethora of processors, from PIC to Linux and many multiple flavours of MSP430. If you're porting to another MSP430 processor and using IAR then the process is:
 * 1) Open the HAL helper project. It is in the workspace HAL / IAR / HAL Utilities.eww
 * 2) Create a new project configuration for the HAL Helper project. (Project : Edit Configurations : New)
 * 3) Edit the project options - be sure to select the processor you will be using! (Project : Options : General Options : Target : Device). Also
 * 4) Create a new HAL file (e.g. hal_fram.c and hal_fram.h) and add it to the project. I recommend starting with blank files and then copy/pasting the relevant functions in as you get each HAL Helper test. That will keep the compiler happy.
 * 5) Be sure that there's only one HAL file enabled for the build. You can either remove the other HAL files from the project, or (the preferred solution) just right click on the file, select Options... and then "Exclude from Build."
 * 6) Pour yourself a cup of coffee and methodically go through each test to get them working one at a time. Don't skip any; as many of them build on previous tests.
 * 7) Once you have all the tests done then your HAL file should be ready. Congratulations.

Now, to use your new HAL file in one of the examples, follow the steps below. I recommend starting with Hello World first just to ensure that the dependencies are correct. Then one of the basic examples (e.g. Get MAC Address) to verify the Module interface, and then do the Network Explorer example, since that is a superset of other functions. FRAM ZM_PHY_SPI
 * 1) Open the IAR workspace for the example (e.g. ZM Interface Examples.eww) and select the Get MAC Address project.
 * 2) In the IAR Project, create a new project configuration (e.g. "FRAM"), edit the project options like you did with HAL helper.
 * 3) Add your new HAL file to the newly created project configuration and deselect the other HAL files like you did for the HAL helper.
 * 4) Open up hal.h (in the HAL directory) and add another board configuration. for example:
 * 1) elif defined FRAM
 * 2) include "../HAL/hal_fram.h"
 * 3) include "../Common/printf.h"
 * 4) else
 * 1) Edit the project configuration to use your new board configuration. Go to Project : Options : C/C++ Compiler : Preprocessor : Defined Symbols, and replace the existing board configuration with your option. For example the Defined Symbols (one per line) should now read:
 * 1) Test thoroughly
 * 2) If you can, please send us your HAL file so that we can help the next person out who wants to port to the same processor.

For more information, see the code documentation, HAL/html/index.html as a starting point.

Creating a new HAL file
When creating a new HAL file, I follow a pattern which works well: /* Port A    * PA0      U0Rx (Debug UART) * PA1     U0Tx (Debug UART) * PA2     Bit-Bang I2C SDA * PA3     Bit-Bang I2C SCL * PA4     BoosterPack RGB LED - Green * PA5     Module SS & MRDY * PA6	BoosterPack RGB LED - Red * PA7	Module SRDY */   SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); PERIPHERAL_ENABLE_DELAY; /* Configure UART pins */ GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); /* Outputs */ GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6); GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_6, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); // For LEDs /* Inputs */ GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_7); /* softI2c */ GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3); SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
 * 1) If there's an existing HAL file that's similar to yours, save it with a new name. Or, you might just want to create a new file from scratch, copy/pasting the relevant content in as you need it.
 * 2) Start with the port settings (portInit in many of our HAL files). Using the schematic, make a list of each pin's function in your circuit. Double and triple check that this is correct - you'll be referring to this regularly, and if you screw it up here then nothing will work. For example, from release 1568 of hal_ek-lm4f120XL.c:
 * 1) Beneath this, put the relevant configuration functions. I like to separate the Inputs, Outputs, and other to make it easier when reading later. Remember that code is usually written once but read many times. Again, from release 1568 of hal_ek-lm4f120XL.c:

Porting to a different Stellaris platform
When changing Stellaris platforms you also need to be sure to modify your interrupt vector table, or else you will get an error and/or the compile will fail. The interrupt vector table is defined in the file "startup_ccs.c" if using Code Composer Studio. In this file you will see a long list of interrupt functions, mainly "IntDefaultHandler". You will need to modify this to match your hardware. For example, if you are using UART2 instead of UART0 then change: IntDefaultHandler,                     // UART2 Rx and Tx to: UARTIntHandler,                     // UART2 Rx and Tx Also, be sure that the interrupt functions are defined above in the same file, e.g: //***************************************************************************** // // External declarations for the interrupt handlers used by the application. // //***************************************************************************** extern void IntGPIOe(void); extern void IntGPIOf(void); extern void UARTIntHandler(void); extern void Timer2IntHandler(void); Finally, you should have a definition of each of these functions in your hal.c file. If you don't then you will get a compile error like: unresolved symbol IntGPIOf, first referenced in ./startup_ccs.obj

Running on fast processors (>50MHz)
If you are porting the examples to an environment that has a fast processor then you may need to include a small delay between successive SPI commands to allow the module enough time to process each command. Otherwise one call could come in while the module is still processing the last one. The delay does not need to be much; others have found that 100nS - 1mS works. See sendSreq in zm_phy_spi.c.