cancel
Showing results for 
Search instead for 
Did you mean: 

I can write to GPIO PORTs 0..7, but not 8 or 9. Anyone here know how?

jwmullens1
Associate II
Posted on March 23, 2007 at 09:13

I can write to GPIO PORTs 0..7, but not 8 or 9. Anyone here know how?

5 REPLIES 5
jwmullens1
Associate II
Posted on May 17, 2011 at 09:39

I'm unable to get port 8 to toggle using the GPIO_Write() command. If change to GPIO3 or GPIO6, my test program works fine, but with port 8, I see nothing. Any feedback people could give me would be greatly appreciated.

Is there an update to the GPIO_Init() function? I tried to assert GPIO_EMIConfig(DISABLE), to insure that the bus was in GPIO mode, but this also didn't seem to do any good.

/* Includes ---------------*/

#include ''91x_lib.h''

GPIO_InitTypeDef GPIO_InitStructure;

u8 a;

/* Private function prototypes -------------*/

void SCU_Configuration(void);

static void Delay(u32 nCount);

int main()

{

#ifdef DEBUG

debug();

#endif

char toggle =0;

char k = 0;

/* Configure the system clocks */

SCU_Configuration();

/* GPIO Configuration -----*/

GPIO_DeInit(GPIO6);

GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;

GPIO_InitStructure.GPIO_Alternate=GPIO_OutputAlt1;

GPIO_Init (GPIO6, &GPIO_InitStructure);

GPIO_DeInit(GPIO7);

GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;

GPIO_InitStructure.GPIO_Alternate=GPIO_OutputAlt1;

GPIO_Init (GPIO7, &GPIO_InitStructure);

GPIO_DeInit(GPIO3);

GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;

GPIO_InitStructure.GPIO_Alternate=GPIO_OutputAlt1;

GPIO_Init (GPIO3, &GPIO_InitStructure);

//GPIO_EMIConfig(DISABLE); //make sure I'm not in EMI mode for P8 or P9; page 78 of the sw_lib man.

GPIO_DeInit(GPIO8);

GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;

GPIO_InitStructure.GPIO_Alternate=GPIO_OutputAlt1;

GPIO_Init (GPIO8, &GPIO_InitStructure);

GPIO_WriteBit(GPIO3,GPIO_Pin_7,Bit_RESET); //turn on the enable of the 3:8 selector, active low

GPIO_Write(GPIO8,0x00);

while(1)

{

if(toggle){

toggle = 0;

GPIO_WriteBit(GPIO6,GPIO_Pin_4,Bit_SET); // dac1_load

}else{

toggle = 1;

GPIO_WriteBit(GPIO6,GPIO_Pin_4,Bit_RESET);

}

if(++k >= 7) k = 0;

GPIO_Write(GPIO8,k); // why does this work for 3 or 6 and not for 8 ?

Delay(0x7FFFF);

}

}

/*******************************************************************************

* Function Name : SCU_Configuration

* Description : Configures the system clocks.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void SCU_Configuration(void)

{

/* Enable the __GPIO6 */

SCU_APBPeriphClockConfig(__GPIO6 ,ENABLE);

/* Enable the __GPIO7 */

SCU_APBPeriphClockConfig(__GPIO7 ,ENABLE);

/* enable the __GPIO3 */

SCU_APBPeriphClockConfig(__GPIO3 ,ENABLE);

/* enable the __GPIO8 */

SCU_APBPeriphClockConfig(__GPIO8 ,ENABLE);

}

/*******************************************************************************

* Function Name : Delay

* Description : Inserts a delay time.

* Input : nCount: specifies the delay time length.

* Output : None

* Return : None

*******************************************************************************/

static void Delay(u32 nCount)

{

u32 j = 0;

for(j = nCount; j != 0; j--);

}

[ This message was edited by: JWM on 20-03-2007 18:36 ]

mark9
Associate II
Posted on May 17, 2011 at 09:39

The str91x library is broken for gpio8 annd gpio9. only 0-7 is supported. if you use the str91x library for gpio8, not only will gpio8 not work, but it will reconfigure gpio0 (a bug!). gpio9 will affect gpio1.

search the forum for hints. best for now is to just write directly to the registers.

supposedly this will be fixed, but don't hold your breath.

mbeakes
Associate II
Posted on May 17, 2011 at 09:39

There is a bug in the 91x_gpio.c

When initializing the GPIO8 or GPIO9, they do not make any verification. So they overwrite other registers. When debugging, you could also have a memery access error if trying to initilize GPIO9 (I already got this problem). To solve this problem just replace the GPIO_Init by this function. You can alos download the attached file.

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

