C - CRC32 checksum does not match Wireshark on Ethernet Frame Check Sequence - c

I'm using an online CRC-32 calculator to check that my output is correct however it seems that Wireshark has a different expected FCS for the ethernet packet.
message2 is the ethernet frame minus the FCS as seen in Wireshark
#include <stdio.h>
#include <stdint.h>
unsigned int crc32b(unsigned char *message) {
int i, j;
unsigned int byte, crc, mask;
i = 0;
crc = 0xFFFFFFFF;
while (message[i] != 0) {
//printf("%i %x \n\n", i, message[i]);
byte = message[i];
crc = crc ^ byte;
for (j = 7; j >= 0; j--) {
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
i = i + 1;
}
return ~crc;
}
int main(void)
{
unsigned char * message = "hello test";
unsigned char * message2 = "aabbccddeeff5cb9017c5a53080000000000000000000000000000";
unsigned int res = crc32b(message2);
printf("%x\n", res);
return 0;
}
I've tried using different Polynomials as defined in [1 - subsection CRC-32 IEEE 802.3], however the result does not match Wireshark.
Output using 0xED Polynomial: 0xd81e4af3
Wireshark FCS expected: 0xa8cd3084
I'd really like to code in the FCS for my ethhdr packet, I guess when creating a software packet, the FCS isn't entered by the NIC...
Sources:
[1] - http://crppit.epfl.ch/documentation/Hash_Function/WiKi/Cyclic_redundancy_check.htm

Your implementation is definitively correct (for NUL terminated C strings). It's a maybe a wrong configuration of the network interface. In default mode Wireshark doesn't get a FCS from the network driver. If you use Linux and the driver supports this, then you must enable this with ethtool to get the FCS.
Unfortunately, on my system this only works for receiving frames:
$ ethtool -K eth0 rx-fcs on
See this for details.
I use a slightly different algorithm in my embedded (for AVR microcontrollers) projects and it works perfectly for me:
#define CRC_POLY 0xEDB88320
uint32_t crc32_calc(uint8_t *data, int len)
{
int i, j;
uint32_t crc;
if (!data)
return 0;
if (len < 1)
return 0;
crc = 0xFFFFFFFF;
for (j = 0; j < len; j++) {
crc ^= data[j];
for (i = 0; i < 8; i++) {
crc = (crc & 1) ? ((crc >> 1) ^ CRC_POLY) : (crc >> 1);
}
}
return (crc ^ 0xFFFFFFFF);
}
A real world example:
The Ethernet frame in Wireshark (with ethtool rx-fcs on):
The test with my used implementation:
uint8_t frame[] = { 0x20, 0xcf, 0x30, 0x1a, 0xce, 0xa1, 0x62, 0x38,
0xe0, 0xc2, 0xbd, 0x30, 0x08, 0x06, 0x00, 0x01,
0x08, 0x00 ,0x06 ,0x04 ,0x00 ,0x01 ,0x62 ,0x38,
0xe0 ,0xc2 ,0xbd ,0x30 ,0x0a, 0x2a, 0x2a, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2a,
0x2a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
printf("0x%x\n", crc32_calc(frame, sizeof(frame)));
The output:
$ ./fcs-test
0x6026b722
$
You can see, Wireshark reports 0x22bf2660 as correct FCS. Here is only a different output because of the byte-order. But the CRC calculation algorithm is correct.
EDIT:
I have modified your code:
uint32_t crc32b(uint8_t *message, int len) {
int i, j;
uint32_t crc, mask;
uint8_t byte;
crc = 0xFFFFFFFF;
for (j = 0; j < len; j++) {
byte = message[j];
crc = crc ^ byte;
for (i = 7; i >= 0; i--) {
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}
I added a length argument, because your implementation only works correct when message is a NUL terminated C string. If your input is a byte array, then you get a incorrect CRC value.
See the differences (Array and C string):
uint8_t msg_arr[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x5c, 0xb9, 0x01, 0x7c, 0x5a, 0x53, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
char *msg_str = "aabbccddeeff5cb9017c5a53080000000000000000000000000000";
printf("0x%x\n", crc32b(msg_arr, sizeof(msg_arr)));
printf("0x%x\n", crc32b(msg_str, strlen(msg_str)));
Output:
$
0x3422dd71
0xd81e4af3
$

There are a number of problems with your code. There are also plenty of existing implementations you could compare (eg, this one linked from the real Wikipedia page on CRC).
unsigned char * message2 = "aabbccddeeff5cb9017c5a53080000000000000000000000000000";
Are you hoping that this will be the octet sequece 0xAA 0xBB 0xCC ... as you see them in Wireshark? Because that isn't at all what you have.
This string actually contains 0x61 0x61 0x62 0x62 ... (assuming your platform uses ASCII encoding) because it is a character string and not an octet string.
specifically, here: byte = message[i]; you assume the first 8 bits of your message are an octet, and again I assume since you didn't say, that you expected this to be 0xAA. It will actually be 0x61.
If you want this to work correctly, translate each pair of characters into an integer value using strtoul(pair, NULL, 16) or similar.
You have a loop for (j = 7; j >= 0; j--) but never use j inside it. You do use the integer constant 1 in an odd-looking way: is there supposed to be a (1 << j) or something?
I suggest fixing the obvious errors, and then writing some self-contained tests before you try comparing whole frames with Wireshark. The code you posted has some basic errors that should be tested, identified and fixed before you get to this point.

Im not sure about your question, but if you want calculate a checksum of a network packet, you have to deploy the data in it's proper structure.
Please make sure your problem is not related with endianness.
The network byte-order is big-endian, here is the point that the things getting a little bit harder.
Little-Endian mostly used in PCs but may vary by hardware and manufacturer.
2byte integer (16 bit integer) with value 255.
Little Endian: FF00
Big Endian: 00FF
Im not sure what kind of checksum you are trying to match with, but checksum not only for data field, mostly it contains all flags and options, issued at last step thats why the implementation require the corresponding data structure.
About checksums, there are a lot of case when you get an invalid checksum with wireshark, it could cause kernel, virtual adapter, accelerated network, dedicated CPU in your NIC, etc...
Example for TCP header:
/* include/linux/tcp.h */
struct tcphdr {
__u16 source;
__u16 dest;
__u32 seq;
__u32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__u16 window;
__u16 check;
__u16 urg_ptr;
};

Related

LibOpenCM3 1-Wire over UART DMA STM32F1

I just began to understand the embedded world (after Arduino, RPi, etc) with the STM32F103 and FreeRTOS + Libopencm3. My first challenge is to interface a DS18B20, temperature sensor with my microprocessor. The 1-Wire bus is quite easy to understand but not native supported so I followed your advised and go for 1-wire over UART with DMA.
DS18B20 has DATA on USART2TX (+4k7 pullup + diode) and USART2RX, VCC to 5V and GND.
Initialization of 1-Wire :
static void ow_init(void)
{
// One-Wire
// Already done : rcc_periph_clock_enable(RCC_GPIOA);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_USART2_RX);
usart_set_baudrate(USART2, 115200);
usart_set_databits(USART2, 8);
usart_set_stopbits(USART2, USART_STOPBITS_1);
usart_set_mode(USART2, USART_MODE_TX);
usart_set_parity(USART2, USART_PARITY_NONE);
usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
usart_enable(USART2);
rcc_periph_clock_enable(RCC_DMA1);
}
1-Wire Reset :
uint8_t ow_reset(void)
{
usart_disable_rx_dma(USART2);
usart_disable_tx_dma(USART2);
usart_set_baudrate(USART2, 9600);
usart_set_databits(USART2, 8);
usart_set_stopbits(USART2, USART_STOPBITS_1);
usart_set_mode(USART2, USART_MODE_TX);
usart_set_parity(USART2, USART_PARITY_NONE);
usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
usart_send(USART2, 0xf0);
while(usart_get_flag(USART2, USART_SR_TC));
uint8_t ow_presence;
ow_presence = usart_recv(USART2);
usart_set_baudrate(USART2, 115200);
usart_set_databits(USART2, 8);
usart_set_stopbits(USART2, USART_STOPBITS_1);
usart_set_mode(USART2, USART_MODE_TX_RX);
usart_set_parity(USART2, USART_PARITY_NONE);
usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
if(ow_presence != 0xf0)
{
return 1;
}
return 0;
}
Getting the scratchpad with :
void ow_convert_to_scratchpad(void)
{
const uint8_t convert_T[] = {0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, // 0xCC
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00}; // 0x44
dma_channel_reset(DMA1, DMA_CHANNEL7);
dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t)&USART2_DR);
dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t) convert_T);
dma_set_number_of_data(DMA1, DMA_CHANNEL7, sizeof(convert_T));
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_8BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_8BIT);
dma_set_priority(DMA1, DMA_CHANNEL7, DMA_CCR_PL_LOW);
dma_enable_channel(DMA1, DMA_CHANNEL7);
usart_enable_tx_dma(USART2);
}
uint16_t ow_get_scratchpad(void)
{
const uint8_t read_scratch[] = {0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, // 0xCC
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, // 0xBE
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t buf[8];
dma_channel_reset(DMA1, DMA_CHANNEL6);
dma_set_peripheral_address(DMA1, DMA_CHANNEL6, (uint32_t)&USART2_DR);
dma_set_memory_address(DMA1, DMA_CHANNEL6, (uint32_t) buf);
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6);
dma_set_number_of_data(DMA1, DMA_CHANNEL6, sizeof(read_scratch));
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL6);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL6);
dma_set_peripheral_size(DMA1, DMA_CHANNEL6, DMA_CCR_PSIZE_8BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL6, DMA_CCR_MSIZE_8BIT);
dma_set_priority(DMA1, DMA_CHANNEL6, DMA_CCR_PL_LOW);
dma_channel_reset(DMA1, DMA_CHANNEL7);
dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t)&USART2_DR);
dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t) read_scratch);
dma_set_number_of_data(DMA1, DMA_CHANNEL7, sizeof(read_scratch));
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_8BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_8BIT);
dma_set_priority(DMA1, DMA_CHANNEL7, DMA_CCR_PL_LOW);
dma_enable_channel(DMA1, DMA_CHANNEL6);
dma_enable_channel(DMA1, DMA_CHANNEL7);
usart_enable_tx_dma(USART2);
usart_enable_rx_dma(USART2);
while(dma_get_interrupt_flag(DMA1, DMA_CHANNEL6, DMA_TCIF));
uint16_t tt = 0;
for(int i=0;i<32; i++)
{
uart1_printf("Bit : %d \n\r", buf[i]);
if(buf[i] == 0xff)
{
tt = (tt >> 1) | 0x8000;
}
else
{
tt = tt >> 1;
}
}
return tt;
}
static void demo_task(void *args)
{
(void)args;
for (;;) {
uart1_printf("Hello\n\r");
uint8_t p = ow_reset();
uart1_printf("presence = %d\n\r", p);
ow_convert_to_scratchpad();
for(int i=0; i<5000000; i++)
{
__asm__("nop");
}
ow_reset();
uint16_t t = ow_get_scratchpad();
uart1_printf("t = %d \n\r", t);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
And finally the task that tries to reach the DS18B20
static void demo_task(void *args)
{
(void)args;
for (;;) {
ow_reset();
ow_convert_to_scratchpad();
vTaskDelay(pdMS_TO_TICKS(500));
ow_reset();
uint16_t t = ow_get_scratchpad();
uart1_printf("t = %d \n\r", t);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
I receive some bits as 0xCC, 0xBE, 0xFF but no more answer.
Ok, so
rcc_periph_clock_enable(RCC_USART2);
was missing so USART2 can't do its job. I can send and receive data now.
The reset function works except this line (it wait indefinitely) :
while(usart_get_flag(USART2, USART_SR_TC));
I don't understand why this flag is not true when the transmission is complete... But I have 0x00 on RX line so I think the sensor is responding (I hope...)
My function ow_convert_to_scratchpad with DMA looks like being blocking. I don"t know why...
I just tried (for fun...) to replace the whole DMA by hardcoding the sent of 0xCC, 0x44, 0xCC, 0xBE and the read but no answer (0x00) from the sensors.
I am kind of late to the party, but... Have you tried something a bit less convoluted first? (Simpler to check I mean)
Like asking a single DS18B20 its address?
Reset bus and check presence.
Send search ROM cmd (write byte 0xF0)
loop 64 times reading address bits from LSB to MSB {
read bit i
read bit i complement
check they are 1 and 0 or the other way around
send bit i back to device so it sends you back the next bit
}
At the end you have the 8 byte of the device address. 1 byte family 0x28 48 bit address 1 byte CRC8 to check the whole thing is correct.

tiny-aes-c AES CTR 128 cuts off decrypted string in some cases

I've been trying to use the AES CTR 128 from tiny-aes-c (https://github.com/kokke/tiny-AES-c) to encrypt a randomly generated token, and it works, but not all the time. In some cases the retrieved string after encrypting and decrypting is cut off at some point. Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "token_auth.h"
#include "aes.h"
uint8_t * create_token() {
static char charset[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
uint8_t *token = malloc(sizeof(uint8_t) * (TOKEN_LENGTH + 1));
int i = 0;
srand ( time(NULL) );
for (i = 0; i < TOKEN_LENGTH; i++) {
int pos = rand() % (int)(strlen(charset) - 1);
token[i] = (int) charset[pos] - 0;
}
token[TOKEN_LENGTH] = 0;
return token;
}
int main() {
uint8_t key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
uint8_t iv[16] = { 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
uint8_t *in = create_token();
printf("\nInput: %s\nSize: %d", (char *) in, strlen((char *) in));
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, key, iv);
AES_CTR_xcrypt_buffer(&ctx, in, strlen((char *) in));
AES_init_ctx_iv(&ctx, key, iv);
AES_CTR_xcrypt_buffer(&ctx, in, strlen((char *) in));
printf("\nDEC: %s\n", (char *) in);
return 0;
}
TOKEN_LENGTH is 128. As an example of the behavior, the string NM5DlWyYInbeNtEWhBxGCdEjHSv2I6FzTMffJNgudrL2UsYe6zVJMA3wvAyhHeQD18UMXckcF8gBAfPGQNqGqwdW9MgS39w7huVfIgtoqJ212SKSIdBaJP9VErOJAmQT comes out NM5DlWyYInbeNtEWhBxGCdEjHSv2 after being encrypted and decrypted. I'm not really good at C, so it might just well be a problem with something else I've done, but at this point I'm lost. Any ideas? Thanks in advance.
The first call to AES_CTR_xcrypt_buffer encrypts the buffer in place in CTR mode.
The buffer still has the same size (128 in your case), but can contain NUL bytes.
The strlen call in the second call of AES_CTR_xcrypt_buffer for decryption can therefore result in a length < 128 if the buffer contains a NUL byte.
By the way: It works in cases where the encryption does not result in a NUL byte in the buffer.
So if you call it with TOKEN_LENGTH as the length parameter decryption will give the original string again:
AES_CTR_xcrypt_buffer(&ctx, in, TOKEN_LENGTH);

read file string and store in uint8_t array in c [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
CHAR fileBuffer[1000];
uint8_t tmpArray[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t tmpArray2] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
for (i = 0; i < sizeof(fileBuffer); i++)
{
printf("%02X ", (uint8_t)tmpArray[i]);
}
take string from the file and convert to a byte array as in tmpArray. The string in the file would be like,
5FE1908F5FA463A9F94B8B1EA460B70A7D946B144E6A5093965A882E7855931A
I did try to read this into two byte arrays like this
memmove(tmpArray, fileBuffer, 32 * sizeof(uint8_t));
memmove(tmpArray2,fileBuffer[32], 32 *sizeof(uint8_t));
it copied in ok to tmpArray first 16bytes but the next 16bytes got messed up in tmpArray2.
If you could help with either way it would be great
string from file, string as above and convert to uint8_t arrays. the two separate arrays should result after reading/converting
uint8_t tmpArray[] = { 0x5F, 0xE1, 0x90, 0x8F, 0x5F, 0xA4, 0x63, 0xA9, 0xF9, 0x4B, 0x8B, 0x1E, 0xA4, 0x60, 0xB7, 0x0A };
uint8_t tmpArray2[] = { 0x7D, 0x94, 0x6B, 0x14, 0x4E, 0x6A, 0x50, 0x93, 0x96, 0x5A, 0x88, 0x2E, 0x78, 0x55, 0x93, 0x1A };
Is that what you wanted? (to test give binary 01 combination as an first argument)
#include <stdio.h>
#include <stdint.h>
uint8_t charToBin(char c)
{
switch(c)
{
case '0': return 0;
case '1': return 1;
}
return 0;
}
uint8_t CstringToU8(const char * ptr)
{
uint8_t value = 0;
for(int i = 0; (ptr[i] != '\0') && (i<8); ++i)
{
value = (value<<1) | charToBin(ptr[i]);
}
return value;
}
int main(int argc,const char *argv[])
{
printf("%d\n",CstringToU8(argv[1]));
return 0;
}
You can use CstringToU8() to convert 8 characters to one u8 number. Read whole data to char array (e.g. char * text) and then convert 8 characters to u8 number, store it and move you pointer 8 bytes further until array won't end.
Because after edit question was changed so here is my new solution. Code reading hex numbers from file and storing it into array.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main()
{
FILE * fp;
uint8_t number = 0;
size_t fileSize = 0;
uint8_t * array = NULL;
size_t readedBytes = 0;
size_t iterator = 0;
fp = fopen ("hexNumbers.txt", "r");
// check file size
fseek(fp, 0L, SEEK_END);
fileSize = ftell(fp);
fseek(fp, 0L, SEEK_SET);
/// allocate max possible array size = fileSize/2
array = malloc(fileSize/2 * sizeof(uint8_t));
/// read data into array
while(!feof(fp))
{
if (fscanf(fp,"%2hhx",&number) == 1)
{
array[readedBytes++] = number;
}
}
fclose(fp);
/// print array output
for (iterator=0; iterator<readedBytes; ++iterator)
{
printf("%02x ", array[iterator]);
}
free(array);
return 0;
}

KL25 DAC Driver shows no output on oscilloscope

I am writing a DAC driver for the Freedom KL25z and it does not work. I am testing it with an oscilloscope, but there is no rise in voltage.
My configuration function is using the only DAC channel available for the KL25...
Connected oscilloscope voltage to PORTE30 pin and oscilloscope ground to KL25 GND pin.
UPDATE, forgot to write filenames and actual question
Here is my DACDriver.c file
#include "DACDriver.h"
unsigned char bflgSendingData = 0;
unsigned short* wpSetPattern;
unsigned short wSetPatternSize;
void vfnDACInit()
{
SIM_SCGC6 |= SIM_SCGC6_DAC0_MASK;
DAC0_C0 |= DAC_C0_DACRFS_MASK;
PORTE_PCR30 = PORT_PCR_MUX(0);
DAC0_DAT0L = 0x00;
DAC0_DAT0H |= 0x0;
DAC0_DAT1L = 0xFF;
DAC0_DAT1H |= 0xF;
DAC0_C0 |= DAC_C0_DACEN_MASK;
}
void vfnDACSetValue(unsigned short wValue)
{
DAC0_DAT0L = (unsigned char)(wValue & 0xFF);
DAC0_DAT0H = (unsigned char)(wValue >> 8);
}
unsigned char bfnDACDriver(void)
{
vfnDACSetValue(0xFF);
/*This is just a test; in my main, I'm just trying to see an output here.
But the main logic should be like the code below*/
/*if(bflgSendingData){
if(wSetPatternSize){
vfnDACSetValue(wpSetPattern);
wpSetPattern++;
wSetPatternSize--;
}
return 1;
}else{
return 0;
}
*/
}
unsigned char bfnDACSetPattern(unsigned short* wpPattern, unsigned short wPatternSize)
{
if(0 == bflgSendingData){
wpSetPattern = wpPattern;
wSetPatternSize = wPatternSize;
bflgSendingData = 1;
return 1;
}else{
return 0;
}
}
UPDATE, forgot to include this file
Here is my DACDriver.h file
#ifndef __DACDRIVER_H_
#define __DACDRIVER_H_
#include "derivative.h"
void vfnDACInit(void);
unsigned char bfnDACDriver(void);
unsigned char bfnDACSetPattern(unsigned short* wpPattern, unsigned short wPatternSize);
#endif /* __DACDRIVER_H_ */
Here is my main.c file, which right now only has a little test so I can see some output
#include "DACDriver.h"
int main(void)
{
unsigned char pattern[] = {
0xFF, 0xEF, 0xDF, 0xCF, 0xBF, 0xAF,
0x9F, 0x8F, 0x7F, 0x6F, 0x5F, 0x4F, 0x3F, 0x2F, 0x1F,
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A,
0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
vfnDACInit();
for(;;) {
bfnDACDriver();
}
return 0;
}
I am trying to be the most autodidact possible, but I have run out of ideas...
My main questions are:
Do you see any error here?
How do I make it work?
Am I missing something?
Thanks a lot!!
So my real problem was not seeing that my oscilloscope didn't have the right voltage/time resolution hence the "null" output so to speak. My driver is fine. Thank you very much to everyone answering and taking an interest in my problem.

The use of "if (strcmp(URL, "/") == 0)" in Arduino network sketches

I'm trying to understand the "if (strcmp(URL, "/") == 0)" line in the Arduino sketch below (see the sendMyPage function about halfway down):
#include <WiServer.h>
#define WIRELESS_MODE_INFRA 1
#define WIRELESS_MODE_ADHOC 2
#define AREF_VOLTAGE 5
const int tmpPin = A0;
int tmpReading = 0;
// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {192,168,31,199}; // IP address of WiShield
unsigned char gateway_ip[] = {192,168,1,1}; // router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0}; // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"MERCURY_7F3F70"}; // max 32 bytes
unsigned char security_type = 3; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"11163127"}; // max 64 characters
// WEP 128-bit keys
// sample HEX keys
prog_uchar wep_keys[] PROGMEM = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, // Key 0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Key 3
};
// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// End of wireless configuration parameters ----------------------------------------
float testTmp (void){
tmpReading = analogRead (tmpPin);
float voltage = tmpReading * AREF_VOLTAGE;
voltage /= 1023;
float tmpC = (voltage - 0.5) * 100;
return tmpC;
}
// This is our page serving function that generates web pages
**boolean sendMyPage(char* URL)** {
// Check if the requested URL matches "/"
**if (strcmp(URL, "/") == 0) {**
// Use WiServer's print and println functions to write out the page content
float tmpC = testTmp ();
WiServer.print("<html>");
// WiServer.print("Hello World!");
WiServer.print(tmpC);
WiServer.print("</html>");
// URL was recognized
return true;
}
// URL not found
return false;
}
void setup() {
// Initialize WiServer and have it use the sendMyPage function to serve pages
WiServer.init(sendMyPage);
// Enable Serial output and ask WiServer to generate log messages (optional)
Serial.begin(57600);
WiServer.enableVerboseMode(true);
}
void loop(){
// Run WiServer
WiServer.server_task();
delay(10);
}
It seems that the function accepts a URL as an argument, and sends data to the page using WiSever.print if the URL is valid. But how does 'if (strcmp(URL, "/") == 0)' determine if the URL is good?
I've seen this kind of check before, but don't understand how it works.
Thanks!
The line:
if (strcmp(URL, "/") == 0) {
Is testing to see if the string URL exactly matches the string literal "/". If so, it returns 0.
Note, if you wanted to test to see if the string URL contained "/", then use:
if (strstr(URL, "/") != NULL) {
Regarding But how does 'if (strcmp(URL, "/") == 0)' determine if the URL is good?
It does not. More would be needed than a single character to determine if URL was good, it appears that the comment, as written, is not really expressing what that code block actually does.

Resources