S&B Volcano vaporizer remote control with Pi Pico W
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * fat_disk.c
  3. *
  4. * Copyright (c) 2022 - 2023 Thomas Buck (thomas@xythobuz.de)
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * See <http://www.gnu.org/licenses/>.
  17. */
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include "pico/stdlib.h"
  22. #include "ff.h"
  23. #include "diskio.h"
  24. #include "config.h"
  25. #include "log.h"
  26. #include "debug.h"
  27. #include "fat_disk.h"
  28. #include "pack_data.h"
  29. static uint8_t disk[DISK_BLOCK_COUNT * DISK_BLOCK_SIZE];
  30. void fat_disk_init(void) {
  31. BYTE work[FF_MAX_SS];
  32. FRESULT res = f_mkfs("", 0, work, sizeof(work));
  33. if (res != FR_OK) {
  34. debug("error: f_mkfs returned %d", res);
  35. return;
  36. }
  37. if (debug_msc_mount() != 0) {
  38. debug("error mounting disk");
  39. return;
  40. }
  41. // maximum length: 11 bytes
  42. f_setlabel("DEBUG DISK");
  43. FIL file;
  44. res = f_open(&file, "README.md", FA_CREATE_ALWAYS | FA_WRITE);
  45. if (res != FR_OK) {
  46. debug("error: f_open returned %d", res);
  47. } else {
  48. char readme[1024];
  49. size_t pos = 0;
  50. pos += snprintf(readme + pos, 1024 - pos, "# Volcano Remote Control Gadget\r\n");
  51. pos += snprintf(readme + pos, 1024 - pos, "\r\n");
  52. pos += snprintf(readme + pos, 1024 - pos, "Project by Thomas Buck <thomas@xythobuz.de>\r\n");
  53. pos += snprintf(readme + pos, 1024 - pos, "Licensed under GPLv3.\r\n");
  54. pos += snprintf(readme + pos, 1024 - pos, "See included src.tar.xz for sources.\r\n");
  55. pos += snprintf(readme + pos, 1024 - pos, "Repo at https://git.xythobuz.de/thomas/sb-py\r\n");
  56. size_t len = strlen(readme);
  57. UINT bw;
  58. res = f_write(&file, readme, len, &bw);
  59. if ((res != FR_OK) || (bw != len)) {
  60. debug("error: f_write returned %d", res);
  61. }
  62. res = f_close(&file);
  63. if (res != FR_OK) {
  64. debug("error: f_close returned %d", res);
  65. }
  66. }
  67. res = f_open(&file, "src.tar.xz", FA_CREATE_ALWAYS | FA_WRITE);
  68. if (res != FR_OK) {
  69. debug("error: f_open returned %d", res);
  70. } else {
  71. UINT bw;
  72. UINT len = 0;
  73. while (1) {
  74. debug("write %d", len);
  75. res = f_write(&file, data_tar_xz + len, data_tar_xz_len - len, &bw);
  76. if (bw == 0) {
  77. debug("abort");
  78. break;
  79. }
  80. len += bw;
  81. if (res != FR_OK) {
  82. debug("error: f_write returned %d", res);
  83. break;
  84. }
  85. if (bw == data_tar_xz_len) {
  86. break;
  87. }
  88. }
  89. res = f_close(&file);
  90. if (res != FR_OK) {
  91. debug("error: f_close returned %d", res);
  92. }
  93. }
  94. if (debug_msc_unmount() != 0) {
  95. debug("error unmounting disk");
  96. }
  97. }
  98. uint8_t *fat_disk_get_sector(uint32_t sector) {
  99. return disk + (sector * DISK_BLOCK_SIZE);
  100. }
  101. /*
  102. * FatFS ffsystem.c
  103. */
  104. void* ff_memalloc(UINT msize) {
  105. return malloc((size_t)msize);
  106. }
  107. void ff_memfree(void* mblock) {
  108. free(mblock);
  109. }
  110. /*
  111. * FatFS diskio.c
  112. */
  113. DSTATUS disk_status(BYTE pdrv) {
  114. if (pdrv != 0) {
  115. debug("invalid drive number %d", pdrv);
  116. return STA_NODISK;
  117. }
  118. return 0;
  119. }
  120. DSTATUS disk_initialize(BYTE pdrv) {
  121. if (pdrv != 0) {
  122. debug("invalid drive number %d", pdrv);
  123. return STA_NODISK;
  124. }
  125. return 0;
  126. }
  127. DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) {
  128. if (pdrv != 0) {
  129. debug("invalid drive number %d", pdrv);
  130. return RES_PARERR;
  131. }
  132. if ((sector + count) > DISK_BLOCK_COUNT) {
  133. debug("invalid read ((%lu + %u) > %u)", sector, count, DISK_BLOCK_COUNT);
  134. return RES_ERROR;
  135. }
  136. memcpy(buff, disk + (sector * DISK_BLOCK_SIZE), count * DISK_BLOCK_SIZE);
  137. return RES_OK;
  138. }
  139. DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count) {
  140. if (pdrv != 0) {
  141. debug("invalid drive number %d", pdrv);
  142. return RES_PARERR;
  143. }
  144. if ((sector + count) > DISK_BLOCK_COUNT) {
  145. debug("invalid read ((%lu + %u) > %u)", sector, count, DISK_BLOCK_COUNT);
  146. return RES_ERROR;
  147. }
  148. memcpy(disk + (sector * DISK_BLOCK_SIZE), buff, count * DISK_BLOCK_SIZE);
  149. return RES_OK;
  150. }
  151. DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) {
  152. if (pdrv != 0) {
  153. debug("invalid drive number %d", pdrv);
  154. return RES_PARERR;
  155. }
  156. switch (cmd) {
  157. case GET_SECTOR_COUNT:
  158. *((LBA_t *)buff) = DISK_BLOCK_COUNT;
  159. break;
  160. case GET_SECTOR_SIZE:
  161. *((WORD *)buff) = DISK_BLOCK_SIZE;
  162. break;
  163. case GET_BLOCK_SIZE:
  164. *((DWORD *)buff) = 1; // non flash memory media
  165. break;
  166. }
  167. return RES_OK;
  168. }