Getting back my output - arm

I am trying to create a hardware accelerator for a cryptography application SHA256
first I am using a Nexys4 FPGA as platform and a Cortex-m0 as a processor with AHBlite bus system.
i created a simple accelerator that adds two integer using a hardware accelerator then i called the output of my accelerator using these instructions
volatile unsigned int regSHA2 __attribute__((at(0x59000000)))...
main{
*(volatile unsigned int *)regSHA2= a;
*(volatile unsigned int *)regSHA2= b;
c = *(volatile signed int *)regSHA2;
All is fine with the adder accelerator . However, when i use the same thing with my SH2 accelerator i get the last inpout that i sent to the accelerator ...although the result of the simulation are correct i get my encrypted message but i can't get it back to my software application

Related

Issues creating a Linux device driver to manage NanoPI TWI (I2C) registers

I'm trying to develop a Linux device driver to manage the GPIO registers of a NanoPI Neo card (Allwinner H3).
I'm using a simple approach to understand the GPIO registers behaviour by means the use of only two driver functions: open and ioctl.
My driver implementation, at now, is able to manage a lot of registers such as RTC and CPU-PORT and to read write some other registers.
But I'm having issues in using/managing TWI registers (I2C).
The blocking me issue is that whathever register I read or read after writing any value to the register itself always returns 0x00000000 and nothing seems to happen at pin HW level (PA11/PA12 see below)
I read on the CPU datasheet (see: paragraph 8.1 of the document) the registers value and base address to manage TWI0, base address should be 0x01C2AC00.
I can't find any AllWinner H3 GPIO programmer's reference and I'm not sure if specific operations are required to activate the TWI register functionality. The only operations I have done are to set registers PA11 and PA12 to be the I/O of TWI0_SCK and TWI0_SDA.
Questions:
Do you have any news of an "AllWinner H3 GPIO Programmer's Reference"?
Do you know which GPIO register I have to set / modify to get TWI enabled or at least give me "signs of life"?
A very strong simplification, aimed at using only TWI0 registers, of the mapping and ioctl functions of the driver I wrote might be the following code, but my code is much more sophisticated and I know it works with many other registers.
#define TWI_IOBASE(n) (0x01C2AC00 + 0x400*((n)&3))
#define TWI_PAGESIZE 0x400
#define IO_ADDRESS_MSK 0x0000FFFFUL
#define IO_CMD_MSK 0xF0000000UL
#define IO_CMD_READ 0x10000000UL
#define IO_CMD_WRITE 0x20000000UL
static unsigned char * vmaddr;
inline static int drv_init_twi_vm(void)
{
vmaddr=ioremap(TWI_IOBASE(0), TWI_PAGESIZE);
}
static long drv_ioctl_twi_rw(struct file *file, unsigned int cmd, unsigned long * arg)
{
long retval = 1;
unsigned c;
uint32_t r;
void *x;
r=cmd & IO_ADDRESS_MSK;
x=vmaddr+r;
c=cmd & IO_CMD_MSK;
switch(c)
{
case IO_CMD_READ:
if ( copy_to_user((void *)arg, x, 4) ) {
retval = -EFAULT;
}
break;
case IO_CMD_WRITE:
*(unsigned long *)x=*arg;
break;
default:
retval=-EFAULT;
break;
}
return retval;
}

Modbus implementation in C for embedded system lpcxpresso

I am new to modbus and I have to program a lpcxpresso baseboard as a master to collect readings from a powermeter using RS485 Modbus protocol.
I am familiar with the protocol (about the PDU ADU frame, function codes, master-slave) through reading of specifications from modbus.org.
However I have difficulties in the implementation when writing the code in C.
So my questions are:
Do I have to open connection, set the baud rate, etc when I am starting the connection?
I am thinking to send the frame as byte[]. Is this correct? or are there any other ways to do it?
Does the data send have to be in hexadecimal, or binary or integer?
CRC generation and checking.
I will really appreciate all kind of help and assistance :) Sorry if the questions are not very specific or too basic
Step 1: Forget about energy meter and modbus for now. Most important thing is to get hardware working. RS485 is simply a serial port. Read manual on how to initialize serial port on your hardware, and send single byte to your PC and back. Then send hundreds of bytes to PC and back.
Setp 2: Get timer on your hardware working also. Modbus protocol has some requirements on timing so you'll need it too.
Step 3: Get modbus specification. It will explain protocol format and checksums. Use modbus library or write your own. Make sure you can make it work with PC, before you move on to the energy meter.
Step 4: If you have a problem, ask specific question about it on SO.
First of all: is ModBus RTu or ASCII?
Yes, of course. You need to specify all things as specs describe.
Yes, it is a unsigned char[]. The structure is described by specs.
The question doesn't make sense: You always send info as "memory
dump", but with RTU you send 1 byte per memory byte, in case of
ASCII you send 2 byte per memory byte. Eg. if you have to send a
byte 0xAE: RTU=0xAE - ASCII= 0x41 0x45. In case of RTU, if you have to send an int (4 byte) you will send those bytes as they are stored in memory, eg: 12345 will be sent as 0x00 0x00 0x30 0x39 (big endian), 0x39 0x30 0x00 0x00 (little endian).
The calculation of CRC is explained in specs. Below the code of my old CBuilder component
unsigned short TLPsComPort::Calculate_CRC16 ( int Message_Length, char *Message
{
char Low_CRC;
char Bit;
// Constant of ModBus protocol
unsigned short CONSTANT = 0xA001;
unsigned short CRC_REGISTER = 0xFFFF;
for (int i=0; i<Message_Length; i++)
{
Low_CRC = CRC_REGISTER;
Low_CRC = *(Message+i) ^ Low_CRC;
CRC_REGISTER = ((CRC_REGISTER & 0xFF00) | (Low_CRC & 0x00FF));
for (int j=0; j<8;j++)
{
Bit = CRC_REGISTER & 0x0001;
CRC_REGISTER = (CRC_REGISTER >> 1) & 0x7FFF;
if (Bit) CRC_REGISTER = CRC_REGISTER ^ CONSTANT;
}
}
return CRC_REGISTER;
}

How to convert serial data from 8 bit controller and show it in asci?

I'm in to embedded coding and i have a problem here.I'm using uart communication and want to send integers over the serial line.each integer must be shown as character in ascii.What all things should i be careful of?.
The data from controller side will be in integer/char/float format.What should i need to take care of while dealing with displaying those data from controller on a serial monitoring s/w?.
I'm coding in c language
Regards
If what you are looking for is converting integers to ascii there is a standard compliant way to do it.
sprintf(str, "%d", your_integer);
I assume you want to send/receive data with UART communication using micro controller such as 8051.
So here are the things you should be looking at.
1) What is the Baud rate you want to send with? [Baud rate is number of symbols transmitted/received per second]
2) How many bits you want to receive per symbol? [Depends on how many bit micro controller do you use]
Here is the code sample for UART communication to send "STACK OVERFLOW" with 9600 Baud rate with 8 bit data for 8051. [From the book "The 8051 Microcontroller and Embedded Systems"]
#include <reg51.h>
void SerTx(unsigned char);
void main(void){
TMOD=0x20; //use Timer 1, mode 2
TH1=0xFD; //9600 baud rate
SCON=0x50;
TR1=1; //start timer
while (1) {
SerTx(‘S’);SerTx(‘T’);SerTx(‘A’);SerTx(‘C’);SerTx(‘K’);
SerTx(‘’);SerTx(‘O’);SerTx(‘V’);SerTx(‘E’);SerTx(‘R’);
SerTx(‘F’);SerTx(‘L’);SerTx(‘O’);SerTx(‘W’);
}}
void SerTx(unsigned char x){
SBUF=x; //place value in buffer
while (TI==0); //wait until transmitted
TI=0;}
When you declare:
unsigned char array[10] = {'F','E','E','D','B','A','B','E','C','A',};
the compiler puts it into a proper digital representation according to the ASCII table (see it below). So on your device side it is like 0x46 for 'F', 0x45 for 'E' and etc. When you send it through the serial by passing by this array to TX function it will go to the other side with same codes, again like 0x46 for 'F', 0x45 for 'E' and etc.
When you put it straight in digital, like here it will remain the values as is.
unsigned char array2[10] = {0xFE,0xED,0xBA,0xBE,0xDE,0xAD,0xBE,0xEF,0xCA,0xFE};
You can transfer actually any data as binary, it is a question of representation sometimes in particular place.

