bootloader avr atmega128RFA1 - avr

I am also working on the bootloader.
I had the problem in the following:
Once the cmd 'B' is received, later, 'F' is received, then I would start to call block load.
static void start_block_flash_load(uint16_t size, uint32_t *addr) {
uint16_t data_word;
uint8_t sreg = SREG;
uint16_t temp;
int i;
uint8_t my_size;
fprintf(lcdout, "B");
cli();
// Disable interrupts
(*addr) <<= 1;
if (size <= SPM_PAGESIZE) {
boot_page_erase(*addr);
boot_spm_busy_wait();
fprintf(lcdout, "%"PRIu16, size);
uint16_t i;
//store all values. PROBLEM here!!!
my_size = 208;
uint8_t buf[SPM_PAGESIZE] = { 0 };
for (i = 0; i < my_size; i++) {
//for (i=0; i<size; i++){
buf[i] = uart_getc();
// lcd_clear();
// lcd_setCursor(0, 2);
// fprintf(lcdout, "%3d", i);
// _delay_ms(500);
}
for (i = 0; i < my_size; i += 2) { //if size is odd, then use do-while
uint16_t w = buf[i];
w += buf[i + 1] << 8; //first one is low byte, second is high???
boot_page_fill((*addr)+i, w);
}
boot_page_write(*addr);
boot_spm_busy_wait();
(*addr) >>= 1;
uart_putc('\r');
} else
uart_putc('?');
boot_rww_enable ();
SREG = sreg;
}
I can see on the lcd that the size of the block is 256. However, when entering the loop to collect data, it will get stuck.
I tested with my_size and I found that only if my_size=208 the program will run further.
The strange thing is that if I put some statements inside the loop, e.g.
lcd_clear();
lcd_setCursor(0, 2);
then 'i' which I printed out on lcd will not go up to 140 something. I put different statements, the 'i' will give different value. That is very strange, since the uart_getc() will not lose data.
What I expect is that the loop will go up to 256. I cannot figure out what happened there.
Please help if you have any idea.
Thanks

Related

Unable to execute interrupt function

