RASPBERRY PI C   - Page 1
Forum section: electronics / general

author: Szabolcs
author_rank: Newbie
timestamp: September 11, 2020, 08:20:16 pm
content: Hy!1. It was loong time that i used this forum. I had to create new accaunt.2. Sorry for bad eng i type at night after work. So my brain is not working sometime.3. What I want ! I want to create C programs that communicate with Raspberry pi hats and other stuff . YES I KNOW THERE IS PHYTON code for evriting.

author: Szabolcs
author_rank: Newbie
timestamp: September 11, 2020, 08:28:09 pm
content: My forst projekt is to wirte driver for SH1107https://shop.pimoroni.com/products/1-12-oled-breakout?variant=12628508704851Not using Wiering pi. bc I don't know how long will last.MY CODE BITBANG because using SPI it wont let me use most of the io pins (or I am wrong)-- i try to use the simplest code//compaile pi@TOSTER:~ $ sudo gcc -o dis -l rt display.c -l bcm2835#include <stdio.h>#include <bcm2835.h>// bcm2835_delayMicroseconds()// Blinks on RPi Plug P1 pin 11 (which is GPIO pin 17)#define MOSI RPI_GPIO_P1_19 //MOSI DATA 8 bit#define SCK RPI_GPIO_P1_23 //SCK Clock#define SS_CS RPI_GPIO_P1_24 //CS Slave slect#define CD RPI_GPIO_P1_21 //CD command select MISO// function to convert Hexadecimal to Binary Numberint J;void DEF (){bcm2835_init();bcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SCK, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(CD, LOW);bcm2835_gpio_write(SS_CS, LOW);bcm2835_gpio_write(MOSI, LOW);bcm2835_gpio_write(SCK, LOW);bcm2835_close();}void SPI8(char* hexdec){int DATA ; //8 biten megy a kommmunikációswitch (hexdec) {case '0':DATA= 0;DATA  = 0;DATA  = 0;DATA  = 0;break;case '1':DATA= 0;DATA  = 0;DATA  = 0;DATA  = 1;break;case '2':DATA= 0;DATA  = 0;DATA  = 1;DATA  = 0;break;case '3':DATA= 0;DATA  = 0;DATA  = 1;DATA  = 1;break;case '4':DATA= 0;DATA  = 1;DATA  = 0;DATA  = 0;break;case '5':DATA= 0;DATA  = 1;DATA  = 0;DATA  = 1;break;case '6':DATA= 0;DATA  = 1;DATA  = 1;DATA  = 0;break;case '7':DATA= 0;DATA  = 1;DATA  = 1;DATA  = 1;break;case '8':DATA= 1;DATA  = 0;DATA  = 0;DATA  = 0;break;case '9':DATA= 1;DATA  = 0;DATA  = 0;DATA  = 1;break;case 'A':case 'a':DATA= 1;DATA  = 0;DATA  = 1;DATA  = 0;break;case 'B':case 'b':DATA= 1;DATA  = 0;DATA  = 1;DATA  = 1;break;case 'C':case 'c':DATA= 1;DATA  = 1;DATA  = 0;DATA  = 0;break;case 'D':case 'd':DATA= 1;DATA  = 1;DATA  = 0;DATA  = 1;break;case 'E':case 'e':DATA= 1;DATA  = 1;DATA  = 1;DATA  = 0;break;case 'F':case 'f':DATA= 1;DATA  = 1;DATA  = 1;DATA  = 1;break;default:break;// printf("\nInvalid hexadecimal digit %c",// hexdec);}switch (hexdec) {case '0':DATA  = 0;DATA  = 0;DATA  = 0;DATA  = 0;break;case '1':DATA  = 0;DATA  = 0;DATA  = 0;DATA  = 1;break;case '2':DATA  = 0;DATA  = 0;DATA  = 1;DATA  = 0;break;case '3':DATA  = 0;DATA  = 0;DATA  = 1;DATA  = 1;break;case '4':DATA  = 0;DATA  = 1;DATA  = 0;DATA  = 0;break;case '5':DATA  = 0;DATA  = 1;DATA  = 0;DATA  = 1;break;case '6':DATA  = 0;DATA  = 1;DATA  = 1;DATA  = 0;break;case '7':DATA  = 0;DATA  = 1;DATA  = 1;DATA  = 1;break;case '8':DATA  = 1;DATA  = 0;DATA  = 0;DATA  = 0;break;case '9':DATA  = 1;DATA  = 0;DATA  = 0;DATA  = 1;break;case 'A':case 'a':DATA  = 1;DATA  = 0;DATA  = 1;DATA  = 0;break;case 'B':case 'b':DATA  = 1;DATA  = 0;DATA  = 1;DATA  = 1;break;case 'C':case 'c':DATA  = 1;DATA  = 1;DATA  = 0;DATA  = 0;break;case 'D':case 'd':DATA  = 1;DATA  = 1;DATA  = 0;DATA  = 1;break;case 'E':case 'e':DATA  = 1;DATA  = 1;DATA  = 1;DATA  = 0;break;case 'F':case 'f':DATA  = 1;DATA  = 1;DATA  = 1;DATA  = 1;break;default:break;// printf("\nInvalid hexadecimal digit %c",// hexdec);}// int main(int argc, char **argv)// {bcm2835_init();bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SCK, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);for(int i = 0; i < 8; i++) {bcm2835_gpio_write(MOSI, DATA);//bcm2835_delayMicroseconds(1);bcm2835_gpio_write(SCK, HIGH);//SCK UP//bcm2835_gpio_write(MOSI, DATA);bcm2835_delayMicroseconds(1);bcm2835_gpio_write(SCK, LOW);//SCK DOWN}bcm2835_gpio_write(MOSI, LOW);//defaul helyzetbcm2835_close();}void ENABLE_H (){bcm2835_init();bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(SS_CS, HIGH);bcm2835_close();}void ENABLE_L (){bcm2835_init();bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(SS_CS, LOW);bcm2835_close();}void CD_H (){bcm2835_init();bcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(CD, HIGH);bcm2835_close();}void CD_L (){bcm2835_init();bcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(CD, LOW);bcm2835_close();}int main(){DEF (); // all out to 0ENABLE_H ();// if starts it the currect posENABLE_L ();CD_L ();SPI8 ("AE") ;SPI8 ("DC") ;SPI8 ("00") ;SPI8 ("81") ;SPI8 ("2F") ;SPI8 ("20") ;SPI8 ("A0") ;SPI8 ("C0") ;SPI8 ("A8") ;SPI8 ("7F") ;SPI8 ("D5") ;SPI8 ("50") ;SPI8 ("D9") ;SPI8 ("22") ;SPI8 ("DB") ;SPI8 ("35") ;SPI8 ("B0") ;SPI8 ("DA") ;SPI8 ("12") ;SPI8 ("A4") ;SPI8 ("A6") ;ENABLE_H ();bcm2835_delay(1);CD_L ();// SCR INI KÉSZ/// one page data --------------------------------------00ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B0") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------01ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B1") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("00") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------02ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B2") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------03ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B3") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------04ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B4") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------05ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B5") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------06ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B6") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------07ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B7") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------08ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B8") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------09ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B9") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------10ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("BA") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------11ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("BB") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------12ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("BC") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------13ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("BD") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------14ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("BE") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// one page data --------------------------------------15ENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("BF") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();//display onCD_L ();ENABLE_L ();SPI8 ("AF") ;ENABLE_H ();CD_L ();//display onCD_L ();ENABLE_L ();SPI8 ("AF") ;ENABLE_H ();CD_L ();/// dataENABLE_L ();SPI8 ("15") ;SPI8 ("08") ;SPI8 ("B0") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();/// dataENABLE_L ();SPI8 ("10") ;SPI8 ("00") ;SPI8 ("B1") ;CD_H ();for(int J = 0; J < 128; J++){SPI8 ("FF") ;}CD_L ();ENABLE_H ();}//main END---------------------------------------------------