Simple code confusion about define directive parameter

I'm trying to learn C to program this small routine on a Texas Instruments MSP430. Could you help me understand the ((unsigned char *) 0x0023) part?
I'm having issues understanding this middle portion of this Define directive. I've tried looking this up but found nothing on the ((unsigned char *) 0x0023) portion. This looks like a type cast but its not casting anything.
My major concern is the 0x0023 (decimal 35). Is this just a unsigned char pointer with 35 bits?
Code:
#define P1IFG_ptr ((unsigned char *) 0x0023) unsigned char result;
Any help is really appreciated and thank you in advance.
((unsigned char *) 0x0023)
Is a pointer to address 0x23
I think there's a missing newline in your code sample...
On the MSP430 this is the port P1 interrupt flag register:
Each PxIFGx bit is the interrupt flag for its corresponding I/O pin
and is set when the selected input signal edge occurs at the pin. All
PxIFGx interrupt flags request an interrupt when their corresponding
PxIE bit and the GIE bit are set. Each PxIFG flag must be reset with
software. Software can also set each PxIFG flag, providing a way to
generate a software initiated interrupt. Bit = 0: No interrupt is
pending Bit = 1: An interrupt is pending Only transitions, not static
levels, cause interrupts. If any PxIFGx flag becomes set during a Px
interrupt service routine, or is set after the RETI instruction of a
Px interrupt service routine is executed, the set PxIFGx flag
generates another interrupt. This ensures that each transition is
acknowledged.
You can read from this register, e.g.:
unsigned char result;
result = *P1IFG_ptr;
Or write to it, e.g.:
*P1IFG_ptr = 1;