Using Mplab ide 5.10 and xc8 compiler for the pic18f4550 I am unable to get the code to get into the interrupt function the goal is to get J to count up in the background until something trigger it to output a value in the lcd. Currently only the lcd display the first message and using ICD 3 the value of J does not change and does not look like the program runs the interrupt function at all
#define _XTAL_FREQ 48000000
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
unsigned char j, output = 0, i, outchar;
char buffer[2] = " ";
char Message[ ] = "Hands Position ";
void interrupt timer0_isr();
void lcd_write_cmd(unsigned char cmd);
void lcd_write_data(unsigned char data);
void lcd_strobe(void); // Generate the E pulse
void lcd_init(void);
void interrupt timer0_ISR() // Timer0 Interrupt Service Routine (ISR)
{
if (INTCONbits.TMR0IF) // TMR0IF:- Timer0 Overflow Interrupt Flag Bit
{
TMR0H = 0x48; // Timer0 start value = 0x48E5 for 1 second
TMR0L = 0xE5;
PORTCbits.RC1 = !PORTCbits.RC1; /* external timing check - toggle every 1ms */
if (j <= 4) { //limit up to 7
j++; // Increase count by 1
PORTB = j; // Output to Demultiplexer
} else {
j = 0; // Reset count aftwr it hit 7
PORTB = j; // Output to Demultiplexer
}
INTCONbits.TMR0IF = 0; // Reset TMR0IF at interrupt end
}
}
void main(void) // Main Function
{
ADCON1 = 0x0F;
CMCON = 0x07;
RCONbits.IPEN = 1; // Bit7 Interrupt Priority Enable Bit
INTCONbits.GIEH = 1; // Bit7 Global Interrupt Enable bit
INTCONbits.GIEL = 0; /* turn on low & high interrupts */
T0CONbits.TMR0ON = 1; // Turn on timer
T0CON = 0b00000111; // bit7:0 Stop Timer0
// bit6:0 Timer0 as 16 bit timer
// bit5:0 Clock source is internal
// bit4:0 Increment on lo to hi transition on TOCKI pin
// bit3:0 Prescaler output is assigned to Timer0
// bit2-bit0:111 1:256 prescaler
INTCON2 = 0b10000100; // bit7 :PORTB Pull-Up Enable bit
// 1 All PORTB pull-ups are disabled
// bit2 :TMR0 Overflow Int Priority Bit
// 1 High Priority
TMR0H = 0x48; // Initialising TMR0H
TMR0L = 0xE5; // Initialising TMR0L for 1 second interrupt
INTCONbits.TMR0IE = 1; // bit5 TMR0 Overflow Int Enable bit
INTCONbits.TMR0IF = 0; // bit2 TMR0 Overflow Int Flag bit
// 0 TMR0 register did not overflow
TRISC = 0; /* all outputs */
TRISAbits.TRISA5 = 1; // RA5 is the check for signal from input Multiplexer.
TRISAbits.TRISA0 = 0; // RA0, RA1 & RA2 output to arduino
TRISAbits.TRISA1 = 0;
TRISAbits.TRISA2 = 0;
TRISD = 0x00; // PortD connects to Demultiplexer
TRISB = 0;
lcd_init(); // LCD init
lcd_write_cmd(0x80); // Cursor set at line 1 positon 1
for (i = 0; i < 16; i++) {
outchar = Message[i]; // Store Message in outchar
lcd_write_data(outchar); // Display Message
}
__delay_ms(100);
PORTD = 0x00; // Clear PortD
PORTB = 0;
j = 0; // Start count from 0
while (1) // Main Process
{
if (PORTAbits.RA5 == 1) { // If RA3 detect a signal
switch (j) { // Switch case to determine hand position & output to RA0, RA1 & RA2 to transmit to arduino
case(0):
output = 10;
PORTAbits.RA0 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 0;
break;
case(1):
output = 20;
PORTAbits.RA0 = 1;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 0;
break;
case(2):
output = 30;
PORTAbits.RA0 = 0;
PORTAbits.RA1 = 1;
PORTAbits.RA2 = 0;
break;
case(3):
output = 40;
PORTAbits.RA0 = 1;
PORTAbits.RA1 = 1;
PORTAbits.RA2 = 0;
break;
case(4):
output = 50;
PORTAbits.RA0 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 1;
break;
}
lcd_write_cmd(0xC0); // Cursor set at line 2 positon 1
sprintf(buffer, "%d", output); // Convert numbers to character
for (i = 0; i < 2; i++)
lcd_write_data(buffer[i]); // Display Hand Position
}
}
}

CUDA string search in large file, wrong result

