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

CCS I2C Bootloader

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
just280



Joined: 17 Apr 2012
Posts: 4
Location: UK

View user's profile Send private message

CCS I2C Bootloader
PostPosted: Tue Jul 15, 2025 9:20 am     Reply with quote

Okay I'm reaching out for help as I've run out of idea's. I'm using the CCS ex_i2c_bootloader which seems to run fine and using the debug will state when the bootloader is running or not. I have a simple test application that flashes an LED and outputs periodically on the UART, this works fine as a standalone. If however I add in the i2c_bootloader.h which imports the bootloader hex file the application just freezes. Any Ideas?

Bootloader
Code:
#include <16F18044.h>

#fuses  RSTOSC_HFINTRC_32MHZ
#fuses  NOMCLR
#fuses  NOWDT
#pin_select U1TX=pin_c3 // 8583 PCB
//#pin_select U1TX=pin_c5 // 8582 PCB
#pin_select U1RX=pin_c4
#pin_select SDA1IN=pin_B4
#pin_select SCL1IN=pin_B6
#use delay(internal=32000000)
#define  defined(__PCM__)
#define INT_I2C_BOOTLOADER INT_SSP
#use i2c(SLAVE, address=0xA0, SDA=PIN_B4, SCL=PIN_B6, STREAM=STREAM_I2C_BOOTLOADER) //SDA=PIN_C4, SCL=PIN_C3
 
#define BUTTON_PRESSED()        (!input(PIN_A2))
#define IS_BOOTLOADER_FORCED()  BUTTON_PRESSED()

#define DEBUG_BOOTLOADER

#ifdef DEBUG_BOOTLOADER
 // The following selects if the bootloader debug message are sent through the
 // ICD or with an RS232 connection.  If defined sent through the ICD, if not
 // defined sent with the RS232 connection.

 #ifdef DEBUG_BOOTLOADER
  #use rs232(xmit=PIN_C3, rcv=PIN_C4, ERRORS, BAUD=57600, BITS=8, stream=DEBUG_STREAM)  // 8583 PCB
  //#use rs232(xmit=PIN_C5, rcv=PIN_C4, ERRORS, BAUD=57600, BITS=8, stream=DEBUG_STREAM) // 8582 PCB
 #endif
 
 #define debug_printf      printf
 
 void debug_putc(char c)
 {
   fputc(c, DEBUG_STREAM);
 }
 
 #if defined(__PCM__)
  #define LOADER_END    0x47F
 #elif defined(__PCH__)
  #define LOADER_END    0x7FF
 #endif
#endif

//////////// end configuration /////////////

#define __bootloader    //tell i2c_bootloader.h that this is the bootloader program

#include "i2c_bootloader.h"

#include "rom_write.c"

#ifndef debug_printf
   #define debug_printf(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
#endif

void goto_application(void)
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_I2C_BOOTLOADER);

  #asm
   GOTO PROGRAM_APP_START
  #endasm
}

#ifndef IS_BOOTLOADER_FORCED
#define IS_BOOTLOADER_FORCED()   FALSE
#endif

#int_global
void isr(void)
{
   jump_to_isr(PROGRAM_ISR_START);
}

int1 g_PointerIsRam;
char *g_RamPointer;
unsigned int32 g_RomPointer;
unsigned int16 g_Magic;
unsigned int8 g_LastCmd;

