I am using the LM3S9D92 eval kit with CCS5. I am trying to use the EPIO on the controller, however I see no activity on the ALE (EPIOS30, PJ6), the WE (EPIOS29, PJ5), or the A1 (EPIOS1, PH2) lines.
The set-up code is
#define EPI_PORTC_PINS (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7)
#define EPI_PORTE_PINS (GPIO_PIN_0 | GPIO_PIN_1)
#define EPI_PORTF_PINS (GPIO_PIN_4 | GPIO_PIN_5)
#define EPI_PORTG_PINS (GPIO_PIN_0 | GPIO_PIN_1)
#define EPI_PORTH_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \
GPIO_PIN_4 | GPIO_PIN_5)
#define EPI_PORTJ_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6)
#define MEM_START_ADDRESS 0X000000
SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0);
GPIOPinConfigure(GPIO_PH3_EPI0S0);
GPIOPinConfigure(GPIO_PH2_EPI0S1);
GPIOPinConfigure(GPIO_PC4_EPI0S2);
GPIOPinConfigure(GPIO_PC5_EPI0S3);
GPIOPinConfigure(GPIO_PC6_EPI0S4);
GPIOPinConfigure(GPIO_PC7_EPI0S5);
GPIOPinConfigure(GPIO_PH0_EPI0S6);
GPIOPinConfigure(GPIO_PH1_EPI0S7);
GPIOPinConfigure(GPIO_PE0_EPI0S8);
GPIOPinConfigure(GPIO_PE1_EPI0S9);
GPIOPinConfigure(GPIO_PH4_EPI0S10);
GPIOPinConfigure(GPIO_PH5_EPI0S11);
GPIOPinConfigure(GPIO_PF4_EPI0S12);
GPIOPinConfigure(GPIO_PG0_EPI0S13);
GPIOPinConfigure(GPIO_PG1_EPI0S14);
GPIOPinConfigure(GPIO_PF5_EPI0S15);
GPIOPinConfigure(GPIO_PJ0_EPI0S16);
GPIOPinConfigure(GPIO_PJ1_EPI0S17);
GPIOPinConfigure(GPIO_PJ2_EPI0S18);
GPIOPinConfigure(GPIO_PJ3_EPI0S19);
GPIOPinConfigure(GPIO_PH6_EPI0S26);
GPIOPinConfigure(GPIO_PH7_EPI0S27);
GPIOPinConfigure(GPIO_PJ4_EPI0S28);
GPIOPinConfigure(GPIO_PJ5_EPI0S29);
GPIOPinConfigure(GPIO_PJ6_EPI0S30);
GPIOPinTypeEPI(GPIO_PORTC_BASE, EPI_PORTC_PINS);
GPIOPinTypeEPI(GPIO_PORTE_BASE, EPI_PORTE_PINS);
GPIOPinTypeEPI(GPIO_PORTF_BASE, EPI_PORTF_PINS);
GPIOPinTypeEPI(GPIO_PORTG_BASE, EPI_PORTG_PINS);
GPIOPinTypeEPI(GPIO_PORTH_BASE, EPI_PORTH_PINS);
GPIOPinTypeEPI(GPIO_PORTJ_BASE, EPI_PORTJ_PINS);
EPIDividerSet(EPI0_BASE, 0);
EPIModeSet(EPI0_BASE, EPI_MODE_HB16);
EPIConfigHB16Set(EPI0_BASE, EPI_HB16_MODE_ADMUX | EPI_HB16_WRWAIT_0 | \
EPI_HB16_RDWAIT_0 | \
EPI_HB16_CSCFG_ALE, 0x01);
EPIAddressMapSet(EPI0_BASE, EPI_ADDR_RAM_SIZE_16MB |EPI_ADDR_RAM_BASE_6);
MEM_ADDR_PTR = (unsigned long *)0x60000000;
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
The code to do the operation is
void Timer0BIntHandler(void)
{
unsigned long z[1];
ADCProcessorTrigger(ADC0_BASE, 3);
TimerIntDisable(TIMER0_BASE, TIMER_TIMB_TIMEOUT);
TimerIntClear(TIMER0_BASE, TIMER_TIMB_TIMEOUT);
GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0x10);
if (count < Samp)
while (!ADCIntStatus(ADC0_BASE,3,false))
}
ADCSequenceDataGet(ADC0_BASE, 3, z);
ADCIntClear(ADC0_BASE, 3);
MEM_ADDR_PTR[MEM_START_ADDRESS + count] = z[0];
count++;
TimerIntEnable(TIMER0_BASE, TIMER_TIMB_TIMEOUT);
GPIOPinWrite(GPIO_PORTE_BASE, DSP_SENSOR_PINS, 0x00);
else
TimerDisable(TIMER0_BASE, TIMER_B);
GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0x00);
Analyze();
Everything seems to work except the EPIO.
Any suggestions/help?
Hello Maurice Givens,
I don't know if that's a copy-paste error or not, but you will want to do your SysCtlPeriphEnable() calls for the GPIO blocks prior to setting up the pins. Beyond that, you might want to simplify things to just the EPI setup and a read/write as appropriate for your connected device. Can you share what you have connected via the EPI?
Hi Mitch, thanks for the reply
I "uncoupled" things to make them flow easier here. The SysCtlPeripheralEnable() calls are in a function init_PERIPH(), the GPIOPinConfigure() and EPI set up is in function init_EPIO(), the clock is set using SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); in function init_CLK().
The timer set up (which I didn't include) is in init_TIMER and looks like
void init_TIMER(void)
TimerConfigure(TIMER0_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_B_PERIODIC);TimerLoadSet(TIMER0_BASE, TIMER_B, SysCtlClockGet()/25000);TimerIntClear(TIMER0_BASE, TIMER_TIMB_TIMEOUT);
TimerIntRegister(TIMER0_BASE, TIMER_B, Timer0BIntHandler);
In main(), the calls are
init_CLK();
init_PERIPFH();
init_TIMER();
init(EPIO();
So, the peripherials are enabled before the pins are configured. At the momenrt, I have nothing"connected" to the EPI. I am just looking at the signals to make sure everything is working. I will be connecting a 1Meg x 16 SRAM to the EPI.
Oh yes. I am using other GPIO pins for other functions, thus the need to configure more than just the EPI.
Hello Maurice,
I tested the code you provided as an isolated EPI test and it appears to be wiggling the signals (ALE/WRn). How are you monitoring the pins?
You mentioned this is a LM3S9D92. Can you provide the values from the DiD0 & DID1 registers?
Also, while it's not causing this problem, you don't have GPIOH pins 6 & 7 in your EPI_PORTH_PINS but are setting them for EPI via GPIOPinConfigure().
1. In case something else in my code is affecting the EPI, Tomorrow I will make a test project with just the EPI code to see what happens.
2. I am monitoring the lines with a Tek TDS 3034B digital scope
3. The data sheet for LM3S9D92 shows that DID0 and DID1 are in register 15. However, when I use VIEW REGISTERS, it stops at register 14. How do I view DID0 and DID1?
4. I noticed the same inconsistency, and removed the configuration of PH6 and PH7
I am now running just the EPI code. I see no movement on PJ5 (WE), PJ6 (ALE), or PH2 (AD1). Here is the code I'm using. The defines and declarations are in a EPI_test.h file.
#define EPI_PORTH_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5)
#define EPI_PORTJ_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6)
#define MEM_START_ADDRESS 0x000000
#define MEM_END_ADDRESS 0xFFFFF
#define TIMER_FLAG (GPIO_PIN_4)
static volatile unsigned long *MEM_ADDR_PTR;
void init_CLK(void);
void init_PERIPH(void);
void init_GPIO(void);
void init_EPIO(void);
void init_TIMER(void);
void Timer0BIntHandler(void);
#include <stdio.h>
#include <math.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_epi.h"
#include "inc/hw_gpio.h"
#include "inc/hw_timer.h"
#include "driverlib/epi.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "EPI_test.h"
unsigned long count, Samp;
int main(void)
init_PERIPH();
init_GPIO();
init_EPIO();
Samp = 0x20000;
count = 0;
TimerEnable(TIMER0_BASE, TIMER_B);
while(1);
z[0] = count;
GPIOPinWrite(GPIO_PORTE_BASE, TIMER_FLAG, 0x10);
GPIOPinWrite(GPIO_PORTE_BASE, TIMER_FLAG, 0x00);
void init_CLK(void)
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | \
SYSCTL_XTAL_16MHZ);
void init_EPIO(void)
EPIAddressMapSet(EPI0_BASE, EPI_ADDR_RAM_SIZE_16MB | EPI_ADDR_RAM_BASE_6);
MEM_ADDR_PTR = (unsigned long *) 0x60000000;
void init_GPIO(void)
GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, TIMER_FLAG);
void init_PERIPH(void)
TimerConfigure(TIMER0_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_B_PERIODIC);
TimerLoadSet(TIMER0_BASE, TIMER_B, SysCtlClockGet()/25000);
I tested this most recent code you provided and I am seeing activity on ALE/WRn/EPI0 during writes. Once your timeout triggers and the writes stop, the ALE goes low and WRn goes high as would be expected by the configuration.
So, let's revisit the DID0/DID1 and verify this is indeed a LM3S9D92 part. These are memory addressable registers in the MCU. You can read the 32bit value at 0x400F_E000 for DID0 and 0x400F_E004 for DID1. These results can then be compared to the datasheet DID0/DID1 descriptions.
Also, is this an evaluation board or a custom board?
EDIT: Also, I noticed you were using a an older Timer configuration #define. I would certainly recommend updating to the latest StellarisWare if you using an older version.
Hello Mitch,
I am using the EKS-LM3S9D92 eval kit. The DIDO/DID1 memory locations have (using memory browser)
0x400FE000 10060002 1092502E
This seems to indicate that the part is indeed a LM3S9D92, Rev A. I have tried a second LM3S9D92 that I have (also an EKS eval kit), with the same results, no activity on the EPI pins. Is it possible something is not getting enabled (missing line of code), do I need to enable the EPI interrupt, or I don't have something set correctly in the configuration file?
Additionally, I don't know if it's related, but to increase the overall run time, I increased the value of variable Samp (more interrupts, longer time). The processor goes to FaultISR subroutine after 131072 samples. Could this be an overflow of the stack? I thought that by putting the WHILE(1) in main(), this would not be a problem.
Not sure what you mean by "older Timer configuration #define". I am using the Stellarisware and examples downloaded from the TI site on March 15, 2012.
Many thanks for the assistance.
Maurice
OK, I see what you are refering to about the older StellarisWare. configurations such as #define GPIO_PH3_EPI0S0 are not in the newer. I downloaded th enewer one, but the project configuration (include options setting) still points to the older. Unless it has an affect on the EPI working or not, I would rather clear this problem before putting another variable in the stew.
RE: older Timer configuration define
I was specifically referring to TIMER_CFG_16_BIT_PAIR. There's no harm in using it. It just reminded me to check if you were using the latest release of StellarisWare.
RE: problem
Have you verified you are getting the Timer interrupts (via breakpoint or some other method)? The handler would have to be added to your startup_xxx.c code for the 'Timer 0 Subtimer B' vector. You can, of course, rule that completely out by adding in a static EPI write to the while(1) loop (and I'd recommend a SysCtlDelay if you do that).
To test your build setup, I have attempted to attach my build of your latest posted code. I think the only change I made was to add 'volatile' to your count and Samp variable declarations to make certain the compiler didn't do any crazy optimizations since the interrupt handler was using them.
8171.epi_hb16_2.zip
In the Timer0BIntHandeler() interrupt routine there is a TIMER_FLAG which sets a GPIO pin to HIGH when the interrupt handler is entered, and returns it to LOW when the inyerrupt handler is completed. This signal is being monitored to ensure the interrupt handler is entered. I put a breakpoint in the "ELSE" portion of the "IF" (and looked at "count" value) to ensure the comparison was working correctly. At the moment, I have two problems.
1. The EPI signals are not moving
2. If "Samp" is set to 131072 or greater, the MEM_ADDR_PTR[MEM_START_ADDRESS + count] = z[0]; line send the PC to the FaultISR handler.
I have unzipped your files and will try to run them today.
Regards,
Mitch,
From the .axf extension of the file you sent, I am assuming you are using the Keil IDE. I am using CCS v5. How do I download the axf file using ccs?
Although I use nearly all the tools we support at one time or another, I more often then not use GCC / OpenOCD (and did so in this case). However, you should be able to load it on the target with CCS.
Switch to the debug view. In the "Debug" tab (generally on the left), right click on the device used to connect to the EK (such as Stellaris ICDI) and select "connect to target". Then under the Target menu, select "Load program". That should allow you to browse out to the *.axf file and load it on the EK.
When I tried to load the .axf file I get the message
Can't find a source file at "C:\develop\repositories\DriverLib\boards\dk-tempest_kitronix\cust_test/epi_hb16_2.c"
Try the attached versions (without debug enabled). You can also use the LMFlash programmer to load the *.bin into flash and run it from there.
0486.epi_hb16_2.zip