View previous topic :: View next topic |
Author |
Message |
saeed
Joined: 07 Mar 2017 Posts: 10
|
bootloader+uart |
Posted: Mon May 29, 2017 4:05 pm |
|
|
Hi
I'm working on ccs bootloader example and i can run them properly. (ex_bootloader.c and ex_bootload.c)
Now i want to add a serial comm in the ex_bootload file. I know i have to use #int_global but i don't know how to use it.
Thanks in advance
ccs:5.049
Here is the changed ex_bootload file:
Code: |
#include <16f877a.h>
#fuses hs,NOWDT
#use delay(crystal=4MHz)
#use rs232(baud=9600, parity=N,xmit=PIN_C6, rcv=PIN_C7,stream=prog,errors)
#include <bootloader.h>
int1 rda_flag = false;
int rc; // received character
int save_w;
#locate save_w=0x7f
int save_status;
#locate save_status=0x20
#byte status = 0x03
#bit zero_flag = status.2
#byte PIR1bits = 0x0C
#bit rcif = PIR1bits.5
#byte RCREG = 0x1A
#byte TXSTAbits = 0x98
#bit TRMT = TXSTAbits.1
#int_global
void isr(void){
#asm
//store current state of processor
MOVWF save_w // move the contents of W register into save_w
SWAPF status,W
BCF status,5
BCF status,6
MOVWF save_status
#endasm
if(rcif == 1){ // rda interrupt
rcif = 0;
rda_flag = true;
rc = RCREG;
while(TRMT == 0);
}
#asm
SWAPF save_status,W
MOVWF status
SWAPF save_w,F
SWAPF save_w,W
#endasm
}
void main()
{
enable_interrupts(int_rda);
enable_interrupts(global);
rda_flag = false;
while(true){
if(rda_flag){
fputc(rc,prog);
rda_flag = false;
delay_ms(100);
}
delay_ms(20);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19386
|
|
Posted: Tue May 30, 2017 3:27 am |
|
|
You are back to front....
You don't want to touch INT_GLOBAL. This is already done for you in the bootloader. Assuming you are using the standard CCS bootloader, you need do nothing except to use the normal INT_RDA
The point is the _bootloader_ has to vector all interrupts 'up' to the address where the main code sits. To do this, it has to intercept the two global vectors and automatically 'jump' them up to where the interrupt handling code will be in the main code.
This line:
while(TRMT == 0);
will also hang the processor for ever....
If the buffer is full, this will loop, and since it is inside the interrupt, the buffer can never be emptied.....
All you need is:
Code: |
#INT_RDA
{
rc=fgetc(PROG);
rda_flag=TRUE;
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
saeed
Joined: 07 Mar 2017 Posts: 10
|
|
Posted: Tue May 30, 2017 6:48 am |
|
|
Thank You Ttelmah
The problem solved as you mentioned.
I have another problem.I want to use Code: | #ROM getenv("EEPROM_ADDRESS") = {x} | in ex_bootload. but when i use Code: | read_eeprom(getenv("EEPROM_ADDRESS")) | in the main, it returns 1 instead of x.
Thank you |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19386
|
|
Posted: Tue May 30, 2017 7:51 am |
|
|
The read_eeprom command accepts the byte number in the EEPROM, not the memory address.
so:
read_eeprom(0);
Returns the byte from the first location in the EEPROM
The 'address', doesn't actually exist in the chip. The EEPROM sits at 'EEPROM_ADDRESS', in the data sent for programming.
So on a PIC, in the programming data, the EEPROM might sit at address 0x3F000 for example, but if you have written data to the EEPROM, this would be at '0' for the read_eeprom command.... ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
saeed
Joined: 07 Mar 2017 Posts: 10
|
|
Posted: Tue May 30, 2017 8:48 am |
|
|
I'm confused
In the absence of bootloader, i used to use Code: | #ROM getenv("EEPROM_ADDRESS")+y = {x} | in the preprocessor to initialize eeprom and Code: | read_eeprom(getenv("EEPROM_ADDRESS")+y) | to call it.
So in the presence of bootloader, how can i use #ROM to initialize the eeprom? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19386
|
|
Posted: Tue May 30, 2017 10:31 am |
|
|
Nothing to do with the bootloader. You were calling the read_eeprom function incorrectly......
However what probably happened, was that the too large number was being automatically truncated to 8 bits, so was losing the 'EEPROM_ADDRESS' part and just received 'y'...
However if you have switched to a chip that supports a larger than 8bit EEPROM (many have 1KB EEPROM's), then this truncation won't happen the same. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19386
|
|
Posted: Tue May 30, 2017 11:32 am |
|
|
Ongoing to this.
You can have a bootloader that will load EEPROM contents. However most won't. Generally you want to keep configuration data if you update the code. The standard way to declare things is to just have a variable declared with the default values you want. Then on boot, have your main code read the EEPROM, and if it contains values you want to use, copy these into the variable, otherwise the variable is already initialised with the values you want. The normal way to know if the EEPROM contains legitimate values would be to have a checksum stored in it.
It's worth just reading the manual for read_eeprom. Note:
Quote: |
The address begins at 0
|
|
|
![](templates/subSilver/images/spacer.gif) |
|