arm cortex m3 display - embedded

hi i am working on arm controller lm3s8962 i m not able to understand the code below as per my understanding it is checking if the character is from the array or not, which he created using the ascii characters{i.e in the while loop : while(*pcStr != 0) },
i am not able to get what he is doing in the code after the line "Build and display the character buffer" plz can anyone explain this
void
RIT128x96x4StringDraw(const char *pcStr, unsigned long ulX,
unsigned long ulY, unsigned char ucLevel)
{
unsigned long ulIdx1, ulIdx2;
unsigned char ucTemp;
//
// Check the arguments.
//
ASSERT(ulX < 128);
ASSERT((ulX & 1) == 0);
ASSERT(ulY < 96);
ASSERT(ucLevel < 16);
//
// Setup a window starting at the specified column and row, ending
// at the right edge of the display and 8 rows down (single character row).
//
g_pucBuffer[0] = 0x15;
g_pucBuffer[1] = ulX / 2;
g_pucBuffer[2] = 63;
RITWriteCommand(g_pucBuffer, 3);
g_pucBuffer[0] = 0x75;
g_pucBuffer[1] = ulY;
g_pucBuffer[2] = ulY + 7;
RITWriteCommand(g_pucBuffer, 3);
RITWriteCommand(g_pucRIT128x96x4VerticalInc,
sizeof(g_pucRIT128x96x4VerticalInc));
//
// Loop while there are more characters in the string.
//
while(*pcStr != 0)
{
//
// Get a working copy of the current character and convert to an
// index into the character bit-map array.
//
ucTemp = *pcStr++ & 0x7f;
if(ucTemp < ' ')
{
ucTemp = 0;
}
else
{
ucTemp -= ' ';
}
//
// Build and display the character buffer.
//
for(ulIdx1 = 0; ulIdx1 < 6; ulIdx1 += 2)
{
//
// Convert two columns of 1-bit font data into a single data
// byte column of 4-bit font data.
//
for(ulIdx2 = 0; ulIdx2 < 8; ulIdx2++)
{
g_pucBuffer[ulIdx2] = 0;
if(g_pucFont[ucTemp][ulIdx1] & (1 << ulIdx2))
{
g_pucBuffer[ulIdx2] = (ucLevel << 4) & 0xf0;
}
if((ulIdx1 < 4) &&
(g_pucFont[ucTemp][ulIdx1 + 1] & (1 << ulIdx2)))
{
g_pucBuffer[ulIdx2] |= (ucLevel << 0) & 0x0f;
}
}
//
// Send this byte column to the display.
//
RITWriteData(g_pucBuffer, 8);
ulX += 2;
//
// Return if the right side of the display has been reached.
//
if(ulX == 128)
{
return;
}
}
}
}

He is doing some bit manipulations to build up bytes.
x |= y is the same as x = x | y, which keeps all the 1s in x and also changes some of the 0s to 1 if y has a 1 in the same position.
1 << i is a byte with a single 1 bit in the ith position from the right.
x = y & 0xf0 copies only the left 4 bits of y into x.
So he is looking up values in an array, checking particular bits of those values, then filling up another array with number created from those bits. You will have to work out the particulars for yourself.

Related

Pset5 (Speller) Weird Valgrind memory errors, no leaks

