Memory mapped area of GPIO in raspberry pi - linux-kernel

I have real struggles with respective to understanding the data sheet part[BCM2835-ARM-Peripherals.pdf] where in which it talks about following:
Q1: Every gpio has 40 registers[refere: Table 6-1 GPIO Register Assignment] which are common for all gpios can be used to SET/CLEAR/GPFSEL[0-5] etc,but what is the purpose of GPIO function select register which has 10 FSEL (0-9) registers [refer: Table 6-2 – GPIO Alternate function select register 0].
Q2: How can I reach to a given GPIO through memorymapped region? , is something like below
Case#1 :GPIO4 with alternate function 5 as Input:
as ( 4 < 10) it will use "0x7E200000" with FSEL4 register[refer: Table 6-2 – GPIO Alternate function select register 0] having 000 and 010 = GPIO Pin 9 takes alternate function 5.
case#2 :GPIO27 with alternate function 3 as Output:
as ( 27 < 30) it will use "0x7E20000C" with FSEL3 register[refer: Table 6-2 – GPIO Alternate function select register 0] having 001 and 111 = GPIO Pin 9 takes alternate function 5.
Please let me know whether my understanding is correct or not?
Q3: what is the purpose of following tables
Table 6-3 – GPIO Alternate function select register 1
Table 6-4 – GPIO Alternate function select register 2
Table 6-5 – GPIO Alternate function select register 3
Table 6-6 – GPIO Alternate function select register 4
Table 6-7 – GPIO Alternate function select register 5
BR,
&Sanumala

http://elinux.org/RPi_GPIO_Code_Samples
//
// Set up a memory regions to access GPIO
//
void setup_io()
{
/* open /dev/mem */
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("can't open /dev/mem \n");
exit(-1);
}
/* mmap GPIO */
gpio_map = mmap(
NULL, //Any adddress in our space will do
BLOCK_SIZE, //Map length
PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
MAP_SHARED, //Shared with other processes
mem_fd, //File to map
GPIO_BASE //Offset to GPIO peripheral
);
close(mem_fd); //No need to keep mem_fd open after mmap
if (gpio_map == MAP_FAILED) {
printf("mmap error %d\n", (int)gpio_map);//errno also set!
exit(-1);
}
// Always use volatile pointer!
gpio = (volatile unsigned *)gpio_map;
} // setup_io

Related

Is there a way to have a gpio output 1 when two nodes are outputting 1 into it?

I'm working on a security system with my raspberry pi and node-red. I have an infrared sensor outputting 1 when motion is detected, 0 when no motion is detected. I also have a switch with the pallete node-red-dashboard that outputs 1 when it is "open" and 0 when "closed". I want to make a function that would output 1 when both of the inputs are 1, kind of like an and gate. Any help?
There are a number of ways to achieve what you want. Import the flow below and see if it behaves like you want.
Credits to Cory Guyyn
[{"id":"326ee761.191508","type":"tab","label":"Flow 6","disabled":false,"info":""},{"id":"aa420627.bdb3e8","type":"function","z":"326ee761.191508","name":"Flow On/Off","func":"var state = context.get(\"state\") || \"on\";\n\n// Display initial state status\nif(state ==\"on\"){\n node.status({fill:\"green\",shape:\"dot\",text:state});\n}else{\n node.status({fill:\"red\",shape:\"ring\",text:state});\n}\n\nif(msg.topic == \"state\"){\n context.set(\"state\",msg.payload);\n state = msg.payload;\n // update status\n if(state == \"on\"){\n node.status({fill:\"green\",shape:\"dot\",text:state});\n }else{\n node.status({fill:\"red\",shape:\"ring\",text:state});\n }\n}else{\n if(state == \"on\"){\n return msg;\n }\n}\n","outputs":1,"noerr":0,"x":570,"y":340,"wires":[["6968506.c5da8b"]]},{"id":"d1c0dabc.ff33f8","type":"ui_switch","z":"326ee761.191508","name":"","label":"Dynamic Input","group":"efb0cd04.2f1fe","order":0,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"state","style":"","onvalue":"on","onvalueType":"str","onicon":"","oncolor":"","offvalue":"off","offvalueType":"str","officon":"","offcolor":"","x":500,"y":240,"wires":[["aa420627.bdb3e8"]]},{"id":"fb35a101.734b3","type":"inject","z":"326ee761.191508","name":"","topic":"state","payload":"on","payloadType":"str","repeat":"","crontab":"","once":true,"x":280,"y":220,"wires":[["d1c0dabc.ff33f8"]]},{"id":"7f455eab.e11b4","type":"inject","z":"326ee761.191508","name":"","topic":"state","payload":"off","payloadType":"str","repeat":"","crontab":"","once":false,"x":270,"y":260,"wires":[["d1c0dabc.ff33f8"]]},{"id":"6968506.c5da8b","type":"debug","z":"326ee761.191508","name":"","active":true,"console":"false","complete":"false","x":750,"y":340,"wires":[]},{"id":"38c4ee82.f54e92","type":"comment","z":"326ee761.191508","name":"Sample Flow Toggle with UI and Link input","info":"","x":300,"y":120,"wires":[]},{"id":"5fb3fc9b.523764","type":"inject","z":"326ee761.191508","name":"PIR - 0","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":340,"wires":[["aa420627.bdb3e8"]]},{"id":"a1e5b421.b65e08","type":"inject","z":"326ee761.191508","name":"PIR - 1","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":380,"wires":[["aa420627.bdb3e8"]]},{"id":"efb0cd04.2f1fe","type":"ui_group","z":"","name":"Flow Toggle","tab":"6dfbaaa8.8cfbb4","disp":true,"width":"6"},{"id":"6dfbaaa8.8cfbb4","type":"ui_tab","z":"","name":"Sandbox","icon":"dashboard"}]