author: hamster_nz
author_rank: Super Contributor
timestamp: September 11, 2020, 10:12:50 pm
content: Hi! I'm quite happy to help. I'll have a look over your code..I'm not sure what your question is though!I have a Raspberry Pi (well, quite a few actually..), but not that model of display, so although I can build it I can't test if it works or not.Mike

author: hamster_nz
author_rank: Super Contributor
timestamp: September 11, 2020, 11:16:08 pm
content: So I've tidied up the code a bit:- Made the ASCII hex to value code a lot shorter- Removed a lot of the repeated code into functionsI've found a bit of inconsistency - have a look at for the WHY IS THIS "00" comment towards the end.I also think you should call bcm2835_init(); only once, but you seem to be calling it every time you send a byte,...Code:#include <stdio.h>#include "bcm2835.h"// bcm2835_delayMicroseconds()// Blinks on RPi Plug P1 pin 11 (which is GPIO pin 17)#define MOSI RPI_GPIO_P1_19 // MOSI DATA 8 bit#define SCK RPI_GPIO_P1_23 // SCK Clock#define SS_CS RPI_GPIO_P1_24 // CS Slave slect#define CD RPI_GPIO_P1_21 // CD command select MISOvoid DEF (){bcm2835_init();bcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SCK, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(CD, LOW);bcm2835_gpio_write(SS_CS, LOW);bcm2835_gpio_write(MOSI, LOW);bcm2835_gpio_write(SCK, LOW);bcm2835_close();}void SPI8(char* hexdec){int value, i;int DATA ; //8 biten megy a kommmunikációfprintf(stderr,"Sending %s",hexdec);if(hexdec >= '0' && hexdec <= '9') {value = hexdec - '0';} else if(hexdec >= 'A' && hexdec <= 'Z') {value = hexdec - 'A' + 10;} else if(hexdec >= 'a' && hexdec <= 'z') {value = hexdec - 'a' + 10;} else {fprintf(stderr,"Bad hexdec\n");return;}value *= 16;if(hexdec >= '0' && hexdec <= '9') {value += hexdec - '0';} else if(hexdec >= 'A' && hexdec <= 'Z') {value += hexdec - 'A' + 10;} else if(hexdec >= 'a' && hexdec <= 'z') {value += hexdec - 'a' + 10;} else {fprintf(stderr,"Bad hexdec\n");return;}for(i=0; i < 8; i++) {DATA = (value & (1<<i)) ? 1 : 0;}bcm2835_init();bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SCK, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);for(int i = 0; i < 8; i++) {bcm2835_gpio_write(MOSI, DATA); //bcm2835_delayMicroseconds(1);bcm2835_gpio_write(SCK, HIGH); //SCK UPbcm2835_delayMicroseconds(1);bcm2835_gpio_write(SCK, LOW); //SCK DOWN}bcm2835_gpio_write(MOSI, LOW);//defaul helyzetbcm2835_close();}void ENABLE_H (){bcm2835_init();bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(SS_CS, HIGH);bcm2835_close();}void ENABLE_L (){bcm2835_init();bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(SS_CS, LOW);bcm2835_close();}void CD_H (){bcm2835_init();bcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(CD, HIGH);bcm2835_close();}void CD_L (){bcm2835_init();bcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(CD, LOW);bcm2835_close();}void send_data_block(char *a, char *b, char *c, char *d) {ENABLE_L ();SPI8 (a) ;SPI8 (b) ;SPI8 (c) ;CD_H ();// An idle pattern to waste some time????for(int i = 0; i < 128; i++) {SPI8 (d) ;}CD_L ();ENABLE_H ();}void display_on(void) {CD_L ();ENABLE_L ();SPI8 ("AF") ;ENABLE_H ();CD_L ();}int main(){DEF (); // all out to 0ENABLE_H ();// if starts it the currect posENABLE_L ();CD_L ();SPI8 ("AE") ;SPI8 ("DC") ;SPI8 ("00") ;SPI8 ("81") ;SPI8 ("2F") ;SPI8 ("20") ;SPI8 ("A0") ;SPI8 ("C0") ;SPI8 ("A8") ;SPI8 ("7F") ;SPI8 ("D5") ;SPI8 ("50") ;SPI8 ("D9") ;SPI8 ("22") ;SPI8 ("DB") ;SPI8 ("35") ;SPI8 ("B0") ;SPI8 ("DA") ;SPI8 ("12") ;SPI8 ("A4") ;SPI8 ("A6") ;ENABLE_H ();bcm2835_delay(1);CD_L ();// SCR INI KÉSZsend_data_block("10","00","B0","FF");send_data_block("10","00","B1","00"); // << WHY IS THIS "00"?send_data_block("10","00","B2","FF");send_data_block("10","00","B3","FF");send_data_block("10","00","B4","FF");send_data_block("10","00","B5","FF");send_data_block("10","00","B6","FF");send_data_block("10","00","B7","FF");send_data_block("10","00","B8","FF");send_data_block("10","00","B9","FF");send_data_block("10","00","BA","FF");send_data_block("10","00","BB","FF");send_data_block("10","00","BC","FF");send_data_block("10","00","BD","FF");send_data_block("10","00","BE","FF");send_data_block("10","00","BF","FF");display_on();display_on();/// datasend_data_block("15","08","B0","FF");send_data_block("10","00","B1","FF");}