Writing Device Drivers for Microcontrollers, where to define IO Port pins?

I always seem to encounter this dilemma when writing low level code for MCU's.
I never know where to declare pin definitions so as to make the code as reusable as possible.
In this case Im writing a driver to interface an 8051 to a MCP4922 12bit serial DAC.
Im unsure how/where I should declare the pin definitions for The CS(chip select) and LDAC(data latch) for the DAC. At the moment there declared in the header file for the driver.
Iv done a lot of research trying to figure out the best approach but havent really found anything.
Im basically want to know what the best practices... if there are some books worth reading or online information, examples etc, any recommendations would be welcome.
Just a snippet of the driver so you get the idea
/**
#brief This function is used to write a 16bit data word to DAC B -12 data bit plus 4 configuration bits
#param dac_data A 12bit word
#param ip_buf_unbuf_select Input Buffered/unbuffered select bit. Buffered = 1; Unbuffered = 0
#param gain_select Output Gain Selection bit. 1 = 1x (VOUT = VREF * D/4096). 0 =2x (VOUT = 2 * VREF * D/4096)
*/
void MCP4922_DAC_B_TX_word(unsigned short int dac_data, bit ip_buf_unbuf_select, bit gain_select)
{
unsigned char low_byte=0, high_byte=0;
CS = 0; /**Select the chip*/
high_byte |= ((0x01 << 7) | (0x01 << 4)); /**Set bit to select DAC A and Set SHDN bit high for DAC A active operation*/
if(ip_buf_unbuf_select) high_byte |= (0x01 << 6);
if(gain_select) high_byte |= (0x01 << 5);
high_byte |= ((dac_data >> 8) & 0x0F);
low_byte |= dac_data;
SPI_master_byte(high_byte);
SPI_master_byte(low_byte);
CS = 1;
LDAC = 0; /**Latch the Data*/
LDAC = 1;
}
This is what I did in a similar case, this example is for writing an I²C driver:
// Structure holding information about an I²C bus
struct IIC_BUS
{
int pin_index_sclk;
int pin_index_sdat;
};
// Initialize I²C bus structure with pin indices
void iic_init_bus( struct IIC_BUS* iic, int idx_sclk, int idx_sdat );
// Write data to an I²C bus, toggling the bits
void iic_write( struct IIC_BUS* iic, uint8_t iicAddress, uint8_t* data, uint8_t length );
All pin indices are declared in an application-dependent header file to allow quick overview, e.g.:
// ...
#define MY_IIC_BUS_SCLK_PIN 12
#define MY_IIC_BUS_SCLK_PIN 13
#define OTHER_PIN 14
// ...
In this example, the I²C bus implementation is completely portable. It only depends on an API that can write to the chip's pins by index.
Edit:
This driver is used like this:
// main.c
#include "iic.h"
#include "pin-declarations.h"
main()
{
struct IIC_BUS mybus;
iic_init_bus( &mybus, MY_IIC_BUS_SCLK_PIN, MY_IIC_BUS_SDAT_PIN );
// ...
iic_write( &mybus, 0x42, some_data_buffer, buffer_length );
}
In one shop I worked at, the pin definitions were put into a processor specific header file. At another shop, I broke the header files into themes associated with modules in the processor, such as DAC, DMA and USB. A master include file for the processor included all of these themed header files. We could model different varieties of the same processor by include different module header files in the processor file.
You could create an implementation header file. This file would define I/O pins in terms of the processor header file. This gives you one layer of abstraction between your application and the hardware. The idea is to loosely couple the application from hardware as much as possible.
If only the driver needs to know about the CS pin, then the declaration should not appear in the header, but within the driver module itself. Code re-use is best served by hiding data at the most restrictive scope possible.
In the event that an external module needs to control CS, add an access function to the device driver module so that you have single point control. This is useful if during debugging you need to know where and when an I/O pin is being asserted; you only have one point to apply instrumentation or breakpoints.
The answer with the run-time configuration will work for a decent CPU like ARM, PowerPC...but the author is running a 8051 here. #define is probably the best way to go. Here's how I would break it down:
blah.h:
#define CSN_LOW() CS = 0
#define CSN_HI() CS = 1
#define LATCH_STROBE() \
do { LDAC = 0; LDAC = 1; } while (0)
blah.c:
#include <blah.h>
void blah_update( U8 high, U8 low )
{
CSN_LOW();
SPI_master_byte(high);
SPI_master_byte(low);
CSN_HI();
LATCH_STROBE();
}
If you need to change the pin definition, or moved to a different CPU, it should be obvious where you need to update. And it's also helps when you have to adjust the timing on the bus (ie. insert a delay here and there) as you don't need to change all over the place. Hope it helps.

Resources