Set GPIO bank number in device tree

Do you know how to set the GPIO bank number in the device tree for an i2c gpio controller?
I tried with gpio-base (described in the gpio driver doc) but it was not very conclusive.
I have a device tree:
...
&i2c2 {
pca9502: pca9502#4C {
compatible = "nxp,pca9502";
reg = <0x4C>;
gpio-controller;
/* HERE */
gpio-base = <1>;
}
}
...
and the driver fetch the DT to find the gpio-base:
of_get_property(dev.of_node, "gpio-base", NULL);
In this case, a gpiochip is created with the number 2^32 giving: gpiochip16777216. And I can't access my GPIO using echo XX > export.
When I don't add gpio-base = <1>;, it works but the gpiochip number is 504 (with -1 as a default bank number) which I don't understand.
I don't know how to define the bank number into the device tree.
Well, my issue was not linked with the device tree structure but with the endianness of the processor.

Visual Studio 2013 SerialPort not receiving all data

I am currently working on a project that requires serial communication between PIC 24FV16KA302 and a PC software.
I have searched the Internet for the past 3 days and i cant find an answer for my problem so i decided to ask here . This is my first visual studio program so i dont have any experience with the software.
The PIC has few variables and two 8x16 tables that i need to view and modify on the PC side . The problem comes when i send the tables , all other information is received without a problem . I am using serial connection ( 38400/8-N-1 ) via uart to usb converter
FT232
When the PC send "AT+RTPM" to the PIC .
Button7.Click
SerialPort1.ReceivedBytesThreshold = 128
MachineState = MS.Receive_table
SerialPort1.Write("AT+RTPM")
End Sub
The PIC sends back 128 Bytes( the values in the table )
case read_table_pwm : // send pwm table
for (yy = 0 ; yy < 8 ; yy ++) {
for (xx = 0 ; xx < 16 ; xx++ ) {
uart_send_char(controll_by_pmw_map_lb[yy][xx]) ;
}
}
at_command = receive_state_idle ;
break ;
Which the software is suppose to get and display in a DataGrid.
Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
If MachineState = MS.Receive_table Then
SerialPort1.Read(Buffer_array_received_data, 0, 128)
cellpos = 0
For grid_y As Int16 = 0 To 7 Step 1
For grid_x As Int16 = 0 To 15 Step 1
DataGridView1.Rows(grid_y).Cells(grid_x).Value = Buffer_array_received_data(cellpos)
cellpos += 1
Next
Next
End Sub
The problem is that most of the time ( 99 % ) it displays only part of the dataset and zeros to the end , and when i try to do it again it display the other part and it starts from the beginning .
First request
Second request
If i try the same thing with another program i always get the full dataset
Realterm
Termite
I have tried doing it cell by cell , but it only works if i request them one very second , other wise i get the same problem .
After that i need to use a timer ( 100 ms ) to request live data from the PIC .
this work better but still some of the time i get some random data. I haven't focused on that for the moment because without the dataset everything else is useless .
Am i missing something or has anyone encountered the same problem ?
I managed to solve the problem by replacing
SerialPort1.Read(Buffer_array_received_data, 0, 128)
with
For byte_pos As Int16 = 0 To 127 Step 1
Buffer_array_received_data(byte_pos) = SerialPort1.ReadByte()
Next
But aren't they supposed to be the same ?

