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.

77 lines
2.6KB

  1. /***************************************************************************
  2. * Copyright (C) 2011 by Andreas Fritiofson *
  3. * andreas.fritiofson@gmail.com *
  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. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
  19. ***************************************************************************/
  20. .text
  21. .syntax unified
  22. .cpu cortex-m0
  23. .thumb
  24. .thumb_func
  25. .global write
  26. /* Params:
  27. * r0 - flash base (in), status (out)
  28. * r1 - count (halfword-16bit)
  29. * r2 - workarea start
  30. * r3 - workarea end
  31. * r4 - target address
  32. * Clobbered:
  33. * r5 - rp
  34. * r6 - wp, tmp
  35. * r7 - tmp
  36. */
  37. #define STM32_FLASH_SR_OFFSET 0x0c /* offset of SR register from flash reg base */
  38. wait_fifo:
  39. ldr r6, [r2, #0] /* read wp */
  40. cmp r6, #0 /* abort if wp == 0 */
  41. beq exit
  42. ldr r5, [r2, #4] /* read rp */
  43. cmp r5, r6 /* wait until rp != wp */
  44. beq wait_fifo
  45. ldrh r6, [r5] /* "*target_address++ = *rp++" */
  46. strh r6, [r4]
  47. adds r5, #2
  48. adds r4, #2
  49. busy:
  50. ldr r6, [r0, #STM32_FLASH_SR_OFFSET] /* wait until BSY flag is reset */
  51. movs r7, #1
  52. tst r6, r7
  53. bne busy
  54. movs r7, #0x14 /* check the error bits */
  55. tst r6, r7
  56. bne error
  57. cmp r5, r3 /* wrap rp at end of buffer */
  58. bcc no_wrap
  59. mov r5, r2
  60. adds r5, #8
  61. no_wrap:
  62. str r5, [r2, #4] /* store rp */
  63. subs r1, r1, #1 /* decrement halfword count */
  64. cmp r1, #0
  65. beq exit /* loop if not done */
  66. b wait_fifo
  67. error:
  68. movs r0, #0
  69. str r0, [r2, #4] /* set rp = 0 on error */
  70. exit:
  71. mov r0, r6 /* return status in r0 */
  72. bkpt #0