kspi.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #include<linux/string.h>
  2. #include "kspi.h"
  3. #include "kfile.h"
  4. //uint8_t mode = SPI_MODE_3;
  5. //uint8_t bits = 8;
  6. //uint32_t speed = 1000000;
  7. #define CMD_ACK 0xcc
  8. #define CMD_NAK 0x33
  9. #define CMD_GET_FIRMWARE_VERSION 0x51
  10. #define CMD_GET_I2C 0x56
  11. #define CMD_SET_I2C 0x57
  12. #define CMD_GET_ADDRESS 0x58
  13. #define CMD_SET_ADDRESS 0x59
  14. #define CMD_SET_BACKLIGHT 0x5B
  15. #define CMD_GET_UPTIME 0x5C
  16. #define CMD_GET_ADC 0x5A
  17. static unsigned char transfer_1(struct file *pf, unsigned char Tx)
  18. {
  19. int ret;
  20. uint8_t tx = Tx;
  21. uint8_t rx;
  22. struct spi_ioc_transfer tr =
  23. {
  24. .tx_buf = (unsigned long) &tx,
  25. .rx_buf = (unsigned long) &rx,
  26. .len = 1,
  27. .delay_usecs = 0,
  28. .speed_hz = 1000000,
  29. .bits_per_word = 8,
  30. };
  31. ret = kf_ioctl(pf, SPI_IOC_MESSAGE(1), (unsigned long)&tr);
  32. if(ret < 0)
  33. {
  34. printk(KERN_ALERT "transfer_1 failed: %d\n", ret);
  35. return 0;
  36. }
  37. return rx;
  38. }
  39. static int WaitACK(struct file *pf)
  40. {
  41. unsigned char rcv = 0;
  42. int i = 0;
  43. // warten auf ACK
  44. while ((rcv != CMD_ACK) && (rcv != CMD_NAK) && i < 1000/*(time(NULL) < endwait)*/)
  45. {
  46. rcv = transfer_1(pf, 0);
  47. ++i;
  48. }
  49. return rcv;
  50. }
  51. int SendCMD(struct file *pf, unsigned char Cmd, unsigned char DataLen, unsigned char *Data)
  52. {
  53. unsigned char Len = DataLen + 3;
  54. unsigned char Chk = Cmd;
  55. int i;
  56. // printk(KERN_ALERT "%s, Ctx: \"%s\"-(%d)\n", __FUNCTION__, current->comm, current->pid);
  57. for (i = 0; i < DataLen; i++)
  58. Chk += *(Data + i);
  59. transfer_1(pf, Len);
  60. transfer_1(pf, Chk);
  61. transfer_1(pf, Cmd);
  62. for (i = 0; i < DataLen; i++) {
  63. transfer_1(pf, *(Data + i));
  64. }
  65. return WaitACK(pf);
  66. }
  67. int ReadCmd(struct file *pf, int MaxLen, unsigned char *Data)
  68. {
  69. unsigned char rcv = 0;
  70. int i = 0;
  71. int len;
  72. unsigned char chksum = 0, chkval = 0;
  73. int ret = 0;
  74. // printk(KERN_ALERT "%s, Ctx: \"%s\"-(%d)\n", __FUNCTION__, current->comm, current->pid);
  75. // warten auf längenbyte der Antwort
  76. while((rcv == 0) && (i < 2000))
  77. {
  78. rcv = transfer_1(pf, 0);
  79. ++i;
  80. }
  81. // daten einlesen
  82. len = rcv;
  83. for(i = 0; i < (len - 1); ++i)
  84. {
  85. rcv = transfer_1(pf, 0);
  86. //printf("%2.2X-", rcv);
  87. if(i == 0) //CHKSUM
  88. {
  89. chkval = 0;
  90. chksum = rcv;
  91. }
  92. else
  93. {
  94. chkval += rcv;
  95. if((i - 1) < MaxLen)
  96. *(Data + i - 1) = rcv;
  97. }
  98. }
  99. if(chksum != chkval)
  100. {
  101. ret = -1;
  102. }
  103. else
  104. {
  105. ret = len - 2;
  106. }
  107. return ret;
  108. }
  109. int CmdGetFirmwareVersion(struct file *pf, int *Hw, int *Sw)
  110. {
  111. int ret = -1;
  112. int len = 0;
  113. // printk(KERN_ALERT "%s, Ctx: \"%s\"-(%d)\n", __FUNCTION__, current->comm, current->pid);
  114. ret = SendCMD(pf, CMD_GET_FIRMWARE_VERSION , 0, NULL);
  115. if(ret == CMD_ACK)
  116. {
  117. unsigned char Data[255];
  118. memset(Data, 0, sizeof(Data));
  119. if((len = ReadCmd(pf, sizeof(Data), Data)) == 9)
  120. {
  121. int HW_Version, SW_Version;
  122. HW_Version = (Data[1] << 24) + (Data[2] << 16) + (Data[3] << 8) + Data[4];
  123. SW_Version = (Data[5] << 24) + (Data[6] << 16) + (Data[7] << 8) + Data[8];
  124. if(Hw != NULL) *Hw = HW_Version;
  125. if(Sw != NULL) *Sw = SW_Version;
  126. ret = 0;
  127. } else {
  128. printk(KERN_ALERT "LEN = %d\n", len);
  129. }
  130. }
  131. transfer_1(pf, CMD_ACK); /* Testweise immer ACK */
  132. return ret;
  133. }
  134. unsigned long long CmdGetUptime(struct file *pf)
  135. {
  136. unsigned long long ret = 0;
  137. int len = 0;
  138. ret = SendCMD(pf, CMD_GET_UPTIME , 0, NULL);
  139. if(ret == CMD_ACK)
  140. {
  141. unsigned char Data[255];
  142. ret = 0; //ACK erhalten soweit gut
  143. memset(Data, 0, sizeof(Data));
  144. if((len = ReadCmd(pf, sizeof(Data), Data)) == 9)
  145. {
  146. ret = (unsigned long long)(Data[1]) << 56 |
  147. (unsigned long long)(Data[2]) << 48 |
  148. (unsigned long long)(Data[3]) << 40 |
  149. (unsigned long long)(Data[4]) << 32 |
  150. (unsigned long long)(Data[5]) << 24 |
  151. (unsigned long long)(Data[6]) << 16 |
  152. (unsigned long long)(Data[7]) << 8 |
  153. (unsigned long long)(Data[8]);
  154. }
  155. transfer_1(pf, CMD_ACK); /**< ACK */
  156. }
  157. return ret;
  158. }
  159. int CmdGetAddress(struct file *pf, unsigned int Addr, unsigned int *Value)
  160. {
  161. int ret = -1;
  162. int len = 0;
  163. unsigned char ReadADDRESS[4];
  164. unsigned char DestData[10];
  165. int DestLen = sizeof(DestData);
  166. ReadADDRESS[0] = (unsigned char)((Addr >> 24) & 0xff);
  167. ReadADDRESS[1] = (unsigned char)((Addr >> 16) & 0xff);
  168. ReadADDRESS[2] = (unsigned char)((Addr >> 8) & 0xff);
  169. ReadADDRESS[3] = (unsigned char)(Addr & 0xff);
  170. ret = SendCMD(pf, CMD_GET_ADDRESS , sizeof(ReadADDRESS), ReadADDRESS);
  171. if(ret == CMD_ACK) {
  172. unsigned char Data[255];
  173. ret = 0; //ACK erhalten soweit gut
  174. memset(Data, 0, sizeof(Data));
  175. if((len = ReadCmd(pf, sizeof(Data), Data)) > 0) {
  176. memcpy(DestData, Data + 1, ((len - 1) <= DestLen)?(len - 1):DestLen);
  177. ret = len - 1;
  178. }
  179. transfer_1(pf, CMD_ACK); /**< ACK */
  180. }
  181. if(Value)
  182. *Value = (unsigned int)(DestData[0]) << 24 |
  183. (unsigned int)(DestData[1]) << 16 |
  184. (unsigned int)(DestData[2]) << 8 |
  185. (unsigned int)(DestData[3]);
  186. return ret;
  187. }
  188. void getUPTIME(struct file *pf, unsigned int Addr, int nFwVersion)
  189. {
  190. unsigned int dd;
  191. int day, hour, min;
  192. if(nFwVersion >= 0x113 )
  193. {
  194. unsigned long long Data;
  195. Data = CmdGetUptime(pf);
  196. day = Data / 86400000;
  197. dd = Data - day * 86400000;
  198. hour = dd / 3600000;
  199. dd -= hour * 3600000;
  200. min = dd / 60000;
  201. }
  202. else
  203. {
  204. unsigned int Data = 0xFFFFFFFF;
  205. CmdGetAddress(pf, Addr, &Data);
  206. day = Data / 86400000;
  207. dd = Data - day * 86400000;
  208. hour = dd / 3600000;
  209. dd -= hour * 3600000;
  210. min = dd / 60000;
  211. }
  212. // printf("%d d %2.2d:%2.2d\n", day, hour, min);
  213. }
  214. static const int g_kty_tab[][2] =
  215. {
  216. {199, 1250},
  217. {351, 1000},
  218. {643, 750},
  219. {1185, 500},
  220. {2048, 250},
  221. {3025, 0},
  222. {3705, -250}
  223. };
  224. #define KTY_TAB_LEN ((sizeof g_kty_tab / sizeof g_kty_tab[0]) - 1)
  225. int lin_kty(int widerstand)
  226. {
  227. int i;
  228. if(widerstand <= g_kty_tab[0][0])
  229. return(g_kty_tab[0][1]);
  230. if(widerstand >= g_kty_tab[KTY_TAB_LEN][0])
  231. return(g_kty_tab[KTY_TAB_LEN][1]);
  232. /* Suchen des nächsten Tabelleneintrags */
  233. for(i=1; i<=KTY_TAB_LEN; i++)
  234. {
  235. if(g_kty_tab[i][0] >= widerstand)
  236. {
  237. break;
  238. }
  239. }
  240. /* Linear interpolieren */
  241. return (long)g_kty_tab[i-1][1] + /* y1 */
  242. (((long)g_kty_tab[i][1] - (long)g_kty_tab[i-1][1]) * /* y2 - y1 */
  243. ((long)widerstand - (long)g_kty_tab[i-1][0]) / /* x - x1 */
  244. ((long)g_kty_tab[i][0] - (long)g_kty_tab[i-1][0])); /* x2 - x1 */
  245. }
  246. static int scale (int in_min, int in_max, int out_min, int out_max, int wert)
  247. {
  248. int abc;
  249. abc = (((long)out_max - (long)out_min) * (long)wert) / ( (long)in_max - (long)in_min);
  250. abc = abc + out_min;
  251. return abc;
  252. }
  253. int CmdGetADC(struct file *pf, LPTIVA_ADC padc)
  254. {
  255. int ret;
  256. int len = 0;
  257. ret = SendCMD(pf, CMD_GET_ADC , 0, NULL);
  258. if(ret == CMD_ACK)
  259. {
  260. unsigned short data[128];
  261. memset(data, 0, sizeof(data));
  262. if((len = ReadCmd(pf, sizeof(data) - 1, ((unsigned char*)data) + 1)) == 13)
  263. {
  264. padc->UVers = scale(0, 4096, 0, 4375, ntohs(data[1])); // val / 100.0 + 0.4
  265. padc->UBatV3 = scale(0, 4096, 0, 500, ntohs(data[2])); // val / 100.0
  266. padc->Temp = lin_kty(ntohs(data[3])); // val / 10.0
  267. padc->UV5Vsys = scale(0, 4096, 0, 570, ntohs(data[4])); // val / 100.0
  268. padc->UV3V6Bat = scale(0, 4096, 0, 500, ntohs(data[5])); // val / 100.0
  269. padc->TempTIVA = ntohs(data[6]); // 147.5 - 187.5 * val / 4096.0
  270. ret = 0;
  271. }
  272. else
  273. {
  274. printk(KERN_ALERT "CmdGetADC - ReadCmd - LEN = %d\n", len);
  275. ret = -1;
  276. }
  277. }
  278. else
  279. {
  280. printk(KERN_ALERT "CmdGetADC - SendCMD - ret = %d\n", ret);
  281. ret = -1;
  282. }
  283. transfer_1(pf, CMD_ACK); /* Testweise immer ACK */
  284. return ret;
  285. }