Parallel port manipulation

Post here first, or if you can't find a relevant section!
Post Reply
Andy2No
Posts: 15
Joined: Mon Dec 30, 2019 8:34 pm

Parallel port manipulation

Post by Andy2No »

I've quite often wanted to do parallel I/O on an arduino, and even more so on STM32 based ones like the Nucleo 64 boards, where there are lots of pins available. Is there a good way to do that?

Googling hasn't got me very far, but it seems it's quite easy in Atmel Studio C, for AVRs, for example - mostly, those are the results I get due to googles inability to stick to the point.

Today, I thought I'd write a quick test for a static RAM chip, since I recently bought some. It seems fairly obvious that the best way to do it would be to have an address bus on one port, a data bus on another, and then some control signals as single bits (just CS,WE and OE, in this case). I'm sure there are restrictions stopping me using certain bits, but in general, is that possible in Arduino on an STM32 Nucleo board?

In particular, I'm trying to do it with a Nucleo 64 STM32F446 board. If necessary, I could substitute an F103 or an F303 Nucleo 64, though it would seem any of those should be suitable.

Unless I'm reading it wrong, I seem to have one full 16 bit port, on PA0-15, and two ports with a bit missing from each, on PB and PC - there is no PB11 or PC10, unless I'm missing something.

For example, I'd like to be able to write something like this, to write a byte to the SRAM:

Code: Select all

void write_byte(unsigned int addr, uint8_t bval)
{
  bset(OE,1);   // Could assume these are already inactive...
  bset(WE,1);
  bset(CS,1);
  pause();	// Ideally, I'd like _delay_us(0.125) (from AVR C), or similar, but I'll settle for delay 1us
  PINA= addr;	// This is the critical part - how can I do this, in STM32 Arduino?
  PINB= bval;
  pause;      // pause a lot more than needed, to make sure
  bset(CS,0); pause();
  bset(WE,0); pause(); pause();
  bset(WE,1);
  bset(CS,1);
  bset(OE,1); 
}
- bset() could just be digitalWrite, or one of the faster variants. I could set up the data and address pins one at a time, in a loop, but that just seems like a really inappropriate way to do it, even if I don't actually need it to be fast.
Andy2No
Posts: 15
Joined: Mon Dec 30, 2019 8:34 pm

Re: Parallel port manipulation

Post by Andy2No »

Okay, I can now answer the main point of that question for myself, after more googling, and some experimentation, but feel free to add to my knowledge about this, which is very little, so far.

For some reason, I can't seem to use PA2 & PA3, which I assumed I could, so I can't have all 16 bits of port A, but in general, this sort of thing works:

Using pinMode() to set pins as inputs and outputs, by port bit name seems okay - sloppy, but good enough for now, since it doesn't have to be done all that often. I'm aware there are port registers to do that directly, and I probably can, but that's not the main issue.

E.g. pinMode(PB0, OUTPUT); // works as you might expect

I can apparently do this (subject to further testing, but it lights some LEDs) :

Code: Select all

void writeParallelA16(uint16_t address) // 16 bits, for address bus
{
 GPIOA->ODR= address; // just want the top 8 bits - other bits hopefully unaffected, as I didn't set those as OUTPUT
 GPIOC->ODR= address & 0xff; // lower 8 bits of the address bus
}

and

Code: Select all

void writeParallelB8(uint8_t data) // 8 bit data
{
 GPIOB->ODR = data;
}

uint8_t readParallelB8()
{
  return GPIOB->IDR & 0xff;
}
- the read is not yet tested, but it does compile. Both are subject to having set the pin modes correctly first.

The new thing I can't seem to do is get the virtual com port to work, to show debugging messages on the console... I'll start a new thread for that.
Andy2No
Posts: 15
Joined: Mon Dec 30, 2019 8:34 pm

Re: Parallel port manipulation

Post by Andy2No »

I see this topic has effectively been covered a few days ago, but without mentioning parallel I/O:

viewtopic.php?f=7&t=21

- and has more of the details.
Post Reply

Return to “General discussion”