SSブログ

HCS08 FLASH書き込み 地獄のリベンジ編 [HCS08]

#259
ならばこれでどうだ!
HCS08のアセンブラの出来に関しては、もう知らんよ!。

/****************************************************************/
/* FLASH ROM書き換え処理                                        */
/* ポインタ型を無理やり整数型で扱って気持ちの悪いところを修正   */
/* アセンブラで記述し直し                                           */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/

#include "derivative.h" /* include peripheral declarations */
#include <string.h>
#define Page_Erase   ((unsigned char(*)(volatile unsigned char *, unsigned char))(pgm))
#define Program_Byte ((unsigned char(*)(volatile unsigned char *, unsigned char))(pgm))

/****************************************************************/
/* 特定のFLASH領域に書き込み/消去を行う                         */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
volatile static unsigned char flash_era_wrt( volatile unsigned char *adr, unsigned char data )
{
#asm
  PSHA ; 

  LDA #0x10  ; FACCERRが立っているかチェックする
  BIT _FSTAT ; FACCERRが立っているかチェックする
  BEQ _NEXT_01 ; 立っていない時は_NEXT_01にブランチ
  ORA _FSTAT ; FACCERRが立っているならクリアして置く
  STA _FSTAT ; 書き戻し

_NEXT_01:  ; 該当する領域にデータを代入する。
  PULA
  STA ,X

  ; コマンド書き込み。最初はERASEコマンド
  LDA #0x40
  STA _FCMD

  ; FCFBEFに1を書き込み
  LDHX @_FSTAT ;

  LDA ,X     ; FCFBEFを1にする
  ORA #0x80  ; FCFBEFを1にする
  STA ,X     ; 書き戻し


  BRN _NEXT_02 ; 4バスサイクル消費する※修正
_NEXT_02 :
  NOP

  ; FACCERRとFVIOLがエラーでない事を確認する
  LDA ,X
  AND #0x30    ; FACCERRとFVIOLの該当bit
  BEQ _NEXT_03 ; 立っていない時は_NEXT_03にブランチ
  LDA #0xff    ; 戻り値を0xffにする※修正
  RTS


  ; FCCFが0の間はコマンド処理中
_NEXT_03 :
  LDA ,X
  AND #0x40    ; FCCFの該当bit
  BEQ _NEXT_03 ; 0の間は_NEXT_03にブランチ
#endasm

  return 0;
}

/****************************************************************/
/* 文字列をFLASH領域に書き込む                                  */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
int FlashCopy( void *adr, void *data, unsigned short size )
{
  unsigned char temp;
  char *ptr = (char *)data;
  volatile unsigned char pgm[ 46 ];

  /*フラッシュ書き込みコードのコピー*/
  (void)memcpy( pgm, flash_era_wrt, sizeof(pgm) );
  pgm[ 0x11 ] = 0x20;  /*コマンドをbyte writeコマンドに変更する*/

  /*フラッシュ書き込み*/
  for( ; size > 0; size-- )
  {
    if( *ptr != 0xff )
    {
      temp = Program_Byte( (volatile unsigned char *)adr, *ptr );
      if( temp == 0xff ) return (-1);
    }

    ((char *)adr)++;
    ptr++;
  }
  return 0;
}

/****************************************************************/
/* 引数のアドレスが存在するブロックを消去する                   */
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/
int FlashErase( void *adr )
{
  unsigned char temp;
  volatile unsigned char pgm[ 46 ];

  /*フラッシュ消去コードのコピー*/
  (void)memcpy( pgm, flash_era_wrt, sizeof(pgm) );

  /*フラッシュ消去*/
  temp = Page_Erase( (volatile unsigned char *)adr, 0x00 );

  if( temp == 0xff ) return (-1);
  return 0;
}

/****************************************************************/
/*                  Copyright (c) せくすぃ部長 since 2007/09/18 */
/****************************************************************/


nice!(0)  コメント(2)  トラックバック(0) 

nice! 0

コメント 2

のりたん

気になったところをいくつか。

> ORA _FSTAT ; FACCERRが立っているならクリアして置く
> STA _FSTAT ; 書き戻し
ORAは、不要です。ORAがあるとすべてのフラグがクリアされてしまいます。

> LDA ,X ; FCFBEFを1にする
> ORA #0x80 ; FCFBEFを1にする
> STA ,X ; 書き戻し
これも同じです。

# ということは、オリジナルのプログラムも変なのか?

> JMP _NEXT_02 ; 4バスサイクル消費する
> _NEXT_02 :
この関数はFLASHに展開されるから、絶対アドレスJUMPはまずいでしょう。私のお勧めは、以下の3バイトです。
> BRN *
> NOP
by のりたん (2007-09-21 12:50) 

hamayan

> この関数はFLASHに展開されるから、絶対アドレスJUMPはまずいでしょう。

ぬあ!本当だ、うっかりしていた。nopを4つ並べるよりも低コストな命令見つけた!と浮かれていてそればっかりになっていた。
なんで動いたんだ?。

FSTATはビット操作命令が使えないので、うーんそうすると関係ない所をマスクして書き戻さないといけないのか?。

> # ということは、オリジナルのプログラムも変なのか?
そう言えば気になる点も有る。
オリジナルはマシン語だからコメントアウトされているCソースをコンパイルして動かした時、0xffの書き込みで失敗していたんですよね。別に0xffなら書き込む理由がないので、条件式で避けるようにしていたんですが。
※マシン語で動かしている時はこれが無かった。
by hamayan (2007-09-21 13:46) 

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。