inline void i2c_slave_interrupt(void)
{
   unsigned int8 incoming, state;
   static union
   {
      unsigned int8 b[4];
      unsigned int16 w[2];
      unsigned int32 dw;
   } val;
   static struct
   {
      unsigned int8 b[2]; //max data bytes in hex file is 32
      unsigned int8 index;
   } data;     
   
   state = i2c_isr_state(STREAM_I2C_BOOTLOADER);
   
   if(state <= 0x80)                      //Master is sending data
   {
      incoming = i2c_read(STREAM_I2C_BOOTLOADER, 2);          //Passing 2 as parameter, causes the function to read the SSPBUF without releasing the clock
   
      if (state == 1)
      { 
         //First received byte is the command
         g_LastCmd = incoming;
      }
      else if
      (
         (g_LastCmd == I2C_LOADER_COMMAND_GOTO_APPLICATION) &&
         ((state==2) || (state==3))
      )
      {
         val.b[state-2] = incoming;
         if ((state == 3) && (val.w[0] == I2C_LOADER_MAGIC))
         {
            debug_printf(debug_putc, "W=GOTO_APPLICATION\r\n");
            rom_flush();
           
            i2c_write(STREAM_I2C_BOOTLOADER, 0);  //dummy write to release the clock lines.  this does not actually TX
            clear_interrupt(INT_I2C_BOOTLOADER);
           
            goto_application();
         }
      }
      else if
      (
         (g_LastCmd == I2C_LOADER_COMMAND_ROM_ADDRESS) &&
         ((state>=2) || (state<=5))
      )
      {
         val.b[state-2] = incoming;
         if (state == 5)
         {
            g_RomPointer = val.dw;
            data.index = 0;
            debug_printf(debug_putc, "W=ADDRESS %LX\r\n", g_RomPointer);
         }
      }
      else if (g_LastCmd == I2C_LOADER_COMMAND_ROM_ACCESS)
      {
         data.b[data.index] = incoming;
         
         if(++data.index >= 2)
            data.index = 0;
     
         if ((g_RomPointer >= PROGRAM_APP_START) && (g_RomPointer < getenv("PROGRAM_MEMORY")))
         {
            if(data.index == 0)
               rom_modify(g_RomPointer, data.b, 2);
         }
         
         if(data.index == 0)
         {
           #if defined(__PCM__)
            g_RomPointer++;
           #elif defined(__PCH__)
            g_RomPointer += 2;
           #endif
         }
      }
     
      if (state != 0x80)
      {
         i2c_write(STREAM_I2C_BOOTLOADER, 0);  //dummy write to release the clock lines.  this does not actually TX
      }
   }
   
   if(state >= 0x80)                      //Master is requesting data
   {
      if (state == 0x80)
      {
         g_PointerIsRam = TRUE;
         if (g_LastCmd == I2C_LOADER_COMMAND_ROM_ADDRESS)
         {
            debug_printf(debug_putc, "R=ROM_ADDRESS %LX\r\n", g_RomPointer);
            g_RamPointer = &g_RomPointer;
         }
         else if (g_LastCmd == I2C_LOADER_COMMAND_ROM_ACCESS)
         {
            debug_printf(debug_putc, "R=ROM_ACCESS %LX\r\n", g_RomPointer);
            g_PointerIsRam = FALSE;
            rom_flush();
         }
         else if (g_LastCmd == I2C_LOADER_COMMAND_GOTO_BOOTLOADER)
         {
            debug_printf(debug_putc, "R=GOTO_BOOTLOADER\r\n");
            g_RamPointer = &g_Magic;
         }
         
         i2c_write(STREAM_I2C_BOOTLOADER, g_LastCmd);
      }
      else
      {
         if (g_RamPointer)
         {
            i2c_write(STREAM_I2C_BOOTLOADER, *g_RamPointer++);
         }
         else
         {
            read_program_memory(g_RomPointer, &val.b[0], 1);
            g_RomPointer++;
            i2c_write(STREAM_I2C_BOOTLOADER, val.b[0]);
         }
      }
   }
   
   clear_interrupt(INT_I2C_BOOTLOADER);
}

void bootloader_loop(void)
{
   g_RomPointer = 0;
   g_Magic = I2C_LOADER_MAGIC;
   g_LastCmd = I2C_LOADER_COMMAND_GOTO_BOOTLOADER;
   
   rom_init();
   
   debug_printf(debug_putc, "BOOTLOADER_STARTED\r\n");
   
   for(;;)
   {
      if (interrupt_active(INT_I2C_BOOTLOADER))
      {
         i2c_slave_interrupt();
      }
   }
}

#org PROGRAM_BOOTLOADER_START, PROGRAM_BOOTLOADER_START+0xf
void proxy_bootloader_start(void)
{
   bootloader_loop();
}

void main(void)
{
   if (IS_BOOTLOADER_FORCED())
   {
      debug_printf(debug_putc, "BOOTLOADER_FORCED\r\n");

      bootloader_loop();
   }
   
   debug_printf(debug_putc, "NO_BOOTLOADER\r\n");

   goto_application();
}


Application Code

Code:

#include <16F18044.h>
#device ADC=10

#FUSES   NOWDT
#FUSES   RSTOSC_HFINTRC_32MHZ
#FUSES   NOMCLR
#FUSES   NOCLKOUT

#use delay(internal=32000000,restart_wdt)

#pin_select U1TX=pin_c3 // 8583 PCB
//#pin_select U1TX=pin_c5 // 8582 PCB
#pin_select U1RX=pin_c4
#use rs232(baud=57600,xmit=PIN_C3,rcv=PIN_C4,bits=8,errors,STREAM=UART) // 8583 PCB
//#use rs232(baud=57600,xmit=PIN_C5,rcv=PIN_C4,bits=8,errors,STREAM=UART) //8582 PCB

#pin_select SDA1IN=pin_B4
#pin_select SCL1IN=pin_B6
#define INT_I2C_BOOTLOADER INT_SSP
//#use i2c(Master,sda=PIN_B4,scl=PIN_B6,FORCE_SW,SLOW,STREAM=STREAM_I2C_BOOTLOADER)
#use i2c(SLAVE, address=0xA0, SDA=PIN_B4, SCL=PIN_B6, STREAM=STREAM_I2C_BOOTLOADER)

