CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

I2C Bootloader PIC16
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Thu Jul 02, 2020 7:29 am     Reply with quote

If there is a CCSC.INI file, the compiler will read options from this. If this
exists it could be overriding the default, which is +O8hex
Now if this setting is wrong, most programmers will still accept the file
(they have a lot more code, and support for multiple formats), but the
bootloader won't.
So look if there is a ccsc.ini file.
If there is, see what it says (text editor).
The other possibility is your linux code is not sending the LSB.
bastirn



Joined: 08 Jan 2020
Posts: 17

View user's profile Send private message

PostPosted: Thu Jul 02, 2020 7:47 am     Reply with quote

I don't have any CCSC.INI file so it should use the default config as you said.
About the i2c, I use linux bash command (i2cset / i2cget).
bastirn



Joined: 08 Jan 2020
Posts: 17

View user's profile Send private message

PostPosted: Thu Jul 02, 2020 9:22 am     Reply with quote

To be more exact: after loading a new program with the bootloader i have this :

Picture of what i read after loading a program:
https://engie-my.sharepoint.com/:i:/p/gd5731/ETwUFkpJZBNCr5ZW3TqhBF8BR8vdG1On0CeCdqpNrlQl_g?e=pOMoN2

So it replace the first 8 bits (LSB) of the opcode with what i send on i2c. The 6 bits left seems to be modify between 1 and 9 in order.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Thu Jul 02, 2020 9:39 am     Reply with quote

So, what options have you got in your I2Cset command?.
This affects massively how the output data is configured.
bastirn



Joined: 08 Jan 2020
Posts: 17

View user's profile Send private message

PostPosted: Thu Jul 02, 2020 9:52 am     Reply with quote

Those command are provided in linux:
https://manpages.debian.org/buster/i2c-tools/i2cset.8.en.html
https://manpages.debian.org/buster/i2c-tools/i2cget.8.en.html

I have checked those commands with an oscilloscope and they look as it is indicated in the i2c_bootloader.h file:

Code:

////   +---+------+------+-------------+---+                           ////
////   | S | ADDY | CMD  |  Payload    | P |                           ////
////   +---+------+------+-------------+---+                           ////
////   | S | 0xA0 | 0x04 | 0x55 | 0xAA | P |                           ////
////   +---+------+------+-------------+---+                           ////
////                                                                   ////
////   +---+------+------+-------------+---+                           ////
////   | S | ADDY | CMD  |  Payload    | P |                           ////
////   +---+------+------+-------------+---+                           ////
////   | S | 0xA1 | 0x04 | 0x55 | 0xAA | P |                           ////
////   +---+------+------+-------------+---+                           ////
////                                                                   ////
//// Write 0x00 0x01 0x02 0x03 to address 0x1122:                      ////
////                                                                   ////
////   +---+------+------+---------------------------+---+             ////
////   | S | ADDY | CMD  |  Payload                  | P |             ////
////   +---+------+------+---------------------------+---+             ////
////   | S | 0xA0 | 0x01 | 0x22 | 0x11 | 0x00 | 0x00 | P |             ////
////   +---+------+------+---------------------------+---+             ////
////                                                                   ////
////   +---+------+------+---------------------------+---+             ////
////   | S | ADDY | CMD  |  Payload                  | P |             ////
////   +---+------+------+---------------------------+---+             ////
////   | S | 0xA0 | 0x02 | 0x00 | 0x01 | 0x02 | 0x03 | P |             ////
////   +---+------+------+---------------------------+---+             ////


But i can read only 2 bytes with i2cget. I wanted to verify that the bootloader is working fine before going any further.

Function to place pointer and to write data:
i2cset -y 1 0x50 0x01 0x22 0x11 0x00 0x00 i
i2cset -y 1 0x50 0x02 0x0FFF w

Function to read data:
i2cget -y 1 0x50 0x02 w
return : 0x0F02

I believe that the problem can be in the i2c protocol to drive the bootloader that i didn't well understand. Maybe you have other documentation / example than the short summary given in the .h file.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri Jul 03, 2020 1:09 am     Reply with quote

OK.

First before you call your 'get', you need to set the address to be used back
to where the data is written. It carries on incrementing.
Then I'd use the byte packet mode for all transmissions.

So:
i2cset -y 1 0x50 0x01 0x22 0x11 0x00 0x00 i
i2cset -y 1 0x50 0x02 0xFF 0x0F i

i2cset -y 1 0x50 0x01 0x22 0x11 0x00 0x00 i
i2cget -y 1 0x50 0x02 w

I'd probably suggest using i2Cdump to actually load a block of addresses
rather than working on single words like this.
bastirn



Joined: 08 Jan 2020
Posts: 17

View user's profile Send private message

PostPosted: Fri Jul 03, 2020 1:19 am     Reply with quote

As you can see on the following picture, i use this command but the result is not as expected.

The window on the right is the read of the program memory that i made after thoose i2c command.