author: greenpossum
author_rank: Frequent Contributor
timestamp: September 11, 2020, 11:51:13 pm
content: Much better than the original, but why send in strings of the hex value, why not just pass in the hex value directly, i.e.Code:SPI8(0xAE);then you don't have to parse anything.

author: hamster_nz
author_rank: Super Contributor
timestamp: September 11, 2020, 11:56:35 pm
content: Quote from: greenpossum on September 11, 2020, 11:51:13 pmI was thinking that, but then I started to see the OPs intent. From their perspective, it would be nicer (but less efficient) to do something likeCode:DEF (); // all out to 0SET_ENABLE(HIGH);// if starts it the currect posSET_ENABLE(LOW);SET_CD(LOW);send_data_block("AE DC 00 81 2F 20 A0 C0 A8 7F D5 50 D9 22 DB 35 B0 DA 12 A4 A6") ;SET_ENABLE(HIGH);bcm2835_delay(1);SET_CD(LOW);// SCR INI KÉSZsend_data_block("10 00 B0");send_data_block("10 00 B1");send_data_block("10 00 B2");send_data_block("10 00 B3");send_data_block("10 00 B4");Well, at least until the display is functioning correctly.

author: TK
author_rank: Super Contributor
timestamp: September 12, 2020, 12:01:51 am
content: Quote from: greenpossum on September 11, 2020, 11:51:13 pmIf you pass an hex value, OP needs to change the bit banging loop to do bit manipulation. Also function call is expensive, it is better to write a new function where you can pass an array of bytes and the number of bytes to transfer and do it in a single function call instead of calling SPI8() all the time.