//#define  UART_DEBUG
#define  defined(__PCM__)
#define DEBUG_BOOTLOADER
#define LOADER_END    0x47F
//#include <85800623.h>
//#include <bootloader.h> // UART version
#include <i2c_bootloader.h>

#define  clk_test          pin_a1
#define  encoder_switch    pin_a2
#define  standby_led_green pin_c2
#define  standby_led_red   pin_c1
#define  RGB_led_red       pin_a1   //a1
#define  RGB_led_green     pin_c5   //c5
#define  RGB_led_blue      pin_a0   //a0
//#define  test_pin2      pin_b7
//#define  test_pin1      pin_b6


#define  OFF      0
#define  ON       1
#define  PAUSE    0
#define  PLAYING  1
#define  STANDBY  0
#define  WORKING  1

#define  NO_FLASH    0
#define  SLOW_FLASH  1
#define  FAST_FLASH  2

#define  RED      1
#define  BLUE     2
#define  GREEN    3
#define  PURPLE   4
#define  WHITE    5
#define  ORANGE   6

#define  VERSION  2.0

#define debug_printf      printf

void debug_putc(char c)
{
   fputc(c, UART);
}

int8  led_toggle;
int8  on_off_status;

int8  switch_latch;

int16 read_count;
int16 switch_debounce;
int16 switch_on_delay;
int16 play_status_count;
int16 m_sec_count;
int16 sec_count;


#INT_TIMER2
void  TIMER2_isr(void)
{
   read_count++;
   switch_debounce++;
   play_status_count++;
   //status_flash_count++;

   switch_on_delay++;
   if(switch_on_delay>2999)  switch_on_delay=3000;
   
   m_sec_count++;
   if(m_sec_count>9999)
   {
      m_sec_count=0;
      sec_count++;
   }

}

#use timer(tick=10ms, bits=16, ISR)

#INT_SSP
void i2c_slave_interrupt()
{
   unsigned int8 state, read;

   state = i2c_isr_state(STREAM_I2C_BOOTLOADER);

   if(state <= 0x80) //Master is sending data
   {
      if(state == 0x80)
         read = i2c_read(STREAM_I2C_BOOTLOADER, 2);  //Passing 2 as parameter, causes the function to read the SSPBUF without releasing the clock
      else
         read = i2c_read(STREAM_I2C_BOOTLOADER);
         
      if (state < 0x80)
      {
         i2c_isr_bootload_check(state, read);
      }
   }

   if(state >= 0x80)                      //Master is requesting data
   {
      i2c_write(STREAM_I2C_BOOTLOADER, 0);  //we don't have any data, write dummy data
   }
}




void main()
{
   //setup_timer_2(T2_DIV_BY_32 | T2_CLK_INTERNAL,255,1);      //1.0 ms overflow, 1.0 ms interrupt
   setup_timer_2(T2_DIV_BY_16 | T2_CLK_INTERNAL,49,1);      //100 us overflow, 100 us interrupt
   //setup_timer_4(T4_DIV_BY_128 | T4_CLK_INTERNAL,255,1);      //1.0 ms overflow, 1.0 ms interrupt
   enable_interrupts(INT_TIMER2);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   set_tris_c(0x11);
   //port_c_pullups(0x00);

   //****** inialise outputs ******

   output_high(RGB_led_red);
   output_low(RGB_led_green);
   output_high(RGB_led_blue);

   delay_ms(200);


   on_off_status=OFF;
   debug_printf(debug_putc, "PROGRAM RUNNING\r\n");

   while(TRUE)
   {
      restart_wdt();
     
      unsigned int16 tick;
     
      tick = get_ticks();
   
      for(;;)
      {
         if ((get_ticks() - tick) >= TICKS_PER_SECOND/2)
         {
            tick = get_ticks();
         }
      }
     
      if((!input(encoder_switch) && switch_debounce>1999) && switch_latch==0)
      {
         switch_latch=1;
         
         if(on_off_status==OFF)
         {
            on_off_status=ON;
            output_low(RGB_led_red);
            output_high(standby_led_red); // off
            output_low(standby_led_green); // on
         }
         else
         {
            on_off_status=OFF;
            output_high(RGB_led_red);
            output_low(standby_led_red); // on
            output_high(standby_led_green); // off
         }
      }
      if(input(encoder_switch))  { switch_latch=0; switch_debounce=0; }
     
      if(read_count>9999)
      {
         read_count=0;
         if(led_toggle>0)  { led_toggle=0; output_low(RGB_led_green); }
         else  { led_toggle=1; output_high(RGB_led_green); }
         debug_printf(debug_putc, "PROGRAM RUNNING\r\n");
      }
     
   }

}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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