Problems making a parallel Flash memory programmer with arduino

I have a very large project and this a small piece of it, but none the less essential. I have a parallel flash memory chip made by SST and Microchip (a bit confusing) and am having trouble bypassing the write protection. I am using an arduino mega to program it because I do not have time to wait for a programmer to ship from china. here is the datasheet for the flash memory: http://ww1.microchip.com/downloads/en/DeviceDoc/25022B.pdf
void setup() {
Serial.begin(19200);
pinMode(A8,OUTPUT);//OE#
pinMode(A9,OUTPUT);//WE#
for(byte i=0;i<15;i++) //15 bit address bus
pinMode(i+20, OUTPUT);
for(byte i=0;i<8;i++) //8 bit bidirectional data bus
pinMode(i+40, OUTPUT);
wrt(0xAA,0x5555);// erase sector 0 to 0xFF
wrt(0x55,0x2AAA);
wrt(0x80,0x5555);
wrt(0xAA,0x5555);
wrt(0x55,0x2AAA);
wrt(0x30,0);
delay(250);
wrt(0xAA,0x5555);// write byte 0 to 3
wrt(0x55,0x2AAA);
wrt(0xA0,0x5555);
wrt(0x03,0);
delay(1000);
Serial.println("reading....");
for(int i=0;i<16;i++)// read data
rd(i);
}
void loop();
void wrt(byte var, int loc){
datbusout();// set data bus to output mode
digitalWrite(20,HIGH&&(loc&1));
digitalWrite(21,HIGH&&(loc&2));
digitalWrite(22,HIGH&&(loc&4));
digitalWrite(23,HIGH&&(loc&8));
digitalWrite(24,HIGH&&(loc&16));
digitalWrite(25,HIGH&&(loc&32));
digitalWrite(26,HIGH&&(loc&64));
digitalWrite(27,HIGH&&(loc&128));
digitalWrite(28,HIGH&&(loc&256));
digitalWrite(29,HIGH&&(loc&1024));
digitalWrite(30,HIGH&&(loc&2048));
digitalWrite(31,HIGH&&(loc&4096));
digitalWrite(32,HIGH&&(loc&8192));
digitalWrite(33,HIGH&&(loc&16384));
digitalWrite(34,HIGH&&(loc&32768));
for(int i=40;i<48;i++)
digitalWrite(i,HIGH&&(var&(1<<i)));
PORTK=1;// write mode
Serial.println(var,HEX);
delayMicroseconds(20);
PORTK=3;// set OE# and WE# high
}
void rd(int loc){
datbusinp();
byte out=0;
digitalWrite(20,HIGH&&(loc&1));
digitalWrite(21,HIGH&&(loc&2));
digitalWrite(22,HIGH&&(loc&4));
digitalWrite(23,HIGH&&(loc&8));
digitalWrite(24,HIGH&&(loc&16));
digitalWrite(25,HIGH&&(loc&32));
digitalWrite(26,HIGH&&(loc&64));
digitalWrite(27,HIGH&&(loc&128));
digitalWrite(28,HIGH&&(loc&256));
digitalWrite(29,HIGH&&(loc&1024));
digitalWrite(30,HIGH&&(loc&2048));
digitalWrite(31,HIGH&&(loc&4096));
digitalWrite(32,HIGH&&(loc&8192));
digitalWrite(33,HIGH&&(loc&16384));
digitalWrite(34,HIGH&&(loc&32768));
PORTK=2;
delayMicroseconds(1); // wait for read to finish
for(int i=0;i<8;i++)
out|=digitalRead(40+i)<<i;
PORTK=3;
Serial.println(out,HEX);
}
void datbusinp(){
DDRG&=252;// did the same thing like this, just faster
DDRL&=3;
}
void datbusout(){
DDRG|=3;
DDRL|=252;// see last comment
}
for(int i=40;i<48;i++)
digitalWrite(i,HIGH&&(var&(1<<i)));
That is wrong, surely?
You are shifting 1 left 40 times at least, which means you are always writing a zero.
I fixed it!!!! so I accidentally had the wrong values for anding when writing to the address bus. A TON of thanks to Nick Gammon, test would have failed today without him. more about the answer: I needed to change my for loop in the wrt function, and not skip 512 when writing to the address bus. :D code:
digitalWrite(20,HIGH&&(loc&1));
digitalWrite(21,HIGH&&(loc&2));
digitalWrite(22,HIGH&&(loc&4));
digitalWrite(23,HIGH&&(loc&8));
digitalWrite(24,HIGH&&(loc&16));
digitalWrite(25,HIGH&&(loc&32));
digitalWrite(26,HIGH&&(loc&64));
digitalWrite(27,HIGH&&(loc&128));
digitalWrite(28,HIGH&&(loc&256));
digitalWrite(29,HIGH&&(loc&1024));
digitalWrite(30,HIGH&&(loc&2048));
digitalWrite(31,HIGH&&(loc&4096));
digitalWrite(32,HIGH&&(loc&8192));
digitalWrite(33,HIGH&&(loc&16384));
digitalWrite(34,HIGH&&(loc&32768));
needed to become
digitalWrite(20,HIGH&&(loc&1));
digitalWrite(21,HIGH&&(loc&2));
digitalWrite(22,HIGH&&(loc&4));
digitalWrite(23,HIGH&&(loc&8));
digitalWrite(24,HIGH&&(loc&16));
digitalWrite(25,HIGH&&(loc&32));
digitalWrite(26,HIGH&&(loc&64));
digitalWrite(27,HIGH&&(loc&128));
digitalWrite(28,HIGH&&(loc&256));
digitalWrite(29,HIGH&&(loc&512));
digitalWrite(30,HIGH&&(loc&1024));
digitalWrite(31,HIGH&&(loc&2048));
digitalWrite(32,HIGH&&(loc&4096));
digitalWrite(33,HIGH&&(loc&8192));
digitalWrite(34,HIGH&&(loc&16384));