author: greenpossum
author_rank: Frequent Contributor
timestamp: September 12, 2020, 12:03:02 am
content: In the second case the only difference between calls is one byte so just write a wrapper around SPI8() to call it with 0x10 0x00 then the desired byte, and any postamble. Make it inline if you are worried about the overhead of the function call but this is probably small compared to the body of the function.In the first case, just wrap a loop that calls SPI8() over an array of bytes, using sizeof() to get the length of the array. If you are worried about the function call overhead, then write a variant of SPI8 for an array of bytes so that the loop is inside the function.Bit extraction from a byte is done all the time, it's just a shift and mask in a loop. You have do it anyway if you pass in a string, the point is changing to a binary argument removes the hex parsing which is done for every call. I'm talking about the improved version by hamster_nz, not the horrible version by OP.

author: hamster_nz
author_rank: Super Contributor
timestamp: September 12, 2020, 12:28:27 am
content: I can see where the OP was coming from... here it is again with slightly more refactoring, and I think it's almost in good enough shape to test.I keep on reposting the code so the OP can see it evolve.Code:#include <stdio.h>#include "bcm2835.h"#define MOSI RPI_GPIO_P1_19 // MOSI DATA 8 bit#define SCK RPI_GPIO_P1_23 // SCK Clock#define SS_CS RPI_GPIO_P1_24 // CS Slave select#define CD RPI_GPIO_P1_21 // CD command select MISOvoid DEF (){// Set pins to outputbcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SCK, BCM2835_GPIO_FSEL_OUTP);// Set inital statebcm2835_gpio_write(CD, LOW);bcm2835_gpio_write(SS_CS, LOW);bcm2835_gpio_write(MOSI, LOW);bcm2835_gpio_write(SCK, LOW);}int hexchar_to_value(char c) {if(c >= '0' && c <= '9') return c - '0';if(c >= 'A' && c <= 'Z') return c - 'A' + 10;if(c >= 'a' && c <= 'z') return c - 'a' + 10;return -1;}int SPI8(char* hexdec){int value, digit1, digit2, i;int DATA ; //8 biten megy a kommmunikációdigit1 = hexchar_to_value(hexdec);if(digit1 < 0) {fprintf(stderr,"Bad hex digit\n");return 0;}digit2 = hexchar_to_value(hexdec);if(digit2 < 0) {fprintf(stderr,"Bad hex digit\n");return 0;}value = digit1*16+digit2;fprintf(stderr,"Sending %02X\n",value);for(i=0; i < 8; i++) {DATA = (value & (1<<i)) ? 1 : 0;}bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SCK, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);for(int i = 0; i < 8; i++) {bcm2835_gpio_write(MOSI, DATA); //bcm2835_delayMicroseconds(1);bcm2835_gpio_write(SCK, HIGH); //SCK UPbcm2835_delayMicroseconds(1);bcm2835_gpio_write(SCK, LOW); //SCK DOWN}bcm2835_gpio_write(MOSI, LOW);//defaul helyzetreturn 1;}void SET_ENABLE (int state){bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(SS_CS, state);fprintf(stderr,"Setting ENABLE to %s\n",state ? "HIGH": "LOW");}void SET_CD (int state){bcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_write(CD, state);fprintf(stderr,"Setting CD to %s\n",state ? "HIGH": "LOW");}void send_data_block(char *data) {// 'data' is a string of hexadecimal bytes e.g. "12 34 AB CD"SET_ENABLE(LOW);// While we are not at the end of the string, send datawhile(data != '\0') {int rtn = SPI8 (data); // Send the dataif(!rtn) // If the send failed the drop out of loopbreak;data += 2; // Skip forward two characters// Eat any spaceswhile(data == ' ') {data++;}}SET_CD(HIGH);// An idle pattern to waste some time????for(int i = 0; i < 128; i++) {SPI8 ("FF") ;}SET_CD(LOW);SET_ENABLE(HIGH);}void display_on(void) {SET_CD(LOW);SET_ENABLE(LOW);SPI8 ("AF") ;SET_ENABLE(HIGH);SET_CD(LOW);}int main(){bcm2835_init();DEF (); // all out to 0SET_ENABLE(HIGH);// if starts it the currect posSET_ENABLE(LOW);SET_CD(LOW);send_data_block("AE DC 00 81 2F 20 A0 C0 A8 7F D5 50 D9 22 DB 35 B0 DA 12 A4 A6") ;SET_ENABLE(HIGH);bcm2835_delay(1);SET_CD(LOW);// SCR INI KÉSZsend_data_block("10 00 B0");send_data_block("10 00 B1");send_data_block("10 00 B2");send_data_block("10 00 B3");send_data_block("10 00 B4");send_data_block("10 00 B5");send_data_block("10 00 B6");send_data_block("10 00 B7");send_data_block("10 00 B8");send_data_block("10 00 B9");send_data_block("10 00 BA");send_data_block("10 00 BB");send_data_block("10 00 BC");send_data_block("10 00 BD");send_data_block("10 00 BE");send_data_block("10 00 BF");display_on();display_on();send_data_block("15 08 B0");send_data_block("10 00 B1");bcm2835_close();}