I am working on simple naive string search in CUDA.
I am new in CUDA. It works fine fol smaller files ( aprox. ~1MB ). After I make these files bigger ( ctrl+a ctrl+c several times in notepad++ ), my program's results are higher ( about +1% ) than a
grep -o text file_name | wc -l
It is very simple function, so I don't know what could cause this. I need it to work with larger files ( ~500MB ).
Kernel code ( gpuCount is a __device__ int global variable ):
__global__ void stringSearchGpu(char *data, int dataLength, char *input, int inputLength){
int id = blockDim.x*blockIdx.x + threadIdx.x;
if (id < dataLength)
{
int fMatch = 1;
for (int j = 0; j < inputLength; j++)
{
if (data[id + j] != input[j]) fMatch = 0;
}
if (fMatch)
{
atomicAdd(&gpuCount, 1);
}
}
}
This is calling the kernel in main function:
int blocks = 1, threads = fileSize;
if (fileSize > 1024)
{
blocks = (fileSize / 1024) + 1;
threads = 1024;
}
clock_t cpu_start = clock();
// kernel call
stringSearchGpu<<<blocks, threads>>>(cudaBuffer, strlen(buffer), cudaInput, strlen(input));
cudaDeviceSynchronize();
After this I just copy the result to Host and print it.
Can anyone please help me with this?
First of all, you should always check return values of CUDA functions to check for errors. Best way to do so would be the following:
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
Wrap your CUDA calls, such as:
gpuErrchk(cudaDeviceSynchronize());
Second, your kernel accesses out of bounds memory. Suppose, dataLength=100, inputLength=7 and id=98. In your kernel code:
if (id < dataLength) // 98 is less than 100, so condition true
{
int fMatch = 1;
for (int j = 0; j < inputLength; j++) // j runs from [0 - 6]
{
// if j>1 then id+j>=100, which is out of bounds, illegal operation
if (data[id + j] != input[j]) fMatch = 0;
}
Change the condition to something like:
if (id < dataLength - inputLength)

Error while freeing an array within a data structure

Status bit_flags_set_flag(BIT_FLAGS hBit_flags, int flag_position) {
Bit_Flags* temp = (Bit_Flags*)hBit_flags;
int* nums;
int i;
int old_size;
if (temp->size < flag_position) {
nums = malloc(sizeof(int)*flag_position+1);
if (nums == NULL) {
return FAILURE;
}
for (i = 0; i < temp->size; i++) {
nums[i] = temp->data[i];
}
free(temp->data);
temp->data = nums;
old_size = temp->size;
temp->size = flag_position + 1;
for (i = old_size; i < temp->size; i++) {
temp->data[i] = 0;
}
}
temp->data[flag_position / 32] |= 1 << flag_position % 32;
return SUCCESS;
}
according to the debugger the error is from the free(temp->data) part. however. I only run into the error the second time I go through the function. any ideas what is happening here.
am getting a heap corruption error on visual studio.
I am writing on some assumptions like you are assuming int size is 32 bits and you are trying to set the bit at flag_position in the bitset and you are using 1 int for 1 bit for setting and unsetting bits
Few comments now
temp->data[flag_position / 32] |= 1 << flag_position % 32; now this doesn't make any sense, this line role is to set bit at flag_position, this should be temp->data[flag_position] = 1; instead because if you see your code your are using ints for each bit.
Also this line temp->size = flag_position + 1; is also incorrect , this should be temp->size = flag_position;

SDCC integer comparison unexpected behavior

I'm trying to get started on a project using a PIC18F24J10. Attempting to use SDCC for this. At this point I've reduced my code to simply trying to nail down what is happening, as I've been seeing bizarre behavior for a while now and can't really proceed until I figure out what is going on. Not sure if this is my only problem at this point, but I have no idea why this is happening. Timer interrupt fires off, coupled with a #defined for loop causes LEDs on PORTC to blink maybe twice a second. If I just do a PORTC=0xFF and PORTC=0 this works fine. But it gets weird when I try to go much beyond that.
...
#define _RC0 31
#define _RC1 32
#define _RC2 33
#define _RC3 34
#define _RC4 35
#define _RC5 36
#define _RC6 37
#define _RC7 38
#define HI 1
#define LO 0
void why(unsigned char p, int z)
{
if(z == HI)
{
if(p == _RC0) PORTCbits.RC0 = 1;
else if(p == _RC1) PORTCbits.RC1 = 1;
else if(p == _RC2) PORTCbits.RC2 = 1;
else if(p == _RC3) PORTCbits.RC3 = 1;
else if(p == _RC4) PORTCbits.RC4 = 1;
else if(p == _RC5) PORTCbits.RC5 = 1;
else if(p == _RC6) PORTCbits.RC6 = 1;
else if(p == _RC7) PORTCbits.RC7 = 1;
}
else if(z == LO)
{
PORTC = 0b11110000;
}
else
{
PORTC = 0b10101010;
}
}
void timer_isr (void) __interrupt(1) __using (1)
{
TMR0H=0;
TMR0L=0;
why(_RC0, LO);
why(_RC1, LO);
why(_RC2, LO);
WAIT_CYCLES(5000);
why(_RC0, HI);
why(_RC1, HI);
why(_RC2, HI);
WAIT_CYCLES(5000);
}
void main(void)
{
WDTCONbits.SWDTE = 0;
WDTCONbits.SWDTEN = 0;
TRISC = 0b00000000;
PORTC=0b00000000;
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
INTCONbits.TMR0IF = 0;
INTCONbits.TMR0IE = 1;
T0CONbits.T08BIT = 0;
T0CONbits.T0CS = 0;
T0CONbits.PSA = 1;
TMR0H = 0;
TMR0L = 0;
T0CONbits.TMR0ON = 1;
while(1)
{
}
}
In the code above, four of the LEDs should blink, while the other four stay on. Instead, the LEDs stay on in the 10101010 pattern that happens in the "else" block, which should happen when "why" is called with any value other than HI or LO. I never call it with anything else, so why does it ever reach that?
UPDATE - Further reduction, no more interrupts or unspecified includes/defines. This is now the entirety of the program, and I am still seeing the same behavior. Changed the pattern from 10101010 to 10101011 so that I could verify the chip is actually being programmed with the new code, and it appears to be.
#include "pic16/pic18f24j10.h"
#define WAIT_CYCLES(A) for(__delay_cycle = 0;__delay_cycle < A;__delay_cycle++)
int __delay_cycle;
#define HI 1
#define LO 0
void why(int z)
{
if(z == HI)
{
PORTC = 0b11111111;
}
else if(z == LO)
{
PORTC = 0b11110000;
}
else
{
PORTC = 0b10101011;
}
}
void main(void)
{
TRISC = 0b00000000;
PORTC=0b00000000;
while(1)
{
why(LO);
WAIT_CYCLES(5000);
why(HI);
WAIT_CYCLES(5000);
}
}
Once the interrupt is asserted it is never cleared. That results in timer_isr() being called repeatedly. No other code is ever reached. The TMR0IF bit must be cleared in software by the Interrupt Service Routine.
Keep in mind you not only need to spend less time in the ISR than the period of the timer - it’s a good practice to spend the minimum amount of time necessary.
Remove the delays and simply toggle a flag or increment a register. In your main while (1) loop monitor the flag or counter and make your calls to why() from there.

dsPic Receive 11byte usart string

I'm using a dsPic33 to try and receive a 11-byte string and place it in a array, but have not been successful at receiving it completely. The string I send is "$123456789#" which should be received by the pic. I have tried using the code below. Any help will be appreciated.
char inBytes[11];
int i;
unsigned char temp;
while (U1STAbits.URXDA != 0)
{
temp = U1RXREG;
if (temp == '$')
{
inBytes[0] = temp;
for(i = 1; i < 10; i++)
{
if (U1STAbits.URXDA != 0)
inChar = U1RXREG;
inBytes[i] = inChar;
}
}
jolati had a good point about the end value beeing too low to get 11 bytes but I must add that you have to wait for your other bytes to become available before you read them.
In your example;
char inBytes[11];
int i;
unsigned char temp;
while (!U1STAbits.URXDA ); //Wait until at least one byte is available
temp = U1RXREG;
if (temp == '$')
{
inBytes[0] = temp;
for(i = 1; i < 11; i++) //Loop over range i = 1 to 10 inclusively
{
while (!U1STAbits.URXDA ); //Wait until at least one byte is available
inBytes[i] = U1RXREG;
}
}
Ideally, you would do this in a non blocking way with interrupts so you handle your data as it comes in but, if you cant use interrupts, you can always use non blocking polling like:
void AsyncRX()
{
//Note that the static variables keeps their value between invocations of the
// function. i is set to 0 only on the first run of this function, it keeps
// its value on every other run after that.
static int i = 0;
static char inBytes[11];
//Nothing more to do until there is at least 1 byte available
if( !U1STAbits.URXDA )
return;
//Save the byte and test that our message starts with $
inBytes[i] = U1RXREG;
if( inBytes[0] != '$' )
return;
//Test the counter to see if we have a full 11 bytes
i++;
if( i < 11 )
return;
//Do something with your 11 bytes
//...
//...
//Reset the counter for the next message
i = 0;
}
For the interrupt example, you could simply grab the polled version and throw it into a ISR. The following is an example. Note that I do not know which dsp33 you are using and I have not programmed interrupts in high end cores (with vector tables) in a while so you may need to make a change or two. Also note that you need to enable interupts by setting the appropriate registers as they are not enabled by default.
void __attribute__ ((interrupt, no_auto_psv)) _U1RXInterrupt(void)
{
//Note that the static variables keeps their value between invocations of the
// function. i is set to 0 only on the first run of this function, it keeps
// its value on every other run after that.
static int i = 0;
static char inBytes[11];
//Reset the interrupt flag
IFS0bits.U1RXIF = 0;
//Use up all bytes in the buffer (the interrupt can be set to only fire
// once the buffer has multiple bytes in it).
while( U1STAbits.URXDA )
{
//Save the byte and test that our message starts with $
inBytes[i] = U1RXREG;
if( inBytes[0] != '$' )
continue;
//Test the counter to see if we have a full 11 bytes
i++;
if( i < 11 )
continue;
//Do something with your 11 bytes
//...
//...
//Reset the counter for the next message
i = 0;
}
}
for(i = 1; i < 10; i++) starts saving data at index 1 and stops at 9, only 9 bytes. Change < 10 to <= 10 or < 11.

Resources