1

I am using a Raspberry Pi(Model 1 B+) and an oscilloscope in order to program SPI with C. I am doing this by using direct access to the GPIO register.

Like this: https://elinux.org/RPi_GPIO_Code_Samples#Direct_register_access.

The datasheet of BCM2835: https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf

The problem is that if I do access the register using a bitwise operation as following :
GPSET0 |= 1 << 8;
it also modifies the GPIO pin 11. I think I heard some of GPIO pins are hard-wired together. Is it because of that? But if I don't use bitwise operation, i.e:
GPSET0 = 1 << 8
It only modifies the GPIO pin 8.

I need advice. Thank you.

P.P.S This is how I initialised GPSET0 and gpiomem is the pointer stored after mapping the memory.


#define GPFSEL0 gpiomem[0]
#define GPFSEL1 gpiomem[1]
#define GPFSEL2 gpiomem[2]
#define GPFSEL3 gpiomem[3]
#define GPSET0 gpiomem[7]
#define GPSET1 gpiomem[8]
#define GPCLR0 gpiomem[10]
#define GPCLR1 gpiomem[11]
#define GPLEV0 gpiomem[13]
#define GPLEV1 gpiomem[14]
#define SEL_FNC(gpfsel, pin, fnc) gpfsel = (gpfsel & (~((0x7)<<(pin*3)))) | (fnc << (pin * 3))
#define SEL_OUTPUT 0x1
#define SEL_INPUT 0x0
extern volatile uint32_t *gpiomem;

P.S.

While the SPI library offered is precise, it seems rather slow because of the delay between the chip select and the data transmission. a few tens of micro-seconds. (To be precise 33.6us but this doesn't work for me because I need to refresh a 128x160 LCD module using ST7735. Taking account of this alone gives me a calculation of 600ms to refresh a screen, approximately) There is a bit longer delay until next transmission.

Maybe I am doing this wrong. If someone can give me an insight into this, that'd be great.

6
  • Is there any reason you are trying to bitbang SPI instead of using the SPI peripheral?
    – crasic
    Commented Aug 27, 2018 at 20:39
  • As I said, @crasic, while the SPI library offered is precise, it seems rather slow because of the delay between the chip select and the data transmission. a few tens of micro-seconds. Please read the "P.S."
    – user167987
    Commented Aug 27, 2018 at 20:40
  • This is configurable, this delay is require by most devices. You will not do any better with bitbang. If there is only one device you can also keep CS asserted with GPIO and use SPI driver for communication
    – crasic
    Commented Aug 27, 2018 at 20:41
  • You also do not provide enough code, how is GPSET0 initialized?
    – crasic
    Commented Aug 27, 2018 at 20:43
  • @crasic could you show me a documentation where I can read more about this? elinux.org/index.php?title=RPi_SPI#Chip_Select doesn't provide enough information it seems. I will edit my question to provide with more detail on GPSET0
    – user167987
    Commented Aug 27, 2018 at 20:44

1 Answer 1

4

You have misunderstood the usage of the set and clear registers.

If bit x is 1 in the set register then GPIO x is set high. If bit x is 0 then the level of GPIO x is not affected (i.e. if high it stays high, if low it stays low).

If bit x is 1 in the clear register then GPIO x is set low. If bit x is 0 then the level of GPIO x is not affected (i.e. if high it stays high, if low it stays low).

So there is no need to read the set/clear register and or in the bits. Just set the bits of the GPIO you want to affect.

Or'ing in the bits wouldn't necessarily be harmful until you consider that the set/clear registers are WRITE only. So when you read the register you will be reading gibberish. So the end result is you are randomly setting and clearing bits by the very act of or'ing.

4
  • Thank you! I understood. With LPC1768 MCU, I used FIOPIN register and then I forgot that I didn't have to do the or'ing. That is the beauty of set and clear register... Thank you again. Rather new on low level, and I got confused on this matter.
    – user167987
    Commented Aug 27, 2018 at 20:58
  • Also, that BCM2835 document seriously need an update. The page 95 says that set register is R/W.
    – user167987
    Commented Aug 27, 2018 at 21:00
  • @user167987 The elinux site does have an errata which documents the known errors. I said the register would read gibberish, in actual fact it probably reads back as 'gpio' (the ASCII characters encoded in the 32 bit word). This happens for a lot of the Broadcom peripherals when you do an illegal register read, e.g. an illegal UART register might read back as 'uart', an illegal SPI register might read back as ' spi' etc.
    – joan
    Commented Aug 27, 2018 at 21:08
  • Yeah. I read the datasheet of BCM2835 and it tells me that reading Timer IRQ clear register would give back "ARMT" in reversed direction. The errata page is great. Although, I could read in between the lines even when things are wrongly written (I made a disastrous error anyhow) but this actually helps me avoiding confusion. I appreciate it.
    – user167987
    Commented Aug 27, 2018 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.