I have read other threads on pset5 Valgrind memory errors, but that didn't help me. I get 0 leaks, but this instead:
==1917== Conditional jump or move depends on uninitialised value(s)
Looks like you're trying to use a variable that might not have a value? Take a closer look at line 34 of dictionary.c.
The error refers to line 34 which is this: lower[i] = tolower(word[i]);
To supply context, the code below attempts to check if a word exists in the dictionary that has been uploaded to a hash table. I am attempting to convert the wanted word to lowercase because all the dictionary words are also lowercase and so that their hashes would be identical. The program successfully completes all tasks, but then stumbles upon these memory errors.
Any hints as to why Valgrind is mad at me? Thank you!
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
Below is the whole dictionary.c file:
// Implements a dictionary's functionality
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table 26^3
const unsigned int N = 17576;
// Hash table
node *table[N];
int count = 0;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// Modified hash function by Dan Berstein taken from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash = 5381;
int c;
while ((c = *word++))
{
hash = (((hash << 5) + hash) + c) % N; /* hash * 33 + c */
}
return hash;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *inptr = fopen(dictionary, "r");
if (dictionary == NULL)
{
printf("Could not load %s\n.", dictionary);
return false;
}
// Create a char array to temporarily hold the new word (r stands for read)
char r_word[N+1];
// Until the end of file
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
// Hash the node
int index = hash(new_node->word);
// Places the node at the right index
new_node->next = table[index];
table[index] = new_node;
}
fclose(inptr);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
if (&load == false)
{
return '0';
}
else
{
return count;
}
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// Interates over the array
for (int i = 0; i < N; i++)
{
node *head = table[i];
while (head != NULL)
{
node *tmp = head;
head = head->next;
free(tmp);
}
}
return true;
}
This loop iterates through the maximum length of word-
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
Except if you look at how word is created-
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
Notice, the variable r_word, may not be exactly of length LENGTH + 1. So what you really have in word is N number of characters, where N is not necessarily LENGTH + 1, it could be less.
So looping over the entire 0 -> LENGTH + 1 becomes problematic for words that are shorter than LENGTH + 1. You're going over array slots that do not have a value, they have garbage values.
What's the solution? This is precisely why c strings have \0-
for (int i = 0; word[i] != '\0'; i++)
{
lower[i] = tolower(word[i]);
}
This will stop the loop as soon as the NULL character is reached, which, you must have already learnt, marks the end of a string - aka a char array.
There may still be more errors in your code. But for your particular question - reading out of bounds is the answer.

In vulkan: I want save a depth image to file, but always got a error depth image

I want to save a depth image that from frame buffer render result.
1, I create a stage buffer used to save image data.
2, use vkCmdCopyImageToBuffer copy depth image to stage buffer.
3, use vkMapMemory map this stage buffer memory to host memory.
4, read host memory and write depth data to a file.
but always got an error depth image. I don't know where have wrong.
application window output.
bug depth image file.
(source file)
save depth image function:
VkDeviceSize size = WIDTH * HEIGHT * 4;
VkBuffer dstBuffer;
VkDeviceMemory dstMemory;
createBuffer(
size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
dstBuffer,
dstMemory);
VkCommandBuffer copyCmd = beginSingleTimeCommands();
// depth format -> VK_FORMAT_D32_SFLOAT_S8_UINT
VkBufferImageCopy region = {};
region.bufferOffset = 0;
region.bufferImageHeight = 0;
region.bufferRowLength = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = VkOffset3D{ 0, 0, 0 };
region.imageExtent = VkExtent3D{ swapChainExtent.width, swapChainExtent.height, 1};
vkCmdCopyImageToBuffer(
copyCmd,
depthImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
dstBuffer,
1,
&region
);
endSingleTimeCommands(copyCmd);
// Map image memory so we can start copying from it
void *data;
vkMapMemory(device, dstMemory, 0, size, 0, &data);
std::ofstream file(path, std::ios::out | std::ios::binary);
// ppm header
file << "P6\n" << WIDTH << "\n" << HEIGHT << "\n" << 255 << "\n";
float *row = (float*)data;
auto size_v = WIDTH * HEIGHT;
for (uint32_t y = 0; y < size_v; y++) {
file.write((char*)row + 1, 1);
file.write((char*)row + 1, 1);
file.write((char*)row + 1, 1);
row++;
}
file.close();
// Clean up resources
vkUnmapMemory(device, dstMemory);
vkFreeMemory(device, dstMemory, nullptr);
vkDestroyBuffer(device, dstBuffer, nullptr);
hope someone drag me out. thanks!
Assuming you've done all the transfer work correctly, your mapped data is basically an array of floats. This is reflected in your code by this line:
float *row = (float*)data;
However, when you actually write out the file you're treating the data like bytes...
file.write((char*)row + 1, 1);
So you're writing out 8 bytes of a 32 bit float. What you need is some function to convert from the float to a color value.
Assuming the depth value is normalized (I can't remember off the top of my head whether this is the case, or if it's dependent on the pipeline or framebuffer setup) and if you just want greyscale, you could use
uint8_t map(float f) {
return (uint8_t)(f * 255.0f);
}
and inside your file writing loop you'd so something like
uint8_t grey = map(*row);
file.write(&grey, 1);
file.write(&grey, 1);
file.write(&grey, 1);
++row;
Alternatively if you want some sort of color gradient for easier visulization you'd want a more complex mapping function...
vec3 colorWheel(float normalizedHue) {
float v = normalizedHue * 6.f;
if (v < 0.f) {
return vec3(1.f, 0.f, 0.f);
} else if (v < 1.f) {
return vec3(1.f, v, 0.f);
} else if (v < 2.f) {
return vec3(1.f - (v-1.f), 1.f, 0.f);
} else if (v < 3.f) {
return vec3(0.f, 1.f, (v-2.f));
} else if (v < 4.f) {
return vec3(0.f, 1.f - (v-3.f), 1.f );
} else if (v < 5.f) {
return vec3((v-4.f), 0.f, 1.f );
} else if (v < 6.f) {
return vec3(1.f, 0.f, 1.f - (v-5.f));
} else {
return vec3(1.f, 0.f, 0.f);
}
}
and in your file output loop...
vec3 color = colorWheel(*row);
uint8_t r = map(color.r);
uint8_t g = map(color.g);
uint8_t b = map(color.b);
file.write(&r, 1);
file.write(&g, 1);
file.write(&b, 1);
++row;