{

/* Select pin direction */

u8 PinNumber = 0;

u8 Counter = 0;

u8 GPIO_Number = 0;

GPIO_Number = GPIO_GetGPIONumber(GPIOx);

if(GPIO_InitStruct->GPIO_Direction == GPIO_PinOutput)

{

GPIOx->DDR |= GPIO_InitStruct->GPIO_Pin;

}

else

{

GPIOx->DDR &= ~GPIO_InitStruct->GPIO_Pin;

}

for (Counter = 0; Counter < 8;Counter++)

{

/*Search pin number*/

PinNumber = (GPIO_InitStruct->GPIO_Pin & (1 <

if((PinNumber >> Counter) == 1)

{

/***********************************************************

IMPORTANT !!! We modify the original ST code to do not write to

GPIOOUT > 7 because writing to GPIOOUT[8-9] overwrite GPIOIN0

and GPIOIN1 registers

***********************************************************/

if(GPIO_Number <= 7)

{

/*Output ALternate 0*/

SCU->GPIOOUT[GPIO_Number] &= ~(0x3 <

if(GPIO_InitStruct->GPIO_Alternate == GPIO_OutputAlt1)

{

/*Output ALternate 1*/

SCU->GPIOOUT[GPIO_Number] |= 1 << (Counter *2);

}

if(GPIO_InitStruct->GPIO_Alternate == GPIO_OutputAlt2)

{

/*Output ALternate 2*/

SCU->GPIOOUT[GPIO_Number] |= 0x2 << (Counter *2);

}

if(GPIO_InitStruct->GPIO_Alternate == GPIO_OutputAlt3)

{

/*Output ALternate 3*/

SCU->GPIOOUT[GPIO_Number] |= 0x3 << (Counter *2);

}

/*IP Connected disable*/

SCU->GPIOIN[GPIO_Number] &= ~(0x1 << Counter) ;

if(GPIO_InitStruct->GPIO_IPConnected == GPIO_IPConnected_Enable)

{

/*IP Connected enable*/

SCU->GPIOIN[GPIO_Number] |= 0x1 << Counter;

}

}

/*Type configuration: PushPull or Open Collector*/

SCU->GPIOTYPE[GPIO_Number] &= ~(0x1 << Counter) ;

if(GPIO_InitStruct->GPIO_Type == GPIO_Type_OpenCollector)

{

/*Open Drain configuration*/

SCU->GPIOTYPE[GPIO_Number] |= 0x1 << Counter;

}

}

}

}

Hope this will help you.

[ This message was edited by: cameleon on 22-03-2007 21:59 ]

jwmullens1
Associate II
Posted on May 17, 2011 at 09:39

Thank you very much for your feedback. After reading this forum, I have also tried to rewrite this function. I think I can keep ports 0 and 1 from getting stepped on this way, but my simple test program using your GPIO_Init() function still wont work. For whatever reason, the demo program that comes from IAR works, but I'm not sure why. If I use their code as a basis, and add just my little while(1) routine , I can even crash the demoboard when toggling port8 some of the time. This is one thing I hate about global variables... something else seems to be getting configured or trashed..

I think my little test program should be consistent with the library guidelines. Is there a trick for writing to ports 8 or 9, should some other functions be used to write these ports?

I'm inclined to write my own functions that read and write the IO registers directly for 8 and 9,

something of the form:

volatile int *pbase = (volatile int *)HW_PORT;

or

*(volatile int *) HW_PORT = val;

Has anyone else here had as much trouble with the GPIO as I seem to be having? Does anyone here have code they've written to talk directly to the hardware registers?

I'm including a copy of my test program that should toggle 3 bits on port 8.

Quote:

On 22-03-2007 at 21:57, Anonymous wrote:

There is a bug in the 91x_gpio.c

When initializing the GPIO8 or GPIO9, they do not make any verification. So they overwrite other registers. When debugging, you could also have a memory access error if trying to initialize GPIO9 (I already got this problem). To solve this problem just replace the GPIO_Init by this function. You can also download the attached file.

mbeakes
Associate II
Posted on May 17, 2011 at 09:39

One easy way to debug this problem is by writing directly to the register like GPIO_DATA, GPIO_SEL, and GPIO_DIR from the debugger. Before writing code, you should try to do this.

Here is the steps that you should follow

1- Make sure that you activate the clock with SCU_APBPeriphClockConfig(__GPIOx) (where x is your gpio port, do it for all gpio)

2- Release the peripheral from reset with: SCU_APBPeriphReset(__GPIOx, DISABLE) *** this part is missing from your code *****

3- GPIO_DeInit();

4- fill the structure with the proper setting GPIO_PinInput or Output

5- GPIO_Init();

(after theses steps normally the gpio should works) If not :

6- Build the application and execute theses line in the debugger

7- Manually write to GPIO_DATA in the debugger . Do it directly in the register. Try setting one bit of the GPIO_DATA.

When you set a bit, for exemple GPIO8_DATA no3 and the bit is going to 0 just after you set a '1' in the register. This is because the Clock and the reset peripheral as not been properly configure. Try setting it directly in the register (activate the clock and reset). When they works by writing manually in the register, try to write C code.

After setting the bit to '1' or '0' in the register, I suggest that you take a scope or voltmeter to validate.

Hope this will help you

[ This message was edited by: cameleon on 23-03-2007 13:45 ]