author: greenpossum
author_rank: Frequent Contributor
timestamp: September 12, 2020, 12:55:02 am
content: You can fold the extraction of the bit into the bit banging loop and avoid the local array DATA.Code:DATA = (value & (1<<i)) ? 1 : 0;

author: hamster_nz
author_rank: Super Contributor
timestamp: September 12, 2020, 03:51:33 am
content: Had a few more minutes to play.- Added check that library initialised OK (make sure that you run it as 'root' with sudo)- Fixed up flapping MOSI- Set default state of MOSI correct- Fixed up the initial state of the CS and ENABLE pins- Got rid of excess calls setting pins to output mode- Connected Raspberry to Logic Analyser and traced (although didn't configure protocol analyser to check bit ordering and so on)- Made SCLK more symmetrical (just because it bugged me)At a glance it looks as if it should work... will add a snapshot from the Logic Analyser later today.Code:#include <stdio.h>#include <unistd.h>#include "bcm2835.h"#define MOSI RPI_GPIO_P1_19 // MOSI DATA 8 bit#define CD RPI_GPIO_P1_21 // CD command select MISO#define SCK RPI_GPIO_P1_23 // SCK Clock#define SS_CS RPI_GPIO_P1_24 // CS Slave slectstatic int verbose = 0;static void DEF () {// Set inital state of pinsbcm2835_gpio_write(CD, HIGH);bcm2835_gpio_write(SS_CS, HIGH);bcm2835_gpio_write(MOSI, LOW);bcm2835_gpio_write(SCK, LOW);// Set pins to outputbcm2835_gpio_fsel(CD, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SS_CS, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_OUTP);bcm2835_gpio_fsel(SCK, BCM2835_GPIO_FSEL_OUTP);}static int hexchar_to_value(char c) {if(c >= '0' && c <= '9') return c - '0';if(c >= 'A' && c <= 'Z') return c - 'A' + 10;if(c >= 'a' && c <= 'z') return c - 'a' + 10;return -1;}static int SPI8(char* hexdec) {int value, digit1, digit2, i;int DATA ; //8 biten megy a kommmunikációdigit1 = hexchar_to_value(hexdec);if(digit1 < 0) {fprintf(stderr,"Bad hex digit\n");return 0; // false}digit2 = hexchar_to_value(hexdec);if(digit2 < 0) {fprintf(stderr,"Bad hex digit\n");return 0; // false}value = digit1*16 + digit2;if(verbose) fprintf(stderr,"Sending %02X\n",value);for(i=0; i < 8; i++) {DATA = (value & (1<<i)) ? 1 : 0;}for(int i = 0; i < 8; i++) {bcm2835_gpio_write(MOSI, DATA ? HIGH : LOW); //bcm2835_delayMicroseconds(1);bcm2835_delayMicroseconds(1);bcm2835_gpio_write(SCK, HIGH); //SCK UPbcm2835_gpio_write(MOSI, DATA ? HIGH : LOW); //bcm2835_delayMicroseconds(1);bcm2835_delayMicroseconds(1);bcm2835_gpio_write(SCK, LOW); //SCK DOWN}return 1; // true}void SET_ENABLE (int state) {if(verbose) fprintf(stderr,"Setting ENABLE to %s\n",state ? "HIGH": "LOW");bcm2835_gpio_write(SS_CS, state);}void SET_CD (int state) {if(verbose) fprintf(stderr,"Setting CD to %s\n",state ? "HIGH": "LOW");bcm2835_gpio_write(CD, state);}void send_data_block(char *data) { // 'data' is a string of hexadecimal bytes e.g. "12 34 AB CD"SET_CD(LOW);SET_ENABLE(LOW);// While we are not at the end of the stringwhile(data != '\0') {int rtn = SPI8 (data); // Send the dataif(!rtn) // If the send failed the drop out of loopbreak;data += 2; // Skip forward two characters// Eat any spaceswhile(data == ' ') {data++;}}// The last byte might have left MOSI high, so set it lowbcm2835_gpio_write(MOSI, LOW); //defaul helyzetSET_CD(HIGH);// An idle pattern to waste some time????for(int i = 0; i < 128; i++) {SPI8 ("00") ;}SET_ENABLE(HIGH); // Keep MOSI LOW}void display_on(void) {send_data_block("AF");}int main() {if(!bcm2835_init()) {fprintf(stderr,"Unable to initialize BCM2835 library\n");return 0;}DEF (); // all out to 0SET_ENABLE(HIGH);// if starts it the currect possend_data_block("AE DC 00 81 2F 20 A0 C0 A8 7F D5 50 D9 22 DB 35 B0 DA 12 A4 A6") ;bcm2835_delay(1);// SCR INI KÉSZsend_data_block("10 00 B0");send_data_block("10 00 B1");send_data_block("10 00 B2");send_data_block("10 00 B3");send_data_block("10 00 B4");send_data_block("10 00 B5");send_data_block("10 00 B6");send_data_block("10 00 B7");send_data_block("10 00 B8");send_data_block("10 00 B9");send_data_block("10 00 BA");send_data_block("10 00 BB");send_data_block("10 00 BC");send_data_block("10 00 BD");send_data_block("10 00 BE");send_data_block("10 00 BF");display_on();display_on();/// datasend_data_block("15 08 B0");send_data_block("10 00 B1");sleep(1);bcm2835_close();}

author: hamster_nz
author_rank: Super Contributor
timestamp: September 12, 2020, 08:13:14 am
content: I set up a protocol decoder... here's the first write. The -on-the-wire bit order is back to front!SoCode:...for(int i = 0; i < 8; i++) {bcm2835_gpio_write(MOSI, DATA ? HIGH : LOW); //bcm2835_delayMicroseconds(1);bcm2835_delayMicroseconds(1);...Should beCode:...for(int i = 7; i >= 0; i--) {bcm2835_gpio_write(MOSI, DATA ? HIGH : LOW); //bcm2835_delayMicroseconds(1);bcm2835_delayMicroseconds(1);...

author: hamster_nz
author_rank: Super Contributor
timestamp: September 12, 2020, 10:57:58 am
content: With that change it now decodes correctly - see attached image.However, I worry that it won't work correctly first time after a reboot, because the pins power up in an non-helpful state.If it only works consistently when it's run for a second time, then sending a dummy command before the true initialization string should fix it.

author: greenpossum
author_rank: Frequent Contributor
timestamp: September 12, 2020, 11:07:37 am
content: Code:for(int i = 7; i >= 0; i--) {bcm2835_gpio_write(MOSI, DATA ? HIGH : LOW); //bcm2835_delayMicroseconds(1);bcm2835_delayMicroseconds(1);...That code can be optimised a lot. You can get rid of the counter and let the bit mask double as the counter like this:Code:for(unsigned int mask = 0x80; mask != 0; mask >>=1) {bcm2835_gpio_write(MOSI, (value & mask) ? HIGH : LOW); //bcm2835_delayMicroseconds(1);bcm2835_delayMicroseconds(1);...And of course by working on value directly you don't need the preceding loop and array DATA.

author: hamster_nz
author_rank: Super Contributor
timestamp: September 13, 2020, 05:51:08 am
content: I wonder where the oeiginal poster is?.... Tumbleweed....Glad I didn't spend my spare time polishing up and testing their code rather than my own stuff.Oh wait.....

author: maginnovision
author_rank: Super Contributor
timestamp: September 13, 2020, 03:31:01 pm
content: Don't worry I'm sure he learned(ctrl+c) and applied those lessons(ctrl+v).

author: Monkeh
author_rank: Super Contributor
timestamp: September 13, 2020, 03:32:26 pm
content: Congratulations, you just did his homework for him.