How to write a value to a port in DIO module AUTOSAR? - c++

I am working in an AUTOSAR project on a STM32 NUCLEO-F767ZI board and I have to write the value for a port in the DIO module. I know that there is a function called HAL_GPIO_WritePin(), but how can I make to write the value for an entire port?

You can do that by writing the value for each channel in that port.
The ports usually have 16 channels so the value you want to write is a 16 bit number containing 0 and 1 (LOW and HIGH). So for each bit in that number you call the function HAL_GPIO_WritePin() and use the parameter RESET for 0 and SET for 1 to write the value to the corresponding channel.

Related

How to copy int to u_char*

I have a u_char* dynamic array having binary data of some network packet. I want to change the destination port number in the packet with some integer value. Suppose that the port number offset within the packet is ofs, with length of 4 bytes.
I tried the following 2 methods:
u_char* packet = new u_char[packet_size]; // Packet still empty
// Read packet from network ...
int new_port = 1234;
Method #1:
std::copy((u_char*)&new_port, (u_char*)&new_port+4, packet+ofs);
Method #2:
std::string new_port_str = std::to_string(new_port);
auto new_port_bytes = new_port_str.c_str();
std::copy(new_port_bytes, new_port_bytes+4, packet+ofs);
Both methods give garbage value for port number (but the rest of the packet is OK). Could anyone help me ?
You have to convert the integer from whatever internal representation your platform happens to use to the format the particular network protocol you're using requires them to be in when sent over the network.
This depends on the particular network protocol you're trying to use -- check its documentation for precisely the format it requires ports to be expressed in. My bet will be it's network byte order. You probably have functions like htons to convert shorts to network byte order.
Another problem -- how many bytes is int on your platform? How many bytes does the network protocol use to express ports? I'll bet the numbers are 4 and 2 respectively. So that's another issue. (Or maybe it isn't. I don't know for sure how many bytes an int is on your platform nor do I know what protocol you're trying to work with, so I have to guess.)
You can't just write code randomly and expect it to work. You have to think about what you're trying to do and understand the requirements.
My recommendation would be to look at the specification for the network protocol you're working with and figure out exactly which bytes in the data have to change and what they have to change to. Then write code to change each byte to the correct value according to the network protocol specification. This will ensure your code works correctly on any platform.

Raspberry Pi with PmodDA2 digital analog conversion

As a part of a project in university, i have to send Data from the Raspberry Pi 2 to the Digilent PmodDA2 using C/C++. For that, i tried to use the bcm2835 library, which can only send 8 bit at a time. The PmodDA2 is a 12 bit device (integer values form 0 to 4095), so how can I transfer alle the bits? In the DACSPI2 Library Reference Manual (functions for Arduino) it even says "this function writes the 12 bits value to the DA converter, by writing 16 bits to SPI..." - so do I have to send 16bits? What do the missing 4 Bits look like then?
What's more, I need information about the clock polarity, the clock phase and if the chip is active at HIGH or at LOW.
Thank's a lot!
PS: For the bit-problem I tried:
char spiOut[3]; char spiIn[3];
if(!bcm2835_init())return 1;
bcm2835_spi_begin();
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
bcm2835_spi_setDataMode(BCM2835_SPI_MODE3);
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_256);
bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
while (k<10) {
spiOut[0]=Data[k] >> 4;//Data[k] contains the Integer values from 0 to 4095
spiOut[1]=((Data[k]&0x00F)<<4)|(Data[k+1]>>8);
spiOut[2]=Data[k+1]&0x0FF;
bcm2835_spi_transfernb(spiOut, spiIn, sizeof(spiOut));

Why do I get an error when read or write more than 3 bytes using libusb to communicate with a PIC 18F2550?

I'm using libusb in Qt to communicate with a PIC microcontroller, 18F2550. The thing is that it's working OK until I try to send or read more than three bytes. Why does it happen?
I've tried using bulk_read transfer and interrupt_read. When I put the size of the buffer equal or less than three, then the transmission works perfectly, using bulk or interrupt. When this size is greater than three, then I'm getting buffer1 and buffer[2] OK, but the rest are wrong.
The error that I'm getting is from timeout. As input I'm using endpoint 0x81.
More information:
The return value from the bulk or interrupt read is -116. The numbers that I'm sending from the PIC to the PC in the two first bytes ([0] and 1) in hex is 0x02D6. With this number, buffer[0] = -42 (when it should be 0xD6 = 214) and buffer[1] = 2 that is correct.
In the [2] and [3] bytes the number is 0x033D, and I get [2] = 61 = 0x3D. That is correct and [3] = -42??? (like [0]).
And the fifth byte is 1, and the SW shows 2???. Might it be a problem in the microcontroller, because I'm programming it as an HID USB?
I don't think that being a HID is the problem. I had a similar issue before; the PIC would randomly timeout when large data was being transmitted. It turned out to be some voltage fluctuation on the MCU. How are you connecting the crystal? Do you have a capacitor on VUSB to regulate it?
Building a PIC18F USB device is a great tutorial on building a PIC HID, and even though it's not based on 18F2550 but on 18F4550, it should be quite similar, and I'm sure you can get a lot out of the schematics and hardware setup. It was the starting point for my PIC-USB projects.

Reading SIO_KEEPALIVE_VALS fields on a Windows socket (for keepalive idle and interval times)

Given a Windows socket, I want to determine which values it is using for the TCP keepalive idle time and the TCP keepalive interval time (roughly equivalent to the TCP_KEEPIDLE and TCP_KEEPINTVL settings on Berkeley sockets).
I see that you can set these values using a WSAIoctl call (see http://msdn.microsoft.com/en-us/library/windows/desktop/dd877220%28v=vs.85%29.aspx ). However, there does not appear to be any API for reading their current values. I tried calling WSAIoctl with a populated output parameter but NULL input parameter, like this:
DWORD bytes_returned;
struct tcp_keepalive keepalive_opts;
int rv = WSAIoctl(socket, SIO_KEEPALIVE_VALS, NULL, 0, &keepalive_opts, sizeof(keepalive_opts), &bytes_returned, NULL, NULL);
But this returns me a WSAEFAULT ("The system detected an invalid pointer address in attempting to use a pointer argument in a call.").
I could call WSAIoctl with both an input and an output parameter, but I don't want to set the values, I just want to read them. And as far as I can tell, providing any non-NULL input parameter would cause the parameters to be set to whatever values happen to be in that memory space (defined by the struct tcp_keepalive; again see http://msdn.microsoft.com/en-us/library/windows/desktop/dd877220%28v=vs.85%29.aspx ).
The above also highlights another problem with not knowing what the current values are: I can't set just one of the keepalive idle time or the keepalive interval time - I must blow away both (unknown) values at the same time since they're both members of the struct I'm required to provide.
I know that I could assume things about what values are set based on Windows documentation, but I'd rather not assume. I see that http://technet.microsoft.com/en-us/library/bb726981.aspx#EDAA defines KeepAliveInterval and KeepAliveTime default values. However, the Parameters folder in my Windows 7 registry does not contain either of those keys, so I really have to rely on the documentation being 100% correct here (to know the default values a socket will receive), which is much worse than programmatically retrieving them (even retrieving them from the registry might be ok, but the above experience shows I can't).
Is there any way to get the current TCP keepalive idle time and the TCP keepalive interval time values for a Windows socket?
Unlike TCP_KEEPIDLE and TCP_KEEPINTVL, which can be used with getsockopt(), there is no way to read the current SIO_KEEPALIVE_VALS values for a socket, only to set them.

Character encoding problem with QextSerialPort (Qt/C++)

I am developing a Qt/C++ programme in QtCreator that reads and writes from/to the serial port using QextSerialPort. My programme sends commands to a Rhino Mark IV controller and must read the response of those commands (just in case they produce any response). My development and deployment platform is Windows XP Professional.
When the Mark IV sends a response to a command and my programme reads that response from the serial port buffer, the data are not properly encoded; my programme does not seem to get plain ASCII data. For example, when the Mark IV sends an ASCII "0" (decimal 48) followed by a carriage return (decimal 13), my buffer (char *) gets -80 and 13. Characters are not properly encoded, but carriage returns are indeed. I have tried using both read (char *data, qint64 maxSize) and readAll ().
I have been monitoring the serial port traffic using two monitors that interpret ASCII data and display the corresponding characters, and the data sent in both ways seem to be correctly encoded (they are actually displayed correctly). Given that QByteArray does not interpret any character encoding and that I have tried using both read (char *data, qint64 maxSize) and readAll (), I have discarded that the problem may be caused by Qt. However, I am not sure if the problem is caused by QextSerialPort, because my programme send (writes) data properly, but does not read the correct bytes.
I have also tried talking to the Mark IV controller by hand using HyperTerminal, and the communication takes place correctly, too. I set up the connection using HyperTerminal with the following parammeters:
Baud rate: 9600
Data bits: 8
Parity bits: 0
Stop bits: 1
Flow control: Hardware
My programme sets up the serial port using the same parammeters. HyperTerminal works, my programme does not.
I started using QextSerialPort 1.1 from qextserialport.sourceforge.net and then tried with the latest source code from QextSerialPort on Google Code, and the problem remains.
What is causing the wrong character encoding?
What do I have to do to solve this issue?
48 vs. -80 smells like a signed char vs. unsigned char mismatch to me. Try with explicit unsigned char* instead of char*.
Finally, I have realized that I was not configuring the serial port correctly, as suggested by Judge Maygarden. I did not find that information in the device's manual, but in the manual of a software product developed for that device.
The correct way to set up the serial port for connecting to the Mark IV controller is to set
Baud rate: 9600
Data bits: 7
Parity: even
Stop bits: 2 bits
Flow control: Hardware
However, I am still wondering why did HyperTerminal show the characters properly even with the wrong configuration.