Arduino convert constant char to unsigned long

I'm asking you to know how to convert a constant char variable[] to a unsigned long variable!
The problem doesn't exist if not for :
I've to convert this value for example "0x20DF10EF" if I convert it to long it return me back "551489775".
What i want is to receive back "0x20DF10EF"!
Hope i've explained well enough my problem!
Best regards D.Tibe!
---- Edit ----
while(O != 'I'){
if(reciver.decode(&results)){
CMD[i] = "0x" + String(results.value, HEX);
CMD[i].toUpperCase();
Val[0] = CMD[i].c_str();
//Vil[0] = CMD[i].c_str();
//for(int i = 0; i < sizeof(Val[0])-1 ;i++)
//{
//}
Byte = String(results.bits, DEC);
delay(1000);
O = 'I';
reciver.resume();
}
This is my code!
I have to convert my Val[0] (that is a Constant char) to Unsigned long variable.
Like said before i'll have a value like this 0x20DF10EF in my constant char and i want to get exactly the same on my unsigned long variable, SO :
Val[0] will be = to 0x20DF10EF and i want to get back the same value but into the unsigned long variable like this
unsigned long Var will be = to 0x20DF10EF
If I understood correctly, you want to parse a const char * string with an hex number and put it into a variable.
If this is correct, there are two ways: using the sscanf function or converting it by hand.
Method 1:
unsigned long result;
if (sscanf(Val[0], "0x%x", &result) != 1)
{
Serial.println("Val[0] is not a valid hex value");
}
Method 2:
unsigned long result = 0;
byte i;
for (i = 2; i < strlen(Val[0]); i++)
{
if ((Val[0][i] >= '0') && (Val[0][i] <= '9'))
{
result = (result << 4) + Val[0][i] - '0';
}
else if ((Val[0][i] >= 'A') && (Val[0][i] <= 'F'))
{
result = (result << 4) + 10 + Val[0][i] - 'A';
}
else if ((Val[0][i] >= 'a') && (Val[0][i] <= 'f'))
{
result = (result << 4) + 10 + Val[0][i] - 'a';
}
else
{
Serial.println("Val[0] is not a valid hex value");
break;
}
}
By the way, adding 0x in front of the string is useless for this conversion. If you can, remove it and then replace "0x%x" with "%x" in the sscanf solution, or i = 2 with i = 0 in the hand-made one.

checking bits in an NSData object

how do i check if bits 0-6 in an NSData object which is 0x0001 are equal to 1?
My code
const char *byte = [dataObject bytes];
for (int i=0; i<2; i++) {
char n = byte[i];
char buffer[9];
buffer[8] = 0; //for null
int j = 8;
while(j > 0)
{
if(n & 0x01)
{
buffer[--j] = '1';
//a bit is equal to 1 from my understanding
} else
{
buffer[--j] = '0';
}
n >>= 1;
}
}
says that bit 1 is a 1 which is clearly not true.
This runs on an iPhone which is a little Endian system
This is what I ended up learning
const char *byte = [fixtureStatusBasic bytes]; //objective c, puts the 2 bytes into *byte
char n = byte[0]; //first byte is now called n
if(n & 0b00111111){ //AND the byte "n" with 6 least significant bits set to 1 to see if any of the 6 bits is set to 1
//if this is true, and the program goes here, that means that one of the bits is set to 1
}
To see if bit 5 is set for example,
if(n & 0b00010000){
//5th least significant byte is set to 1.
}
thank you freenode.

How to increase an ipv6 address based on mask in java?

i am trying to increment ipv6 address based on mask.
i am getting problem when there is F in place of increment.
could any one plz check this
public String IncrementIPV6ForPrefixLength (String IPv6String, int times) throws UnknownHostException
{
int result , carry = 0, i;
int bits;
int mask=0;
int index=IPv6String.indexOf("/");
mask=Integer.parseInt(IPv6String.substring(index+1, IPv6String.length()));
IPv6String=IPv6String.substring(0, index);
InetAddress iaddr=InetAddress.getByName(IPv6String);
byte[] IPv6Arr=iaddr.getAddress();
if(mask > 128 || mask < 0)
return null;
i = mask/8;
bits = mask%8;
if(bits>0)
{
result = ((int)(IPv6Arr[i]>>(8-bits))) + times;
IPv6Arr[i] =(byte) ((result << (8-bits)) | (IPv6Arr[i] & (0xff >> (bits))));
carry = (result << (8-bits))/256;
times /= 256;
}
i--;
for(;i>=0;i--)
{
result = ((int)IPv6Arr[i]) + ((times + carry)& 0xFF);
IPv6Arr[i] = (byte)(result % 256);
carry = result / 256;
if(carry == 0)
{
iaddr=InetAddress.getByAddress(IPv6Arr);
String s=iaddr.toString();
if(s.indexOf('/') != -1){
s = s.substring(1, s.length()).toUpperCase();
}
StringBuffer buff =new StringBuffer("");
String[] ss = s.split(":");
for(int k=0;k<ss.length;k++){
int Differ = 4 - ss[k].length();
for(int j = 0; j<Differ;j++){
buff.append("0");
}
buff.append(ss[k]);
if(k!=7)buff=buff.append(":");
}
return buff.toString()+"/"+mask;
}
times /= 256;
}
return null;
}
input like this:
FD34:4FB7:FFFF:A13F:1325:2252:1525:325F/48
FD34:41B7:FFFF::/48
FD34:4FBF:F400:A13E:1325:2252:1525:3256/35
output like this
if increment by 1
FD34:4FB8:0000:A13F:1325:2252:1525:325F/48
FD34:41B8:0000::/48
FD34:4FC0:0400:A13E:1325:2252:1525:3256/35
if increment by 2
FD34:4FB8:0001:A13F:1325:2252:1525:325F/48
FD34:41B8:0001::/48
FD34:4FC0:1400:A13E:1325:2252:1525:3256/35
can u plz find where i am doing wrong.
Disregarding the posted code, try to model the operation as a direct numerical operation on the 128-bit number that the IPv6 address really is. Convert to BigInteger and use BigInteger.add.