https://engie-my.sharepoint.com/:i:/p/gd5731/Efqyo35P64VAu1Y4rl72lOEBoXOBQe0chqzUpVAwXNlQcw?e=yFlqVo

I think the problem is somewhere else. Can i send you my program by mail so you will know excatly what is done.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri Jul 03, 2020 1:31 am     Reply with quote

Why are you using -y?.
This overrides the bus synchronisation. Needed for EEPROM access.....
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri Jul 03, 2020 1:40 am     Reply with quote

I'd suspect you may have an issue with the turn round timing.

Now this driver is written to talk to things like chips, that can turn round
from a write transaction to a read transaction 'immediately'.
However on the PIC, the controller has to exit the interrupt and then get
back into the interrupt and load the byte before the next transaction can
occur. This is why when using a slave and master PIC together, it is vital
that the slave is running at least as fast as the master, or it cannot
load the byte in time for the master transaction.
Now the problem is that the I2Cget command loads the address byte,
command byte, and then automatically issues the bus restart, read
controller address, and starts to read. Your chip will need a pause of perhaps
20uSec between the read address, and actually being ready to send data.
Depending on the speed of your Linux system, this just won't be happening...
Result the address byte that is already in the control register on the
PIC gets sent back before a new byte is loaded... :(
bastirn



Joined: 08 Jan 2020
Posts: 17

View user's profile Send private message

PostPosted: Fri Jul 03, 2020 2:12 am     Reply with quote

The i2cget isn't the most important problem i have. It is the i2cset because i need to see that the program memory of the PIC is modified to validate that the bootloader is working fine. I will try to replace the bash command by a c pre-compiled program.

Can you affirm that the file "rom_write.c" is compatible with a PIC 16LF1829 ?
bastirn



Joined: 08 Jan 2020
Posts: 17

View user's profile Send private message

PostPosted: Tue Jul 07, 2020 10:07 am     Reply with quote

Hello,

I need some explanation about how work the command "write_program_memory" and what is needed to make it fully work for my PIC16LF1829.

I read the ccs manual carefully and i see a function "write_program_memory8" which only writes the LSB of the opcode. It perfectly describe my problem, i can't write the upper part of the opcode. I try this command, and, indeed it only modify the LSB. As the manual say:

"This function only writes the least significant byte
to each address in program memory. See write_program_memory() for a function that
can write all the data to each address in program memory."

I assume that I'm not using the function "write_program_memory" well.
Is there any particular config or way to use it.

Here is what i tried :
Code:

char val[2];
val[0]=0x31;
val[1]=0x32;
write_program_memory(0x00001122, &val, 2);
// also tried : write_program_memory(0x00001122, &val, 1);
// also tried : write_program_memory8(0x00001122, &val, 1);
// also tried : write_program_memory8(0x00001122, &val, 2);


Thank you for any answer,
Best regards,

Bastien
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed Jul 08, 2020 1:23 am     Reply with quote

Using the block based 'write_program_memory' function to just transfer
two bytes at a time, is a terrifyingly inefficient way of working. I'm perhaps
not surprised it has issues when used this way.

To write just two bytes, is handled much 'better' by the write_program_eeprom
function. On most chips I'd simply say 'use this'. However for some
(unknown)
reason, on your chip the erase_program_eeprom function is not present.
Now normally to use the write_program_eeprom, you need to erase every
64 bytes, and then use the write through this block. Then when you get to
the end of the block erase again. So the sequence is:
Code:

    if (address%64==0)
        erase_program_eeprom(address);
    write_program_eeprom(address, int16_val_to_write);

Now given the compiler is missing the erase function, I've simply generated
one:
Code:

#word EEADR=getenv("SFR:EEADRL")
#word EEDAT=getenv("SFR:EEDATL")
#byte EECON1=getenv("SFR:EECON1")
#byte EECON2=getenv("SFR:EECON2")
#bit EEPGD=getenv("BIT:EEPGD")
#bit FREE=getenv("BIT:FREE")
#bit CFGS=getenv("BIT:CFGS")
#bit WREN=getenv("BIT:WREN")
#bit WR=getenv("BIT:WR")

void erase_program_eeprom(unsigned int16 address)
{
   //erase an EEPROM page
   EEADR=address;
   disable_interrupts(GLOBAL); //ensure interrupts disabled for write
   CFGS=FALSE;
   EEPGD=TRUE;
   FREE=TRUE;
   WREN=TRUE;  //setup transaction
   EECON2=0x55;
   EECON2=0xAA; //unlock
   WR=TRUE; //trigger operation
   delay_cycles(1); //ignored instructions
   delay_cycles(1);
   WREN=FALSE;
   enable_interrupts(GLOBAL); //re-enable interrupts
}


Then a quick test using:
Code:

   unsigned int16 val=0x4241;
   erase_program_eeprom(0x1100); //erase the page containing the target
   write_program_eeprom(0x1122, val);


Merrily works, and results in the word at 0x1122 containing 0x0241, which
given the program memory is only 14bits wide, is exactly what would be
expected.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group