You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

185 lines
4.1 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2015 by Ivan Meleca *
  3. * ivan@artekit.eu *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. ***************************************************************************/
  15. /* Params:
  16. * r0 = flash destination address, status
  17. * r1 = longword count
  18. * r2 = workarea start address
  19. * r3 = workarea end address
  20. */
  21. .text
  22. .cpu cortex-m0plus
  23. .code 16
  24. .thumb_func
  25. .align 2
  26. /* r5 = rp
  27. * r6 = wp, tmp
  28. * r7 = tmp
  29. */
  30. wait_fifo:
  31. ldr r6, [r2, #0] /* read wp */
  32. cmp r6, #0 /* abort if wp == 0 */
  33. beq exit
  34. ldr r5, [r2, #4] /* read rp */
  35. cmp r5, r6 /* wait until rp != wp */
  36. beq wait_fifo
  37. ldr r6, fstat /* Clear error flags */
  38. mov r7, #48
  39. strb r7, [r6]
  40. ldr r6, fccobix /* FCCOBIX = 0 */
  41. mov r7, #0
  42. strb r7, [r6]
  43. ldr r6, fccobhi /* Program FLASH command */
  44. mov r7, #6 /* FCCOBHI = 6 */
  45. strb r7, [r6]
  46. lsr r7, r0, #16 /* FCCOBLO = flash destination address >> 16 */
  47. ldr r6, fccoblo
  48. strb r7, [r6]
  49. ldr r6, fccobix /* Index for lower byte address bits[15:0] */
  50. mov r7, #1
  51. strb r7, [r6] /* FCCOBIX = 1*/
  52. uxtb r7, r0 /* Memory address bits[15:0] */
  53. ldr r6, fccoblo
  54. strb r7, [r6] /* FCCOBLO = flash destination address */
  55. lsr r7, r0, #8
  56. ldr r6, fccobhi
  57. strb r7, [r6] /* FCCOBHI = flash destination address >> 8 */
  58. ldr r6, fccobix /* FCCOBIX = 2 */
  59. mov r7, #2
  60. strb r7, [r6]
  61. ldrb r7, [r5, #1] /* FCCOBHI = rp >> 8 */
  62. ldr r6, fccobhi
  63. strb r7, [r6]
  64. ldrb r7, [r5] /* FCCOBLO = rp */
  65. ldr r6, fccoblo
  66. strb r7, [r6]
  67. ldr r6, fccobix /* FCCOBIX = 3 */
  68. mov r7, #3
  69. strb r7, [r6]
  70. ldrb r7, [r5, #3] /* FCCOBHI = rp >> 24 */
  71. ldr r6, fccobhi
  72. strb r7, [r6]
  73. ldrb r7, [r5, #2] /* FCCOBLO = rp >> 16 */
  74. ldr r6, fccoblo
  75. strb r7, [r6]
  76. sub r1, r1, #1 /* Two words (4 bytes) queued, decrement counter */
  77. add r0, r0, #4 /* flash address += 4 */
  78. add r5, r5, #4 /* rp += 4 */
  79. cmp r5, r3 /* Wrap? */
  80. bcc no_wrap
  81. mov r5, r2
  82. add r5, r5, #8
  83. no_wrap:
  84. cmp r1, #0 /* Done? */
  85. beq execute
  86. ldr r6, [r2, #0] /* read wp */
  87. cmp r6, r5
  88. beq execute /* execute if rp == wp */
  89. ldr r6, fccobix /* FCCOBIX = 4 */
  90. mov r7, #4
  91. strb r7, [r6]
  92. ldrb r7, [r5, #1] /* FCCOBHI = rp >> 8 */
  93. ldr r6, fccobhi
  94. strb r7, [r6]
  95. ldrb r7, [r5] /* FCCOBLO = rp */
  96. ldr r6, fccoblo
  97. strb r7, [r6]
  98. ldr r6, fccobix /* FCCOBIX = 5 */
  99. mov r7, #5
  100. strb r7, [r6]
  101. ldrb r7, [r5, #3] /* FCCOBHI = rp >> 24 */
  102. ldr r6, fccobhi
  103. strb r7, [r6]
  104. ldrb r7, [r5, #2] /* FCCOBLO = rp >> 16 */
  105. ldr r6, fccoblo
  106. strb r7, [r6]
  107. sub r1, r1, #1 /* Two words (4 bytes) queued, decrement counter */
  108. add r0, r0, #4 /* flash address += 4 */
  109. add r5, r5, #4 /* rp += 4 */
  110. cmp r5, r3 /* Wrap? */
  111. bcc execute
  112. mov r5, r2
  113. add r5, r5, #8
  114. execute:
  115. ldr r6, fstat /* Launch the command */
  116. mov r7, #128
  117. strb r7, [r6]
  118. wait_busy:
  119. ldr r6, fstat
  120. ldrb r6, [r6] /* Wait until finished */
  121. tst r6, r7
  122. beq wait_busy
  123. mov r7, #48 /* Check error */
  124. tst r6, r7
  125. bne error
  126. mov r6, #0 /* Clear error */
  127. str r5, [r2, #4] /* Store rp */
  128. cmp r1, #0 /* Done? */
  129. beq done
  130. b wait_fifo
  131. error:
  132. mov r0, #0
  133. str r0, [r2, #4] /* set rp = 0 on error */
  134. done:
  135. mov r0, r6 /* Set result code */
  136. bkpt #0
  137. .align 2
  138. fstat:
  139. .word 0
  140. fccobix:
  141. .word 0
  142. fccobhi:
  143. .word 0
  144. fccoblo:
  145. .word 0