Constraint Error warning using Enum in ADA

I'd like to know why constraint Errors warnings are prompted in Ada when enums are used as in the example below. As I've been using Enums I can replace them for a better implementation.
type Uart_Instance_Type is (COM1, COM2, COM3);
for Uart_Instance_Type use
( COM1 => 16#0001# ,
COM2 => 16#0002# ,
COM3 => 16#0003#
);
type UART_Register_Type is record
SR : Half_Word; -- USART Status register
Reserved_0 : Half_Word;
DR : Half_Word; -- USART Data register
Reserved_1 : Half_Word;
BRR : Half_Word; -- USART Baud rate register
Reserved_2 : Half_Word;
end record
with volatile;
for UART_Register_Type use record
SR at 0 range 0 .. 15;
Reserved_0 at 2 range 0 .. 15;
DR at 4 range 0 .. 15;
Reserved_1 at 6 range 0 .. 15;
BRR at 8 range 0 .. 15;
Reserved_2 at 10 range 0 .. 15;
end record;
type UART_Register_Access is access all UART_Register_Type;
UARTs: array (Uart_Instance_Type range COM1 .. COM3) of aliased UART_Register_Access;
The compiler prompt at the last line ("UARTs: ...) and shows:
warning: "Constraint Error" may call Last_Chance_Handler
Is there a better implementation to avoid these warnings when using Enums?
Thanks in advance! :)
I think you must be compiling for a restricted (Ravenscar?) runtime, which is why any exception will result in a call to Last_Chance_Handler.
I encountered a lot of irritating warnings like this, and eventually traced it to compiling with
-gnatwa (“turn on all info/warnings marked below with +”) which enables
-gnatw.x ("turn on warnings for non-local exception”).
You can suppress the warnings with -gnatw.X.
(For info, you can see the command line options by saying gnatmake -h (or arm-eabi-gnatmake -h). There are a lot.)

Resources